brintos

brintos / linux-shallow public Read only

0
0
Text · 20.5 KiB · 56d1139 Raw
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