0001
0002
0003
0004
0005
0006
0007
0008 #include "main.h"
0009 #include "usb.h"
0010
0011 #define USB_VERSION "1.0"
0012
0013 static struct mwifiex_if_ops usb_ops;
0014
0015 static const struct usb_device_id mwifiex_usb_table[] = {
0016
0017 {USB_DEVICE(USB8XXX_VID, USB8766_PID_1)},
0018 {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8766_PID_2,
0019 USB_CLASS_VENDOR_SPEC,
0020 USB_SUBCLASS_VENDOR_SPEC, 0xff)},
0021
0022 {USB_DEVICE(USB8XXX_VID, USB8797_PID_1)},
0023 {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8797_PID_2,
0024 USB_CLASS_VENDOR_SPEC,
0025 USB_SUBCLASS_VENDOR_SPEC, 0xff)},
0026
0027 {USB_DEVICE(USB8XXX_VID, USB8801_PID_1)},
0028 {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8801_PID_2,
0029 USB_CLASS_VENDOR_SPEC,
0030 USB_SUBCLASS_VENDOR_SPEC, 0xff)},
0031
0032 {USB_DEVICE(USB8XXX_VID, USB8997_PID_1)},
0033 {USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8997_PID_2,
0034 USB_CLASS_VENDOR_SPEC,
0035 USB_SUBCLASS_VENDOR_SPEC, 0xff)},
0036 { }
0037 };
0038
0039 MODULE_DEVICE_TABLE(usb, mwifiex_usb_table);
0040
0041 static int mwifiex_usb_submit_rx_urb(struct urb_context *ctx, int size);
0042
0043
0044
0045
0046 static int mwifiex_usb_recv(struct mwifiex_adapter *adapter,
0047 struct sk_buff *skb, u8 ep)
0048 {
0049 u32 recv_type;
0050 __le32 tmp;
0051 int ret;
0052
0053 if (adapter->hs_activated)
0054 mwifiex_process_hs_config(adapter);
0055
0056 if (skb->len < INTF_HEADER_LEN) {
0057 mwifiex_dbg(adapter, ERROR,
0058 "%s: invalid skb->len\n", __func__);
0059 return -1;
0060 }
0061
0062 switch (ep) {
0063 case MWIFIEX_USB_EP_CMD_EVENT:
0064 mwifiex_dbg(adapter, EVENT,
0065 "%s: EP_CMD_EVENT\n", __func__);
0066 skb_copy_from_linear_data(skb, &tmp, INTF_HEADER_LEN);
0067 recv_type = le32_to_cpu(tmp);
0068 skb_pull(skb, INTF_HEADER_LEN);
0069
0070 switch (recv_type) {
0071 case MWIFIEX_USB_TYPE_CMD:
0072 if (skb->len > MWIFIEX_SIZE_OF_CMD_BUFFER) {
0073 mwifiex_dbg(adapter, ERROR,
0074 "CMD: skb->len too large\n");
0075 ret = -1;
0076 goto exit_restore_skb;
0077 } else if (!adapter->curr_cmd) {
0078 mwifiex_dbg(adapter, WARN, "CMD: no curr_cmd\n");
0079 if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
0080 mwifiex_process_sleep_confirm_resp(
0081 adapter, skb->data,
0082 skb->len);
0083 ret = 0;
0084 goto exit_restore_skb;
0085 }
0086 ret = -1;
0087 goto exit_restore_skb;
0088 }
0089
0090 adapter->curr_cmd->resp_skb = skb;
0091 adapter->cmd_resp_received = true;
0092 break;
0093 case MWIFIEX_USB_TYPE_EVENT:
0094 if (skb->len < sizeof(u32)) {
0095 mwifiex_dbg(adapter, ERROR,
0096 "EVENT: skb->len too small\n");
0097 ret = -1;
0098 goto exit_restore_skb;
0099 }
0100 skb_copy_from_linear_data(skb, &tmp, sizeof(u32));
0101 adapter->event_cause = le32_to_cpu(tmp);
0102 mwifiex_dbg(adapter, EVENT,
0103 "event_cause %#x\n", adapter->event_cause);
0104
0105 if (skb->len > MAX_EVENT_SIZE) {
0106 mwifiex_dbg(adapter, ERROR,
0107 "EVENT: event body too large\n");
0108 ret = -1;
0109 goto exit_restore_skb;
0110 }
0111
0112 memcpy(adapter->event_body, skb->data +
0113 MWIFIEX_EVENT_HEADER_LEN, skb->len);
0114
0115 adapter->event_received = true;
0116 adapter->event_skb = skb;
0117 break;
0118 default:
0119 mwifiex_dbg(adapter, ERROR,
0120 "unknown recv_type %#x\n", recv_type);
0121 ret = -1;
0122 goto exit_restore_skb;
0123 }
0124 break;
0125 case MWIFIEX_USB_EP_DATA:
0126 mwifiex_dbg(adapter, DATA, "%s: EP_DATA\n", __func__);
0127 if (skb->len > MWIFIEX_RX_DATA_BUF_SIZE) {
0128 mwifiex_dbg(adapter, ERROR,
0129 "DATA: skb->len too large\n");
0130 return -1;
0131 }
0132
0133 skb_queue_tail(&adapter->rx_data_q, skb);
0134 adapter->data_received = true;
0135 atomic_inc(&adapter->rx_pending);
0136 break;
0137 default:
0138 mwifiex_dbg(adapter, ERROR,
0139 "%s: unknown endport %#x\n", __func__, ep);
0140 return -1;
0141 }
0142
0143 return -EINPROGRESS;
0144
0145 exit_restore_skb:
0146
0147 skb_push(skb, INTF_HEADER_LEN);
0148
0149 return ret;
0150 }
0151
0152 static void mwifiex_usb_rx_complete(struct urb *urb)
0153 {
0154 struct urb_context *context = (struct urb_context *)urb->context;
0155 struct mwifiex_adapter *adapter = context->adapter;
0156 struct sk_buff *skb = context->skb;
0157 struct usb_card_rec *card;
0158 int recv_length = urb->actual_length;
0159 int size, status;
0160
0161 if (!adapter || !adapter->card) {
0162 pr_err("mwifiex adapter or card structure is not valid\n");
0163 return;
0164 }
0165
0166 card = (struct usb_card_rec *)adapter->card;
0167 if (card->rx_cmd_ep == context->ep)
0168 atomic_dec(&card->rx_cmd_urb_pending);
0169 else
0170 atomic_dec(&card->rx_data_urb_pending);
0171
0172 if (recv_length) {
0173 if (urb->status ||
0174 test_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags)) {
0175 mwifiex_dbg(adapter, ERROR,
0176 "URB status is failed: %d\n", urb->status);
0177
0178 if (card->rx_cmd_ep != context->ep)
0179 dev_kfree_skb_any(skb);
0180 goto setup_for_next;
0181 }
0182 if (skb->len > recv_length)
0183 skb_trim(skb, recv_length);
0184 else
0185 skb_put(skb, recv_length - skb->len);
0186
0187 status = mwifiex_usb_recv(adapter, skb, context->ep);
0188
0189 mwifiex_dbg(adapter, INFO,
0190 "info: recv_length=%d, status=%d\n",
0191 recv_length, status);
0192 if (status == -EINPROGRESS) {
0193 mwifiex_queue_main_work(adapter);
0194
0195
0196
0197
0198
0199 if (card->rx_cmd_ep == context->ep)
0200 return;
0201 } else {
0202 if (status == -1)
0203 mwifiex_dbg(adapter, ERROR,
0204 "received data processing failed!\n");
0205
0206
0207 if (card->rx_cmd_ep != context->ep)
0208 dev_kfree_skb_any(skb);
0209 }
0210 } else if (urb->status) {
0211 if (!test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) {
0212 mwifiex_dbg(adapter, FATAL,
0213 "Card is removed: %d\n", urb->status);
0214 set_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags);
0215 }
0216 dev_kfree_skb_any(skb);
0217 return;
0218 } else {
0219
0220 if (card->rx_cmd_ep != context->ep)
0221 dev_kfree_skb_any(skb);
0222
0223
0224 }
0225
0226 setup_for_next:
0227 if (card->rx_cmd_ep == context->ep)
0228 size = MWIFIEX_RX_CMD_BUF_SIZE;
0229 else
0230 size = MWIFIEX_RX_DATA_BUF_SIZE;
0231
0232 if (card->rx_cmd_ep == context->ep) {
0233 mwifiex_usb_submit_rx_urb(context, size);
0234 } else {
0235 if (atomic_read(&adapter->rx_pending) <= HIGH_RX_PENDING) {
0236 mwifiex_usb_submit_rx_urb(context, size);
0237 } else {
0238 context->skb = NULL;
0239 }
0240 }
0241
0242 return;
0243 }
0244
0245 static void mwifiex_usb_tx_complete(struct urb *urb)
0246 {
0247 struct urb_context *context = (struct urb_context *)(urb->context);
0248 struct mwifiex_adapter *adapter = context->adapter;
0249 struct usb_card_rec *card = adapter->card;
0250 struct usb_tx_data_port *port;
0251 int i;
0252
0253 mwifiex_dbg(adapter, INFO,
0254 "%s: status: %d\n", __func__, urb->status);
0255
0256 if (context->ep == card->tx_cmd_ep) {
0257 mwifiex_dbg(adapter, CMD,
0258 "%s: CMD\n", __func__);
0259 atomic_dec(&card->tx_cmd_urb_pending);
0260 adapter->cmd_sent = false;
0261 } else {
0262 mwifiex_dbg(adapter, DATA,
0263 "%s: DATA\n", __func__);
0264 mwifiex_write_data_complete(adapter, context->skb, 0,
0265 urb->status ? -1 : 0);
0266 for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
0267 port = &card->port[i];
0268 if (context->ep == port->tx_data_ep) {
0269 atomic_dec(&port->tx_data_urb_pending);
0270 port->block_status = false;
0271 break;
0272 }
0273 }
0274 adapter->data_sent = false;
0275 }
0276
0277 if (card->mc_resync_flag)
0278 mwifiex_multi_chan_resync(adapter);
0279
0280 mwifiex_queue_main_work(adapter);
0281
0282 return;
0283 }
0284
0285 static int mwifiex_usb_submit_rx_urb(struct urb_context *ctx, int size)
0286 {
0287 struct mwifiex_adapter *adapter = ctx->adapter;
0288 struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
0289
0290 if (test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) {
0291 if (card->rx_cmd_ep == ctx->ep) {
0292 mwifiex_dbg(adapter, INFO, "%s: free rx_cmd skb\n",
0293 __func__);
0294 dev_kfree_skb_any(ctx->skb);
0295 ctx->skb = NULL;
0296 }
0297 mwifiex_dbg(adapter, ERROR,
0298 "%s: card removed/suspended, EP %d rx_cmd URB submit skipped\n",
0299 __func__, ctx->ep);
0300 return -1;
0301 }
0302
0303 if (card->rx_cmd_ep != ctx->ep) {
0304 ctx->skb = dev_alloc_skb(size);
0305 if (!ctx->skb) {
0306 mwifiex_dbg(adapter, ERROR,
0307 "%s: dev_alloc_skb failed\n", __func__);
0308 return -ENOMEM;
0309 }
0310 }
0311
0312 if (card->rx_cmd_ep == ctx->ep &&
0313 card->rx_cmd_ep_type == USB_ENDPOINT_XFER_INT)
0314 usb_fill_int_urb(ctx->urb, card->udev,
0315 usb_rcvintpipe(card->udev, ctx->ep),
0316 ctx->skb->data, size, mwifiex_usb_rx_complete,
0317 (void *)ctx, card->rx_cmd_interval);
0318 else
0319 usb_fill_bulk_urb(ctx->urb, card->udev,
0320 usb_rcvbulkpipe(card->udev, ctx->ep),
0321 ctx->skb->data, size, mwifiex_usb_rx_complete,
0322 (void *)ctx);
0323
0324 if (card->rx_cmd_ep == ctx->ep)
0325 atomic_inc(&card->rx_cmd_urb_pending);
0326 else
0327 atomic_inc(&card->rx_data_urb_pending);
0328
0329 if (usb_submit_urb(ctx->urb, GFP_ATOMIC)) {
0330 mwifiex_dbg(adapter, ERROR, "usb_submit_urb failed\n");
0331 dev_kfree_skb_any(ctx->skb);
0332 ctx->skb = NULL;
0333
0334 if (card->rx_cmd_ep == ctx->ep)
0335 atomic_dec(&card->rx_cmd_urb_pending);
0336 else
0337 atomic_dec(&card->rx_data_urb_pending);
0338
0339 return -1;
0340 }
0341
0342 return 0;
0343 }
0344
0345 static void mwifiex_usb_free(struct usb_card_rec *card)
0346 {
0347 struct usb_tx_data_port *port;
0348 int i, j;
0349
0350 if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb)
0351 usb_kill_urb(card->rx_cmd.urb);
0352
0353 usb_free_urb(card->rx_cmd.urb);
0354 card->rx_cmd.urb = NULL;
0355
0356 if (atomic_read(&card->rx_data_urb_pending))
0357 for (i = 0; i < MWIFIEX_RX_DATA_URB; i++)
0358 if (card->rx_data_list[i].urb)
0359 usb_kill_urb(card->rx_data_list[i].urb);
0360
0361 for (i = 0; i < MWIFIEX_RX_DATA_URB; i++) {
0362 usb_free_urb(card->rx_data_list[i].urb);
0363 card->rx_data_list[i].urb = NULL;
0364 }
0365
0366 for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
0367 port = &card->port[i];
0368 for (j = 0; j < MWIFIEX_TX_DATA_URB; j++) {
0369 usb_kill_urb(port->tx_data_list[j].urb);
0370 usb_free_urb(port->tx_data_list[j].urb);
0371 port->tx_data_list[j].urb = NULL;
0372 }
0373 }
0374
0375 usb_free_urb(card->tx_cmd.urb);
0376 card->tx_cmd.urb = NULL;
0377
0378 return;
0379 }
0380
0381
0382
0383
0384
0385 static int mwifiex_usb_probe(struct usb_interface *intf,
0386 const struct usb_device_id *id)
0387 {
0388 struct usb_device *udev = interface_to_usbdev(intf);
0389 struct usb_host_interface *iface_desc = intf->cur_altsetting;
0390 struct usb_endpoint_descriptor *epd;
0391 int ret, i;
0392 struct usb_card_rec *card;
0393 u16 id_vendor, id_product, bcd_device;
0394
0395 card = devm_kzalloc(&intf->dev, sizeof(*card), GFP_KERNEL);
0396 if (!card)
0397 return -ENOMEM;
0398
0399 init_completion(&card->fw_done);
0400
0401 id_vendor = le16_to_cpu(udev->descriptor.idVendor);
0402 id_product = le16_to_cpu(udev->descriptor.idProduct);
0403 bcd_device = le16_to_cpu(udev->descriptor.bcdDevice);
0404 pr_debug("info: VID/PID = %X/%X, Boot2 version = %X\n",
0405 id_vendor, id_product, bcd_device);
0406
0407
0408 switch (id_product) {
0409 case USB8766_PID_1:
0410 case USB8797_PID_1:
0411 case USB8801_PID_1:
0412 case USB8997_PID_1:
0413 card->usb_boot_state = USB8XXX_FW_DNLD;
0414 break;
0415 case USB8766_PID_2:
0416 case USB8797_PID_2:
0417 case USB8801_PID_2:
0418 case USB8997_PID_2:
0419 card->usb_boot_state = USB8XXX_FW_READY;
0420 break;
0421 default:
0422 pr_warn("unknown id_product %#x\n", id_product);
0423 card->usb_boot_state = USB8XXX_FW_DNLD;
0424 break;
0425 }
0426
0427 card->udev = udev;
0428 card->intf = intf;
0429
0430 pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n",
0431 le16_to_cpu(udev->descriptor.bcdUSB),
0432 udev->descriptor.bDeviceClass,
0433 udev->descriptor.bDeviceSubClass,
0434 udev->descriptor.bDeviceProtocol);
0435
0436 for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
0437 epd = &iface_desc->endpoint[i].desc;
0438 if (usb_endpoint_dir_in(epd) &&
0439 usb_endpoint_num(epd) == MWIFIEX_USB_EP_CMD_EVENT &&
0440 (usb_endpoint_xfer_bulk(epd) ||
0441 usb_endpoint_xfer_int(epd))) {
0442 card->rx_cmd_ep_type = usb_endpoint_type(epd);
0443 card->rx_cmd_interval = epd->bInterval;
0444 pr_debug("info: Rx CMD/EVT:: max pkt size: %d, addr: %d, ep_type: %d\n",
0445 le16_to_cpu(epd->wMaxPacketSize),
0446 epd->bEndpointAddress, card->rx_cmd_ep_type);
0447 card->rx_cmd_ep = usb_endpoint_num(epd);
0448 atomic_set(&card->rx_cmd_urb_pending, 0);
0449 }
0450 if (usb_endpoint_dir_in(epd) &&
0451 usb_endpoint_num(epd) == MWIFIEX_USB_EP_DATA &&
0452 usb_endpoint_xfer_bulk(epd)) {
0453 pr_debug("info: bulk IN: max pkt size: %d, addr: %d\n",
0454 le16_to_cpu(epd->wMaxPacketSize),
0455 epd->bEndpointAddress);
0456 card->rx_data_ep = usb_endpoint_num(epd);
0457 atomic_set(&card->rx_data_urb_pending, 0);
0458 }
0459 if (usb_endpoint_dir_out(epd) &&
0460 usb_endpoint_num(epd) == MWIFIEX_USB_EP_DATA &&
0461 usb_endpoint_xfer_bulk(epd)) {
0462 pr_debug("info: bulk OUT: max pkt size: %d, addr: %d\n",
0463 le16_to_cpu(epd->wMaxPacketSize),
0464 epd->bEndpointAddress);
0465 card->port[0].tx_data_ep = usb_endpoint_num(epd);
0466 atomic_set(&card->port[0].tx_data_urb_pending, 0);
0467 }
0468 if (usb_endpoint_dir_out(epd) &&
0469 usb_endpoint_num(epd) == MWIFIEX_USB_EP_DATA_CH2 &&
0470 usb_endpoint_xfer_bulk(epd)) {
0471 pr_debug("info: bulk OUT chan2:\t"
0472 "max pkt size: %d, addr: %d\n",
0473 le16_to_cpu(epd->wMaxPacketSize),
0474 epd->bEndpointAddress);
0475 card->port[1].tx_data_ep = usb_endpoint_num(epd);
0476 atomic_set(&card->port[1].tx_data_urb_pending, 0);
0477 }
0478 if (usb_endpoint_dir_out(epd) &&
0479 usb_endpoint_num(epd) == MWIFIEX_USB_EP_CMD_EVENT &&
0480 (usb_endpoint_xfer_bulk(epd) ||
0481 usb_endpoint_xfer_int(epd))) {
0482 card->tx_cmd_ep_type = usb_endpoint_type(epd);
0483 card->tx_cmd_interval = epd->bInterval;
0484 pr_debug("info: bulk OUT: max pkt size: %d, addr: %d\n",
0485 le16_to_cpu(epd->wMaxPacketSize),
0486 epd->bEndpointAddress);
0487 pr_debug("info: Tx CMD:: max pkt size: %d, addr: %d, ep_type: %d\n",
0488 le16_to_cpu(epd->wMaxPacketSize),
0489 epd->bEndpointAddress, card->tx_cmd_ep_type);
0490 card->tx_cmd_ep = usb_endpoint_num(epd);
0491 atomic_set(&card->tx_cmd_urb_pending, 0);
0492 card->bulk_out_maxpktsize =
0493 le16_to_cpu(epd->wMaxPacketSize);
0494 }
0495 }
0496
0497 switch (card->usb_boot_state) {
0498 case USB8XXX_FW_DNLD:
0499
0500 if (!card->rx_cmd_ep || !card->tx_cmd_ep)
0501 return -ENODEV;
0502 if (card->bulk_out_maxpktsize == 0)
0503 return -ENODEV;
0504 break;
0505 case USB8XXX_FW_READY:
0506
0507 break;
0508 default:
0509 WARN_ON(1);
0510 return -ENODEV;
0511 }
0512
0513 usb_set_intfdata(intf, card);
0514
0515 ret = mwifiex_add_card(card, &card->fw_done, &usb_ops,
0516 MWIFIEX_USB, &card->udev->dev);
0517 if (ret) {
0518 pr_err("%s: mwifiex_add_card failed: %d\n", __func__, ret);
0519 usb_reset_device(udev);
0520 return ret;
0521 }
0522
0523 usb_get_dev(udev);
0524
0525 return 0;
0526 }
0527
0528
0529
0530
0531
0532
0533
0534
0535 static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message)
0536 {
0537 struct usb_card_rec *card = usb_get_intfdata(intf);
0538 struct mwifiex_adapter *adapter;
0539 struct usb_tx_data_port *port;
0540 int i, j;
0541
0542
0543 wait_for_completion(&card->fw_done);
0544
0545 adapter = card->adapter;
0546 if (!adapter) {
0547 dev_err(&intf->dev, "card is not valid\n");
0548 return 0;
0549 }
0550
0551 if (unlikely(test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)))
0552 mwifiex_dbg(adapter, WARN,
0553 "Device already suspended\n");
0554
0555
0556 if (!mwifiex_enable_hs(adapter)) {
0557 mwifiex_dbg(adapter, ERROR,
0558 "cmd: failed to suspend\n");
0559 clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);
0560 return -EFAULT;
0561 }
0562
0563
0564
0565
0566
0567
0568
0569
0570 set_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);
0571 clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);
0572
0573 if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb)
0574 usb_kill_urb(card->rx_cmd.urb);
0575
0576 if (atomic_read(&card->rx_data_urb_pending))
0577 for (i = 0; i < MWIFIEX_RX_DATA_URB; i++)
0578 if (card->rx_data_list[i].urb)
0579 usb_kill_urb(card->rx_data_list[i].urb);
0580
0581 for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
0582 port = &card->port[i];
0583 for (j = 0; j < MWIFIEX_TX_DATA_URB; j++) {
0584 if (port->tx_data_list[j].urb)
0585 usb_kill_urb(port->tx_data_list[j].urb);
0586 }
0587 }
0588
0589 if (card->tx_cmd.urb)
0590 usb_kill_urb(card->tx_cmd.urb);
0591
0592 return 0;
0593 }
0594
0595
0596
0597
0598
0599
0600
0601
0602 static int mwifiex_usb_resume(struct usb_interface *intf)
0603 {
0604 struct usb_card_rec *card = usb_get_intfdata(intf);
0605 struct mwifiex_adapter *adapter;
0606 int i;
0607
0608 if (!card->adapter) {
0609 dev_err(&intf->dev, "%s: card->adapter is NULL\n",
0610 __func__);
0611 return 0;
0612 }
0613 adapter = card->adapter;
0614
0615 if (unlikely(!test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags))) {
0616 mwifiex_dbg(adapter, WARN,
0617 "Device already resumed\n");
0618 return 0;
0619 }
0620
0621
0622
0623
0624 clear_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);
0625
0626 if (!atomic_read(&card->rx_data_urb_pending))
0627 for (i = 0; i < MWIFIEX_RX_DATA_URB; i++)
0628 mwifiex_usb_submit_rx_urb(&card->rx_data_list[i],
0629 MWIFIEX_RX_DATA_BUF_SIZE);
0630
0631 if (!atomic_read(&card->rx_cmd_urb_pending)) {
0632 card->rx_cmd.skb = dev_alloc_skb(MWIFIEX_RX_CMD_BUF_SIZE);
0633 if (card->rx_cmd.skb)
0634 mwifiex_usb_submit_rx_urb(&card->rx_cmd,
0635 MWIFIEX_RX_CMD_BUF_SIZE);
0636 }
0637
0638
0639 if (adapter->hs_activated)
0640 mwifiex_cancel_hs(mwifiex_get_priv(adapter,
0641 MWIFIEX_BSS_ROLE_ANY),
0642 MWIFIEX_ASYNC_CMD);
0643
0644 return 0;
0645 }
0646
0647 static void mwifiex_usb_disconnect(struct usb_interface *intf)
0648 {
0649 struct usb_card_rec *card = usb_get_intfdata(intf);
0650 struct mwifiex_adapter *adapter;
0651
0652 wait_for_completion(&card->fw_done);
0653
0654 adapter = card->adapter;
0655 if (!adapter || !adapter->priv_num)
0656 return;
0657
0658 if (card->udev->state != USB_STATE_NOTATTACHED && !adapter->mfg_mode) {
0659 mwifiex_deauthenticate_all(adapter);
0660
0661 mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,
0662 MWIFIEX_BSS_ROLE_ANY),
0663 MWIFIEX_FUNC_SHUTDOWN);
0664 }
0665
0666 mwifiex_dbg(adapter, FATAL,
0667 "%s: removing card\n", __func__);
0668 mwifiex_remove_card(adapter);
0669
0670 usb_put_dev(interface_to_usbdev(intf));
0671 }
0672
0673 static void mwifiex_usb_coredump(struct device *dev)
0674 {
0675 struct usb_interface *intf = to_usb_interface(dev);
0676 struct usb_card_rec *card = usb_get_intfdata(intf);
0677
0678 mwifiex_fw_dump_event(mwifiex_get_priv(card->adapter,
0679 MWIFIEX_BSS_ROLE_ANY));
0680 }
0681
0682 static struct usb_driver mwifiex_usb_driver = {
0683 .name = "mwifiex_usb",
0684 .probe = mwifiex_usb_probe,
0685 .disconnect = mwifiex_usb_disconnect,
0686 .id_table = mwifiex_usb_table,
0687 .suspend = mwifiex_usb_suspend,
0688 .resume = mwifiex_usb_resume,
0689 .soft_unbind = 1,
0690 .drvwrap.driver = {
0691 .coredump = mwifiex_usb_coredump,
0692 },
0693 };
0694
0695 static int mwifiex_write_data_sync(struct mwifiex_adapter *adapter, u8 *pbuf,
0696 u32 *len, u8 ep, u32 timeout)
0697 {
0698 struct usb_card_rec *card = adapter->card;
0699 int actual_length, ret;
0700
0701 if (!(*len % card->bulk_out_maxpktsize))
0702 (*len)++;
0703
0704
0705 ret = usb_bulk_msg(card->udev, usb_sndbulkpipe(card->udev, ep), pbuf,
0706 *len, &actual_length, timeout);
0707 if (ret) {
0708 mwifiex_dbg(adapter, ERROR,
0709 "usb_bulk_msg for tx failed: %d\n", ret);
0710 return ret;
0711 }
0712
0713 *len = actual_length;
0714
0715 return ret;
0716 }
0717
0718 static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *pbuf,
0719 u32 *len, u8 ep, u32 timeout)
0720 {
0721 struct usb_card_rec *card = adapter->card;
0722 int actual_length, ret;
0723
0724
0725 ret = usb_bulk_msg(card->udev, usb_rcvbulkpipe(card->udev, ep), pbuf,
0726 *len, &actual_length, timeout);
0727 if (ret) {
0728 mwifiex_dbg(adapter, ERROR,
0729 "usb_bulk_msg for rx failed: %d\n", ret);
0730 return ret;
0731 }
0732
0733 *len = actual_length;
0734
0735 return ret;
0736 }
0737
0738 static void mwifiex_usb_port_resync(struct mwifiex_adapter *adapter)
0739 {
0740 struct usb_card_rec *card = adapter->card;
0741 u8 active_port = MWIFIEX_USB_EP_DATA;
0742 struct mwifiex_private *priv = NULL;
0743 int i;
0744
0745 if (adapter->usb_mc_status) {
0746 for (i = 0; i < adapter->priv_num; i++) {
0747 priv = adapter->priv[i];
0748 if (!priv)
0749 continue;
0750 if ((priv->bss_role == MWIFIEX_BSS_ROLE_UAP &&
0751 !priv->bss_started) ||
0752 (priv->bss_role == MWIFIEX_BSS_ROLE_STA &&
0753 !priv->media_connected))
0754 priv->usb_port = MWIFIEX_USB_EP_DATA;
0755 }
0756 for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++)
0757 card->port[i].block_status = false;
0758 } else {
0759 for (i = 0; i < adapter->priv_num; i++) {
0760 priv = adapter->priv[i];
0761 if (!priv)
0762 continue;
0763 if ((priv->bss_role == MWIFIEX_BSS_ROLE_UAP &&
0764 priv->bss_started) ||
0765 (priv->bss_role == MWIFIEX_BSS_ROLE_STA &&
0766 priv->media_connected)) {
0767 active_port = priv->usb_port;
0768 break;
0769 }
0770 }
0771 for (i = 0; i < adapter->priv_num; i++) {
0772 priv = adapter->priv[i];
0773 if (priv)
0774 priv->usb_port = active_port;
0775 }
0776 for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
0777 if (active_port == card->port[i].tx_data_ep)
0778 card->port[i].block_status = false;
0779 else
0780 card->port[i].block_status = true;
0781 }
0782 }
0783 }
0784
0785 static bool mwifiex_usb_is_port_ready(struct mwifiex_private *priv)
0786 {
0787 struct usb_card_rec *card = priv->adapter->card;
0788 int idx;
0789
0790 for (idx = 0; idx < MWIFIEX_TX_DATA_PORT; idx++) {
0791 if (priv->usb_port == card->port[idx].tx_data_ep)
0792 return !card->port[idx].block_status;
0793 }
0794
0795 return false;
0796 }
0797
0798 static inline u8 mwifiex_usb_data_sent(struct mwifiex_adapter *adapter)
0799 {
0800 struct usb_card_rec *card = adapter->card;
0801 int i;
0802
0803 for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++)
0804 if (!card->port[i].block_status)
0805 return false;
0806
0807 return true;
0808 }
0809
0810 static int mwifiex_usb_construct_send_urb(struct mwifiex_adapter *adapter,
0811 struct usb_tx_data_port *port, u8 ep,
0812 struct urb_context *context,
0813 struct sk_buff *skb_send)
0814 {
0815 struct usb_card_rec *card = adapter->card;
0816 int ret = -EINPROGRESS;
0817 struct urb *tx_urb;
0818
0819 context->adapter = adapter;
0820 context->ep = ep;
0821 context->skb = skb_send;
0822 tx_urb = context->urb;
0823
0824 if (ep == card->tx_cmd_ep &&
0825 card->tx_cmd_ep_type == USB_ENDPOINT_XFER_INT)
0826 usb_fill_int_urb(tx_urb, card->udev,
0827 usb_sndintpipe(card->udev, ep), skb_send->data,
0828 skb_send->len, mwifiex_usb_tx_complete,
0829 (void *)context, card->tx_cmd_interval);
0830 else
0831 usb_fill_bulk_urb(tx_urb, card->udev,
0832 usb_sndbulkpipe(card->udev, ep),
0833 skb_send->data, skb_send->len,
0834 mwifiex_usb_tx_complete, (void *)context);
0835
0836 tx_urb->transfer_flags |= URB_ZERO_PACKET;
0837
0838 if (ep == card->tx_cmd_ep)
0839 atomic_inc(&card->tx_cmd_urb_pending);
0840 else
0841 atomic_inc(&port->tx_data_urb_pending);
0842
0843 if (ep != card->tx_cmd_ep &&
0844 atomic_read(&port->tx_data_urb_pending) ==
0845 MWIFIEX_TX_DATA_URB) {
0846 port->block_status = true;
0847 adapter->data_sent = mwifiex_usb_data_sent(adapter);
0848 ret = -ENOSR;
0849 }
0850
0851 if (usb_submit_urb(tx_urb, GFP_ATOMIC)) {
0852 mwifiex_dbg(adapter, ERROR,
0853 "%s: usb_submit_urb failed\n", __func__);
0854 if (ep == card->tx_cmd_ep) {
0855 atomic_dec(&card->tx_cmd_urb_pending);
0856 } else {
0857 atomic_dec(&port->tx_data_urb_pending);
0858 port->block_status = false;
0859 adapter->data_sent = false;
0860 if (port->tx_data_ix)
0861 port->tx_data_ix--;
0862 else
0863 port->tx_data_ix = MWIFIEX_TX_DATA_URB;
0864 }
0865 ret = -1;
0866 }
0867
0868 return ret;
0869 }
0870
0871 static int mwifiex_usb_prepare_tx_aggr_skb(struct mwifiex_adapter *adapter,
0872 struct usb_tx_data_port *port,
0873 struct sk_buff **skb_send)
0874 {
0875 struct sk_buff *skb_aggr, *skb_tmp;
0876 u8 *payload, pad;
0877 u16 align = adapter->bus_aggr.tx_aggr_align;
0878 struct mwifiex_txinfo *tx_info = NULL;
0879 bool is_txinfo_set = false;
0880
0881
0882
0883
0884 if (port->tx_aggr.timer_cnxt.is_hold_timer_set) {
0885 del_timer(&port->tx_aggr.timer_cnxt.hold_timer);
0886 port->tx_aggr.timer_cnxt.is_hold_timer_set = false;
0887 port->tx_aggr.timer_cnxt.hold_tmo_msecs = 0;
0888 }
0889
0890 skb_aggr = mwifiex_alloc_dma_align_buf(port->tx_aggr.aggr_len,
0891 GFP_ATOMIC);
0892 if (!skb_aggr) {
0893 mwifiex_dbg(adapter, ERROR,
0894 "%s: alloc skb_aggr failed\n", __func__);
0895
0896 while ((skb_tmp = skb_dequeue(&port->tx_aggr.aggr_list)))
0897 mwifiex_write_data_complete(adapter, skb_tmp, 0, -1);
0898
0899 port->tx_aggr.aggr_num = 0;
0900 port->tx_aggr.aggr_len = 0;
0901 return -EBUSY;
0902 }
0903
0904 tx_info = MWIFIEX_SKB_TXCB(skb_aggr);
0905 memset(tx_info, 0, sizeof(*tx_info));
0906
0907 while ((skb_tmp = skb_dequeue(&port->tx_aggr.aggr_list))) {
0908
0909 pad = (align - (skb_tmp->len & (align - 1))) % align;
0910 payload = skb_put(skb_aggr, skb_tmp->len + pad);
0911 memcpy(payload, skb_tmp->data, skb_tmp->len);
0912 if (skb_queue_empty(&port->tx_aggr.aggr_list)) {
0913
0914 *(u16 *)payload = cpu_to_le16(skb_tmp->len);
0915 *(u16 *)&payload[2] =
0916 cpu_to_le16(MWIFIEX_TYPE_AGGR_DATA_V2 | 0x80);
0917 skb_trim(skb_aggr, skb_aggr->len - pad);
0918 } else {
0919
0920 *(u16 *)payload = cpu_to_le16(skb_tmp->len + pad);
0921 *(u16 *)&payload[2] =
0922 cpu_to_le16(MWIFIEX_TYPE_AGGR_DATA_V2);
0923 }
0924
0925 if (!is_txinfo_set) {
0926 tx_info->bss_num = MWIFIEX_SKB_TXCB(skb_tmp)->bss_num;
0927 tx_info->bss_type = MWIFIEX_SKB_TXCB(skb_tmp)->bss_type;
0928 is_txinfo_set = true;
0929 }
0930
0931 port->tx_aggr.aggr_num--;
0932 port->tx_aggr.aggr_len -= (skb_tmp->len + pad);
0933 mwifiex_write_data_complete(adapter, skb_tmp, 0, 0);
0934 }
0935
0936 tx_info->pkt_len = skb_aggr->len -
0937 (sizeof(struct txpd) + adapter->intf_hdr_len);
0938 tx_info->flags |= MWIFIEX_BUF_FLAG_AGGR_PKT;
0939
0940 port->tx_aggr.aggr_num = 0;
0941 port->tx_aggr.aggr_len = 0;
0942 *skb_send = skb_aggr;
0943
0944 return 0;
0945 }
0946
0947
0948
0949
0950
0951
0952
0953
0954
0955
0956 static int mwifiex_usb_aggr_tx_data(struct mwifiex_adapter *adapter, u8 ep,
0957 struct sk_buff *skb,
0958 struct mwifiex_tx_param *tx_param,
0959 struct usb_tx_data_port *port)
0960 {
0961 u8 *payload, pad;
0962 u16 align = adapter->bus_aggr.tx_aggr_align;
0963 struct sk_buff *skb_send = NULL;
0964 struct urb_context *context = NULL;
0965 struct txpd *local_tx_pd =
0966 (struct txpd *)((u8 *)skb->data + adapter->intf_hdr_len);
0967 u8 f_send_aggr_buf = 0;
0968 u8 f_send_cur_buf = 0;
0969 u8 f_precopy_cur_buf = 0;
0970 u8 f_postcopy_cur_buf = 0;
0971 u32 timeout;
0972 int ret;
0973
0974
0975 pad = (align - (skb->len & (align - 1))) % align;
0976
0977 if (tx_param && tx_param->next_pkt_len) {
0978
0979 if (port->tx_aggr.aggr_len + skb->len + pad >
0980 adapter->bus_aggr.tx_aggr_max_size) {
0981 f_send_aggr_buf = 1;
0982 f_postcopy_cur_buf = 1;
0983 } else {
0984
0985 f_precopy_cur_buf = 1;
0986
0987 if (port->tx_aggr.aggr_len + skb->len + pad +
0988 tx_param->next_pkt_len >
0989 adapter->bus_aggr.tx_aggr_max_size ||
0990 port->tx_aggr.aggr_num + 2 >
0991 adapter->bus_aggr.tx_aggr_max_num) {
0992
0993
0994
0995 f_send_aggr_buf = 1;
0996 }
0997 }
0998 } else {
0999
1000 if (port->tx_aggr.aggr_num > 0) {
1001
1002 if (port->tx_aggr.aggr_len + skb->len + pad >
1003 adapter->bus_aggr.tx_aggr_max_size) {
1004
1005
1006
1007 f_send_cur_buf = 1;
1008 } else {
1009
1010 f_precopy_cur_buf = 1;
1011 }
1012
1013 f_send_aggr_buf = 1;
1014 } else {
1015
1016
1017
1018 f_send_cur_buf = 1;
1019 }
1020 }
1021
1022 if (local_tx_pd->flags & MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET) {
1023
1024 if (f_precopy_cur_buf) {
1025 if (skb_queue_empty(&port->tx_aggr.aggr_list)) {
1026 f_precopy_cur_buf = 0;
1027 f_send_aggr_buf = 0;
1028 f_send_cur_buf = 1;
1029 } else {
1030 f_send_aggr_buf = 1;
1031 }
1032 } else if (f_postcopy_cur_buf) {
1033 f_send_cur_buf = 1;
1034 f_postcopy_cur_buf = 0;
1035 }
1036 }
1037
1038 if (f_precopy_cur_buf) {
1039 skb_queue_tail(&port->tx_aggr.aggr_list, skb);
1040 port->tx_aggr.aggr_len += (skb->len + pad);
1041 port->tx_aggr.aggr_num++;
1042 if (f_send_aggr_buf)
1043 goto send_aggr_buf;
1044
1045
1046
1047
1048
1049
1050 if (!port->tx_aggr.timer_cnxt.is_hold_timer_set) {
1051 port->tx_aggr.timer_cnxt.hold_tmo_msecs =
1052 MWIFIEX_USB_TX_AGGR_TMO_MIN;
1053 timeout =
1054 port->tx_aggr.timer_cnxt.hold_tmo_msecs;
1055 mod_timer(&port->tx_aggr.timer_cnxt.hold_timer,
1056 jiffies + msecs_to_jiffies(timeout));
1057 port->tx_aggr.timer_cnxt.is_hold_timer_set = true;
1058 } else {
1059 if (port->tx_aggr.timer_cnxt.hold_tmo_msecs <
1060 MWIFIEX_USB_TX_AGGR_TMO_MAX) {
1061
1062 timeout =
1063 ++port->tx_aggr.timer_cnxt.hold_tmo_msecs;
1064 mod_timer(&port->tx_aggr.timer_cnxt.hold_timer,
1065 jiffies + msecs_to_jiffies(timeout));
1066 }
1067 }
1068 }
1069
1070 send_aggr_buf:
1071 if (f_send_aggr_buf) {
1072 ret = mwifiex_usb_prepare_tx_aggr_skb(adapter, port, &skb_send);
1073 if (!ret) {
1074 context = &port->tx_data_list[port->tx_data_ix++];
1075 ret = mwifiex_usb_construct_send_urb(adapter, port, ep,
1076 context, skb_send);
1077 if (ret == -1)
1078 mwifiex_write_data_complete(adapter, skb_send,
1079 0, -1);
1080 }
1081 }
1082
1083 if (f_send_cur_buf) {
1084 if (f_send_aggr_buf) {
1085 if (atomic_read(&port->tx_data_urb_pending) >=
1086 MWIFIEX_TX_DATA_URB) {
1087 port->block_status = true;
1088 adapter->data_sent =
1089 mwifiex_usb_data_sent(adapter);
1090
1091 f_postcopy_cur_buf = 1;
1092 goto postcopy_cur_buf;
1093 }
1094
1095 if (port->tx_data_ix >= MWIFIEX_TX_DATA_URB)
1096 port->tx_data_ix = 0;
1097 }
1098
1099 payload = skb->data;
1100 *(u16 *)&payload[2] =
1101 cpu_to_le16(MWIFIEX_TYPE_AGGR_DATA_V2 | 0x80);
1102 *(u16 *)payload = cpu_to_le16(skb->len);
1103 skb_send = skb;
1104 context = &port->tx_data_list[port->tx_data_ix++];
1105 return mwifiex_usb_construct_send_urb(adapter, port, ep,
1106 context, skb_send);
1107 }
1108
1109 postcopy_cur_buf:
1110 if (f_postcopy_cur_buf) {
1111 skb_queue_tail(&port->tx_aggr.aggr_list, skb);
1112 port->tx_aggr.aggr_len += (skb->len + pad);
1113 port->tx_aggr.aggr_num++;
1114
1115 if (!port->tx_aggr.timer_cnxt.is_hold_timer_set) {
1116 port->tx_aggr.timer_cnxt.hold_tmo_msecs =
1117 MWIFIEX_USB_TX_AGGR_TMO_MIN;
1118 timeout = port->tx_aggr.timer_cnxt.hold_tmo_msecs;
1119 mod_timer(&port->tx_aggr.timer_cnxt.hold_timer,
1120 jiffies + msecs_to_jiffies(timeout));
1121 port->tx_aggr.timer_cnxt.is_hold_timer_set = true;
1122 }
1123 }
1124
1125 return -EINPROGRESS;
1126 }
1127
1128 static void mwifiex_usb_tx_aggr_tmo(struct timer_list *t)
1129 {
1130 struct urb_context *urb_cnxt = NULL;
1131 struct sk_buff *skb_send = NULL;
1132 struct tx_aggr_tmr_cnxt *timer_context =
1133 from_timer(timer_context, t, hold_timer);
1134 struct mwifiex_adapter *adapter = timer_context->adapter;
1135 struct usb_tx_data_port *port = timer_context->port;
1136 int err = 0;
1137
1138 spin_lock_bh(&port->tx_aggr_lock);
1139 err = mwifiex_usb_prepare_tx_aggr_skb(adapter, port, &skb_send);
1140 if (err) {
1141 mwifiex_dbg(adapter, ERROR,
1142 "prepare tx aggr skb failed, err=%d\n", err);
1143 goto unlock;
1144 }
1145
1146 if (atomic_read(&port->tx_data_urb_pending) >=
1147 MWIFIEX_TX_DATA_URB) {
1148 port->block_status = true;
1149 adapter->data_sent =
1150 mwifiex_usb_data_sent(adapter);
1151 err = -1;
1152 goto done;
1153 }
1154
1155 if (port->tx_data_ix >= MWIFIEX_TX_DATA_URB)
1156 port->tx_data_ix = 0;
1157
1158 urb_cnxt = &port->tx_data_list[port->tx_data_ix++];
1159 err = mwifiex_usb_construct_send_urb(adapter, port, port->tx_data_ep,
1160 urb_cnxt, skb_send);
1161 done:
1162 if (err == -1)
1163 mwifiex_write_data_complete(adapter, skb_send, 0, -1);
1164 unlock:
1165 spin_unlock_bh(&port->tx_aggr_lock);
1166 }
1167
1168
1169 static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,
1170 struct sk_buff *skb,
1171 struct mwifiex_tx_param *tx_param)
1172 {
1173 struct usb_card_rec *card = adapter->card;
1174 struct urb_context *context = NULL;
1175 struct usb_tx_data_port *port = NULL;
1176 int idx, ret;
1177
1178 if (test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) {
1179 mwifiex_dbg(adapter, ERROR,
1180 "%s: not allowed while suspended\n", __func__);
1181 return -1;
1182 }
1183
1184 if (test_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags)) {
1185 mwifiex_dbg(adapter, ERROR, "%s: device removed\n", __func__);
1186 return -1;
1187 }
1188
1189 mwifiex_dbg(adapter, INFO, "%s: ep=%d\n", __func__, ep);
1190
1191 if (ep == card->tx_cmd_ep) {
1192 context = &card->tx_cmd;
1193 } else {
1194
1195 for (idx = 0; idx < MWIFIEX_TX_DATA_PORT; idx++) {
1196 if (ep == card->port[idx].tx_data_ep) {
1197 port = &card->port[idx];
1198 if (atomic_read(&port->tx_data_urb_pending)
1199 >= MWIFIEX_TX_DATA_URB) {
1200 port->block_status = true;
1201 adapter->data_sent =
1202 mwifiex_usb_data_sent(adapter);
1203 return -EBUSY;
1204 }
1205 if (port->tx_data_ix >= MWIFIEX_TX_DATA_URB)
1206 port->tx_data_ix = 0;
1207 break;
1208 }
1209 }
1210
1211 if (!port) {
1212 mwifiex_dbg(adapter, ERROR, "Wrong usb tx data port\n");
1213 return -1;
1214 }
1215
1216 if (adapter->bus_aggr.enable) {
1217 spin_lock_bh(&port->tx_aggr_lock);
1218 ret = mwifiex_usb_aggr_tx_data(adapter, ep, skb,
1219 tx_param, port);
1220 spin_unlock_bh(&port->tx_aggr_lock);
1221 return ret;
1222 }
1223
1224 context = &port->tx_data_list[port->tx_data_ix++];
1225 }
1226
1227 return mwifiex_usb_construct_send_urb(adapter, port, ep, context, skb);
1228 }
1229
1230 static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter)
1231 {
1232 struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
1233 struct usb_tx_data_port *port;
1234 int i, j;
1235
1236 card->tx_cmd.adapter = adapter;
1237 card->tx_cmd.ep = card->tx_cmd_ep;
1238
1239 card->tx_cmd.urb = usb_alloc_urb(0, GFP_KERNEL);
1240 if (!card->tx_cmd.urb)
1241 return -ENOMEM;
1242
1243 for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {
1244 port = &card->port[i];
1245 if (!port->tx_data_ep)
1246 continue;
1247 port->tx_data_ix = 0;
1248 skb_queue_head_init(&port->tx_aggr.aggr_list);
1249 if (port->tx_data_ep == MWIFIEX_USB_EP_DATA)
1250 port->block_status = false;
1251 else
1252 port->block_status = true;
1253 for (j = 0; j < MWIFIEX_TX_DATA_URB; j++) {
1254 port->tx_data_list[j].adapter = adapter;
1255 port->tx_data_list[j].ep = port->tx_data_ep;
1256 port->tx_data_list[j].urb =
1257 usb_alloc_urb(0, GFP_KERNEL);
1258 if (!port->tx_data_list[j].urb)
1259 return -ENOMEM;
1260 }
1261
1262 port->tx_aggr.timer_cnxt.adapter = adapter;
1263 port->tx_aggr.timer_cnxt.port = port;
1264 port->tx_aggr.timer_cnxt.is_hold_timer_set = false;
1265 port->tx_aggr.timer_cnxt.hold_tmo_msecs = 0;
1266 timer_setup(&port->tx_aggr.timer_cnxt.hold_timer,
1267 mwifiex_usb_tx_aggr_tmo, 0);
1268 }
1269
1270 return 0;
1271 }
1272
1273 static int mwifiex_usb_rx_init(struct mwifiex_adapter *adapter)
1274 {
1275 struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
1276 int i;
1277
1278 card->rx_cmd.adapter = adapter;
1279 card->rx_cmd.ep = card->rx_cmd_ep;
1280
1281 card->rx_cmd.urb = usb_alloc_urb(0, GFP_KERNEL);
1282 if (!card->rx_cmd.urb)
1283 return -ENOMEM;
1284
1285 card->rx_cmd.skb = dev_alloc_skb(MWIFIEX_RX_CMD_BUF_SIZE);
1286 if (!card->rx_cmd.skb)
1287 return -ENOMEM;
1288
1289 if (mwifiex_usb_submit_rx_urb(&card->rx_cmd, MWIFIEX_RX_CMD_BUF_SIZE))
1290 return -1;
1291
1292 for (i = 0; i < MWIFIEX_RX_DATA_URB; i++) {
1293 card->rx_data_list[i].adapter = adapter;
1294 card->rx_data_list[i].ep = card->rx_data_ep;
1295
1296 card->rx_data_list[i].urb = usb_alloc_urb(0, GFP_KERNEL);
1297 if (!card->rx_data_list[i].urb)
1298 return -1;
1299 if (mwifiex_usb_submit_rx_urb(&card->rx_data_list[i],
1300 MWIFIEX_RX_DATA_BUF_SIZE))
1301 return -1;
1302 }
1303
1304 return 0;
1305 }
1306
1307
1308 static int mwifiex_register_dev(struct mwifiex_adapter *adapter)
1309 {
1310 struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
1311
1312 card->adapter = adapter;
1313
1314 switch (le16_to_cpu(card->udev->descriptor.idProduct)) {
1315 case USB8997_PID_1:
1316 case USB8997_PID_2:
1317 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;
1318 strcpy(adapter->fw_name, USB8997_DEFAULT_FW_NAME);
1319 adapter->ext_scan = true;
1320 break;
1321 case USB8766_PID_1:
1322 case USB8766_PID_2:
1323 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
1324 strcpy(adapter->fw_name, USB8766_DEFAULT_FW_NAME);
1325 adapter->ext_scan = true;
1326 break;
1327 case USB8801_PID_1:
1328 case USB8801_PID_2:
1329 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
1330 strcpy(adapter->fw_name, USB8801_DEFAULT_FW_NAME);
1331 adapter->ext_scan = false;
1332 break;
1333 case USB8797_PID_1:
1334 case USB8797_PID_2:
1335 default:
1336 adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
1337 strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME);
1338 break;
1339 }
1340
1341 adapter->usb_mc_status = false;
1342 adapter->usb_mc_setup = false;
1343
1344 return 0;
1345 }
1346
1347 static void mwifiex_usb_cleanup_tx_aggr(struct mwifiex_adapter *adapter)
1348 {
1349 struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
1350 struct usb_tx_data_port *port;
1351 struct sk_buff *skb_tmp;
1352 int idx;
1353
1354 for (idx = 0; idx < MWIFIEX_TX_DATA_PORT; idx++) {
1355 port = &card->port[idx];
1356 if (adapter->bus_aggr.enable)
1357 while ((skb_tmp =
1358 skb_dequeue(&port->tx_aggr.aggr_list)))
1359 mwifiex_write_data_complete(adapter, skb_tmp,
1360 0, -1);
1361 if (port->tx_aggr.timer_cnxt.hold_timer.function)
1362 del_timer_sync(&port->tx_aggr.timer_cnxt.hold_timer);
1363 port->tx_aggr.timer_cnxt.is_hold_timer_set = false;
1364 port->tx_aggr.timer_cnxt.hold_tmo_msecs = 0;
1365 }
1366 }
1367
1368 static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)
1369 {
1370 struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
1371
1372 mwifiex_usb_free(card);
1373
1374 mwifiex_usb_cleanup_tx_aggr(adapter);
1375
1376 card->adapter = NULL;
1377 }
1378
1379 static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
1380 struct mwifiex_fw_image *fw)
1381 {
1382 int ret = 0;
1383 u8 *firmware = fw->fw_buf, *recv_buff;
1384 u32 retries = USB8XXX_FW_MAX_RETRY + 1;
1385 u32 dlen;
1386 u32 fw_seqnum = 0, tlen = 0, dnld_cmd = 0;
1387 struct fw_data *fwdata;
1388 struct fw_sync_header sync_fw;
1389 u8 check_winner = 1;
1390
1391 if (!firmware) {
1392 mwifiex_dbg(adapter, ERROR,
1393 "No firmware image found! Terminating download\n");
1394 ret = -1;
1395 goto fw_exit;
1396 }
1397
1398
1399 fwdata = kzalloc(FW_DNLD_TX_BUF_SIZE, GFP_KERNEL);
1400 if (!fwdata) {
1401 ret = -ENOMEM;
1402 goto fw_exit;
1403 }
1404
1405
1406 recv_buff = kzalloc(FW_DNLD_RX_BUF_SIZE, GFP_KERNEL);
1407 if (!recv_buff) {
1408 ret = -ENOMEM;
1409 goto cleanup;
1410 }
1411
1412 do {
1413
1414 if (check_winner) {
1415 memset(&fwdata->fw_hdr, 0, sizeof(struct fw_header));
1416 dlen = 0;
1417 } else {
1418
1419 memcpy(&fwdata->fw_hdr, &firmware[tlen],
1420 sizeof(struct fw_header));
1421
1422 dlen = le32_to_cpu(fwdata->fw_hdr.data_len);
1423 dnld_cmd = le32_to_cpu(fwdata->fw_hdr.dnld_cmd);
1424 tlen += sizeof(struct fw_header);
1425
1426
1427 if (dnld_cmd == FW_CMD_7)
1428 dlen = 0;
1429
1430 memcpy(fwdata->data, &firmware[tlen], dlen);
1431
1432 fwdata->seq_num = cpu_to_le32(fw_seqnum);
1433 tlen += dlen;
1434 }
1435
1436
1437 while (--retries) {
1438 u8 *buf = (u8 *)fwdata;
1439 u32 len = FW_DATA_XMIT_SIZE;
1440
1441
1442 ret = mwifiex_write_data_sync(adapter, buf, &len,
1443 MWIFIEX_USB_EP_CMD_EVENT,
1444 MWIFIEX_USB_TIMEOUT);
1445 if (ret) {
1446 mwifiex_dbg(adapter, ERROR,
1447 "write_data_sync: failed: %d\n",
1448 ret);
1449 continue;
1450 }
1451
1452 buf = recv_buff;
1453 len = FW_DNLD_RX_BUF_SIZE;
1454
1455
1456 ret = mwifiex_read_data_sync(adapter, buf, &len,
1457 MWIFIEX_USB_EP_CMD_EVENT,
1458 MWIFIEX_USB_TIMEOUT);
1459 if (ret) {
1460 mwifiex_dbg(adapter, ERROR,
1461 "read_data_sync: failed: %d\n",
1462 ret);
1463 continue;
1464 }
1465
1466 memcpy(&sync_fw, recv_buff,
1467 sizeof(struct fw_sync_header));
1468
1469
1470 if (check_winner) {
1471 if (le32_to_cpu(sync_fw.cmd) & 0x80000000) {
1472 mwifiex_dbg(adapter, WARN,
1473 "USB is not the winner %#x\n",
1474 sync_fw.cmd);
1475
1476
1477 ret = 0;
1478 goto cleanup;
1479 }
1480
1481 mwifiex_dbg(adapter, MSG,
1482 "start to download FW...\n");
1483
1484 check_winner = 0;
1485 break;
1486 }
1487
1488
1489 if (sync_fw.cmd) {
1490 mwifiex_dbg(adapter, ERROR,
1491 "FW received block with CRC %#x\n",
1492 sync_fw.cmd);
1493 ret = -1;
1494 continue;
1495 }
1496
1497 retries = USB8XXX_FW_MAX_RETRY + 1;
1498 break;
1499 }
1500 fw_seqnum++;
1501 } while ((dnld_cmd != FW_HAS_LAST_BLOCK) && retries);
1502
1503 cleanup:
1504 mwifiex_dbg(adapter, MSG,
1505 "info: FW download over, size %d bytes\n", tlen);
1506
1507 kfree(recv_buff);
1508 kfree(fwdata);
1509
1510 if (retries)
1511 ret = 0;
1512 fw_exit:
1513 return ret;
1514 }
1515
1516 static int mwifiex_usb_dnld_fw(struct mwifiex_adapter *adapter,
1517 struct mwifiex_fw_image *fw)
1518 {
1519 int ret;
1520 struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
1521
1522 if (card->usb_boot_state == USB8XXX_FW_DNLD) {
1523 ret = mwifiex_prog_fw_w_helper(adapter, fw);
1524 if (ret)
1525 return -1;
1526
1527
1528 if (card->usb_boot_state == USB8XXX_FW_DNLD)
1529 return -1;
1530 }
1531
1532 ret = mwifiex_usb_rx_init(adapter);
1533 if (!ret)
1534 ret = mwifiex_usb_tx_init(adapter);
1535
1536 return ret;
1537 }
1538
1539 static void mwifiex_submit_rx_urb(struct mwifiex_adapter *adapter, u8 ep)
1540 {
1541 struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
1542
1543 skb_push(card->rx_cmd.skb, INTF_HEADER_LEN);
1544 if ((ep == card->rx_cmd_ep) &&
1545 (!atomic_read(&card->rx_cmd_urb_pending)))
1546 mwifiex_usb_submit_rx_urb(&card->rx_cmd,
1547 MWIFIEX_RX_CMD_BUF_SIZE);
1548
1549 return;
1550 }
1551
1552 static int mwifiex_usb_cmd_event_complete(struct mwifiex_adapter *adapter,
1553 struct sk_buff *skb)
1554 {
1555 mwifiex_submit_rx_urb(adapter, MWIFIEX_USB_EP_CMD_EVENT);
1556
1557 return 0;
1558 }
1559
1560
1561 static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
1562 {
1563
1564 adapter->pm_wakeup_fw_try = false;
1565 del_timer(&adapter->wakeup_timer);
1566 adapter->pm_wakeup_card_req = false;
1567 adapter->ps_state = PS_STATE_AWAKE;
1568
1569 return 0;
1570 }
1571
1572 static void mwifiex_usb_submit_rem_rx_urbs(struct mwifiex_adapter *adapter)
1573 {
1574 struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;
1575 int i;
1576 struct urb_context *ctx;
1577
1578 for (i = 0; i < MWIFIEX_RX_DATA_URB; i++) {
1579 if (card->rx_data_list[i].skb)
1580 continue;
1581 ctx = &card->rx_data_list[i];
1582 mwifiex_usb_submit_rx_urb(ctx, MWIFIEX_RX_DATA_BUF_SIZE);
1583 }
1584 }
1585
1586
1587 static inline int
1588 mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)
1589 {
1590 return 0;
1591 }
1592
1593 static struct mwifiex_if_ops usb_ops = {
1594 .register_dev = mwifiex_register_dev,
1595 .unregister_dev = mwifiex_unregister_dev,
1596 .wakeup = mwifiex_pm_wakeup_card,
1597 .wakeup_complete = mwifiex_pm_wakeup_card_complete,
1598
1599
1600 .dnld_fw = mwifiex_usb_dnld_fw,
1601 .cmdrsp_complete = mwifiex_usb_cmd_event_complete,
1602 .event_complete = mwifiex_usb_cmd_event_complete,
1603 .host_to_card = mwifiex_usb_host_to_card,
1604 .submit_rem_rx_urbs = mwifiex_usb_submit_rem_rx_urbs,
1605 .multi_port_resync = mwifiex_usb_port_resync,
1606 .is_port_ready = mwifiex_usb_is_port_ready,
1607 };
1608
1609 module_usb_driver(mwifiex_usb_driver);
1610
1611 MODULE_AUTHOR("Marvell International Ltd.");
1612 MODULE_DESCRIPTION("Marvell WiFi-Ex USB Driver version" USB_VERSION);
1613 MODULE_VERSION(USB_VERSION);
1614 MODULE_LICENSE("GPL v2");
1615 MODULE_FIRMWARE(USB8766_DEFAULT_FW_NAME);
1616 MODULE_FIRMWARE(USB8797_DEFAULT_FW_NAME);
1617 MODULE_FIRMWARE(USB8801_DEFAULT_FW_NAME);
1618 MODULE_FIRMWARE(USB8997_DEFAULT_FW_NAME);