896 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2021 pureLiFi4 */5 6#include <linux/kernel.h>7#include <linux/init.h>8#include <linux/device.h>9#include <linux/errno.h>10#include <linux/slab.h>11#include <linux/skbuff.h>12#include <linux/usb.h>13#include <linux/workqueue.h>14#include <linux/proc_fs.h>15#include <linux/fs.h>16#include <linux/string.h>17#include <linux/module.h>18#include <net/mac80211.h>19#include <linux/unaligned.h>20#include <linux/sysfs.h>21 22#include "mac.h"23#include "usb.h"24#include "chip.h"25 26static const struct usb_device_id usb_ids[] = {27 { USB_DEVICE(PURELIFI_X_VENDOR_ID_0, PURELIFI_X_PRODUCT_ID_0),28 .driver_info = DEVICE_LIFI_X },29 { USB_DEVICE(PURELIFI_XC_VENDOR_ID_0, PURELIFI_XC_PRODUCT_ID_0),30 .driver_info = DEVICE_LIFI_XC },31 { USB_DEVICE(PURELIFI_XL_VENDOR_ID_0, PURELIFI_XL_PRODUCT_ID_0),32 .driver_info = DEVICE_LIFI_XL },33 {}34};35 36void plfxlc_send_packet_from_data_queue(struct plfxlc_usb *usb)37{38 struct plfxlc_usb_tx *tx = &usb->tx;39 struct sk_buff *skb = NULL;40 unsigned long flags;41 u8 last_served_sidx;42 43 spin_lock_irqsave(&tx->lock, flags);44 last_served_sidx = usb->sidx;45 do {46 usb->sidx = (usb->sidx + 1) % MAX_STA_NUM;47 if (!(tx->station[usb->sidx].flag & STATION_CONNECTED_FLAG))48 continue;49 if (!(tx->station[usb->sidx].flag & STATION_FIFO_FULL_FLAG))50 skb = skb_peek(&tx->station[usb->sidx].data_list);51 } while ((usb->sidx != last_served_sidx) && (!skb));52 53 if (skb) {54 skb = skb_dequeue(&tx->station[usb->sidx].data_list);55 plfxlc_usb_wreq_async(usb, skb->data, skb->len, USB_REQ_DATA_TX,56 plfxlc_tx_urb_complete, skb);57 if (skb_queue_len(&tx->station[usb->sidx].data_list) <= 60)58 ieee80211_wake_queues(plfxlc_usb_to_hw(usb));59 }60 spin_unlock_irqrestore(&tx->lock, flags);61}62 63static void handle_rx_packet(struct plfxlc_usb *usb, const u8 *buffer,64 unsigned int length)65{66 plfxlc_mac_rx(plfxlc_usb_to_hw(usb), buffer, length);67}68 69static void rx_urb_complete(struct urb *urb)70{71 struct plfxlc_usb_tx *tx;72 struct plfxlc_usb *usb;73 unsigned int length;74 const u8 *buffer;75 u16 status;76 u8 sidx;77 int r;78 79 if (!urb) {80 pr_err("urb is NULL\n");81 return;82 }83 if (!urb->context) {84 pr_err("urb ctx is NULL\n");85 return;86 }87 usb = urb->context;88 89 if (usb->initialized != 1) {90 pr_err("usb is not initialized\n");91 return;92 }93 94 tx = &usb->tx;95 switch (urb->status) {96 case 0:97 break;98 case -ESHUTDOWN:99 case -EINVAL:100 case -ENODEV:101 case -ENOENT:102 case -ECONNRESET:103 case -EPIPE:104 dev_dbg(plfxlc_urb_dev(urb), "urb %p error %d\n", urb, urb->status);105 return;106 default:107 dev_dbg(plfxlc_urb_dev(urb), "urb %p error %d\n", urb, urb->status);108 if (tx->submitted_urbs++ < PURELIFI_URB_RETRY_MAX) {109 dev_dbg(plfxlc_urb_dev(urb), "urb %p resubmit %d", urb,110 tx->submitted_urbs++);111 goto resubmit;112 } else {113 dev_dbg(plfxlc_urb_dev(urb), "urb %p max resubmits reached", urb);114 tx->submitted_urbs = 0;115 return;116 }117 }118 119 buffer = urb->transfer_buffer;120 length = le32_to_cpu(*(__le32 *)(buffer + sizeof(struct rx_status)))121 + sizeof(u32);122 123 if (urb->actual_length != (PLF_MSG_STATUS_OFFSET + 1)) {124 if (usb->initialized && usb->link_up)125 handle_rx_packet(usb, buffer, length);126 goto resubmit;127 }128 129 status = buffer[PLF_MSG_STATUS_OFFSET];130 131 switch (status) {132 case STATION_FIFO_ALMOST_FULL_NOT_MESSAGE:133 dev_dbg(&usb->intf->dev,134 "FIFO full not packet receipt\n");135 tx->mac_fifo_full = 1;136 for (sidx = 0; sidx < MAX_STA_NUM; sidx++)137 tx->station[sidx].flag |= STATION_FIFO_FULL_FLAG;138 break;139 case STATION_FIFO_ALMOST_FULL_MESSAGE:140 dev_dbg(&usb->intf->dev, "FIFO full packet receipt\n");141 142 for (sidx = 0; sidx < MAX_STA_NUM; sidx++)143 tx->station[sidx].flag &= STATION_ACTIVE_FLAG;144 145 plfxlc_send_packet_from_data_queue(usb);146 break;147 case STATION_CONNECT_MESSAGE:148 usb->link_up = 1;149 dev_dbg(&usb->intf->dev, "ST_CONNECT_MSG packet receipt\n");150 break;151 case STATION_DISCONNECT_MESSAGE:152 usb->link_up = 0;153 dev_dbg(&usb->intf->dev, "ST_DISCONN_MSG packet receipt\n");154 break;155 default:156 dev_dbg(&usb->intf->dev, "Unknown packet receipt\n");157 break;158 }159 160resubmit:161 r = usb_submit_urb(urb, GFP_ATOMIC);162 if (r)163 dev_dbg(plfxlc_urb_dev(urb), "urb %p resubmit fail (%d)\n", urb, r);164}165 166static struct urb *alloc_rx_urb(struct plfxlc_usb *usb)167{168 struct usb_device *udev = plfxlc_usb_to_usbdev(usb);169 struct urb *urb;170 void *buffer;171 172 urb = usb_alloc_urb(0, GFP_KERNEL);173 if (!urb)174 return NULL;175 176 buffer = usb_alloc_coherent(udev, USB_MAX_RX_SIZE, GFP_KERNEL,177 &urb->transfer_dma);178 if (!buffer) {179 usb_free_urb(urb);180 return NULL;181 }182 183 usb_fill_bulk_urb(urb, udev, usb_rcvbulkpipe(udev, EP_DATA_IN),184 buffer, USB_MAX_RX_SIZE,185 rx_urb_complete, usb);186 urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;187 188 return urb;189}190 191static void free_rx_urb(struct urb *urb)192{193 if (!urb)194 return;195 usb_free_coherent(urb->dev, urb->transfer_buffer_length,196 urb->transfer_buffer, urb->transfer_dma);197 usb_free_urb(urb);198}199 200static int __lf_x_usb_enable_rx(struct plfxlc_usb *usb)201{202 struct plfxlc_usb_rx *rx = &usb->rx;203 struct urb **urbs;204 int i, r;205 206 r = -ENOMEM;207 urbs = kcalloc(RX_URBS_COUNT, sizeof(struct urb *), GFP_KERNEL);208 if (!urbs)209 goto error;210 211 for (i = 0; i < RX_URBS_COUNT; i++) {212 urbs[i] = alloc_rx_urb(usb);213 if (!urbs[i])214 goto error;215 }216 217 spin_lock_irq(&rx->lock);218 219 dev_dbg(plfxlc_usb_dev(usb), "irq_disabled %d\n", irqs_disabled());220 221 if (rx->urbs) {222 spin_unlock_irq(&rx->lock);223 r = 0;224 goto error;225 }226 rx->urbs = urbs;227 rx->urbs_count = RX_URBS_COUNT;228 spin_unlock_irq(&rx->lock);229 230 for (i = 0; i < RX_URBS_COUNT; i++) {231 r = usb_submit_urb(urbs[i], GFP_KERNEL);232 if (r)233 goto error_submit;234 }235 236 return 0;237 238error_submit:239 for (i = 0; i < RX_URBS_COUNT; i++)240 usb_kill_urb(urbs[i]);241 spin_lock_irq(&rx->lock);242 rx->urbs = NULL;243 rx->urbs_count = 0;244 spin_unlock_irq(&rx->lock);245error:246 if (urbs) {247 for (i = 0; i < RX_URBS_COUNT; i++)248 free_rx_urb(urbs[i]);249 }250 kfree(urbs);251 return r;252}253 254int plfxlc_usb_enable_rx(struct plfxlc_usb *usb)255{256 struct plfxlc_usb_rx *rx = &usb->rx;257 int r;258 259 mutex_lock(&rx->setup_mutex);260 r = __lf_x_usb_enable_rx(usb);261 if (!r)262 usb->rx_usb_enabled = 1;263 264 mutex_unlock(&rx->setup_mutex);265 266 return r;267}268 269static void __lf_x_usb_disable_rx(struct plfxlc_usb *usb)270{271 struct plfxlc_usb_rx *rx = &usb->rx;272 unsigned long flags;273 unsigned int count;274 struct urb **urbs;275 int i;276 277 spin_lock_irqsave(&rx->lock, flags);278 urbs = rx->urbs;279 count = rx->urbs_count;280 spin_unlock_irqrestore(&rx->lock, flags);281 282 if (!urbs)283 return;284 285 for (i = 0; i < count; i++) {286 usb_kill_urb(urbs[i]);287 free_rx_urb(urbs[i]);288 }289 kfree(urbs);290 rx->urbs = NULL;291 rx->urbs_count = 0;292}293 294void plfxlc_usb_disable_rx(struct plfxlc_usb *usb)295{296 struct plfxlc_usb_rx *rx = &usb->rx;297 298 mutex_lock(&rx->setup_mutex);299 __lf_x_usb_disable_rx(usb);300 usb->rx_usb_enabled = 0;301 mutex_unlock(&rx->setup_mutex);302}303 304void plfxlc_usb_disable_tx(struct plfxlc_usb *usb)305{306 struct plfxlc_usb_tx *tx = &usb->tx;307 unsigned long flags;308 309 clear_bit(PLF_BIT_ENABLED, &tx->enabled);310 311 /* kill all submitted tx-urbs */312 usb_kill_anchored_urbs(&tx->submitted);313 314 spin_lock_irqsave(&tx->lock, flags);315 WARN_ON(!skb_queue_empty(&tx->submitted_skbs));316 WARN_ON(tx->submitted_urbs != 0);317 tx->submitted_urbs = 0;318 spin_unlock_irqrestore(&tx->lock, flags);319 320 /* The stopped state is ignored, relying on ieee80211_wake_queues()321 * in a potentionally following plfxlc_usb_enable_tx().322 */323}324 325void plfxlc_usb_enable_tx(struct plfxlc_usb *usb)326{327 struct plfxlc_usb_tx *tx = &usb->tx;328 unsigned long flags;329 330 spin_lock_irqsave(&tx->lock, flags);331 set_bit(PLF_BIT_ENABLED, &tx->enabled);332 tx->submitted_urbs = 0;333 ieee80211_wake_queues(plfxlc_usb_to_hw(usb));334 tx->stopped = 0;335 spin_unlock_irqrestore(&tx->lock, flags);336}337 338void plfxlc_tx_urb_complete(struct urb *urb)339{340 struct ieee80211_tx_info *info;341 struct plfxlc_usb *usb;342 struct sk_buff *skb;343 344 skb = urb->context;345 info = IEEE80211_SKB_CB(skb);346 /* grab 'usb' pointer before handing off the skb (since347 * it might be freed by plfxlc_mac_tx_to_dev or mac80211)348 */349 usb = &plfxlc_hw_mac(info->rate_driver_data[0])->chip.usb;350 351 switch (urb->status) {352 case 0:353 break;354 case -ESHUTDOWN:355 case -EINVAL:356 case -ENODEV:357 case -ENOENT:358 case -ECONNRESET:359 case -EPIPE:360 dev_dbg(plfxlc_urb_dev(urb), "urb %p error %d\n", urb, urb->status);361 break;362 default:363 dev_dbg(plfxlc_urb_dev(urb), "urb %p error %d\n", urb, urb->status);364 return;365 }366 367 plfxlc_mac_tx_to_dev(skb, urb->status);368 plfxlc_send_packet_from_data_queue(usb);369 usb_free_urb(urb);370}371 372static inline void init_usb_rx(struct plfxlc_usb *usb)373{374 struct plfxlc_usb_rx *rx = &usb->rx;375 376 spin_lock_init(&rx->lock);377 mutex_init(&rx->setup_mutex);378 379 if (interface_to_usbdev(usb->intf)->speed == USB_SPEED_HIGH)380 rx->usb_packet_size = 512;381 else382 rx->usb_packet_size = 64;383 384 if (rx->fragment_length != 0)385 dev_dbg(plfxlc_usb_dev(usb), "fragment_length error\n");386}387 388static inline void init_usb_tx(struct plfxlc_usb *usb)389{390 struct plfxlc_usb_tx *tx = &usb->tx;391 392 spin_lock_init(&tx->lock);393 clear_bit(PLF_BIT_ENABLED, &tx->enabled);394 tx->stopped = 0;395 skb_queue_head_init(&tx->submitted_skbs);396 init_usb_anchor(&tx->submitted);397}398 399void plfxlc_usb_init(struct plfxlc_usb *usb, struct ieee80211_hw *hw,400 struct usb_interface *intf)401{402 memset(usb, 0, sizeof(*usb));403 usb->intf = usb_get_intf(intf);404 usb_set_intfdata(usb->intf, hw);405 init_usb_tx(usb);406 init_usb_rx(usb);407}408 409void plfxlc_usb_release(struct plfxlc_usb *usb)410{411 plfxlc_op_stop(plfxlc_usb_to_hw(usb), false);412 plfxlc_usb_disable_tx(usb);413 plfxlc_usb_disable_rx(usb);414 usb_set_intfdata(usb->intf, NULL);415 usb_put_intf(usb->intf);416}417 418const char *plfxlc_speed(enum usb_device_speed speed)419{420 switch (speed) {421 case USB_SPEED_LOW:422 return "low";423 case USB_SPEED_FULL:424 return "full";425 case USB_SPEED_HIGH:426 return "high";427 default:428 return "unknown";429 }430}431 432int plfxlc_usb_init_hw(struct plfxlc_usb *usb)433{434 int r;435 436 r = usb_reset_configuration(plfxlc_usb_to_usbdev(usb));437 if (r) {438 dev_err(plfxlc_usb_dev(usb), "cfg reset failed (%d)\n", r);439 return r;440 }441 return 0;442}443 444static void get_usb_req(struct usb_device *udev, void *buffer,445 u32 buffer_len, enum plf_usb_req_enum usb_req_id,446 struct plf_usb_req *usb_req)447{448 __be32 payload_len_nw = cpu_to_be32(buffer_len + FCS_LEN);449 const u8 *buffer_src_p = buffer;450 u8 *buffer_dst = usb_req->buf;451 u32 temp_usb_len = 0;452 453 usb_req->id = cpu_to_be32(usb_req_id);454 usb_req->len = cpu_to_be32(0);455 456 /* Copy buffer length into the transmitted buffer, as it is important457 * for the Rx MAC to know its exact length.458 */459 if (usb_req->id == cpu_to_be32(USB_REQ_BEACON_WR)) {460 memcpy(buffer_dst, &payload_len_nw, sizeof(payload_len_nw));461 buffer_dst += sizeof(payload_len_nw);462 temp_usb_len += sizeof(payload_len_nw);463 }464 465 memcpy(buffer_dst, buffer_src_p, buffer_len);466 buffer_dst += buffer_len;467 buffer_src_p += buffer_len;468 temp_usb_len += buffer_len;469 470 /* Set the FCS_LEN (4) bytes as 0 for CRC checking. */471 memset(buffer_dst, 0, FCS_LEN);472 buffer_dst += FCS_LEN;473 temp_usb_len += FCS_LEN;474 475 /* Round the packet to be transmitted to 4 bytes. */476 if (temp_usb_len % PURELIFI_BYTE_NUM_ALIGNMENT) {477 memset(buffer_dst, 0, PURELIFI_BYTE_NUM_ALIGNMENT -478 (temp_usb_len %479 PURELIFI_BYTE_NUM_ALIGNMENT));480 buffer_dst += PURELIFI_BYTE_NUM_ALIGNMENT -481 (temp_usb_len %482 PURELIFI_BYTE_NUM_ALIGNMENT);483 temp_usb_len += PURELIFI_BYTE_NUM_ALIGNMENT -484 (temp_usb_len % PURELIFI_BYTE_NUM_ALIGNMENT);485 }486 487 usb_req->len = cpu_to_be32(temp_usb_len);488}489 490int plfxlc_usb_wreq_async(struct plfxlc_usb *usb, const u8 *buffer,491 int buffer_len, enum plf_usb_req_enum usb_req_id,492 usb_complete_t complete_fn,493 void *context)494{495 struct usb_device *udev = interface_to_usbdev(usb->ez_usb);496 struct urb *urb;497 int r;498 499 urb = usb_alloc_urb(0, GFP_ATOMIC);500 if (!urb)501 return -ENOMEM;502 usb_fill_bulk_urb(urb, udev, usb_sndbulkpipe(udev, EP_DATA_OUT),503 (void *)buffer, buffer_len, complete_fn, context);504 505 r = usb_submit_urb(urb, GFP_ATOMIC);506 if (r)507 dev_err(&udev->dev, "Async write submit failed (%d)\n", r);508 509 return r;510}511 512int plfxlc_usb_wreq(struct usb_interface *ez_usb, void *buffer, int buffer_len,513 enum plf_usb_req_enum usb_req_id)514{515 struct usb_device *udev = interface_to_usbdev(ez_usb);516 unsigned char *dma_buffer = NULL;517 struct plf_usb_req usb_req;518 int usb_bulk_msg_len;519 int actual_length;520 int r;521 522 get_usb_req(udev, buffer, buffer_len, usb_req_id, &usb_req);523 usb_bulk_msg_len = sizeof(__le32) + sizeof(__le32) +524 be32_to_cpu(usb_req.len);525 526 dma_buffer = kmemdup(&usb_req, usb_bulk_msg_len, GFP_KERNEL);527 528 if (!dma_buffer) {529 r = -ENOMEM;530 goto error;531 }532 533 r = usb_bulk_msg(udev,534 usb_sndbulkpipe(udev, EP_DATA_OUT),535 dma_buffer, usb_bulk_msg_len,536 &actual_length, USB_BULK_MSG_TIMEOUT_MS);537 kfree(dma_buffer);538error:539 if (r) {540 r = -ENOMEM;541 dev_err(&udev->dev, "usb_bulk_msg failed (%d)\n", r);542 }543 544 return r;545}546 547static void slif_data_plane_sap_timer_callb(struct timer_list *t)548{549 struct plfxlc_usb *usb = from_timer(usb, t, tx.tx_retry_timer);550 551 plfxlc_send_packet_from_data_queue(usb);552 timer_setup(&usb->tx.tx_retry_timer,553 slif_data_plane_sap_timer_callb, 0);554 mod_timer(&usb->tx.tx_retry_timer, jiffies + TX_RETRY_BACKOFF_JIFF);555}556 557static void sta_queue_cleanup_timer_callb(struct timer_list *t)558{559 struct plfxlc_usb *usb = from_timer(usb, t, sta_queue_cleanup);560 struct plfxlc_usb_tx *tx = &usb->tx;561 int sidx;562 563 for (sidx = 0; sidx < MAX_STA_NUM - 1; sidx++) {564 if (!(tx->station[sidx].flag & STATION_CONNECTED_FLAG))565 continue;566 if (tx->station[sidx].flag & STATION_HEARTBEAT_FLAG) {567 tx->station[sidx].flag ^= STATION_HEARTBEAT_FLAG;568 } else {569 eth_zero_addr(tx->station[sidx].mac);570 tx->station[sidx].flag = 0;571 }572 }573 timer_setup(&usb->sta_queue_cleanup,574 sta_queue_cleanup_timer_callb, 0);575 mod_timer(&usb->sta_queue_cleanup, jiffies + STA_QUEUE_CLEANUP_JIFF);576}577 578static int probe(struct usb_interface *intf,579 const struct usb_device_id *id)580{581 u8 serial_number[PURELIFI_SERIAL_LEN];582 struct ieee80211_hw *hw = NULL;583 struct plfxlc_usb_tx *tx;584 struct plfxlc_chip *chip;585 struct plfxlc_usb *usb;586 u8 hw_address[ETH_ALEN];587 unsigned int i;588 int r = 0;589 590 hw = plfxlc_mac_alloc_hw(intf);591 592 if (!hw) {593 r = -ENOMEM;594 goto error;595 }596 597 chip = &plfxlc_hw_mac(hw)->chip;598 usb = &chip->usb;599 usb->ez_usb = intf;600 tx = &usb->tx;601 602 r = plfxlc_upload_mac_and_serial(intf, hw_address, serial_number);603 if (r) {604 dev_err(&intf->dev, "MAC and Serial upload failed (%d)\n", r);605 goto error;606 }607 608 chip->unit_type = STA;609 dev_err(&intf->dev, "Unit type is station");610 611 r = plfxlc_mac_preinit_hw(hw, hw_address);612 if (r) {613 dev_err(&intf->dev, "Init mac failed (%d)\n", r);614 goto error;615 }616 617 r = ieee80211_register_hw(hw);618 if (r) {619 dev_err(&intf->dev, "Register device failed (%d)\n", r);620 goto error;621 }622 623 if ((le16_to_cpu(interface_to_usbdev(intf)->descriptor.idVendor) ==624 PURELIFI_XL_VENDOR_ID_0) &&625 (le16_to_cpu(interface_to_usbdev(intf)->descriptor.idProduct) ==626 PURELIFI_XL_PRODUCT_ID_0)) {627 r = plfxlc_download_xl_firmware(intf);628 } else {629 r = plfxlc_download_fpga(intf);630 }631 if (r != 0) {632 dev_err(&intf->dev, "FPGA download failed (%d)\n", r);633 goto error;634 }635 636 tx->mac_fifo_full = 0;637 spin_lock_init(&tx->lock);638 639 msleep(PLF_MSLEEP_TIME);640 r = plfxlc_usb_init_hw(usb);641 if (r < 0) {642 dev_err(&intf->dev, "usb_init_hw failed (%d)\n", r);643 goto error;644 }645 646 msleep(PLF_MSLEEP_TIME);647 r = plfxlc_chip_switch_radio(chip, PLFXLC_RADIO_ON);648 if (r < 0) {649 dev_dbg(&intf->dev, "chip_switch_radio_on failed (%d)\n", r);650 goto error;651 }652 653 msleep(PLF_MSLEEP_TIME);654 r = plfxlc_chip_set_rate(chip, 8);655 if (r < 0) {656 dev_dbg(&intf->dev, "chip_set_rate failed (%d)\n", r);657 goto error;658 }659 660 msleep(PLF_MSLEEP_TIME);661 r = plfxlc_usb_wreq(usb->ez_usb,662 hw_address, ETH_ALEN, USB_REQ_MAC_WR);663 if (r < 0) {664 dev_dbg(&intf->dev, "MAC_WR failure (%d)\n", r);665 goto error;666 }667 668 plfxlc_chip_enable_rxtx(chip);669 670 /* Initialise the data plane Tx queue */671 for (i = 0; i < MAX_STA_NUM; i++) {672 skb_queue_head_init(&tx->station[i].data_list);673 tx->station[i].flag = 0;674 }675 676 tx->station[STA_BROADCAST_INDEX].flag |= STATION_CONNECTED_FLAG;677 for (i = 0; i < ETH_ALEN; i++)678 tx->station[STA_BROADCAST_INDEX].mac[i] = 0xFF;679 680 timer_setup(&tx->tx_retry_timer, slif_data_plane_sap_timer_callb, 0);681 tx->tx_retry_timer.expires = jiffies + TX_RETRY_BACKOFF_JIFF;682 add_timer(&tx->tx_retry_timer);683 684 timer_setup(&usb->sta_queue_cleanup,685 sta_queue_cleanup_timer_callb, 0);686 usb->sta_queue_cleanup.expires = jiffies + STA_QUEUE_CLEANUP_JIFF;687 add_timer(&usb->sta_queue_cleanup);688 689 plfxlc_mac_init_hw(hw);690 usb->initialized = true;691 return 0;692error:693 if (hw) {694 plfxlc_mac_release(plfxlc_hw_mac(hw));695 ieee80211_unregister_hw(hw);696 ieee80211_free_hw(hw);697 }698 dev_err(&intf->dev, "pureLifi:Device error");699 return r;700}701 702static void disconnect(struct usb_interface *intf)703{704 struct ieee80211_hw *hw = plfxlc_intf_to_hw(intf);705 struct plfxlc_mac *mac;706 struct plfxlc_usb *usb;707 708 /* Either something really bad happened, or709 * we're just dealing with a DEVICE_INSTALLER.710 */711 if (!hw)712 return;713 714 mac = plfxlc_hw_mac(hw);715 usb = &mac->chip.usb;716 717 del_timer_sync(&usb->tx.tx_retry_timer);718 del_timer_sync(&usb->sta_queue_cleanup);719 720 ieee80211_unregister_hw(hw);721 722 plfxlc_chip_disable_rxtx(&mac->chip);723 724 /* If the disconnect has been caused by a removal of the725 * driver module, the reset allows reloading of the driver. If the726 * reset will not be executed here, the upload of the firmware in the727 * probe function caused by the reloading of the driver will fail.728 */729 usb_reset_device(interface_to_usbdev(intf));730 731 plfxlc_mac_release(mac);732 ieee80211_free_hw(hw);733}734 735static void plfxlc_usb_resume(struct plfxlc_usb *usb)736{737 struct plfxlc_mac *mac = plfxlc_usb_to_mac(usb);738 int r;739 740 r = plfxlc_op_start(plfxlc_usb_to_hw(usb));741 if (r < 0) {742 dev_warn(plfxlc_usb_dev(usb),743 "Device resume failed (%d)\n", r);744 745 if (usb->was_running)746 set_bit(PURELIFI_DEVICE_RUNNING, &mac->flags);747 748 usb_queue_reset_device(usb->intf);749 return;750 }751 752 if (mac->type != NL80211_IFTYPE_UNSPECIFIED) {753 r = plfxlc_restore_settings(mac);754 if (r < 0) {755 dev_dbg(plfxlc_usb_dev(usb),756 "Restore failed (%d)\n", r);757 return;758 }759 }760}761 762static void plfxlc_usb_stop(struct plfxlc_usb *usb)763{764 plfxlc_op_stop(plfxlc_usb_to_hw(usb), false);765 plfxlc_usb_disable_tx(usb);766 plfxlc_usb_disable_rx(usb);767 768 usb->initialized = false;769}770 771static int pre_reset(struct usb_interface *intf)772{773 struct ieee80211_hw *hw = usb_get_intfdata(intf);774 struct plfxlc_mac *mac;775 struct plfxlc_usb *usb;776 777 if (!hw || intf->condition != USB_INTERFACE_BOUND)778 return 0;779 780 mac = plfxlc_hw_mac(hw);781 usb = &mac->chip.usb;782 783 usb->was_running = test_bit(PURELIFI_DEVICE_RUNNING, &mac->flags);784 785 plfxlc_usb_stop(usb);786 787 return 0;788}789 790static int post_reset(struct usb_interface *intf)791{792 struct ieee80211_hw *hw = usb_get_intfdata(intf);793 struct plfxlc_mac *mac;794 struct plfxlc_usb *usb;795 796 if (!hw || intf->condition != USB_INTERFACE_BOUND)797 return 0;798 799 mac = plfxlc_hw_mac(hw);800 usb = &mac->chip.usb;801 802 if (usb->was_running)803 plfxlc_usb_resume(usb);804 805 return 0;806}807 808#ifdef CONFIG_PM809 810static struct plfxlc_usb *get_plfxlc_usb(struct usb_interface *intf)811{812 struct ieee80211_hw *hw = plfxlc_intf_to_hw(intf);813 struct plfxlc_mac *mac;814 815 /* Either something really bad happened, or816 * we're just dealing with a DEVICE_INSTALLER.817 */818 if (!hw)819 return NULL;820 821 mac = plfxlc_hw_mac(hw);822 return &mac->chip.usb;823}824 825static int suspend(struct usb_interface *interface,826 pm_message_t message)827{828 struct plfxlc_usb *pl = get_plfxlc_usb(interface);829 struct plfxlc_mac *mac = plfxlc_usb_to_mac(pl);830 831 if (!pl)832 return -ENODEV;833 if (pl->initialized == 0)834 return 0;835 pl->was_running = test_bit(PURELIFI_DEVICE_RUNNING, &mac->flags);836 plfxlc_usb_stop(pl);837 return 0;838}839 840static int resume(struct usb_interface *interface)841{842 struct plfxlc_usb *pl = get_plfxlc_usb(interface);843 844 if (!pl)845 return -ENODEV;846 if (pl->was_running)847 plfxlc_usb_resume(pl);848 return 0;849}850 851#endif852 853static struct usb_driver driver = {854 .name = KBUILD_MODNAME,855 .id_table = usb_ids,856 .probe = probe,857 .disconnect = disconnect,858 .pre_reset = pre_reset,859 .post_reset = post_reset,860#ifdef CONFIG_PM861 .suspend = suspend,862 .resume = resume,863#endif864 .disable_hub_initiated_lpm = 1,865};866 867static int __init usb_init(void)868{869 int r;870 871 r = usb_register(&driver);872 if (r) {873 pr_err("%s usb_register() failed %d\n", driver.name, r);874 return r;875 }876 877 pr_debug("Driver initialized :%s\n", driver.name);878 return 0;879}880 881static void __exit usb_exit(void)882{883 usb_deregister(&driver);884 pr_debug("%s %s\n", driver.name, __func__);885}886 887MODULE_LICENSE("GPL");888MODULE_DESCRIPTION("USB driver for pureLiFi devices");889MODULE_AUTHOR("pureLiFi");890MODULE_VERSION("1.0");891MODULE_FIRMWARE("plfxlc/lifi-x.bin");892MODULE_DEVICE_TABLE(usb, usb_ids);893 894module_init(usb_init);895module_exit(usb_exit);896