brintos

brintos / linux-shallow public Read only

0
0
Text · 43.6 KiB · 6085cd5 Raw
1614 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * NXP Wireless LAN device driver: USB specific handling4 *5 * Copyright 2011-2020 NXP6 */7 8#include "main.h"9#include "usb.h"10 11#define USB_VERSION	"1.0"12 13static struct mwifiex_if_ops usb_ops;14 15static const struct usb_device_id mwifiex_usb_table[] = {16	/* 8766 */17	{USB_DEVICE(USB8XXX_VID, USB8766_PID_1)},18	{USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8766_PID_2,19				       USB_CLASS_VENDOR_SPEC,20				       USB_SUBCLASS_VENDOR_SPEC, 0xff)},21	/* 8797 */22	{USB_DEVICE(USB8XXX_VID, USB8797_PID_1)},23	{USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8797_PID_2,24				       USB_CLASS_VENDOR_SPEC,25				       USB_SUBCLASS_VENDOR_SPEC, 0xff)},26	/* 8801 */27	{USB_DEVICE(USB8XXX_VID, USB8801_PID_1)},28	{USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8801_PID_2,29				       USB_CLASS_VENDOR_SPEC,30				       USB_SUBCLASS_VENDOR_SPEC, 0xff)},31	/* 8997 */32	{USB_DEVICE(USB8XXX_VID, USB8997_PID_1)},33	{USB_DEVICE_AND_INTERFACE_INFO(USB8XXX_VID, USB8997_PID_2,34				       USB_CLASS_VENDOR_SPEC,35				       USB_SUBCLASS_VENDOR_SPEC, 0xff)},36	{ }	/* Terminating entry */37};38 39MODULE_DEVICE_TABLE(usb, mwifiex_usb_table);40 41static int mwifiex_usb_submit_rx_urb(struct urb_context *ctx, int size);42 43/* This function handles received packet. Necessary action is taken based on44 * cmd/event/data.45 */46static int mwifiex_usb_recv(struct mwifiex_adapter *adapter,47			    struct sk_buff *skb, u8 ep)48{49	u32 recv_type;50	__le32 tmp;51	int ret;52 53	if (adapter->hs_activated)54		mwifiex_process_hs_config(adapter);55 56	if (skb->len < INTF_HEADER_LEN) {57		mwifiex_dbg(adapter, ERROR,58			    "%s: invalid skb->len\n", __func__);59		return -1;60	}61 62	switch (ep) {63	case MWIFIEX_USB_EP_CMD_EVENT:64		mwifiex_dbg(adapter, EVENT,65			    "%s: EP_CMD_EVENT\n", __func__);66		skb_copy_from_linear_data(skb, &tmp, INTF_HEADER_LEN);67		recv_type = le32_to_cpu(tmp);68		skb_pull(skb, INTF_HEADER_LEN);69 70		switch (recv_type) {71		case MWIFIEX_USB_TYPE_CMD:72			if (skb->len > MWIFIEX_SIZE_OF_CMD_BUFFER) {73				mwifiex_dbg(adapter, ERROR,74					    "CMD: skb->len too large\n");75				ret = -1;76				goto exit_restore_skb;77			} else if (!adapter->curr_cmd) {78				mwifiex_dbg(adapter, WARN, "CMD: no curr_cmd\n");79				if (adapter->ps_state == PS_STATE_SLEEP_CFM) {80					mwifiex_process_sleep_confirm_resp(81							adapter, skb->data,82							skb->len);83					ret = 0;84					goto exit_restore_skb;85				}86				ret = -1;87				goto exit_restore_skb;88			}89 90			adapter->curr_cmd->resp_skb = skb;91			adapter->cmd_resp_received = true;92			break;93		case MWIFIEX_USB_TYPE_EVENT:94			if (skb->len < sizeof(u32)) {95				mwifiex_dbg(adapter, ERROR,96					    "EVENT: skb->len too small\n");97				ret = -1;98				goto exit_restore_skb;99			}100			skb_copy_from_linear_data(skb, &tmp, sizeof(u32));101			adapter->event_cause = le32_to_cpu(tmp);102			mwifiex_dbg(adapter, EVENT,103				    "event_cause %#x\n", adapter->event_cause);104 105			if (skb->len > MAX_EVENT_SIZE) {106				mwifiex_dbg(adapter, ERROR,107					    "EVENT: event body too large\n");108				ret = -1;109				goto exit_restore_skb;110			}111 112			memcpy(adapter->event_body, skb->data +113			       MWIFIEX_EVENT_HEADER_LEN, skb->len);114 115			adapter->event_received = true;116			adapter->event_skb = skb;117			break;118		default:119			mwifiex_dbg(adapter, ERROR,120				    "unknown recv_type %#x\n", recv_type);121			ret = -1;122			goto exit_restore_skb;123		}124		break;125	case MWIFIEX_USB_EP_DATA:126		mwifiex_dbg(adapter, DATA, "%s: EP_DATA\n", __func__);127		if (skb->len > MWIFIEX_RX_DATA_BUF_SIZE) {128			mwifiex_dbg(adapter, ERROR,129				    "DATA: skb->len too large\n");130			return -1;131		}132 133		skb_queue_tail(&adapter->rx_data_q, skb);134		adapter->data_received = true;135		atomic_inc(&adapter->rx_pending);136		break;137	default:138		mwifiex_dbg(adapter, ERROR,139			    "%s: unknown endport %#x\n", __func__, ep);140		return -1;141	}142 143	return -EINPROGRESS;144 145exit_restore_skb:146	/* The buffer will be reused for further cmds/events */147	skb_push(skb, INTF_HEADER_LEN);148 149	return ret;150}151 152static void mwifiex_usb_rx_complete(struct urb *urb)153{154	struct urb_context *context = (struct urb_context *)urb->context;155	struct mwifiex_adapter *adapter = context->adapter;156	struct sk_buff *skb = context->skb;157	struct usb_card_rec *card;158	int recv_length = urb->actual_length;159	int size, status;160 161	if (!adapter || !adapter->card) {162		pr_err("mwifiex adapter or card structure is not valid\n");163		return;164	}165 166	card = (struct usb_card_rec *)adapter->card;167	if (card->rx_cmd_ep == context->ep)168		atomic_dec(&card->rx_cmd_urb_pending);169	else170		atomic_dec(&card->rx_data_urb_pending);171 172	if (recv_length) {173		if (urb->status ||174		    test_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags)) {175			mwifiex_dbg(adapter, ERROR,176				    "URB status is failed: %d\n", urb->status);177			/* Do not free skb in case of command ep */178			if (card->rx_cmd_ep != context->ep)179				dev_kfree_skb_any(skb);180			goto setup_for_next;181		}182		if (skb->len > recv_length)183			skb_trim(skb, recv_length);184		else185			skb_put(skb, recv_length - skb->len);186 187		status = mwifiex_usb_recv(adapter, skb, context->ep);188 189		mwifiex_dbg(adapter, INFO,190			    "info: recv_length=%d, status=%d\n",191			    recv_length, status);192		if (status == -EINPROGRESS) {193			mwifiex_queue_main_work(adapter);194 195			/* urb for data_ep is re-submitted now;196			 * urb for cmd_ep will be re-submitted in callback197			 * mwifiex_usb_recv_complete198			 */199			if (card->rx_cmd_ep == context->ep)200				return;201		} else {202			if (status == -1)203				mwifiex_dbg(adapter, ERROR,204					    "received data processing failed!\n");205 206			/* Do not free skb in case of command ep */207			if (card->rx_cmd_ep != context->ep)208				dev_kfree_skb_any(skb);209		}210	} else if (urb->status) {211		if (!test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) {212			mwifiex_dbg(adapter, FATAL,213				    "Card is removed: %d\n", urb->status);214			set_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags);215		}216		dev_kfree_skb_any(skb);217		return;218	} else {219		/* Do not free skb in case of command ep */220		if (card->rx_cmd_ep != context->ep)221			dev_kfree_skb_any(skb);222 223		/* fall through setup_for_next */224	}225 226setup_for_next:227	if (card->rx_cmd_ep == context->ep)228		size = MWIFIEX_RX_CMD_BUF_SIZE;229	else230		size = MWIFIEX_RX_DATA_BUF_SIZE;231 232	if (card->rx_cmd_ep == context->ep) {233		mwifiex_usb_submit_rx_urb(context, size);234	} else {235		if (atomic_read(&adapter->rx_pending) <= HIGH_RX_PENDING) {236			mwifiex_usb_submit_rx_urb(context, size);237		} else {238			context->skb = NULL;239		}240	}241 242	return;243}244 245static void mwifiex_usb_tx_complete(struct urb *urb)246{247	struct urb_context *context = (struct urb_context *)(urb->context);248	struct mwifiex_adapter *adapter = context->adapter;249	struct usb_card_rec *card = adapter->card;250	struct usb_tx_data_port *port;251	int i;252 253	mwifiex_dbg(adapter, INFO,254		    "%s: status: %d\n", __func__, urb->status);255 256	if (context->ep == card->tx_cmd_ep) {257		mwifiex_dbg(adapter, CMD,258			    "%s: CMD\n", __func__);259		atomic_dec(&card->tx_cmd_urb_pending);260		adapter->cmd_sent = false;261	} else {262		mwifiex_dbg(adapter, DATA,263			    "%s: DATA\n", __func__);264		mwifiex_write_data_complete(adapter, context->skb, 0,265					    urb->status ? -1 : 0);266		for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {267			port = &card->port[i];268			if (context->ep == port->tx_data_ep) {269				atomic_dec(&port->tx_data_urb_pending);270				port->block_status = false;271				break;272			}273		}274		adapter->data_sent = false;275	}276 277	if (card->mc_resync_flag)278		mwifiex_multi_chan_resync(adapter);279 280	mwifiex_queue_main_work(adapter);281 282	return;283}284 285static int mwifiex_usb_submit_rx_urb(struct urb_context *ctx, int size)286{287	struct mwifiex_adapter *adapter = ctx->adapter;288	struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;289 290	if (test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) {291		if (card->rx_cmd_ep == ctx->ep) {292			mwifiex_dbg(adapter, INFO, "%s: free rx_cmd skb\n",293				    __func__);294			dev_kfree_skb_any(ctx->skb);295			ctx->skb = NULL;296		}297		mwifiex_dbg(adapter, ERROR,298			    "%s: card removed/suspended, EP %d rx_cmd URB submit skipped\n",299			    __func__, ctx->ep);300		return -1;301	}302 303	if (card->rx_cmd_ep != ctx->ep) {304		ctx->skb = dev_alloc_skb(size);305		if (!ctx->skb) {306			mwifiex_dbg(adapter, ERROR,307				    "%s: dev_alloc_skb failed\n", __func__);308			return -ENOMEM;309		}310	}311 312	if (card->rx_cmd_ep == ctx->ep &&313	    card->rx_cmd_ep_type == USB_ENDPOINT_XFER_INT)314		usb_fill_int_urb(ctx->urb, card->udev,315				 usb_rcvintpipe(card->udev, ctx->ep),316				 ctx->skb->data, size, mwifiex_usb_rx_complete,317				 (void *)ctx, card->rx_cmd_interval);318	else319		usb_fill_bulk_urb(ctx->urb, card->udev,320				  usb_rcvbulkpipe(card->udev, ctx->ep),321				  ctx->skb->data, size, mwifiex_usb_rx_complete,322				  (void *)ctx);323 324	if (card->rx_cmd_ep == ctx->ep)325		atomic_inc(&card->rx_cmd_urb_pending);326	else327		atomic_inc(&card->rx_data_urb_pending);328 329	if (usb_submit_urb(ctx->urb, GFP_ATOMIC)) {330		mwifiex_dbg(adapter, ERROR, "usb_submit_urb failed\n");331		dev_kfree_skb_any(ctx->skb);332		ctx->skb = NULL;333 334		if (card->rx_cmd_ep == ctx->ep)335			atomic_dec(&card->rx_cmd_urb_pending);336		else337			atomic_dec(&card->rx_data_urb_pending);338 339		return -1;340	}341 342	return 0;343}344 345static void mwifiex_usb_free(struct usb_card_rec *card)346{347	struct usb_tx_data_port *port;348	int i, j;349 350	if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb)351		usb_kill_urb(card->rx_cmd.urb);352 353	usb_free_urb(card->rx_cmd.urb);354	card->rx_cmd.urb = NULL;355 356	if (atomic_read(&card->rx_data_urb_pending))357		for (i = 0; i < MWIFIEX_RX_DATA_URB; i++)358			if (card->rx_data_list[i].urb)359				usb_kill_urb(card->rx_data_list[i].urb);360 361	for (i = 0; i < MWIFIEX_RX_DATA_URB; i++) {362		usb_free_urb(card->rx_data_list[i].urb);363		card->rx_data_list[i].urb = NULL;364	}365 366	for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {367		port = &card->port[i];368		for (j = 0; j < MWIFIEX_TX_DATA_URB; j++) {369			usb_kill_urb(port->tx_data_list[j].urb);370			usb_free_urb(port->tx_data_list[j].urb);371			port->tx_data_list[j].urb = NULL;372		}373	}374 375	usb_free_urb(card->tx_cmd.urb);376	card->tx_cmd.urb = NULL;377 378	return;379}380 381/* This function probes an mwifiex device and registers it. It allocates382 * the card structure, initiates the device registration and initialization383 * procedure by adding a logical interface.384 */385static int mwifiex_usb_probe(struct usb_interface *intf,386			     const struct usb_device_id *id)387{388	struct usb_device *udev = interface_to_usbdev(intf);389	struct usb_host_interface *iface_desc = intf->cur_altsetting;390	struct usb_endpoint_descriptor *epd;391	int ret, i;392	struct usb_card_rec *card;393	u16 id_vendor, id_product, bcd_device;394 395	card = devm_kzalloc(&intf->dev, sizeof(*card), GFP_KERNEL);396	if (!card)397		return -ENOMEM;398 399	init_completion(&card->fw_done);400 401	id_vendor = le16_to_cpu(udev->descriptor.idVendor);402	id_product = le16_to_cpu(udev->descriptor.idProduct);403	bcd_device = le16_to_cpu(udev->descriptor.bcdDevice);404	pr_debug("info: VID/PID = %X/%X, Boot2 version = %X\n",405		 id_vendor, id_product, bcd_device);406 407	/* PID_1 is used for firmware downloading only */408	switch (id_product) {409	case USB8766_PID_1:410	case USB8797_PID_1:411	case USB8801_PID_1:412	case USB8997_PID_1:413		card->usb_boot_state = USB8XXX_FW_DNLD;414		break;415	case USB8766_PID_2:416	case USB8797_PID_2:417	case USB8801_PID_2:418	case USB8997_PID_2:419		card->usb_boot_state = USB8XXX_FW_READY;420		break;421	default:422		pr_warn("unknown id_product %#x\n", id_product);423		card->usb_boot_state = USB8XXX_FW_DNLD;424		break;425	}426 427	card->udev = udev;428	card->intf = intf;429 430	pr_debug("info: bcdUSB=%#x Device Class=%#x SubClass=%#x Protocol=%#x\n",431		 le16_to_cpu(udev->descriptor.bcdUSB),432		 udev->descriptor.bDeviceClass,433		 udev->descriptor.bDeviceSubClass,434		 udev->descriptor.bDeviceProtocol);435 436	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {437		epd = &iface_desc->endpoint[i].desc;438		if (usb_endpoint_dir_in(epd) &&439		    usb_endpoint_num(epd) == MWIFIEX_USB_EP_CMD_EVENT &&440		    (usb_endpoint_xfer_bulk(epd) ||441		     usb_endpoint_xfer_int(epd))) {442			card->rx_cmd_ep_type = usb_endpoint_type(epd);443			card->rx_cmd_interval = epd->bInterval;444			pr_debug("info: Rx CMD/EVT:: max pkt size: %d, addr: %d, ep_type: %d\n",445				 le16_to_cpu(epd->wMaxPacketSize),446				 epd->bEndpointAddress, card->rx_cmd_ep_type);447			card->rx_cmd_ep = usb_endpoint_num(epd);448			atomic_set(&card->rx_cmd_urb_pending, 0);449		}450		if (usb_endpoint_dir_in(epd) &&451		    usb_endpoint_num(epd) == MWIFIEX_USB_EP_DATA &&452		    usb_endpoint_xfer_bulk(epd)) {453			pr_debug("info: bulk IN: max pkt size: %d, addr: %d\n",454				 le16_to_cpu(epd->wMaxPacketSize),455				 epd->bEndpointAddress);456			card->rx_data_ep = usb_endpoint_num(epd);457			atomic_set(&card->rx_data_urb_pending, 0);458		}459		if (usb_endpoint_dir_out(epd) &&460		    usb_endpoint_num(epd) == MWIFIEX_USB_EP_DATA &&461		    usb_endpoint_xfer_bulk(epd)) {462			pr_debug("info: bulk OUT: max pkt size: %d, addr: %d\n",463				 le16_to_cpu(epd->wMaxPacketSize),464				 epd->bEndpointAddress);465			card->port[0].tx_data_ep = usb_endpoint_num(epd);466			atomic_set(&card->port[0].tx_data_urb_pending, 0);467		}468		if (usb_endpoint_dir_out(epd) &&469		    usb_endpoint_num(epd) == MWIFIEX_USB_EP_DATA_CH2 &&470		    usb_endpoint_xfer_bulk(epd)) {471			pr_debug("info: bulk OUT chan2:\t"472				 "max pkt size: %d, addr: %d\n",473				 le16_to_cpu(epd->wMaxPacketSize),474				 epd->bEndpointAddress);475			card->port[1].tx_data_ep = usb_endpoint_num(epd);476			atomic_set(&card->port[1].tx_data_urb_pending, 0);477		}478		if (usb_endpoint_dir_out(epd) &&479		    usb_endpoint_num(epd) == MWIFIEX_USB_EP_CMD_EVENT &&480		    (usb_endpoint_xfer_bulk(epd) ||481		     usb_endpoint_xfer_int(epd))) {482			card->tx_cmd_ep_type = usb_endpoint_type(epd);483			card->tx_cmd_interval = epd->bInterval;484			pr_debug("info: bulk OUT: max pkt size: %d, addr: %d\n",485				 le16_to_cpu(epd->wMaxPacketSize),486				 epd->bEndpointAddress);487			pr_debug("info: Tx CMD:: max pkt size: %d, addr: %d, ep_type: %d\n",488				 le16_to_cpu(epd->wMaxPacketSize),489				 epd->bEndpointAddress, card->tx_cmd_ep_type);490			card->tx_cmd_ep = usb_endpoint_num(epd);491			atomic_set(&card->tx_cmd_urb_pending, 0);492			card->bulk_out_maxpktsize =493					le16_to_cpu(epd->wMaxPacketSize);494		}495	}496 497	switch (card->usb_boot_state) {498	case USB8XXX_FW_DNLD:499		/* Reject broken descriptors. */500		if (!card->rx_cmd_ep || !card->tx_cmd_ep)501			return -ENODEV;502		if (card->bulk_out_maxpktsize == 0)503			return -ENODEV;504		break;505	case USB8XXX_FW_READY:506		/* Assume the driver can handle missing endpoints for now. */507		break;508	default:509		WARN_ON(1);510		return -ENODEV;511	}512 513	usb_set_intfdata(intf, card);514 515	ret = mwifiex_add_card(card, &card->fw_done, &usb_ops,516			       MWIFIEX_USB, &card->udev->dev);517	if (ret) {518		pr_err("%s: mwifiex_add_card failed: %d\n", __func__, ret);519		usb_reset_device(udev);520		return ret;521	}522 523	usb_get_dev(udev);524 525	return 0;526}527 528/* Kernel needs to suspend all functions separately. Therefore all529 * registered functions must have drivers with suspend and resume530 * methods. Failing that the kernel simply removes the whole card.531 *532 * If already not suspended, this function allocates and sends a533 * 'host sleep activate' request to the firmware and turns off the traffic.534 */535static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message)536{537	struct usb_card_rec *card = usb_get_intfdata(intf);538	struct mwifiex_adapter *adapter;539	struct usb_tx_data_port *port;540	int i, j;541 542	/* Might still be loading firmware */543	wait_for_completion(&card->fw_done);544 545	adapter = card->adapter;546	if (!adapter) {547		dev_err(&intf->dev, "card is not valid\n");548		return 0;549	}550 551	if (unlikely(test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)))552		mwifiex_dbg(adapter, WARN,553			    "Device already suspended\n");554 555	/* Enable the Host Sleep */556	if (!mwifiex_enable_hs(adapter)) {557		mwifiex_dbg(adapter, ERROR,558			    "cmd: failed to suspend\n");559		clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);560		return -EFAULT;561	}562 563 564	/* 'MWIFIEX_IS_SUSPENDED' bit indicates device is suspended.565	 * It must be set here before the usb_kill_urb() calls. Reason566	 * is in the complete handlers, urb->status(= -ENOENT) and567	 * this flag is used in combination to distinguish between a568	 * 'suspended' state and a 'disconnect' one.569	 */570	set_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);571	clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);572 573	if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb)574		usb_kill_urb(card->rx_cmd.urb);575 576	if (atomic_read(&card->rx_data_urb_pending))577		for (i = 0; i < MWIFIEX_RX_DATA_URB; i++)578			if (card->rx_data_list[i].urb)579				usb_kill_urb(card->rx_data_list[i].urb);580 581	for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {582		port = &card->port[i];583		for (j = 0; j < MWIFIEX_TX_DATA_URB; j++) {584			if (port->tx_data_list[j].urb)585				usb_kill_urb(port->tx_data_list[j].urb);586		}587	}588 589	if (card->tx_cmd.urb)590		usb_kill_urb(card->tx_cmd.urb);591 592	return 0;593}594 595/* Kernel needs to suspend all functions separately. Therefore all596 * registered functions must have drivers with suspend and resume597 * methods. Failing that the kernel simply removes the whole card.598 *599 * If already not resumed, this function turns on the traffic and600 * sends a 'host sleep cancel' request to the firmware.601 */602static int mwifiex_usb_resume(struct usb_interface *intf)603{604	struct usb_card_rec *card = usb_get_intfdata(intf);605	struct mwifiex_adapter *adapter;606	int i;607 608	if (!card->adapter) {609		dev_err(&intf->dev, "%s: card->adapter is NULL\n",610			__func__);611		return 0;612	}613	adapter = card->adapter;614 615	if (unlikely(!test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags))) {616		mwifiex_dbg(adapter, WARN,617			    "Device already resumed\n");618		return 0;619	}620 621	/* Indicate device resumed. The netdev queue will be resumed only622	 * after the urbs have been re-submitted623	 */624	clear_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);625 626	if (!atomic_read(&card->rx_data_urb_pending))627		for (i = 0; i < MWIFIEX_RX_DATA_URB; i++)628			mwifiex_usb_submit_rx_urb(&card->rx_data_list[i],629						  MWIFIEX_RX_DATA_BUF_SIZE);630 631	if (!atomic_read(&card->rx_cmd_urb_pending)) {632		card->rx_cmd.skb = dev_alloc_skb(MWIFIEX_RX_CMD_BUF_SIZE);633		if (card->rx_cmd.skb)634			mwifiex_usb_submit_rx_urb(&card->rx_cmd,635						  MWIFIEX_RX_CMD_BUF_SIZE);636	}637 638	/* Disable Host Sleep */639	if (adapter->hs_activated)640		mwifiex_cancel_hs(mwifiex_get_priv(adapter,641						   MWIFIEX_BSS_ROLE_ANY),642				  MWIFIEX_ASYNC_CMD);643 644	return 0;645}646 647static void mwifiex_usb_disconnect(struct usb_interface *intf)648{649	struct usb_card_rec *card = usb_get_intfdata(intf);650	struct mwifiex_adapter *adapter;651 652	wait_for_completion(&card->fw_done);653 654	adapter = card->adapter;655	if (!adapter || !adapter->priv_num)656		return;657 658	if (card->udev->state != USB_STATE_NOTATTACHED && !adapter->mfg_mode) {659		mwifiex_deauthenticate_all(adapter);660 661		mwifiex_init_shutdown_fw(mwifiex_get_priv(adapter,662							  MWIFIEX_BSS_ROLE_ANY),663					 MWIFIEX_FUNC_SHUTDOWN);664	}665 666	mwifiex_dbg(adapter, FATAL,667		    "%s: removing card\n", __func__);668	mwifiex_remove_card(adapter);669 670	usb_put_dev(interface_to_usbdev(intf));671}672 673static void mwifiex_usb_coredump(struct device *dev)674{675	struct usb_interface *intf = to_usb_interface(dev);676	struct usb_card_rec *card = usb_get_intfdata(intf);677 678	mwifiex_fw_dump_event(mwifiex_get_priv(card->adapter,679					       MWIFIEX_BSS_ROLE_ANY));680}681 682static struct usb_driver mwifiex_usb_driver = {683	.name = "mwifiex_usb",684	.probe = mwifiex_usb_probe,685	.disconnect = mwifiex_usb_disconnect,686	.id_table = mwifiex_usb_table,687	.suspend = mwifiex_usb_suspend,688	.resume = mwifiex_usb_resume,689	.soft_unbind = 1,690	.driver = {691		.coredump = mwifiex_usb_coredump,692	},693};694 695static int mwifiex_write_data_sync(struct mwifiex_adapter *adapter, u8 *pbuf,696				   u32 *len, u8 ep, u32 timeout)697{698	struct usb_card_rec *card = adapter->card;699	int actual_length, ret;700 701	if (!(*len % card->bulk_out_maxpktsize))702		(*len)++;703 704	/* Send the data block */705	ret = usb_bulk_msg(card->udev, usb_sndbulkpipe(card->udev, ep), pbuf,706			   *len, &actual_length, timeout);707	if (ret) {708		mwifiex_dbg(adapter, ERROR,709			    "usb_bulk_msg for tx failed: %d\n", ret);710		return ret;711	}712 713	*len = actual_length;714 715	return ret;716}717 718static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *pbuf,719				  u32 *len, u8 ep, u32 timeout)720{721	struct usb_card_rec *card = adapter->card;722	int actual_length, ret;723 724	/* Receive the data response */725	ret = usb_bulk_msg(card->udev, usb_rcvbulkpipe(card->udev, ep), pbuf,726			   *len, &actual_length, timeout);727	if (ret) {728		mwifiex_dbg(adapter, ERROR,729			    "usb_bulk_msg for rx failed: %d\n", ret);730		return ret;731	}732 733	*len = actual_length;734 735	return ret;736}737 738static void mwifiex_usb_port_resync(struct mwifiex_adapter *adapter)739{740	struct usb_card_rec *card = adapter->card;741	u8 active_port = MWIFIEX_USB_EP_DATA;742	struct mwifiex_private *priv = NULL;743	int i;744 745	if (adapter->usb_mc_status) {746		for (i = 0; i < adapter->priv_num; i++) {747			priv = adapter->priv[i];748			if ((priv->bss_role == MWIFIEX_BSS_ROLE_UAP &&749			     !priv->bss_started) ||750			    (priv->bss_role == MWIFIEX_BSS_ROLE_STA &&751			     !priv->media_connected))752				priv->usb_port = MWIFIEX_USB_EP_DATA;753		}754		for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++)755			card->port[i].block_status = false;756	} else {757		for (i = 0; i < adapter->priv_num; i++) {758			priv = adapter->priv[i];759			if ((priv->bss_role == MWIFIEX_BSS_ROLE_UAP &&760			     priv->bss_started) ||761			    (priv->bss_role == MWIFIEX_BSS_ROLE_STA &&762			     priv->media_connected)) {763				active_port = priv->usb_port;764				break;765			}766		}767		for (i = 0; i < adapter->priv_num; i++) {768			priv = adapter->priv[i];769			priv->usb_port = active_port;770		}771		for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {772			if (active_port == card->port[i].tx_data_ep)773				card->port[i].block_status = false;774			else775				card->port[i].block_status = true;776		}777	}778}779 780static bool mwifiex_usb_is_port_ready(struct mwifiex_private *priv)781{782	struct usb_card_rec *card = priv->adapter->card;783	int idx;784 785	for (idx = 0; idx < MWIFIEX_TX_DATA_PORT; idx++) {786		if (priv->usb_port == card->port[idx].tx_data_ep)787			return !card->port[idx].block_status;788	}789 790	return false;791}792 793static inline u8 mwifiex_usb_data_sent(struct mwifiex_adapter *adapter)794{795	struct usb_card_rec *card = adapter->card;796	int i;797 798	for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++)799		if (!card->port[i].block_status)800			return false;801 802	return true;803}804 805static int mwifiex_usb_construct_send_urb(struct mwifiex_adapter *adapter,806					  struct usb_tx_data_port *port, u8 ep,807					  struct urb_context *context,808					  struct sk_buff *skb_send)809{810	struct usb_card_rec *card = adapter->card;811	int ret = -EINPROGRESS;812	struct urb *tx_urb;813 814	context->adapter = adapter;815	context->ep = ep;816	context->skb = skb_send;817	tx_urb = context->urb;818 819	if (ep == card->tx_cmd_ep &&820	    card->tx_cmd_ep_type == USB_ENDPOINT_XFER_INT)821		usb_fill_int_urb(tx_urb, card->udev,822				 usb_sndintpipe(card->udev, ep), skb_send->data,823				 skb_send->len, mwifiex_usb_tx_complete,824				 (void *)context, card->tx_cmd_interval);825	else826		usb_fill_bulk_urb(tx_urb, card->udev,827				  usb_sndbulkpipe(card->udev, ep),828				  skb_send->data, skb_send->len,829				  mwifiex_usb_tx_complete, (void *)context);830 831	tx_urb->transfer_flags |= URB_ZERO_PACKET;832 833	if (ep == card->tx_cmd_ep)834		atomic_inc(&card->tx_cmd_urb_pending);835	else836		atomic_inc(&port->tx_data_urb_pending);837 838	if (ep != card->tx_cmd_ep &&839	    atomic_read(&port->tx_data_urb_pending) ==840					MWIFIEX_TX_DATA_URB) {841		port->block_status = true;842		adapter->data_sent = mwifiex_usb_data_sent(adapter);843		ret = -ENOSR;844	}845 846	if (usb_submit_urb(tx_urb, GFP_ATOMIC)) {847		mwifiex_dbg(adapter, ERROR,848			    "%s: usb_submit_urb failed\n", __func__);849		if (ep == card->tx_cmd_ep) {850			atomic_dec(&card->tx_cmd_urb_pending);851		} else {852			atomic_dec(&port->tx_data_urb_pending);853			port->block_status = false;854			adapter->data_sent = false;855			if (port->tx_data_ix)856				port->tx_data_ix--;857			else858				port->tx_data_ix = MWIFIEX_TX_DATA_URB;859		}860		ret = -1;861	}862 863	return ret;864}865 866static int mwifiex_usb_prepare_tx_aggr_skb(struct mwifiex_adapter *adapter,867					   struct usb_tx_data_port *port,868					   struct sk_buff **skb_send)869{870	struct sk_buff *skb_aggr, *skb_tmp;871	u8 *payload, pad;872	u16 align = adapter->bus_aggr.tx_aggr_align;873	struct mwifiex_txinfo *tx_info = NULL;874	bool is_txinfo_set = false;875 876	/* Packets in aggr_list will be send in either skb_aggr or877	 * write complete, delete the tx_aggr timer878	 */879	if (port->tx_aggr.timer_cnxt.is_hold_timer_set) {880		del_timer(&port->tx_aggr.timer_cnxt.hold_timer);881		port->tx_aggr.timer_cnxt.is_hold_timer_set = false;882		port->tx_aggr.timer_cnxt.hold_tmo_msecs = 0;883	}884 885	skb_aggr = mwifiex_alloc_dma_align_buf(port->tx_aggr.aggr_len,886					       GFP_ATOMIC);887	if (!skb_aggr) {888		mwifiex_dbg(adapter, ERROR,889			    "%s: alloc skb_aggr failed\n", __func__);890 891		while ((skb_tmp = skb_dequeue(&port->tx_aggr.aggr_list)))892			mwifiex_write_data_complete(adapter, skb_tmp, 0, -1);893 894		port->tx_aggr.aggr_num = 0;895		port->tx_aggr.aggr_len = 0;896		return -EBUSY;897	}898 899	tx_info = MWIFIEX_SKB_TXCB(skb_aggr);900	memset(tx_info, 0, sizeof(*tx_info));901 902	while ((skb_tmp = skb_dequeue(&port->tx_aggr.aggr_list))) {903		/* padding for aligning next packet header*/904		pad = (align - (skb_tmp->len & (align - 1))) % align;905		payload = skb_put(skb_aggr, skb_tmp->len + pad);906		memcpy(payload, skb_tmp->data, skb_tmp->len);907		if (skb_queue_empty(&port->tx_aggr.aggr_list)) {908			/* do not padding for last packet*/909			*(__le16 *)payload = cpu_to_le16(skb_tmp->len);910			*(__le16 *)&payload[2] =911				cpu_to_le16(MWIFIEX_TYPE_AGGR_DATA_V2 | 0x80);912			skb_trim(skb_aggr, skb_aggr->len - pad);913		} else {914			/* add aggregation interface header */915			*(__le16 *)payload = cpu_to_le16(skb_tmp->len + pad);916			*(__le16 *)&payload[2] =917				cpu_to_le16(MWIFIEX_TYPE_AGGR_DATA_V2);918		}919 920		if (!is_txinfo_set) {921			tx_info->bss_num = MWIFIEX_SKB_TXCB(skb_tmp)->bss_num;922			tx_info->bss_type = MWIFIEX_SKB_TXCB(skb_tmp)->bss_type;923			is_txinfo_set = true;924		}925 926		port->tx_aggr.aggr_num--;927		port->tx_aggr.aggr_len -= (skb_tmp->len + pad);928		mwifiex_write_data_complete(adapter, skb_tmp, 0, 0);929	}930 931	tx_info->pkt_len = skb_aggr->len -932			(sizeof(struct txpd) + adapter->intf_hdr_len);933	tx_info->flags |= MWIFIEX_BUF_FLAG_AGGR_PKT;934 935	port->tx_aggr.aggr_num = 0;936	port->tx_aggr.aggr_len = 0;937	*skb_send = skb_aggr;938 939	return 0;940}941 942/* This function prepare data packet to be send under usb tx aggregation943 * protocol, check current usb aggregation status, link packet to aggrgation944 * list if possible, work flow as below:945 * (1) if only 1 packet available, add usb tx aggregation header and send.946 * (2) if packet is able to aggregated, link it to current aggregation list.947 * (3) if packet is not able to aggregated, aggregate and send exist packets948 *     in aggrgation list. Then, link packet in the list if there is more949 *     packet in transmit queue, otherwise try to transmit single packet.950 */951static int mwifiex_usb_aggr_tx_data(struct mwifiex_adapter *adapter, u8 ep,952				    struct sk_buff *skb,953				    struct mwifiex_tx_param *tx_param,954				    struct usb_tx_data_port *port)955{956	u8 *payload, pad;957	u16 align = adapter->bus_aggr.tx_aggr_align;958	struct sk_buff *skb_send = NULL;959	struct urb_context *context = NULL;960	struct txpd *local_tx_pd =961		(struct txpd *)((u8 *)skb->data + adapter->intf_hdr_len);962	u8 f_send_aggr_buf = 0;963	u8 f_send_cur_buf = 0;964	u8 f_precopy_cur_buf = 0;965	u8 f_postcopy_cur_buf = 0;966	u32 timeout;967	int ret;968 969	/* padding to ensure each packet alginment */970	pad = (align - (skb->len & (align - 1))) % align;971 972	if (tx_param && tx_param->next_pkt_len) {973		/* next packet available in tx queue*/974		if (port->tx_aggr.aggr_len + skb->len + pad >975		    adapter->bus_aggr.tx_aggr_max_size) {976			f_send_aggr_buf = 1;977			f_postcopy_cur_buf = 1;978		} else {979			/* current packet could be aggregated*/980			f_precopy_cur_buf = 1;981 982			if (port->tx_aggr.aggr_len + skb->len + pad +983			    tx_param->next_pkt_len >984			    adapter->bus_aggr.tx_aggr_max_size ||985			    port->tx_aggr.aggr_num + 2 >986			    adapter->bus_aggr.tx_aggr_max_num) {987			    /* next packet could not be aggregated988			     * send current aggregation buffer989			     */990				f_send_aggr_buf = 1;991			}992		}993	} else {994		/* last packet in tx queue */995		if (port->tx_aggr.aggr_num > 0) {996			/* pending packets in aggregation buffer*/997			if (port->tx_aggr.aggr_len + skb->len + pad >998			    adapter->bus_aggr.tx_aggr_max_size) {999				/* current packet not be able to aggregated,1000				 * send aggr buffer first, then send packet.1001				 */1002				f_send_cur_buf = 1;1003			} else {1004				/* last packet, Aggregation and send */1005				f_precopy_cur_buf = 1;1006			}1007 1008			f_send_aggr_buf = 1;1009		} else {1010			/* no pending packets in aggregation buffer,1011			 * send current packet immediately1012			 */1013			 f_send_cur_buf = 1;1014		}1015	}1016 1017	if (local_tx_pd->flags & MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET) {1018		/* Send NULL packet immediately*/1019		if (f_precopy_cur_buf) {1020			if (skb_queue_empty(&port->tx_aggr.aggr_list)) {1021				f_precopy_cur_buf = 0;1022				f_send_aggr_buf = 0;1023				f_send_cur_buf = 1;1024			} else {1025				f_send_aggr_buf = 1;1026			}1027		} else if (f_postcopy_cur_buf) {1028			f_send_cur_buf = 1;1029			f_postcopy_cur_buf = 0;1030		}1031	}1032 1033	if (f_precopy_cur_buf) {1034		skb_queue_tail(&port->tx_aggr.aggr_list, skb);1035		port->tx_aggr.aggr_len += (skb->len + pad);1036		port->tx_aggr.aggr_num++;1037		if (f_send_aggr_buf)1038			goto send_aggr_buf;1039 1040		/* packet will not been send immediately,1041		 * set a timer to make sure it will be sent under1042		 * strict time limit. Dynamically fit the timeout1043		 * value, according to packets number in aggr_list1044		 */1045		if (!port->tx_aggr.timer_cnxt.is_hold_timer_set) {1046			port->tx_aggr.timer_cnxt.hold_tmo_msecs =1047					MWIFIEX_USB_TX_AGGR_TMO_MIN;1048			timeout =1049				port->tx_aggr.timer_cnxt.hold_tmo_msecs;1050			mod_timer(&port->tx_aggr.timer_cnxt.hold_timer,1051				  jiffies + msecs_to_jiffies(timeout));1052			port->tx_aggr.timer_cnxt.is_hold_timer_set = true;1053		} else {1054			if (port->tx_aggr.timer_cnxt.hold_tmo_msecs <1055			    MWIFIEX_USB_TX_AGGR_TMO_MAX) {1056				/* Dyanmic fit timeout */1057				timeout =1058				++port->tx_aggr.timer_cnxt.hold_tmo_msecs;1059				mod_timer(&port->tx_aggr.timer_cnxt.hold_timer,1060					  jiffies + msecs_to_jiffies(timeout));1061			}1062		}1063	}1064 1065send_aggr_buf:1066	if (f_send_aggr_buf) {1067		ret = mwifiex_usb_prepare_tx_aggr_skb(adapter, port, &skb_send);1068		if (!ret) {1069			context = &port->tx_data_list[port->tx_data_ix++];1070			ret = mwifiex_usb_construct_send_urb(adapter, port, ep,1071							     context, skb_send);1072			if (ret == -1)1073				mwifiex_write_data_complete(adapter, skb_send,1074							    0, -1);1075		}1076	}1077 1078	if (f_send_cur_buf) {1079		if (f_send_aggr_buf) {1080			if (atomic_read(&port->tx_data_urb_pending) >=1081			    MWIFIEX_TX_DATA_URB) {1082				port->block_status = true;1083				adapter->data_sent =1084					mwifiex_usb_data_sent(adapter);1085				/* no available urb, postcopy packet*/1086				f_postcopy_cur_buf = 1;1087				goto postcopy_cur_buf;1088			}1089 1090			if (port->tx_data_ix >= MWIFIEX_TX_DATA_URB)1091				port->tx_data_ix = 0;1092		}1093 1094		payload = skb->data;1095		*(__le16 *)&payload[2] =1096			cpu_to_le16(MWIFIEX_TYPE_AGGR_DATA_V2 | 0x80);1097		*(__le16 *)payload = cpu_to_le16(skb->len);1098		skb_send = skb;1099		context = &port->tx_data_list[port->tx_data_ix++];1100		return mwifiex_usb_construct_send_urb(adapter, port, ep,1101						      context, skb_send);1102	}1103 1104postcopy_cur_buf:1105	if (f_postcopy_cur_buf) {1106		skb_queue_tail(&port->tx_aggr.aggr_list, skb);1107		port->tx_aggr.aggr_len += (skb->len + pad);1108		port->tx_aggr.aggr_num++;1109		/* New aggregation begin, start timer */1110		if (!port->tx_aggr.timer_cnxt.is_hold_timer_set) {1111			port->tx_aggr.timer_cnxt.hold_tmo_msecs =1112					MWIFIEX_USB_TX_AGGR_TMO_MIN;1113			timeout = port->tx_aggr.timer_cnxt.hold_tmo_msecs;1114			mod_timer(&port->tx_aggr.timer_cnxt.hold_timer,1115				  jiffies + msecs_to_jiffies(timeout));1116			port->tx_aggr.timer_cnxt.is_hold_timer_set = true;1117		}1118	}1119 1120	return -EINPROGRESS;1121}1122 1123static void mwifiex_usb_tx_aggr_tmo(struct timer_list *t)1124{1125	struct urb_context *urb_cnxt = NULL;1126	struct sk_buff *skb_send = NULL;1127	struct tx_aggr_tmr_cnxt *timer_context =1128		from_timer(timer_context, t, hold_timer);1129	struct mwifiex_adapter *adapter = timer_context->adapter;1130	struct usb_tx_data_port *port = timer_context->port;1131	int err = 0;1132 1133	spin_lock_bh(&port->tx_aggr_lock);1134	err = mwifiex_usb_prepare_tx_aggr_skb(adapter, port, &skb_send);1135	if (err) {1136		mwifiex_dbg(adapter, ERROR,1137			    "prepare tx aggr skb failed, err=%d\n", err);1138		goto unlock;1139	}1140 1141	if (atomic_read(&port->tx_data_urb_pending) >=1142	    MWIFIEX_TX_DATA_URB) {1143		port->block_status = true;1144		adapter->data_sent =1145			mwifiex_usb_data_sent(adapter);1146		err = -1;1147		goto done;1148	}1149 1150	if (port->tx_data_ix >= MWIFIEX_TX_DATA_URB)1151		port->tx_data_ix = 0;1152 1153	urb_cnxt = &port->tx_data_list[port->tx_data_ix++];1154	err = mwifiex_usb_construct_send_urb(adapter, port, port->tx_data_ep,1155					     urb_cnxt, skb_send);1156done:1157	if (err == -1)1158		mwifiex_write_data_complete(adapter, skb_send, 0, -1);1159unlock:1160	spin_unlock_bh(&port->tx_aggr_lock);1161}1162 1163/* This function write a command/data packet to card. */1164static int mwifiex_usb_host_to_card(struct mwifiex_adapter *adapter, u8 ep,1165				    struct sk_buff *skb,1166				    struct mwifiex_tx_param *tx_param)1167{1168	struct usb_card_rec *card = adapter->card;1169	struct urb_context *context = NULL;1170	struct usb_tx_data_port *port = NULL;1171	int idx, ret;1172 1173	if (test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) {1174		mwifiex_dbg(adapter, ERROR,1175			    "%s: not allowed while suspended\n", __func__);1176		return -1;1177	}1178 1179	if (test_bit(MWIFIEX_SURPRISE_REMOVED, &adapter->work_flags)) {1180		mwifiex_dbg(adapter, ERROR, "%s: device removed\n", __func__);1181		return -1;1182	}1183 1184	mwifiex_dbg(adapter, INFO, "%s: ep=%d\n", __func__, ep);1185 1186	if (ep == card->tx_cmd_ep) {1187		context = &card->tx_cmd;1188	} else {1189		/* get the data port structure for endpoint */1190		for (idx = 0; idx < MWIFIEX_TX_DATA_PORT; idx++) {1191			if (ep == card->port[idx].tx_data_ep) {1192				port = &card->port[idx];1193				if (atomic_read(&port->tx_data_urb_pending)1194				    >= MWIFIEX_TX_DATA_URB) {1195					port->block_status = true;1196					adapter->data_sent =1197						mwifiex_usb_data_sent(adapter);1198					return -EBUSY;1199				}1200				if (port->tx_data_ix >= MWIFIEX_TX_DATA_URB)1201					port->tx_data_ix = 0;1202				break;1203			}1204		}1205 1206		if (!port) {1207			mwifiex_dbg(adapter, ERROR, "Wrong usb tx data port\n");1208			return -1;1209		}1210 1211		if (adapter->bus_aggr.enable) {1212			spin_lock_bh(&port->tx_aggr_lock);1213			ret =  mwifiex_usb_aggr_tx_data(adapter, ep, skb,1214							tx_param, port);1215			spin_unlock_bh(&port->tx_aggr_lock);1216			return ret;1217		}1218 1219		context = &port->tx_data_list[port->tx_data_ix++];1220	}1221 1222	return mwifiex_usb_construct_send_urb(adapter, port, ep, context, skb);1223}1224 1225static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter)1226{1227	struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;1228	struct usb_tx_data_port *port;1229	int i, j;1230 1231	card->tx_cmd.adapter = adapter;1232	card->tx_cmd.ep = card->tx_cmd_ep;1233 1234	card->tx_cmd.urb = usb_alloc_urb(0, GFP_KERNEL);1235	if (!card->tx_cmd.urb)1236		return -ENOMEM;1237 1238	for (i = 0; i < MWIFIEX_TX_DATA_PORT; i++) {1239		port = &card->port[i];1240		if (!port->tx_data_ep)1241			continue;1242		port->tx_data_ix = 0;1243		skb_queue_head_init(&port->tx_aggr.aggr_list);1244		if (port->tx_data_ep == MWIFIEX_USB_EP_DATA)1245			port->block_status = false;1246		else1247			port->block_status = true;1248		for (j = 0; j < MWIFIEX_TX_DATA_URB; j++) {1249			port->tx_data_list[j].adapter = adapter;1250			port->tx_data_list[j].ep = port->tx_data_ep;1251			port->tx_data_list[j].urb =1252					usb_alloc_urb(0, GFP_KERNEL);1253			if (!port->tx_data_list[j].urb)1254				return -ENOMEM;1255		}1256 1257		port->tx_aggr.timer_cnxt.adapter = adapter;1258		port->tx_aggr.timer_cnxt.port = port;1259		port->tx_aggr.timer_cnxt.is_hold_timer_set = false;1260		port->tx_aggr.timer_cnxt.hold_tmo_msecs = 0;1261		timer_setup(&port->tx_aggr.timer_cnxt.hold_timer,1262			    mwifiex_usb_tx_aggr_tmo, 0);1263	}1264 1265	return 0;1266}1267 1268static int mwifiex_usb_rx_init(struct mwifiex_adapter *adapter)1269{1270	struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;1271	int i;1272 1273	card->rx_cmd.adapter = adapter;1274	card->rx_cmd.ep = card->rx_cmd_ep;1275 1276	card->rx_cmd.urb = usb_alloc_urb(0, GFP_KERNEL);1277	if (!card->rx_cmd.urb)1278		return -ENOMEM;1279 1280	card->rx_cmd.skb = dev_alloc_skb(MWIFIEX_RX_CMD_BUF_SIZE);1281	if (!card->rx_cmd.skb)1282		return -ENOMEM;1283 1284	if (mwifiex_usb_submit_rx_urb(&card->rx_cmd, MWIFIEX_RX_CMD_BUF_SIZE))1285		return -1;1286 1287	for (i = 0; i < MWIFIEX_RX_DATA_URB; i++) {1288		card->rx_data_list[i].adapter = adapter;1289		card->rx_data_list[i].ep = card->rx_data_ep;1290 1291		card->rx_data_list[i].urb = usb_alloc_urb(0, GFP_KERNEL);1292		if (!card->rx_data_list[i].urb)1293			return -1;1294		if (mwifiex_usb_submit_rx_urb(&card->rx_data_list[i],1295					      MWIFIEX_RX_DATA_BUF_SIZE))1296			return -1;1297	}1298 1299	return 0;1300}1301 1302/* This function register usb device and initialize parameter. */1303static int mwifiex_register_dev(struct mwifiex_adapter *adapter)1304{1305	struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;1306 1307	card->adapter = adapter;1308 1309	switch (le16_to_cpu(card->udev->descriptor.idProduct)) {1310	case USB8997_PID_1:1311	case USB8997_PID_2:1312		adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K;1313		strcpy(adapter->fw_name, USB8997_DEFAULT_FW_NAME);1314		adapter->ext_scan = true;1315		break;1316	case USB8766_PID_1:1317	case USB8766_PID_2:1318		adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;1319		strcpy(adapter->fw_name, USB8766_DEFAULT_FW_NAME);1320		adapter->ext_scan = true;1321		break;1322	case USB8801_PID_1:1323	case USB8801_PID_2:1324		adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;1325		strcpy(adapter->fw_name, USB8801_DEFAULT_FW_NAME);1326		adapter->ext_scan = false;1327		break;1328	case USB8797_PID_1:1329	case USB8797_PID_2:1330	default:1331		adapter->tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;1332		strcpy(adapter->fw_name, USB8797_DEFAULT_FW_NAME);1333		break;1334	}1335 1336	adapter->usb_mc_status = false;1337	adapter->usb_mc_setup = false;1338 1339	return 0;1340}1341 1342static void mwifiex_usb_cleanup_tx_aggr(struct mwifiex_adapter *adapter)1343{1344	struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;1345	struct usb_tx_data_port *port;1346	struct sk_buff *skb_tmp;1347	int idx;1348 1349	for (idx = 0; idx < MWIFIEX_TX_DATA_PORT; idx++) {1350		port = &card->port[idx];1351		if (adapter->bus_aggr.enable)1352			while ((skb_tmp =1353				skb_dequeue(&port->tx_aggr.aggr_list)))1354				mwifiex_write_data_complete(adapter, skb_tmp,1355							    0, -1);1356		if (port->tx_aggr.timer_cnxt.hold_timer.function)1357			del_timer_sync(&port->tx_aggr.timer_cnxt.hold_timer);1358		port->tx_aggr.timer_cnxt.is_hold_timer_set = false;1359		port->tx_aggr.timer_cnxt.hold_tmo_msecs = 0;1360	}1361}1362 1363static void mwifiex_unregister_dev(struct mwifiex_adapter *adapter)1364{1365	struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;1366 1367	mwifiex_usb_free(card);1368 1369	mwifiex_usb_cleanup_tx_aggr(adapter);1370 1371	card->adapter = NULL;1372}1373 1374static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,1375				    struct mwifiex_fw_image *fw)1376{1377	int ret = 0;1378	u8 *firmware = fw->fw_buf, *recv_buff;1379	u32 retries = USB8XXX_FW_MAX_RETRY + 1;1380	u32 dlen;1381	u32 fw_seqnum = 0, tlen = 0, dnld_cmd = 0;1382	struct fw_data *fwdata;1383	struct fw_sync_header sync_fw;1384	u8 check_winner = 1;1385 1386	if (!firmware) {1387		mwifiex_dbg(adapter, ERROR,1388			    "No firmware image found! Terminating download\n");1389		ret = -1;1390		goto fw_exit;1391	}1392 1393	/* Allocate memory for transmit */1394	fwdata = kzalloc(FW_DNLD_TX_BUF_SIZE, GFP_KERNEL);1395	if (!fwdata) {1396		ret = -ENOMEM;1397		goto fw_exit;1398	}1399 1400	/* Allocate memory for receive */1401	recv_buff = kzalloc(FW_DNLD_RX_BUF_SIZE, GFP_KERNEL);1402	if (!recv_buff) {1403		ret = -ENOMEM;1404		goto cleanup;1405	}1406 1407	do {1408		/* Send pseudo data to check winner status first */1409		if (check_winner) {1410			memset(&fwdata->fw_hdr, 0, sizeof(struct fw_header));1411			dlen = 0;1412		} else {1413			/* copy the header of the fw_data to get the length */1414			memcpy(&fwdata->fw_hdr, &firmware[tlen],1415			       sizeof(struct fw_header));1416 1417			dlen = le32_to_cpu(fwdata->fw_hdr.data_len);1418			dnld_cmd = le32_to_cpu(fwdata->fw_hdr.dnld_cmd);1419			tlen += sizeof(struct fw_header);1420 1421			/* Command 7 doesn't have data length field */1422			if (dnld_cmd == FW_CMD_7)1423				dlen = 0;1424 1425			memcpy(fwdata->data, &firmware[tlen], dlen);1426 1427			fwdata->seq_num = cpu_to_le32(fw_seqnum);1428			tlen += dlen;1429		}1430 1431		/* If the send/receive fails or CRC occurs then retry */1432		while (--retries) {1433			u8 *buf = (u8 *)fwdata;1434			u32 len = FW_DATA_XMIT_SIZE;1435 1436			/* send the firmware block */1437			ret = mwifiex_write_data_sync(adapter, buf, &len,1438						MWIFIEX_USB_EP_CMD_EVENT,1439						MWIFIEX_USB_TIMEOUT);1440			if (ret) {1441				mwifiex_dbg(adapter, ERROR,1442					    "write_data_sync: failed: %d\n",1443					    ret);1444				continue;1445			}1446 1447			buf = recv_buff;1448			len = FW_DNLD_RX_BUF_SIZE;1449 1450			/* Receive the firmware block response */1451			ret = mwifiex_read_data_sync(adapter, buf, &len,1452						MWIFIEX_USB_EP_CMD_EVENT,1453						MWIFIEX_USB_TIMEOUT);1454			if (ret) {1455				mwifiex_dbg(adapter, ERROR,1456					    "read_data_sync: failed: %d\n",1457					    ret);1458				continue;1459			}1460 1461			memcpy(&sync_fw, recv_buff,1462			       sizeof(struct fw_sync_header));1463 1464			/* check 1st firmware block resp for highest bit set */1465			if (check_winner) {1466				if (le32_to_cpu(sync_fw.cmd) & 0x80000000) {1467					mwifiex_dbg(adapter, WARN,1468						    "USB is not the winner %#x\n",1469						    sync_fw.cmd);1470 1471					/* returning success */1472					ret = 0;1473					goto cleanup;1474				}1475 1476				mwifiex_dbg(adapter, MSG,1477					    "start to download FW...\n");1478 1479				check_winner = 0;1480				break;1481			}1482 1483			/* check the firmware block response for CRC errors */1484			if (sync_fw.cmd) {1485				mwifiex_dbg(adapter, ERROR,1486					    "FW received block with CRC %#x\n",1487					    sync_fw.cmd);1488				ret = -1;1489				continue;1490			}1491 1492			retries = USB8XXX_FW_MAX_RETRY + 1;1493			break;1494		}1495		fw_seqnum++;1496	} while ((dnld_cmd != FW_HAS_LAST_BLOCK) && retries);1497 1498cleanup:1499	mwifiex_dbg(adapter, MSG,1500		    "info: FW download over, size %d bytes\n", tlen);1501 1502	kfree(recv_buff);1503	kfree(fwdata);1504 1505	if (retries)1506		ret = 0;1507fw_exit:1508	return ret;1509}1510 1511static int mwifiex_usb_dnld_fw(struct mwifiex_adapter *adapter,1512			struct mwifiex_fw_image *fw)1513{1514	int ret;1515	struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;1516 1517	if (card->usb_boot_state == USB8XXX_FW_DNLD) {1518		ret = mwifiex_prog_fw_w_helper(adapter, fw);1519		if (ret)1520			return -1;1521 1522		/* Boot state changes after successful firmware download */1523		if (card->usb_boot_state == USB8XXX_FW_DNLD)1524			return -1;1525	}1526 1527	ret = mwifiex_usb_rx_init(adapter);1528	if (!ret)1529		ret = mwifiex_usb_tx_init(adapter);1530 1531	return ret;1532}1533 1534static void mwifiex_submit_rx_urb(struct mwifiex_adapter *adapter, u8 ep)1535{1536	struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;1537 1538	skb_push(card->rx_cmd.skb, INTF_HEADER_LEN);1539	if ((ep == card->rx_cmd_ep) &&1540	    (!atomic_read(&card->rx_cmd_urb_pending)))1541		mwifiex_usb_submit_rx_urb(&card->rx_cmd,1542					  MWIFIEX_RX_CMD_BUF_SIZE);1543 1544	return;1545}1546 1547static int mwifiex_usb_cmd_event_complete(struct mwifiex_adapter *adapter,1548				       struct sk_buff *skb)1549{1550	mwifiex_submit_rx_urb(adapter, MWIFIEX_USB_EP_CMD_EVENT);1551 1552	return 0;1553}1554 1555/* This function wakes up the card. */1556static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)1557{1558	/* Simulation of HS_AWAKE event */1559	adapter->pm_wakeup_fw_try = false;1560	del_timer(&adapter->wakeup_timer);1561	adapter->pm_wakeup_card_req = false;1562	adapter->ps_state = PS_STATE_AWAKE;1563 1564	return 0;1565}1566 1567static void mwifiex_usb_submit_rem_rx_urbs(struct mwifiex_adapter *adapter)1568{1569	struct usb_card_rec *card = (struct usb_card_rec *)adapter->card;1570	int i;1571	struct urb_context *ctx;1572 1573	for (i = 0; i < MWIFIEX_RX_DATA_URB; i++) {1574		if (card->rx_data_list[i].skb)1575			continue;1576		ctx = &card->rx_data_list[i];1577		mwifiex_usb_submit_rx_urb(ctx, MWIFIEX_RX_DATA_BUF_SIZE);1578	}1579}1580 1581/* This function is called after the card has woken up. */1582static inline int1583mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)1584{1585	return 0;1586}1587 1588static struct mwifiex_if_ops usb_ops = {1589	.register_dev =		mwifiex_register_dev,1590	.unregister_dev =	mwifiex_unregister_dev,1591	.wakeup =		mwifiex_pm_wakeup_card,1592	.wakeup_complete =	mwifiex_pm_wakeup_card_complete,1593 1594	/* USB specific */1595	.dnld_fw =		mwifiex_usb_dnld_fw,1596	.cmdrsp_complete =	mwifiex_usb_cmd_event_complete,1597	.event_complete =	mwifiex_usb_cmd_event_complete,1598	.host_to_card =		mwifiex_usb_host_to_card,1599	.submit_rem_rx_urbs =	mwifiex_usb_submit_rem_rx_urbs,1600	.multi_port_resync =	mwifiex_usb_port_resync,1601	.is_port_ready =	mwifiex_usb_is_port_ready,1602};1603 1604module_usb_driver(mwifiex_usb_driver);1605 1606MODULE_AUTHOR("Marvell International Ltd.");1607MODULE_DESCRIPTION("Marvell WiFi-Ex USB Driver version" USB_VERSION);1608MODULE_VERSION(USB_VERSION);1609MODULE_LICENSE("GPL v2");1610MODULE_FIRMWARE(USB8766_DEFAULT_FW_NAME);1611MODULE_FIRMWARE(USB8797_DEFAULT_FW_NAME);1612MODULE_FIRMWARE(USB8801_DEFAULT_FW_NAME);1613MODULE_FIRMWARE(USB8997_DEFAULT_FW_NAME);1614