xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/nxp/mlinux/moal_usb.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /** @file moal_usb.c
2  *
3  * @brief This file contains the interfaceing to USB bus
4  * driver.
5  *
6  *
7  * Copyright 2008-2021 NXP
8  *
9  * This software file (the File) is distributed by NXP
10  * under the terms of the GNU General Public License Version 2, June 1991
11  * (the License).  You may use, redistribute and/or modify the File in
12  * accordance with the terms and conditions of the License, a copy of which
13  * is available by writing to the Free Software Foundation, Inc.,
14  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
15  * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
16  *
17  * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
19  * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
20  * this warranty disclaimer.
21  *
22  */
23 
24 /********************************************************
25 Change log:
26     10/21/2008: initial version
27 ********************************************************/
28 
29 #include "moal_main.h"
30 #include "moal_usb.h"
31 extern struct semaphore AddRemoveCardSem;
32 
33 /********************************************************
34 		Local Variables
35 ********************************************************/
36 
37 #if defined(USB8997) || defined(USB9098) || defined(USB9097) ||                \
38 	defined(USB8978) || defined(USBNW62X)
39 /** Card-type detection frame response */
40 typedef struct {
41 	/** 32-bit ACK+WINNER field */
42 	t_u32 ack_winner;
43 	/** 32-bit Sequence number */
44 	t_u32 seq;
45 	/** 32-bit extend */
46 	t_u32 extend;
47 	/** 32-bit chip-revision code */
48 	t_u32 chip_rev;
49 	/** 32-bit strap setting */
50 	t_u32 strap;
51 } usb_ack_pkt;
52 #endif
53 
54 /** NXP USB device */
55 #define NXP_USB_DEVICE(vid, pid, name)                                         \
56 	USB_DEVICE(vid, pid), .driver_info = (t_ptr)name
57 
58 /** Name of the USB driver */
59 static const char usbdriver_name[] = "usbxxx";
60 
61 /** This structure contains the device signature */
62 static struct usb_device_id woal_usb_table[] = {
63 /* Enter the device signature inside */
64 #ifdef USB8801
65 	{NXP_USB_DEVICE(USB8801_VID_1, USB8801_PID_1, "NXP WLAN USB Adapter")},
66 	{NXP_USB_DEVICE(USB8801_VID_1, USB8801_PID_2, "NXP WLAN USB Adapter")},
67 #endif
68 #ifdef USB8897
69 	{NXP_USB_DEVICE(USB8897_VID_1, USB8897_PID_1, "NXP WLAN USB Adapter")},
70 	{NXP_USB_DEVICE(USB8897_VID_1, USB8897_PID_2, "NXP WLAN USB Adapter")},
71 #endif
72 #ifdef USB8997
73 	{NXP_USB_DEVICE(USB8997_VID_1, USB8997_PID_1, "NXP WLAN USB Adapter")},
74 	{NXP_USB_DEVICE(USB8997_VID_1, USB8997V2_PID_1,
75 			"NXP WLAN USB Adapter")},
76 	{NXP_USB_DEVICE(USB8997_VID_1, USB8997_PID_2, "NXP WLAN USB Adapter")},
77 	{NXP_USB_DEVICE(USB8997_VID_1, USB8997_PID_3, "NXP WLAN USB Adapter")},
78 	{NXP_USB_DEVICE(USB8997_VID_1, USB8997_PID_4, "NXP WLAN USB Adapter")},
79 	{NXP_USB_DEVICE(USB8997_VID_1, USB8997_PID_5, "NXP WLAN USB Adapter")},
80 	{NXP_USB_DEVICE(USB8997_VID_1, USB8997_PID_6, "NXP WLAN USB Adapter")},
81 #endif
82 #ifdef USB8978
83 	{NXP_USB_DEVICE(USB8978_VID_1, USB8978_PID_1, "NXP WLAN USB Adapter")},
84 	{NXP_USB_DEVICE(USB8978_VID_1, USB8978_PID_1_BT,
85 			"NXP WLAN USB Adapter")},
86 	{NXP_USB_DEVICE(USB8978_VID_1, USB8978_PID_2, "NXP WLAN USB Adapter")},
87 	{NXP_USB_DEVICE(USB8978_VID_1, USB8978_PID_2_BT,
88 			"NXP WLAN USB Adapter")},
89 #endif
90 #ifdef USB9098
91 	{NXP_USB_DEVICE(USB9098_VID_1, USB9098_PID_1, "NXP WLAN USB Adapter")},
92 	{NXP_USB_DEVICE(USB9098_VID_1, USB9098_PID_2, "NXP WLAN USB Adapter")},
93 #endif
94 #ifdef USB9097
95 	{NXP_USB_DEVICE(USB9097_VID_1, USB9097_PID_1, "NXP WLAN USB Adapter")},
96 	{NXP_USB_DEVICE(USB9097_VID_1, USB9097_PID_2, "NXP WLAN USB Adapter")},
97 #endif
98 #ifdef USBNW62X
99 	{NXP_USB_DEVICE(USBNW62X_VID_1, USBNW62X_PID_1,
100 			"NXP WLAN USB Adapter")},
101 	{NXP_USB_DEVICE(USBNW62X_VID_1, USBNW62X_PID_2,
102 			"NXP WLAN USB Adapter")},
103 #endif
104 	/* Terminating entry */
105 	{},
106 };
107 
108 /** This structure contains the device signature */
109 static struct usb_device_id woal_usb_table_skip_fwdnld[] = {
110 /* Enter the device signature inside */
111 #ifdef USB8801
112 	{NXP_USB_DEVICE(USB8801_VID_1, USB8801_PID_2, "NXP WLAN USB Adapter")},
113 #endif
114 #ifdef USB8897
115 	{NXP_USB_DEVICE(USB8897_VID_1, USB8897_PID_2, "NXP WLAN USB Adapter")},
116 #endif
117 #ifdef USB8997
118 	{NXP_USB_DEVICE(USB8997_VID_1, USB8997_PID_2, "NXP WLAN USB Adapter")},
119 #endif
120 #ifdef USB8978
121 	{NXP_USB_DEVICE(USB8978_VID_1, USB8978_PID_2, "NXP WLAN USB Adapter")},
122 	{NXP_USB_DEVICE(USB8978_VID_1, USB8978_PID_2_BT,
123 			"NXP WLAN USB Adapter")},
124 #endif
125 #ifdef USB9098
126 	{NXP_USB_DEVICE(USB9098_VID_1, USB9098_PID_2, "NXP WLAN USB Adapter")},
127 #endif
128 #ifdef USB9097
129 	{NXP_USB_DEVICE(USB9097_VID_1, USB9097_PID_2, "NXP WLAN USB Adapter")},
130 #endif
131 #ifdef USBNW62X
132 	{NXP_USB_DEVICE(USBNW62X_VID_1, USBNW62X_PID_2,
133 			"NXP WLAN USB Adapter")},
134 #endif
135 	/* Terminating entry */
136 	{},
137 };
138 
139 static mlan_status woal_usb_submit_rx_urb(urb_context *ctx, int size);
140 static int woal_usb_probe(struct usb_interface *intf,
141 			  const struct usb_device_id *id);
142 static void woal_usb_disconnect(struct usb_interface *intf);
143 static mlan_status woal_usb_write_data_sync(moal_handle *handle,
144 					    mlan_buffer *pmbuf, t_u32 endpoint,
145 					    t_u32 timeout);
146 static mlan_status woal_usb_read_data_sync(moal_handle *handle,
147 					   mlan_buffer *pmbuf, t_u32 endpoint,
148 					   t_u32 timeout);
149 #ifdef CONFIG_PM
150 static int woal_usb_suspend(struct usb_interface *intf, pm_message_t message);
151 static int woal_usb_resume(struct usb_interface *intf);
152 #endif /* CONFIG_PM */
153 
154 /** woal_usb_driver */
155 static struct usb_driver REFDATA woal_usb_driver = {
156 	/* Driver name */
157 	.name = usbdriver_name,
158 
159 	/* Probe function name */
160 	.probe = woal_usb_probe,
161 
162 	/* Disconnect function name */
163 	.disconnect = woal_usb_disconnect,
164 
165 	/* Device signature table */
166 	.id_table = woal_usb_table,
167 #ifdef CONFIG_PM
168 	/* Suspend function name */
169 	.suspend = woal_usb_suspend,
170 
171 	/* Resume function name */
172 	.resume = woal_usb_resume,
173 
174 	/* Reset resume function name */
175 	.reset_resume = woal_usb_resume,
176 
177 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
178 	/* Driver supports autosuspend */
179 	.supports_autosuspend = 1,
180 #endif
181 #endif /* CONFIG_PM */
182 };
183 
184 MODULE_DEVICE_TABLE(usb, woal_usb_table);
185 MODULE_DEVICE_TABLE(usb, woal_usb_table_skip_fwdnld);
186 
187 /* moal interface ops */
188 static moal_if_ops usb_ops;
189 
190 /********************************************************
191 		Global Variables
192 ********************************************************/
193 
194 /********************************************************
195 		Local Functions
196 ********************************************************/
197 
198 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
199 /**
200  *  @brief This function receive packet of the data/cmd/event packet
201  *         and pass to MLAN
202  *
203  *  @param urb		Pointer to struct urb
204  *  @param regs		Registers
205  *
206  *  @return 	   	N/A
207  */
woal_usb_receive(struct urb * urb,struct pt_regs * regs)208 static void woal_usb_receive(struct urb *urb, struct pt_regs *regs)
209 #else
210 /**
211  * @brief This function receive packet of the data/cmd/event packet
212  *         and pass to MLAN
213  *
214  *  @param urb		Pointer to struct urb
215  *
216  *  @return 	   	N/A
217  */
218 static void woal_usb_receive(struct urb *urb)
219 #endif
220 {
221 	urb_context *context = NULL;
222 	moal_handle *handle = NULL;
223 	mlan_buffer *pmbuf = NULL;
224 	struct usb_card_rec *cardp = NULL;
225 	int recv_length;
226 	int size;
227 	mlan_status status = MLAN_STATUS_SUCCESS;
228 
229 	ENTER();
230 
231 	if (!urb || !urb->context) {
232 		PRINTM(MERROR, "URB or URB context is not valid in USB Rx\n");
233 		LEAVE();
234 		return;
235 	}
236 	context = (urb_context *)urb->context;
237 	handle = context->handle;
238 	pmbuf = context->pmbuf;
239 	recv_length = urb->actual_length;
240 
241 	if (!handle || !handle->card || !pmbuf) {
242 		PRINTM(MERROR,
243 		       "moal handle, card structure or mlan_buffer is not valid in USB Rx\n");
244 		LEAVE();
245 		return;
246 	}
247 	cardp = (struct usb_card_rec *)handle->card;
248 	if (cardp->rx_cmd_ep == context->ep)
249 		atomic_dec(&cardp->rx_cmd_urb_pending);
250 	else
251 		atomic_dec(&cardp->rx_data_urb_pending);
252 
253 	if (recv_length) {
254 		if (urb->status || (handle->surprise_removed == MTRUE)) {
255 			if (handle->surprise_removed || handle->is_suspended) {
256 				woal_free_mlan_buffer(handle, pmbuf);
257 				context->pmbuf = NULL;
258 				goto rx_exit;
259 			} else {
260 				PRINTM(MERROR,
261 				       "EP %d Rx URB status failure: %d\n",
262 				       context->ep, urb->status);
263 				/* Do not free mlan_buffer in case of command ep
264 				 */
265 				if (cardp->rx_cmd_ep != context->ep)
266 					woal_free_mlan_buffer(handle, pmbuf);
267 				goto setup_for_next;
268 			}
269 		}
270 		pmbuf->data_len = recv_length;
271 		pmbuf->flags |= MLAN_BUF_FLAG_RX_DEAGGR;
272 		/* Send packet to MLAN */
273 		atomic_inc(&handle->rx_pending);
274 		status = mlan_recv(handle->pmlan_adapter, pmbuf, context->ep);
275 		PRINTM(MINFO, "Receive length = 0x%x, status=%d\n", recv_length,
276 		       status);
277 		if (status == MLAN_STATUS_PENDING) {
278 			queue_work(handle->workqueue, &handle->main_work);
279 			/* urb for data_ep is re-submitted now, unless we reach
280 			 * USB_HIGH_RX_PENDING */
281 			/* urb for cmd_ep will be re-submitted in callback
282 			 * moal_recv_complete */
283 			if (cardp->rx_cmd_ep == context->ep)
284 				goto rx_exit;
285 			else if (atomic_read(&handle->rx_pending) >=
286 				 USB_HIGH_RX_PENDING) {
287 				context->pmbuf = NULL;
288 				goto rx_exit;
289 			}
290 		} else {
291 			atomic_dec(&handle->rx_pending);
292 			if (status == MLAN_STATUS_FAILURE) {
293 				PRINTM(MERROR,
294 				       "MLAN fail to process the receive data\n");
295 			} else if ((status == MLAN_STATUS_SUCCESS) &&
296 				   (pmbuf->flags &
297 				    MLAN_BUF_FLAG_SLEEPCFM_RESP)) {
298 				pmbuf->flags &= ~MLAN_BUF_FLAG_SLEEPCFM_RESP;
299 				queue_work(handle->workqueue,
300 					   &handle->main_work);
301 			}
302 			/* Do not free mlan_buffer in case of command ep */
303 			if (cardp->rx_cmd_ep != context->ep)
304 				woal_free_mlan_buffer(handle, pmbuf);
305 		}
306 	} else if (urb->status) {
307 		if (!((cardp->rx_data_ep == context->ep) &&
308 		      (cardp->resubmit_urbs == 1))) {
309 			if (!handle->is_suspended) {
310 				PRINTM(MMSG, "Card is removed: %d\n",
311 				       urb->status);
312 				handle->surprise_removed = MTRUE;
313 			}
314 		}
315 		woal_free_mlan_buffer(handle, pmbuf);
316 		context->pmbuf = NULL;
317 		goto rx_exit;
318 	} else {
319 		/* Do not free mlan_buffer in case of command ep */
320 		if (cardp->rx_cmd_ep != context->ep)
321 			woal_free_mlan_buffer(handle, pmbuf);
322 		goto setup_for_next;
323 	}
324 
325 setup_for_next:
326 	if (cardp->rx_cmd_ep == context->ep) {
327 		size = MLAN_RX_CMD_BUF_SIZE;
328 	} else {
329 		if (cardp->rx_deaggr_ctrl.enable) {
330 			size = cardp->rx_deaggr_ctrl.aggr_max;
331 			if (cardp->rx_deaggr_ctrl.aggr_mode ==
332 			    MLAN_USB_AGGR_MODE_NUM) {
333 				size *= MAX(MLAN_USB_MAX_PKT_SIZE,
334 					    cardp->rx_deaggr_ctrl.aggr_align);
335 				size = MAX(size, MLAN_RX_DATA_BUF_SIZE);
336 			}
337 		} else
338 			size = MLAN_RX_DATA_BUF_SIZE;
339 	}
340 	woal_usb_submit_rx_urb(context, size);
341 
342 rx_exit:
343 	LEAVE();
344 	return;
345 }
346 
347 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
348 /**
349  *  @brief  Call back function to handle the status of the Tx data URB
350  *
351  *  @param urb      Pointer to urb structure
352  *  @param regs     Registers
353  *
354  *  @return         N/A
355  */
woal_usb_tx_complete(struct urb * urb,struct pt_regs * regs)356 static void woal_usb_tx_complete(struct urb *urb, struct pt_regs *regs)
357 #else
358 /**
359  * @brief  Call back function to handle the status of the Tx data URB
360  *
361  * @param urb      Pointer to urb structure
362  *
363  * @return         N/A
364  */
365 static void woal_usb_tx_complete(struct urb *urb)
366 #endif
367 {
368 	urb_context *context = NULL;
369 	moal_handle *handle = NULL;
370 	struct usb_card_rec *cardp = NULL;
371 
372 	ENTER();
373 
374 	if (!urb || !urb->context) {
375 		PRINTM(MERROR,
376 		       "URB or URB context is not valid in USB Tx complete\n");
377 		LEAVE();
378 		return;
379 	}
380 	context = (urb_context *)urb->context;
381 	handle = context->handle;
382 
383 	if (!handle || !handle->card || !context->pmbuf) {
384 		PRINTM(MERROR,
385 		       "moal handle, card structure or mlan_buffer is not valid in USB Tx complete\n");
386 		LEAVE();
387 		return;
388 	}
389 	cardp = handle->card;
390 
391 	/* Handle the transmission complete validations */
392 	if (urb->status) {
393 		PRINTM(MERROR, "EP %d Tx URB status failure: %d\n", context->ep,
394 		       urb->status);
395 		mlan_write_data_async_complete(handle->pmlan_adapter,
396 					       context->pmbuf, context->ep,
397 					       MLAN_STATUS_FAILURE);
398 	} else {
399 		mlan_write_data_async_complete(handle->pmlan_adapter,
400 					       context->pmbuf, context->ep,
401 					       MLAN_STATUS_SUCCESS);
402 	}
403 
404 	/* Decrease pending URB counter */
405 	if (context->ep == cardp->tx_cmd_ep)
406 		atomic_dec(&cardp->tx_cmd_urb_pending);
407 	else if (context->ep == cardp->tx_data_ep)
408 		atomic_dec(&cardp->tx_data_urb_pending);
409 
410 	queue_work(handle->workqueue, &handle->main_work);
411 
412 	LEAVE();
413 	return;
414 }
415 
416 /**
417  *  @brief This function sets up the data to receive
418  *
419  *  @param ctx		Pointer to urb_context structure
420  *  @param size	        Skb size
421  *
422  *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
423  */
woal_usb_submit_rx_urb(urb_context * ctx,int size)424 static mlan_status woal_usb_submit_rx_urb(urb_context *ctx, int size)
425 {
426 	moal_handle *handle = ctx->handle;
427 	struct usb_card_rec *cardp = (struct usb_card_rec *)handle->card;
428 	mlan_status ret = MLAN_STATUS_FAILURE;
429 	t_u8 *data = NULL;
430 
431 	ENTER();
432 
433 	if (handle->surprise_removed || handle->is_suspended) {
434 		if ((cardp->rx_cmd_ep == ctx->ep) && ctx->pmbuf) {
435 			woal_free_mlan_buffer(handle, ctx->pmbuf);
436 			ctx->pmbuf = NULL;
437 		}
438 		PRINTM(MERROR,
439 		       "Card removed/suspended, EP %d Rx URB submit skipped\n",
440 		       ctx->ep);
441 		goto rx_ret;
442 	}
443 
444 	if (cardp->rx_cmd_ep != ctx->ep) {
445 		ctx->pmbuf = woal_alloc_mlan_buffer(handle, size);
446 		if (!ctx->pmbuf) {
447 			PRINTM(MERROR,
448 			       "Fail to submit Rx URB due to no memory/skb\n");
449 			goto rx_ret;
450 		}
451 		ctx->pmbuf->data_offset = MLAN_RX_HEADER_LEN;
452 		data = ctx->pmbuf->pbuf + ctx->pmbuf->data_offset;
453 	} else {
454 		ctx->pmbuf->data_offset = 0;
455 		data = ctx->pmbuf->pbuf + ctx->pmbuf->data_offset;
456 	}
457 
458 	if (cardp->rx_cmd_ep == ctx->ep &&
459 	    cardp->rx_cmd_ep_type == USB_ENDPOINT_XFER_INT)
460 		usb_fill_int_urb(ctx->urb, cardp->udev,
461 				 usb_rcvintpipe(cardp->udev, ctx->ep), data,
462 				 size - ctx->pmbuf->data_offset,
463 				 woal_usb_receive, (void *)ctx,
464 				 cardp->rx_cmd_interval);
465 	else
466 		usb_fill_bulk_urb(ctx->urb, cardp->udev,
467 				  usb_rcvbulkpipe(cardp->udev, ctx->ep), data,
468 				  size - ctx->pmbuf->data_offset,
469 				  woal_usb_receive, (void *)ctx);
470 	if (cardp->rx_cmd_ep == ctx->ep)
471 		atomic_inc(&cardp->rx_cmd_urb_pending);
472 	else
473 		atomic_inc(&cardp->rx_data_urb_pending);
474 	if (usb_submit_urb(ctx->urb, GFP_ATOMIC)) {
475 		/* Submit URB failure */
476 		PRINTM(MERROR, "Submit EP %d Rx URB failed: %d\n", ctx->ep,
477 		       ret);
478 		woal_free_mlan_buffer(handle, ctx->pmbuf);
479 		if (cardp->rx_cmd_ep == ctx->ep)
480 			atomic_dec(&cardp->rx_cmd_urb_pending);
481 		else
482 			atomic_dec(&cardp->rx_data_urb_pending);
483 		ctx->pmbuf = NULL;
484 		ret = MLAN_STATUS_FAILURE;
485 	} else {
486 		ret = MLAN_STATUS_SUCCESS;
487 	}
488 rx_ret:
489 	LEAVE();
490 	return ret;
491 }
492 
493 /********************************************************
494 		Global Functions
495 ********************************************************/
496 
497 #if defined(USB8997) || defined(USB9098) || defined(USB9097) ||                \
498 	defined(USB8978) || defined(USBNW62X)
499 /**
500  *  @brief  Check chip revision
501  *
502  *  @param handle        A pointer to moal_handle structure
503  *  @param usb_chip_rev  A pointer to usb_chip_rev variable
504  *  @param usb_strap     A pointer to usb_strap
505  *
506  *  @return 	   	 MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
507  */
woal_check_chip_revision(moal_handle * handle,t_u32 * usb_chip_rev,t_u32 * usb_strap)508 static mlan_status woal_check_chip_revision(moal_handle *handle,
509 					    t_u32 *usb_chip_rev,
510 					    t_u32 *usb_strap)
511 {
512 	mlan_status ret = MLAN_STATUS_SUCCESS;
513 	mlan_buffer mbuf;
514 	t_u8 *tx_buff = NULL;
515 	t_u8 *recv_buff = NULL;
516 	usb_ack_pkt ack_pkt;
517 	t_u32 extend_ver;
518 	t_u8 tx_size = CHIP_REV_TX_BUF_SIZE;
519 	struct usb_card_rec *cardp = handle->card;
520 
521 	ENTER();
522 
523 	/* Allocate memory for transmit */
524 	tx_buff = kzalloc(tx_size, GFP_ATOMIC | GFP_DMA);
525 	if (tx_buff == NULL) {
526 		PRINTM(MERROR,
527 		       "Could not allocate buffer for chip revision check frame transmission\n");
528 		ret = MLAN_STATUS_FAILURE;
529 		goto cleanup;
530 	}
531 
532 	/* Allocate memory for receive */
533 	recv_buff = kzalloc(CHIP_REV_RX_BUF_SIZE, GFP_ATOMIC | GFP_DMA);
534 	if (recv_buff == NULL) {
535 		PRINTM(MERROR,
536 		       "Could not allocate buffer for chip revision check frame response\n");
537 		ret = MLAN_STATUS_FAILURE;
538 		goto cleanup;
539 	}
540 
541 	/* The struct is initialised to all zero */
542 	memset(&ack_pkt, 0, sizeof(usb_ack_pkt));
543 
544 	/* Send pseudo data to check winner status first */
545 	memset(&mbuf, 0, sizeof(mlan_buffer));
546 	mbuf.pbuf = (t_u8 *)tx_buff;
547 	mbuf.data_len = tx_size;
548 
549 	/* Send the chip revision check frame */
550 	ret = woal_usb_write_data_sync(handle, &mbuf, cardp->tx_cmd_ep,
551 				       MLAN_USB_BULK_MSG_TIMEOUT);
552 	if (ret != MLAN_STATUS_SUCCESS) {
553 		PRINTM(MERROR,
554 		       "Chip revision check frame dnld: write_data failed, ret %d\n",
555 		       ret);
556 		ret = MLAN_STATUS_FAILURE;
557 		goto cleanup;
558 	}
559 
560 	memset(&mbuf, 0, sizeof(mlan_buffer));
561 	mbuf.pbuf = (t_u8 *)recv_buff;
562 	mbuf.data_len = CHIP_REV_RX_BUF_SIZE;
563 
564 	/* Receive the chip revision check frame response */
565 	ret = woal_usb_read_data_sync(handle, &mbuf, cardp->rx_cmd_ep,
566 				      MLAN_USB_BULK_MSG_TIMEOUT);
567 	if (ret != MLAN_STATUS_SUCCESS) {
568 		PRINTM(MERROR,
569 		       "Chip revision check frame response: read_data failed, ret %d\n",
570 		       ret);
571 		ret = MLAN_STATUS_FAILURE;
572 		goto cleanup;
573 	}
574 	moal_memcpy_ext(handle, &ack_pkt, recv_buff, sizeof(usb_ack_pkt),
575 			sizeof(ack_pkt));
576 	ack_pkt.ack_winner = woal_le32_to_cpu(ack_pkt.ack_winner);
577 	ack_pkt.seq = woal_le32_to_cpu(ack_pkt.seq);
578 	ack_pkt.extend = woal_le32_to_cpu(ack_pkt.extend);
579 	ack_pkt.chip_rev = woal_le32_to_cpu(ack_pkt.chip_rev);
580 	ack_pkt.strap = woal_le32_to_cpu(ack_pkt.strap);
581 
582 	if ((ack_pkt.extend & 0xffff0000) == EXTEND_HDR) {
583 		extend_ver = ack_pkt.extend & 0x0000ffff;
584 		*usb_chip_rev = ack_pkt.chip_rev & 0x000000ff;
585 		if (extend_ver >= EXTEND_V2) {
586 			PRINTM(MINFO, "chip_rev=0x%x, strap=0x%x\n",
587 			       *usb_chip_rev, ack_pkt.strap);
588 			*usb_strap = ack_pkt.strap & 0x7;
589 		} else
590 			PRINTM(MINFO, "chip_rev=0x%x\n", *usb_chip_rev);
591 	}
592 cleanup:
593 	kfree(recv_buff);
594 	kfree(tx_buff);
595 
596 	LEAVE();
597 	return ret;
598 }
599 #endif
600 
601 /**
602  *  @brief This function unlink urb
603  *
604  *  @param handle A pointer to moal_handle structure
605  *  @return 	  N/A
606  */
woal_usb_unlink_urb(void * card_desc)607 static void woal_usb_unlink_urb(void *card_desc)
608 {
609 	struct usb_card_rec *cardp = (struct usb_card_rec *)card_desc;
610 	int i;
611 	ENTER();
612 	if (cardp) {
613 		/* Unlink Rx cmd URB */
614 		if (atomic_read(&cardp->rx_cmd_urb_pending) &&
615 		    cardp->rx_cmd.urb) {
616 			usb_kill_urb(cardp->rx_cmd.urb);
617 		}
618 		/* Unlink Rx data URBs */
619 		if (atomic_read(&cardp->rx_data_urb_pending)) {
620 			for (i = 0; i < MVUSB_RX_DATA_URB; i++) {
621 				if (cardp->rx_data_list[i].urb)
622 					usb_kill_urb(
623 						cardp->rx_data_list[i].urb);
624 			}
625 		}
626 		/* Unlink Tx cmd URB */
627 		if (atomic_read(&cardp->tx_cmd_urb_pending) &&
628 		    cardp->tx_cmd.urb) {
629 			usb_kill_urb(cardp->tx_cmd.urb);
630 		}
631 		/* Unlink Tx data URBs */
632 		if (atomic_read(&cardp->tx_data_urb_pending)) {
633 			for (i = 0; i < MVUSB_TX_HIGH_WMARK; i++) {
634 				if (cardp->tx_data_list[i].urb) {
635 					usb_kill_urb(
636 						cardp->tx_data_list[i].urb);
637 				}
638 			}
639 		}
640 	}
641 	LEAVE();
642 }
643 
644 /**
645  *  @brief  Free Tx/Rx urb, skb and Rx buffer
646  *
647  *  @param cardp	Pointer usb_card_rec
648  *
649  *  @return 	   	N/A
650  */
woal_usb_free(struct usb_card_rec * cardp)651 void woal_usb_free(struct usb_card_rec *cardp)
652 {
653 	int i;
654 
655 	ENTER();
656 
657 	woal_usb_unlink_urb(cardp);
658 	/* Free Rx data URBs */
659 	for (i = 0; i < MVUSB_RX_DATA_URB; i++) {
660 		if (cardp->rx_data_list[i].urb) {
661 			usb_free_urb(cardp->rx_data_list[i].urb);
662 			cardp->rx_data_list[i].urb = NULL;
663 		}
664 	}
665 	/* Free Rx cmd URB */
666 	if (cardp->rx_cmd.urb) {
667 		usb_free_urb(cardp->rx_cmd.urb);
668 		cardp->rx_cmd.urb = NULL;
669 	}
670 
671 	/* Free Tx data URBs */
672 	for (i = 0; i < MVUSB_TX_HIGH_WMARK; i++) {
673 		if (cardp->tx_data_list[i].urb) {
674 			usb_free_urb(cardp->tx_data_list[i].urb);
675 			cardp->tx_data_list[i].urb = NULL;
676 		}
677 	}
678 	/* Free Tx cmd URB */
679 	if (cardp->tx_cmd.urb) {
680 		usb_free_urb(cardp->tx_cmd.urb);
681 		cardp->tx_cmd.urb = NULL;
682 	}
683 
684 	LEAVE();
685 	return;
686 }
687 
woal_update_card_type(t_void * card)688 static t_u16 woal_update_card_type(t_void *card)
689 {
690 	struct usb_card_rec *cardp_usb = (struct usb_card_rec *)card;
691 	t_u16 card_type = 0;
692 
693 	/* Update card type */
694 #ifdef USB8801
695 	if (woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
696 		    (__force __le16)USB8801_PID_1 ||
697 	    woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
698 		    (__force __le16)USB8801_PID_2) {
699 		card_type = CARD_TYPE_USB8801;
700 		moal_memcpy_ext(NULL, driver_version, CARD_USB8801,
701 				strlen(CARD_USB8801), strlen(driver_version));
702 		moal_memcpy_ext(NULL,
703 				driver_version + strlen(INTF_CARDTYPE) +
704 					strlen(KERN_VERSION),
705 				V14, strlen(V14),
706 				strlen(driver_version) - strlen(INTF_CARDTYPE) -
707 					strlen(KERN_VERSION));
708 	}
709 #endif
710 #ifdef USB8897
711 	if (woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
712 		    (__force __le16)USB8897_PID_1 ||
713 	    woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
714 		    (__force __le16)USB8897_PID_2) {
715 		card_type = CARD_TYPE_USB8897;
716 		moal_memcpy_ext(NULL, driver_version, CARD_USB8897,
717 				strlen(CARD_USB8897), strlen(driver_version));
718 		moal_memcpy_ext(NULL,
719 				driver_version + strlen(INTF_CARDTYPE) +
720 					strlen(KERN_VERSION),
721 				V15, strlen(V15),
722 				strlen(driver_version) - strlen(INTF_CARDTYPE) -
723 					strlen(KERN_VERSION));
724 	}
725 #endif
726 #ifdef USB8997
727 	if (woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
728 		    (__force __le16)USB8997_PID_1 ||
729 	    woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
730 		    (__force __le16)USB8997_PID_2 ||
731 	    woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
732 		    (__force __le16)USB8997_PID_3 ||
733 	    woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
734 		    (__force __le16)USB8997_PID_4 ||
735 	    woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
736 		    (__force __le16)USB8997_PID_5 ||
737 	    woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
738 		    (__force __le16)USB8997_PID_6 ||
739 	    woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
740 		    (__force __le16)USB8997V2_PID_1) {
741 		card_type = CARD_TYPE_USB8997;
742 		moal_memcpy_ext(NULL, driver_version, CARD_USB8997,
743 				strlen(CARD_USB8997), strlen(driver_version));
744 		moal_memcpy_ext(NULL,
745 				driver_version + strlen(INTF_CARDTYPE) +
746 					strlen(KERN_VERSION),
747 				V16, strlen(V16),
748 				strlen(driver_version) - strlen(INTF_CARDTYPE) -
749 					strlen(KERN_VERSION));
750 	}
751 #endif
752 #ifdef USB8978
753 	if (woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
754 		    (__force __le16)USB8978_PID_1 ||
755 	    woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
756 		    (__force __le16)USB8978_PID_2) {
757 		card_type = CARD_TYPE_USB8978;
758 		moal_memcpy_ext(NULL, driver_version, "USBIW416",
759 				strlen("USBIW416"), strlen(driver_version));
760 		moal_memcpy_ext(NULL,
761 				driver_version + strlen(INTF_CARDTYPE) +
762 					strlen(KERN_VERSION),
763 				V16, strlen(V16),
764 				strlen(driver_version) - strlen(INTF_CARDTYPE) -
765 					strlen(KERN_VERSION));
766 	}
767 #endif
768 #ifdef USB9098
769 	if (woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
770 		    (__force __le16)USB9098_PID_1 ||
771 	    woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
772 		    (__force __le16)USB9098_PID_2) {
773 		card_type = CARD_TYPE_USB9098;
774 		moal_memcpy_ext(NULL, driver_version, CARD_USB9098,
775 				strlen(CARD_USB9098), strlen(driver_version));
776 		moal_memcpy_ext(NULL,
777 				driver_version + strlen(INTF_CARDTYPE) +
778 					strlen(KERN_VERSION),
779 				V17, strlen(V17),
780 				strlen(driver_version) - strlen(INTF_CARDTYPE) -
781 					strlen(KERN_VERSION));
782 	}
783 #endif
784 #ifdef USB9097
785 	if (woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
786 		    (__force __le16)USB9097_PID_1 ||
787 	    woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
788 		    (__force __le16)USB9097_PID_2) {
789 		card_type = CARD_TYPE_USB9097;
790 		moal_memcpy_ext(NULL, driver_version, CARD_USB9097,
791 				strlen(CARD_USB9097), strlen(driver_version));
792 		moal_memcpy_ext(NULL,
793 				driver_version + strlen(INTF_CARDTYPE) +
794 					strlen(KERN_VERSION),
795 				V17, strlen(V17),
796 				strlen(driver_version) - strlen(INTF_CARDTYPE) -
797 					strlen(KERN_VERSION));
798 	}
799 #endif
800 #ifdef USBNW62X
801 	if (woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
802 		    (__force __le16)USBNW62X_PID_1 ||
803 	    woal_cpu_to_le16(cardp_usb->udev->descriptor.idProduct) ==
804 		    (__force __le16)USBNW62X_PID_2) {
805 		card_type = CARD_TYPE_USBNW62X;
806 		moal_memcpy_ext(NULL, driver_version, CARD_USBNW62X,
807 				strlen(CARD_USBNW62X), strlen(driver_version));
808 		moal_memcpy_ext(NULL,
809 				driver_version + strlen(INTF_CARDTYPE) +
810 					strlen(KERN_VERSION),
811 				V17, strlen(V17),
812 				strlen(driver_version) - strlen(INTF_CARDTYPE) -
813 					strlen(KERN_VERSION));
814 	}
815 #endif
816 	return card_type;
817 }
818 
819 /**
820  *  @brief Sets the configuration values
821  *
822  *  @param intf		Pointer to usb_interface
823  *  @param id		Pointer to usb_device_id
824  *
825  *  @return 	   	Address of variable usb_cardp, error code otherwise
826  */
woal_usb_probe(struct usb_interface * intf,const struct usb_device_id * id)827 static int woal_usb_probe(struct usb_interface *intf,
828 			  const struct usb_device_id *id)
829 {
830 	struct usb_device *udev;
831 	struct usb_host_interface *iface_desc;
832 	struct usb_endpoint_descriptor *endpoint;
833 	int i;
834 	struct usb_card_rec *usb_cardp = NULL;
835 	t_u16 card_type = 0;
836 
837 	ENTER();
838 
839 #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)
840 	PRINTM(MMSG,
841 	       "USB probe: idVendor=%x idProduct=%x bInterfaceNumber=%d\n",
842 	       id->idVendor, id->idProduct, id->bInterfaceNumber);
843 #endif
844 
845 	udev = interface_to_usbdev(intf);
846 	usb_cardp = kzalloc(sizeof(struct usb_card_rec), GFP_KERNEL);
847 	if (!usb_cardp) {
848 		LEAVE();
849 		return -ENOMEM;
850 	}
851 
852 	/* Check probe is for our device */
853 	for (i = 0; woal_usb_table[i].idVendor; i++) {
854 		if (woal_cpu_to_le16(udev->descriptor.idVendor) ==
855 			    (__force __le16)woal_usb_table[i].idVendor &&
856 		    woal_cpu_to_le16(udev->descriptor.idProduct) ==
857 			    (__force __le16)woal_usb_table[i].idProduct) {
858 			PRINTM(MMSG, "VID/PID = %X/%X, Boot2 version = %X\n",
859 			       woal_cpu_to_le16(udev->descriptor.idVendor),
860 			       woal_cpu_to_le16(udev->descriptor.idProduct),
861 			       woal_cpu_to_le16(udev->descriptor.bcdDevice));
862 			switch (woal_cpu_to_le16(udev->descriptor.idProduct)) {
863 #ifdef USB8801
864 			case (__force __le16)USB8801_PID_1:
865 #endif /* USB8801 */
866 #ifdef USB8897
867 			case (__force __le16)USB8897_PID_1:
868 #endif /* USB8897 */
869 #ifdef USB8997
870 			case (__force __le16)USB8997_PID_1:
871 			case (__force __le16)USB8997V2_PID_1:
872 #endif /* USB8997 */
873 #ifdef USB8978
874 			case (__force __le16)USB8978_PID_1:
875 			case (__force __le16)USB8978_PID_1_BT:
876 #endif /* USB8978 */
877 #ifdef USB9098
878 			case (__force __le16)USB9098_PID_1:
879 #endif /* USB9098 */
880 #ifdef USB9097
881 			case (__force __le16)USB9097_PID_1:
882 #endif /* USB9097 */
883 #ifdef USBNW62X
884 			case (__force __le16)USBNW62X_PID_1:
885 #endif /* USBNW62X */
886 
887 				/* If skip FW is set, we must return error so
888 				 * the next driver can download the FW */
889 				if (skip_fwdnld)
890 					goto error;
891 				else
892 					usb_cardp->boot_state = USB_FW_DNLD;
893 				break;
894 #ifdef USB8801
895 			case (__force __le16)USB8801_PID_2:
896 #endif /* USB8801 */
897 #ifdef USB8897
898 			case (__force __le16)USB8897_PID_2:
899 #endif /* USB8897 */
900 #ifdef USB8997
901 			case (__force __le16)USB8997_PID_2:
902 #endif /* USB8997 */
903 #ifdef USB8978
904 			case (__force __le16)USB8978_PID_2:
905 			case (__force __le16)USB8978_PID_2_BT:
906 #endif /* USB8978 */
907 #ifdef USB9098
908 			case (__force __le16)USB9098_PID_2:
909 #endif /* USB9098 */
910 #ifdef USB9097
911 			case (__force __le16)USB9097_PID_2:
912 #endif /* USB9097 */
913 #ifdef USBNW62X
914 			case (__force __le16)USBNW62X_PID_2:
915 #endif /* USBNW62X */
916 
917 				usb_cardp->boot_state = USB_FW_READY;
918 				break;
919 			}
920 			/*To do, get card type*/
921 			/*			if
922 			   (woal_cpu_to_le16(udev->descriptor.idProduct) ==
923 			   USB8897_PID_2) usb_cardp->card_type =
924 			   CARD_TYPE_USB8897; else if
925 			   (woal_cpu_to_le16(udev->descriptor.idProduct) ==
926 			   USB8997_PID_2) usb_cardp->card_type =
927 			   CARD_TYPE_USB997;
928 			*/
929 			break;
930 		}
931 	}
932 
933 	if (woal_usb_table[i].idVendor) {
934 		usb_cardp->udev = udev;
935 		iface_desc = intf->cur_altsetting;
936 		usb_cardp->intf = intf;
937 
938 		PRINTM(MINFO,
939 		       "bcdUSB = 0x%X bDeviceClass = 0x%X"
940 		       " bDeviceSubClass = 0x%X, bDeviceProtocol = 0x%X\n",
941 		       woal_cpu_to_le16(udev->descriptor.bcdUSB),
942 		       udev->descriptor.bDeviceClass,
943 		       udev->descriptor.bDeviceSubClass,
944 		       udev->descriptor.bDeviceProtocol);
945 
946 		for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
947 			endpoint = &iface_desc->endpoint[i].desc;
948 			if ((usb_endpoint_is_bulk_in(endpoint) ||
949 			     usb_endpoint_is_int_in(endpoint)) &&
950 			    (usb_endpoint_num(endpoint) ==
951 				     MLAN_USB_EP_CMD_EVENT ||
952 			     usb_endpoint_num(endpoint) ==
953 				     MLAN_USB_EP_CMD_EVENT_IF2)) {
954 				usb_cardp->rx_cmd_ep_type =
955 					usb_endpoint_type(endpoint);
956 				usb_cardp->rx_cmd_interval =
957 					endpoint->bInterval;
958 				/* We found a bulk in command/event endpoint */
959 				PRINTM(MCMND,
960 				       "Rx CMD/EVT: max packet size = %d, address = %d ep_type=%d\n",
961 				       woal_le16_to_cpu(
962 					       endpoint->wMaxPacketSize),
963 				       endpoint->bEndpointAddress,
964 				       usb_cardp->rx_cmd_ep_type);
965 				usb_cardp->rx_cmd_ep =
966 					(endpoint->bEndpointAddress &
967 					 USB_ENDPOINT_NUMBER_MASK);
968 
969 				atomic_set(&usb_cardp->rx_cmd_urb_pending, 0);
970 				if (usb_endpoint_num(endpoint) ==
971 				    MLAN_USB_EP_CMD_EVENT_IF2)
972 					usb_cardp->second_mac = MTRUE;
973 			}
974 			if (usb_endpoint_is_bulk_in(endpoint) &&
975 			    (usb_endpoint_num(endpoint) == MLAN_USB_EP_DATA ||
976 			     usb_endpoint_num(endpoint) ==
977 				     MLAN_USB_EP_DATA_IF2)) {
978 				/* We found a bulk in data endpoint */
979 				PRINTM(MINFO,
980 				       "Bulk IN: max packet size = %d, address = %d\n",
981 				       woal_le16_to_cpu(
982 					       endpoint->wMaxPacketSize),
983 				       endpoint->bEndpointAddress);
984 				usb_cardp->rx_data_ep =
985 					(endpoint->bEndpointAddress &
986 					 USB_ENDPOINT_NUMBER_MASK);
987 				atomic_set(&usb_cardp->rx_data_urb_pending, 0);
988 			}
989 			if (usb_endpoint_is_bulk_out(endpoint) &&
990 			    (usb_endpoint_num(endpoint) == MLAN_USB_EP_DATA ||
991 			     usb_endpoint_num(endpoint) ==
992 				     MLAN_USB_EP_DATA_IF2)) {
993 				/* We found a bulk out data endpoint */
994 				PRINTM(MCMND,
995 				       "Bulk OUT: max packet size = %d, address = %d\n",
996 				       woal_le16_to_cpu(
997 					       endpoint->wMaxPacketSize),
998 				       endpoint->bEndpointAddress);
999 				usb_cardp->tx_data_ep =
1000 					endpoint->bEndpointAddress;
1001 				atomic_set(&usb_cardp->tx_data_urb_pending, 0);
1002 				usb_cardp->tx_data_maxpktsize =
1003 					(__force int)woal_le16_to_cpu(
1004 						endpoint->wMaxPacketSize);
1005 			}
1006 
1007 			if ((usb_endpoint_is_bulk_out(endpoint) ||
1008 			     usb_endpoint_is_int_out(endpoint)) &&
1009 			    (usb_endpoint_num(endpoint) ==
1010 				     MLAN_USB_EP_CMD_EVENT ||
1011 			     usb_endpoint_num(endpoint) ==
1012 				     MLAN_USB_EP_CMD_EVENT_IF2)) {
1013 				usb_cardp->tx_cmd_ep_type =
1014 					usb_endpoint_type(endpoint);
1015 				usb_cardp->tx_cmd_interval =
1016 					endpoint->bInterval;
1017 				/* We found a bulk out command/event endpoint */
1018 				PRINTM(MCMND,
1019 				       "Tx CMD: max packet size = %d, address = %d ep_type=%d\n",
1020 				       woal_le16_to_cpu(
1021 					       endpoint->wMaxPacketSize),
1022 				       endpoint->bEndpointAddress,
1023 				       usb_cardp->tx_cmd_ep_type);
1024 				usb_cardp->tx_cmd_ep =
1025 					endpoint->bEndpointAddress;
1026 				atomic_set(&usb_cardp->tx_cmd_urb_pending, 0);
1027 				usb_cardp->tx_cmd_maxpktsize =
1028 					(__force int)woal_le16_to_cpu(
1029 						endpoint->wMaxPacketSize);
1030 			}
1031 		}
1032 
1033 		if (usb_cardp->boot_state == USB_FW_DNLD) {
1034 			if (!usb_cardp->tx_cmd_ep || !usb_cardp->rx_cmd_ep)
1035 				goto error;
1036 		} else if (usb_cardp->boot_state == USB_FW_READY) {
1037 			if (!usb_cardp->tx_cmd_ep || !usb_cardp->tx_data_ep ||
1038 			    !usb_cardp->rx_cmd_ep || !usb_cardp->rx_data_ep) {
1039 				PRINTM(MERROR,
1040 				       "%s: invalid endpoint assignment\n",
1041 				       __FUNCTION__);
1042 				goto error;
1043 			}
1044 		}
1045 
1046 		usb_cardp->tx_aggr_ctrl.enable = MFALSE;
1047 		usb_cardp->tx_aggr_ctrl.aggr_mode = MLAN_USB_AGGR_MODE_NUM;
1048 		usb_cardp->tx_aggr_ctrl.aggr_align =
1049 			MAX(max_tx_buf, MLAN_USB_TX_AGGR_ALIGN);
1050 		usb_cardp->tx_aggr_ctrl.aggr_max = MLAN_USB_TX_MAX_AGGR_NUM;
1051 		usb_cardp->tx_aggr_ctrl.aggr_tmo =
1052 			MLAN_USB_TX_AGGR_TIMEOUT_MSEC * 1000;
1053 		usb_cardp->rx_deaggr_ctrl.enable = MFALSE;
1054 		usb_cardp->rx_deaggr_ctrl.aggr_mode = MLAN_USB_AGGR_MODE_NUM;
1055 		usb_cardp->rx_deaggr_ctrl.aggr_align = MLAN_USB_RX_ALIGN_SIZE;
1056 		usb_cardp->rx_deaggr_ctrl.aggr_max = MLAN_USB_RX_MAX_AGGR_NUM;
1057 		usb_cardp->rx_deaggr_ctrl.aggr_tmo =
1058 			MLAN_USB_RX_DEAGGR_TIMEOUT_USEC;
1059 		usb_set_intfdata(intf, usb_cardp);
1060 
1061 		card_type = woal_update_card_type(usb_cardp);
1062 		if (!card_type) {
1063 			PRINTM(MERROR,
1064 			       "usb probe: woal_update_card_type() failed\n");
1065 			goto error;
1066 		}
1067 
1068 		/* At this point wlan_add_card() will be called */
1069 		if (!(woal_add_card(usb_cardp, &usb_cardp->udev->dev, &usb_ops,
1070 				    card_type))) {
1071 			PRINTM(MERROR, "%s: woal_add_card failed\n",
1072 			       __FUNCTION__);
1073 			goto error;
1074 		}
1075 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
1076 		/* Note: From 2.6.34.2 onwards, remote wakeup is NOT enabled by
1077 		 * default. So drivers wanting remote wakeup will have to enable
1078 		 * this using -
1079 		 * device_set_wakeup_enable(&udev->dev, 1);
1080 		 * It has been observed that some cards having device attr =
1081 		 * 0xa0 do not support remote wakeup. These cards come
1082 		 * immediately out of the suspend when power/wakeup file is set
1083 		 * to 'enabled'. To support all types of cards i.e. with/without
1084 		 * remote wakeup, we are NOT setting the 'power/wakeup' file
1085 		 * from here. Also in principle, we are not supposed to change
1086 		 * the wakeup policy, which is purely a userspace decision.
1087 		 */
1088 		/* if (udev->actconfig->desc.bmAttributes &
1089 		   USB_CONFIG_ATT_WAKEUP) intf->needs_remote_wakeup = 1; */
1090 #endif
1091 		usb_get_dev(udev);
1092 		LEAVE();
1093 		return 0;
1094 	} else {
1095 		PRINTM(MINFO, "Discard the Probe request\n");
1096 		PRINTM(MINFO, "VID = 0x%X PID = 0x%X\n",
1097 		       woal_cpu_to_le16(udev->descriptor.idVendor),
1098 		       woal_cpu_to_le16(udev->descriptor.idProduct));
1099 	}
1100 error:
1101 	kfree(usb_cardp);
1102 	usb_cardp = NULL;
1103 	LEAVE();
1104 	return -ENXIO;
1105 }
1106 
1107 /**
1108  *  @brief Free resource and cleanup
1109  *
1110  *  @param intf		Pointer to usb_interface
1111  *
1112  *  @return 	   	N/A
1113  */
woal_usb_disconnect(struct usb_interface * intf)1114 static void woal_usb_disconnect(struct usb_interface *intf)
1115 {
1116 	struct usb_card_rec *cardp = usb_get_intfdata(intf);
1117 	moal_handle *phandle = NULL;
1118 	ENTER();
1119 	if (!cardp || !cardp->phandle) {
1120 		PRINTM(MERROR, "Card or phandle is not valid\n");
1121 		LEAVE();
1122 		return;
1123 	}
1124 	phandle = (moal_handle *)cardp->phandle;
1125 
1126 	/*
1127 	 * Update Surprise removed to TRUE
1128 	 *  Free all the URB's allocated
1129 	 */
1130 	phandle->surprise_removed = MTRUE;
1131 
1132 	/* Card is removed and we can call wlan_remove_card */
1133 	PRINTM(MINFO, "Call remove card\n");
1134 	woal_remove_card(cardp);
1135 
1136 	usb_set_intfdata(intf, NULL);
1137 	usb_put_dev(interface_to_usbdev(intf));
1138 	kfree(cardp);
1139 	LEAVE();
1140 	return;
1141 }
1142 
1143 /**
1144  *  @brief killall pending urbs
1145  *
1146  *  @param handle	  Pointer to moal_handle
1147  *
1148  *
1149  *  @return 	   	  N/A
1150  */
woal_kill_urbs(moal_handle * handle)1151 void woal_kill_urbs(moal_handle *handle)
1152 {
1153 	ENTER();
1154 	handle->is_suspended = MTRUE;
1155 	woal_usb_unlink_urb(handle->card);
1156 	LEAVE();
1157 }
1158 
1159 /**
1160  *  @brief resubmit urbs
1161  *
1162  *  @param handle	  Pointer to moal_handle
1163  *
1164  *
1165  *  @return 	   	  N/A
1166  */
woal_resubmit_urbs(moal_handle * handle)1167 void woal_resubmit_urbs(moal_handle *handle)
1168 {
1169 	struct usb_card_rec *cardp = handle->card;
1170 
1171 	ENTER();
1172 	handle->is_suspended = MFALSE;
1173 
1174 	if (!atomic_read(&cardp->rx_data_urb_pending)) {
1175 		/* Submit multiple Rx data URBs */
1176 		woal_usb_submit_rx_data_urbs(handle);
1177 	}
1178 	if (!atomic_read(&cardp->rx_cmd_urb_pending)) {
1179 		cardp->rx_cmd.pmbuf =
1180 			woal_alloc_mlan_buffer(handle, MLAN_RX_CMD_BUF_SIZE);
1181 		if (cardp->rx_cmd.pmbuf)
1182 			woal_usb_submit_rx_urb(&cardp->rx_cmd,
1183 					       MLAN_RX_CMD_BUF_SIZE);
1184 	}
1185 	LEAVE();
1186 }
1187 
1188 #ifdef CONFIG_PM
1189 /**
1190  *  @brief Handle suspend
1191  *
1192  *  @param intf		  Pointer to usb_interface
1193  *  @param message	  Pointer to pm_message_t structure
1194  *
1195  *  @return 	   	  MLAN_STATUS_SUCCESS
1196  */
woal_usb_suspend(struct usb_interface * intf,pm_message_t message)1197 static int woal_usb_suspend(struct usb_interface *intf, pm_message_t message)
1198 {
1199 	struct usb_card_rec *cardp = usb_get_intfdata(intf);
1200 	moal_handle *handle = NULL;
1201 	int i;
1202 	int ret = 0;
1203 
1204 	ENTER();
1205 
1206 	PRINTM(MCMND, "<--- Enter woal_usb_suspend --->\n");
1207 	if (!cardp || !cardp->phandle) {
1208 		PRINTM(MERROR, "Card or moal_handle structure is not valid\n");
1209 		ret = 0;
1210 		goto done;
1211 	}
1212 	handle = cardp->phandle;
1213 	if (handle->is_suspended == MTRUE) {
1214 		PRINTM(MWARN, "Device already suspended\n");
1215 		ret = 0;
1216 		goto done;
1217 	}
1218 #ifdef STA_SUPPORT
1219 	for (i = 0; i < MIN(handle->priv_num, MLAN_MAX_BSS_NUM); i++) {
1220 		if (handle->priv[i] &&
1221 		    (GET_BSS_ROLE(handle->priv[i]) == MLAN_BSS_ROLE_STA))
1222 			woal_cancel_scan(handle->priv[i], MOAL_IOCTL_WAIT);
1223 	}
1224 #endif
1225 	/* Enable Host Sleep */
1226 	woal_enable_hs(woal_get_priv(handle, MLAN_BSS_ROLE_ANY));
1227 
1228 	/* Indicate device suspended */
1229 	/* The flag must be set here before the usb_kill_urb() calls.
1230 	 * Reason: In the complete handlers, urb->status(= -ENOENT) and
1231 	 * 'is_suspended' flag is used in combination to distinguish
1232 	 * between a suspended state and a 'disconnect' one.
1233 	 */
1234 	handle->is_suspended = MTRUE;
1235 	for (i = 0; i < handle->priv_num; i++)
1236 		netif_carrier_off(handle->priv[i]->netdev);
1237 
1238 	/* Unlink Rx cmd URB */
1239 	if (atomic_read(&cardp->rx_cmd_urb_pending) && cardp->rx_cmd.urb) {
1240 		usb_kill_urb(cardp->rx_cmd.urb);
1241 	}
1242 	/* Unlink Rx data URBs */
1243 	if (atomic_read(&cardp->rx_data_urb_pending)) {
1244 		for (i = 0; i < MVUSB_RX_DATA_URB; i++) {
1245 			if (cardp->rx_data_list[i].urb) {
1246 				usb_kill_urb(cardp->rx_data_list[i].urb);
1247 				usb_init_urb(cardp->rx_data_list[i].urb);
1248 			}
1249 		}
1250 	}
1251 
1252 	/* Unlink Tx data URBs */
1253 	for (i = 0; i < MVUSB_TX_HIGH_WMARK; i++) {
1254 		if (cardp->tx_data_list[i].urb) {
1255 			usb_kill_urb(cardp->tx_data_list[i].urb);
1256 		}
1257 	}
1258 	/* Unlink Tx cmd URB */
1259 	if (cardp->tx_cmd.urb) {
1260 		usb_kill_urb(cardp->tx_cmd.urb);
1261 	}
1262 
1263 	handle->suspend_wait_q_woken = MTRUE;
1264 	wake_up_interruptible(&handle->suspend_wait_q);
1265 
1266 done:
1267 	PRINTM(MCMND, "<--- Leave woal_usb_suspend --->\n");
1268 	LEAVE();
1269 	return ret;
1270 }
1271 
1272 /**
1273  *  @brief Handle resume
1274  *
1275  *  @param intf		  Pointer to usb_interface
1276  *
1277  *  @return 	   	  MLAN_STATUS_SUCCESS
1278  */
woal_usb_resume(struct usb_interface * intf)1279 static int woal_usb_resume(struct usb_interface *intf)
1280 {
1281 	struct usb_card_rec *cardp = usb_get_intfdata(intf);
1282 	moal_handle *handle = NULL;
1283 	int i;
1284 
1285 	ENTER();
1286 
1287 	PRINTM(MCMND, "<--- Enter woal_usb_resume --->\n");
1288 	if (!cardp || !cardp->phandle) {
1289 		PRINTM(MERROR, "Card or adapter structure is not valid\n");
1290 		goto done;
1291 	}
1292 	handle = cardp->phandle;
1293 
1294 	if (handle->is_suspended == MFALSE) {
1295 		PRINTM(MWARN, "Device already resumed\n");
1296 		goto done;
1297 	}
1298 
1299 	/* Indicate device resumed.
1300 	 * The netdev queue will be resumed only after the urbs
1301 	 * have been resubmitted */
1302 	handle->is_suspended = MFALSE;
1303 
1304 	if (!atomic_read(&cardp->rx_data_urb_pending)) {
1305 		/* Submit multiple Rx data URBs */
1306 		woal_usb_submit_rx_data_urbs(handle);
1307 	}
1308 	if (!atomic_read(&cardp->rx_cmd_urb_pending)) {
1309 		cardp->rx_cmd.pmbuf =
1310 			woal_alloc_mlan_buffer(handle, MLAN_RX_CMD_BUF_SIZE);
1311 		if (cardp->rx_cmd.pmbuf)
1312 			woal_usb_submit_rx_urb(&cardp->rx_cmd,
1313 					       MLAN_RX_CMD_BUF_SIZE);
1314 	}
1315 
1316 	for (i = 0; i < handle->priv_num; i++)
1317 		if (handle->priv[i]->media_connected == MTRUE)
1318 			netif_carrier_on(handle->priv[i]->netdev);
1319 
1320 	/* Disable Host Sleep */
1321 	if (handle->hs_activated)
1322 		woal_cancel_hs(woal_get_priv(handle, MLAN_BSS_ROLE_ANY),
1323 			       MOAL_NO_WAIT);
1324 
1325 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1326 		/* Resume handler may be called due to remote wakeup,
1327 		   force to exit suspend anyway */
1328 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35)
1329 	cardp->udev->autosuspend_disabled = 1;
1330 #else
1331 #ifdef CONFIG_PM_RUNTIME
1332 	cardp->udev->dev.power.runtime_auto = 0;
1333 #endif
1334 #endif /* < 2.6.35 */
1335 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
1336 	cardp->udev->autoresume_disabled = 0;
1337 #endif /* < 2.6.33 */
1338 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
1339 #ifdef CONFIG_PM_RUNTIME
1340 	atomic_inc(&(cardp->udev)->dev.power.usage_count);
1341 #endif
1342 #endif /* >= 2.6.34 */
1343 #endif /* >= 2.6.24 */
1344 
1345 done:
1346 	PRINTM(MCMND, "<--- Leave woal_usb_resume --->\n");
1347 	LEAVE();
1348 	return 0;
1349 }
1350 #endif /* CONFIG_PM */
1351 
1352 /**
1353  *  @brief This function initialize the tx URBs
1354  *
1355  *  @param handle 	Pointer to moal_handle structure
1356  *
1357  *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1358  */
woal_usb_tx_init(moal_handle * handle)1359 mlan_status woal_usb_tx_init(moal_handle *handle)
1360 {
1361 	struct usb_card_rec *cardp = (struct usb_card_rec *)handle->card;
1362 	int i;
1363 	mlan_status ret = MLAN_STATUS_SUCCESS;
1364 
1365 	ENTER();
1366 
1367 	cardp->tx_cmd.handle = handle;
1368 	cardp->tx_cmd.ep = cardp->tx_cmd_ep;
1369 	/* Allocate URB for command */
1370 	cardp->tx_cmd.urb = usb_alloc_urb(0, GFP_KERNEL);
1371 	if (!cardp->tx_cmd.urb) {
1372 		PRINTM(MERROR, "Tx command URB allocation failed\n");
1373 		ret = MLAN_STATUS_FAILURE;
1374 		goto init_exit;
1375 	}
1376 
1377 	cardp->tx_data_ix = 0;
1378 	for (i = 0; i < MVUSB_TX_HIGH_WMARK; i++) {
1379 		cardp->tx_data_list[i].handle = handle;
1380 		cardp->tx_data_list[i].ep = cardp->tx_data_ep;
1381 		/* Allocate URB for data */
1382 		cardp->tx_data_list[i].urb = usb_alloc_urb(0, GFP_KERNEL);
1383 		if (!cardp->tx_data_list[i].urb) {
1384 			PRINTM(MERROR, "Tx data URB allocation failed\n");
1385 			ret = MLAN_STATUS_FAILURE;
1386 			goto init_exit;
1387 		}
1388 	}
1389 
1390 init_exit:
1391 	LEAVE();
1392 	return ret;
1393 }
1394 
1395 /**
1396  *  @brief This function submits the rx data URBs
1397  *
1398  *  @param handle 	Pointer to moal_handle structure
1399  *
1400  *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1401  */
woal_usb_submit_rx_data_urbs(moal_handle * handle)1402 mlan_status woal_usb_submit_rx_data_urbs(moal_handle *handle)
1403 {
1404 	struct usb_card_rec *cardp = (struct usb_card_rec *)handle->card;
1405 	int i;
1406 	mlan_status ret = MLAN_STATUS_FAILURE;
1407 	t_u32 buffer_len = MLAN_RX_DATA_BUF_SIZE;
1408 
1409 	ENTER();
1410 
1411 	if (cardp->rx_deaggr_ctrl.enable) {
1412 		buffer_len = cardp->rx_deaggr_ctrl.aggr_max;
1413 		if (cardp->rx_deaggr_ctrl.aggr_mode == MLAN_USB_AGGR_MODE_NUM) {
1414 			buffer_len *= MAX(MLAN_USB_MAX_PKT_SIZE,
1415 					  cardp->rx_deaggr_ctrl.aggr_align);
1416 			buffer_len = MAX(buffer_len, MLAN_RX_DATA_BUF_SIZE);
1417 		}
1418 	}
1419 
1420 	for (i = 0; i < MVUSB_RX_DATA_URB; i++) {
1421 		/* Submit Rx data URB */
1422 		if (!cardp->rx_data_list[i].pmbuf) {
1423 			if (woal_usb_submit_rx_urb(&cardp->rx_data_list[i],
1424 						   buffer_len))
1425 				continue;
1426 		}
1427 		ret = MLAN_STATUS_SUCCESS;
1428 	}
1429 	LEAVE();
1430 	return ret;
1431 }
1432 
1433 /**
1434  *  @brief This function initialize the rx URBs and submit them
1435  *
1436  *  @param handle 	Pointer to moal_handle structure
1437  *
1438  *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1439  */
woal_usb_rx_init(moal_handle * handle)1440 mlan_status woal_usb_rx_init(moal_handle *handle)
1441 {
1442 	struct usb_card_rec *cardp = (struct usb_card_rec *)handle->card;
1443 	int i;
1444 	mlan_status ret = MLAN_STATUS_SUCCESS;
1445 
1446 	ENTER();
1447 
1448 	cardp->rx_cmd.handle = handle;
1449 	cardp->rx_cmd.ep = cardp->rx_cmd_ep;
1450 	/* Allocate URB for command/event */
1451 	cardp->rx_cmd.urb = usb_alloc_urb(0, GFP_KERNEL);
1452 	if (!cardp->rx_cmd.urb) {
1453 		PRINTM(MERROR, "Rx command URB allocation failed\n");
1454 		ret = MLAN_STATUS_FAILURE;
1455 		goto init_exit;
1456 	}
1457 
1458 	cardp->rx_cmd.pmbuf =
1459 		woal_alloc_mlan_buffer(handle, MLAN_RX_CMD_BUF_SIZE);
1460 	if (cardp->rx_cmd.pmbuf) {
1461 		/* Submit Rx command URB */
1462 		if (woal_usb_submit_rx_urb(&cardp->rx_cmd,
1463 					   MLAN_RX_CMD_BUF_SIZE)) {
1464 			ret = MLAN_STATUS_FAILURE;
1465 			goto init_exit;
1466 		}
1467 	}
1468 	for (i = 0; i < MVUSB_RX_DATA_URB; i++) {
1469 		cardp->rx_data_list[i].handle = handle;
1470 		cardp->rx_data_list[i].ep = cardp->rx_data_ep;
1471 		/* Allocate URB for data */
1472 		cardp->rx_data_list[i].urb = usb_alloc_urb(0, GFP_KERNEL);
1473 		if (!cardp->rx_data_list[i].urb) {
1474 			PRINTM(MERROR, "Rx data URB allocation failed\n");
1475 			ret = MLAN_STATUS_FAILURE;
1476 			goto init_exit;
1477 		}
1478 	}
1479 	ret = woal_usb_submit_rx_data_urbs(handle);
1480 	if (ret) {
1481 		PRINTM(MERROR, "Rx data URB submission failed\n");
1482 		goto init_exit;
1483 	}
1484 
1485 init_exit:
1486 	LEAVE();
1487 	return ret;
1488 }
1489 
1490 /**
1491  *  @brief  This function downloads data blocks to device
1492  *
1493  *  @param handle	Pointer to moal_handle structure
1494  *  @param pmbuf	Pointer to mlan_buffer structure
1495  *  @param ep		Endpoint to send
1496  *  @param timeout 	Timeout value in milliseconds (if 0 the wait is forever)
1497  *
1498  *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1499  */
woal_usb_write_data_sync(moal_handle * handle,mlan_buffer * pmbuf,t_u32 endpoint,t_u32 timeout)1500 static mlan_status woal_usb_write_data_sync(moal_handle *handle,
1501 					    mlan_buffer *pmbuf, t_u32 endpoint,
1502 					    t_u32 timeout)
1503 {
1504 	struct usb_card_rec *cardp = handle->card;
1505 	t_u8 *data = (t_u8 *)(pmbuf->pbuf + pmbuf->data_offset);
1506 	t_u8 ep = endpoint;
1507 	t_u32 length = pmbuf->data_len;
1508 	int actual_length;
1509 	mlan_status ret = MLAN_STATUS_SUCCESS;
1510 	int bulk_out_maxpktsize = 512;
1511 
1512 	if (ep == cardp->tx_cmd_ep)
1513 		bulk_out_maxpktsize = cardp->tx_cmd_maxpktsize;
1514 	else if (ep == cardp->tx_data_ep)
1515 		bulk_out_maxpktsize = cardp->tx_data_maxpktsize;
1516 
1517 	if (length % bulk_out_maxpktsize == 0)
1518 		length++;
1519 
1520 	/* Send the data block */
1521 	ret = usb_bulk_msg(cardp->udev, usb_sndbulkpipe(cardp->udev, ep),
1522 			   (t_u8 *)data, length, &actual_length, timeout);
1523 	if (ret) {
1524 		PRINTM(MERROR, "usb_blk_msg for send failed, ret %d\n", ret);
1525 		ret = MLAN_STATUS_FAILURE;
1526 	}
1527 
1528 	pmbuf->data_len = actual_length;
1529 	DBG_HEXDUMP(MIF_D, "write sync", data, actual_length);
1530 
1531 	return ret;
1532 }
1533 
1534 /**
1535  *  @brief  This function read data blocks to device
1536  *
1537  *  @param handle	Pointer to moal_handle structure
1538  *  @param pmbuf	Pointer to mlan_buffer structure
1539  *  @param ep		Endpoint to receive
1540  *  @param timeout 	Timeout value in milliseconds (if 0 the wait is forever)
1541  *
1542  *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1543  */
woal_usb_read_data_sync(moal_handle * handle,mlan_buffer * pmbuf,t_u32 endpoint,t_u32 timeout)1544 static mlan_status woal_usb_read_data_sync(moal_handle *handle,
1545 					   mlan_buffer *pmbuf, t_u32 endpoint,
1546 					   t_u32 timeout)
1547 {
1548 	struct usb_card_rec *cardp = handle->card;
1549 	t_u8 *data = (t_u8 *)(pmbuf->pbuf + pmbuf->data_offset);
1550 	t_u8 ep = endpoint;
1551 	t_u32 buf_len = pmbuf->data_len;
1552 	int actual_length;
1553 	mlan_status ret = MLAN_STATUS_SUCCESS;
1554 	ENTER();
1555 	/* Receive the data response */
1556 	ret = usb_bulk_msg(cardp->udev, usb_rcvbulkpipe(cardp->udev, ep), data,
1557 			   buf_len, &actual_length, timeout);
1558 	if (ret) {
1559 		PRINTM(MERROR, "usb_bulk_msg failed: %d\n", ret);
1560 		ret = MLAN_STATUS_FAILURE;
1561 	}
1562 	pmbuf->data_len = actual_length;
1563 	DBG_HEXDUMP(MIF_D, "read sync", data, actual_length);
1564 	LEAVE();
1565 	return ret;
1566 }
1567 
1568 /**
1569  *  @brief  This function downloads data/command packet to device
1570  *
1571  *  @param handle	Pointer to moal_handle structure
1572  *  @param pmbuf	Pointer to mlan_buffer structure
1573  *  @param ep		Endpoint to send
1574  *
1575  *  @return 	   	MLAN_STATUS_PENDING or MLAN_STATUS_FAILURE or
1576  * MLAN_STATUS_RESOURCE
1577  */
woal_write_data_async(moal_handle * handle,mlan_buffer * pmbuf,t_u8 ep)1578 mlan_status woal_write_data_async(moal_handle *handle, mlan_buffer *pmbuf,
1579 				  t_u8 ep)
1580 {
1581 	struct usb_card_rec *cardp = handle->card;
1582 	urb_context *context = NULL;
1583 	t_u8 *data = (t_u8 *)(pmbuf->pbuf + pmbuf->data_offset);
1584 	struct urb *tx_urb = NULL;
1585 	mlan_status ret = MLAN_STATUS_SUCCESS;
1586 	t_u32 data_len = pmbuf->data_len;
1587 	int bulk_out_maxpktsize = 512;
1588 
1589 	ENTER();
1590 
1591 	/* Check if device is removed */
1592 	if (handle->surprise_removed) {
1593 		PRINTM(MERROR, "Device removed\n");
1594 		ret = MLAN_STATUS_FAILURE;
1595 		goto tx_ret;
1596 	}
1597 
1598 	if ((ep == cardp->tx_data_ep) &&
1599 	    (atomic_read(&cardp->tx_data_urb_pending) >= MVUSB_TX_HIGH_WMARK)) {
1600 		ret = MLAN_STATUS_RESOURCE;
1601 		goto tx_ret;
1602 	}
1603 	PRINTM(MINFO, "woal_write_data_async: ep=%d\n", ep);
1604 
1605 	if (ep == cardp->tx_cmd_ep) {
1606 		context = &cardp->tx_cmd;
1607 		bulk_out_maxpktsize = cardp->tx_cmd_maxpktsize;
1608 	} else {
1609 		if (ep == cardp->tx_data_ep) {
1610 			bulk_out_maxpktsize = cardp->tx_data_maxpktsize;
1611 			if (cardp->tx_data_ix >= MVUSB_TX_HIGH_WMARK)
1612 				cardp->tx_data_ix = 0;
1613 			context = &cardp->tx_data_list[cardp->tx_data_ix++];
1614 		}
1615 	}
1616 
1617 	if (!context) {
1618 		PRINTM(MERROR, "Cannot allocate Tx urb_context\n");
1619 		ret = MLAN_STATUS_FAILURE;
1620 		goto tx_ret;
1621 	}
1622 	context->handle = handle;
1623 	context->ep = ep;
1624 	context->pmbuf = pmbuf;
1625 
1626 	tx_urb = context->urb;
1627 
1628 	if (data_len % bulk_out_maxpktsize == 0)
1629 		data_len++;
1630 
1631 	/*
1632 	 * Use USB API usb_fill_bulk_urb() to set the
1633 	 * configuration information of the Tx bulk URB
1634 	 * and initialize the Tx callback
1635 	 */
1636 
1637 	if (ep == cardp->tx_cmd_ep &&
1638 	    cardp->tx_cmd_ep_type == USB_ENDPOINT_XFER_INT) {
1639 		usb_fill_int_urb(tx_urb, cardp->udev,
1640 				 usb_sndintpipe(cardp->udev, ep), data,
1641 				 data_len, woal_usb_tx_complete,
1642 				 (void *)context, cardp->tx_cmd_interval);
1643 	} else
1644 		usb_fill_bulk_urb(tx_urb, cardp->udev,
1645 				  usb_sndbulkpipe(cardp->udev, ep), data,
1646 				  data_len, woal_usb_tx_complete,
1647 				  (void *)context);
1648 	/* We find on Ubuntu 12.10 this flag does not work */
1649 	// tx_urb->transfer_flags |= URB_ZERO_PACKET;
1650 
1651 	if (ep == cardp->tx_cmd_ep)
1652 		atomic_inc(&cardp->tx_cmd_urb_pending);
1653 	else if (ep == cardp->tx_data_ep)
1654 		atomic_inc(&cardp->tx_data_urb_pending);
1655 	if (usb_submit_urb(tx_urb, GFP_ATOMIC)) {
1656 		/* Submit URB failure */
1657 		PRINTM(MERROR, "Submit EP %d Tx URB failed: %d\n", ep, ret);
1658 		if (ep == cardp->tx_cmd_ep)
1659 			atomic_dec(&cardp->tx_cmd_urb_pending);
1660 		else {
1661 			if (ep == cardp->tx_data_ep) {
1662 				atomic_dec(&cardp->tx_data_urb_pending);
1663 				if (cardp->tx_data_ix)
1664 					cardp->tx_data_ix--;
1665 				else
1666 					cardp->tx_data_ix = MVUSB_TX_HIGH_WMARK;
1667 			}
1668 		}
1669 		ret = MLAN_STATUS_FAILURE;
1670 	} else {
1671 		if (ep == cardp->tx_data_ep &&
1672 		    (atomic_read(&cardp->tx_data_urb_pending) ==
1673 		     MVUSB_TX_HIGH_WMARK))
1674 			ret = MLAN_STATUS_PRESOURCE;
1675 		else
1676 			ret = MLAN_STATUS_SUCCESS;
1677 	}
1678 
1679 tx_ret:
1680 
1681 	if (!ret)
1682 		ret = MLAN_STATUS_PENDING;
1683 
1684 	LEAVE();
1685 	return ret;
1686 }
1687 
1688 /**
1689  *  @brief  This function register usb device and initialize parameter
1690  *
1691  *  @param handle	Pointer to moal_handle structure
1692  *
1693  *  @return 	   	MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1694  */
woal_usb_register_dev(moal_handle * handle)1695 static mlan_status woal_usb_register_dev(moal_handle *handle)
1696 {
1697 	struct usb_card_rec *cardp = (struct usb_card_rec *)handle->card;
1698 	mlan_status ret = MLAN_STATUS_SUCCESS;
1699 
1700 	ENTER();
1701 
1702 	cardp->phandle = handle;
1703 	LEAVE();
1704 	return ret;
1705 }
1706 
woal_usb_unregister_dev(moal_handle * handle)1707 static void woal_usb_unregister_dev(moal_handle *handle)
1708 {
1709 	struct usb_card_rec *cardp = (struct usb_card_rec *)handle->card;
1710 	PRINTM(MMSG, "USB: unregister device\n");
1711 	woal_usb_free(cardp);
1712 	cardp->phandle = NULL;
1713 	return;
1714 }
1715 
1716 /**
1717  *  @brief This function registers driver.
1718  *
1719  *  @return 	 MLAN_STATUS_SUCCESS or MLAN_STATUS_FAILURE
1720  */
woal_usb_bus_register(void)1721 mlan_status woal_usb_bus_register(void)
1722 {
1723 	mlan_status ret = MLAN_STATUS_SUCCESS;
1724 	ENTER();
1725 
1726 	if (skip_fwdnld) {
1727 		woal_usb_driver.id_table = woal_usb_table_skip_fwdnld;
1728 	}
1729 	/*
1730 	 * API registers the NXP USB driver
1731 	 * to the USB system
1732 	 */
1733 	if (usb_register(&woal_usb_driver)) {
1734 		PRINTM(MFATAL, "USB Driver Registration Failed \n");
1735 		ret = MLAN_STATUS_FAILURE;
1736 	}
1737 	LEAVE();
1738 	return ret;
1739 }
1740 
1741 /**
1742  *  @brief This function removes usb driver.
1743  *
1744  *  @return 	   	N/A
1745  */
woal_usb_bus_unregister(void)1746 void woal_usb_bus_unregister(void)
1747 {
1748 	ENTER();
1749 	/* API unregisters the driver from USB subsystem */
1750 	usb_deregister(&woal_usb_driver);
1751 	LEAVE();
1752 	return;
1753 }
1754 
1755 /**
1756  *  @brief This function check if this is second mac
1757  *
1758  *  @param handle   A pointer to moal_handle structure
1759  *  @return         MTRUE/MFALSE
1760  *
1761  */
woal_usb_is_second_mac(moal_handle * handle)1762 static t_u8 woal_usb_is_second_mac(moal_handle *handle)
1763 {
1764 	return ((struct usb_card_rec *)(handle->card))->second_mac;
1765 }
1766 
1767 #ifdef CONFIG_USB_SUSPEND
1768 /**
1769  *  @brief This function makes USB device to suspend.
1770  *
1771  *  @param handle  A pointer to moal_handle structure
1772  *
1773  *  @return             0 --success, otherwise fail
1774  */
woal_enter_usb_suspend(moal_handle * handle)1775 int woal_enter_usb_suspend(moal_handle *handle)
1776 {
1777 	struct usb_device *udev = ((struct usb_card_rec *)(handle->card))->udev;
1778 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1779 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
1780 	struct usb_interface *intf =
1781 		((struct usb_card_rec *)(handle->card))->intf;
1782 #endif /* < 2.6.34 */
1783 #endif /* >= 2.6.24 */
1784 
1785 	ENTER();
1786 
1787 	PRINTM(MIOCTL, "USB suspend ioctl (state %d)\n", udev->state);
1788 
1789 	if (handle->is_suspended == MTRUE) {
1790 		PRINTM(MERROR, "Device already suspended\n");
1791 		LEAVE();
1792 		return -EFAULT;
1793 	}
1794 
1795 	handle->suspend_wait_q_woken = MFALSE;
1796 
1797 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1798 	/* Enter into USB suspend */
1799 	usb_lock_device(udev);
1800 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38)
1801 	udev->autosuspend_delay = 0; /* Autosuspend delay in jiffies */
1802 #else
1803 	pm_runtime_set_autosuspend_delay(&udev->dev, 0); /* Autosuspend delay in
1804 							    jiffies */
1805 #endif /* < 2.6.38 */
1806 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
1807 	udev->autosuspend_disabled = 0; /* /sys/bus/usb/devices/.../power/level
1808 					   < auto */
1809 #endif /* < 2.6.34 */
1810 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
1811 	udev->autoresume_disabled = 0;
1812 #endif /* < 2.6.33 */
1813 	usb_unlock_device(udev);
1814 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
1815 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
1816 	intf->pm_usage_cnt = 1;
1817 #else
1818 	atomic_set(&intf->pm_usage_cnt, 1);
1819 #endif /* < 2.6.32 */
1820 	usb_autopm_put_interface(intf);
1821 #else
1822 	usb_lock_device(udev);
1823 	atomic_set(&udev->dev.power.usage_count, 1);
1824 	usb_enable_autosuspend(udev);
1825 	usb_unlock_device(udev);
1826 #endif /* < 2.6.34 */
1827 #endif /* >= 2.6.24 */
1828 
1829 	/* Wait for suspend to complete */
1830 	wait_event_interruptible(handle->suspend_wait_q,
1831 				 handle->suspend_wait_q_woken);
1832 
1833 	LEAVE();
1834 	return 0;
1835 }
1836 
1837 /**
1838  *  @brief This function makes USB device to resume.
1839  *
1840  *  @param handle  A pointer to moal_handle structure
1841  *
1842  *  @return             0 --success, otherwise fail
1843  */
woal_exit_usb_suspend(moal_handle * handle)1844 int woal_exit_usb_suspend(moal_handle *handle)
1845 {
1846 	struct usb_device *udev = ((struct usb_card_rec *)(handle->card))->udev;
1847 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1848 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
1849 	struct usb_interface *intf =
1850 		((struct usb_card_rec *)(handle->card))->intf;
1851 #endif /* < 2.6.34 */
1852 #endif /* >= 2.6.24 */
1853 
1854 	ENTER();
1855 
1856 	PRINTM(MIOCTL, "USB resume ioctl (state %d)\n", udev->state);
1857 
1858 	if (handle->is_suspended == MFALSE ||
1859 	    udev->state != USB_STATE_SUSPENDED) {
1860 		PRINTM(MERROR, "Device already resumed\n");
1861 		LEAVE();
1862 		return -EFAULT;
1863 	}
1864 
1865 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
1866 	/* Exit from USB suspend */
1867 	usb_lock_device(udev);
1868 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
1869 	udev->autosuspend_disabled = 1; /* /sys/bus/usb/devices/.../power/level
1870 					   < on */
1871 #endif /* < 2.6.34 */
1872 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)
1873 	udev->autoresume_disabled = 0;
1874 #endif /* < 2.6.33 */
1875 	usb_unlock_device(udev);
1876 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34)
1877 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32)
1878 	intf->pm_usage_cnt = 0;
1879 #else
1880 	atomic_set(&intf->pm_usage_cnt, 0);
1881 #endif /* < 2.6.32 */
1882 	usb_autopm_get_interface(intf);
1883 #else
1884 	usb_lock_device(udev);
1885 	atomic_set(&udev->dev.power.usage_count, 0);
1886 	usb_disable_autosuspend(udev);
1887 	usb_unlock_device(udev);
1888 #endif /* < 2.6.34 */
1889 #endif /* >= 2.6.24 */
1890 
1891 	LEAVE();
1892 	return 0;
1893 }
1894 #endif /* CONFIG_USB_SUSPEND */
1895 
1896 /**
1897  *  @brief This function will submit rx urb.
1898  *
1899  *  @param handle   Pointer to moal_handle
1900  *  @param ep       Endpoint to re-submit urb
1901  *
1902  *  @return 	   	N/A
1903  */
woal_submit_rx_urb(moal_handle * handle,t_u8 ep)1904 void woal_submit_rx_urb(moal_handle *handle, t_u8 ep)
1905 {
1906 	struct usb_card_rec *cardp = (struct usb_card_rec *)handle->card;
1907 
1908 	ENTER();
1909 
1910 	if ((ep == cardp->rx_cmd_ep) &&
1911 	    (!atomic_read(&cardp->rx_cmd_urb_pending))) {
1912 		woal_usb_submit_rx_urb(&cardp->rx_cmd, MLAN_RX_CMD_BUF_SIZE);
1913 	}
1914 
1915 	LEAVE();
1916 	return;
1917 }
1918 
1919 /**
1920  *  @brief This function dump firmware memory to file
1921  *
1922  *  @param phandle   A pointer to moal_handle
1923  *
1924  *  @return         N/A
1925  */
woal_usb_dump_fw_info(moal_handle * phandle)1926 static void woal_usb_dump_fw_info(moal_handle *phandle)
1927 {
1928 	moal_private *priv = NULL;
1929 	mlan_ioctl_req *req = NULL;
1930 	mlan_ds_misc_cfg *pcfg_misc = NULL;
1931 	mlan_status status = MLAN_STATUS_SUCCESS;
1932 
1933 	ENTER();
1934 
1935 	priv = woal_get_priv(phandle, MLAN_BSS_ROLE_ANY);
1936 	if (!priv) {
1937 		PRINTM(MERROR, "woal_usb_dump_fw_info: priv is NULL!\n");
1938 		goto done;
1939 	}
1940 	/* Allocate an IOCTL request buffer */
1941 	req = woal_alloc_mlan_ioctl_req(sizeof(mlan_ds_misc_cfg));
1942 	if (req == NULL) {
1943 		PRINTM(MERROR, "woal_usb_dump_fw_info: alloc req fail!\n");
1944 		goto done;
1945 	}
1946 
1947 	/* Fill request buffer */
1948 	pcfg_misc = (mlan_ds_misc_cfg *)req->pbuf;
1949 	pcfg_misc->sub_command = MLAN_OID_MISC_FW_DUMP_EVENT;
1950 	req->req_id = MLAN_IOCTL_MISC_CFG;
1951 	req->action = MLAN_ACT_GET;
1952 
1953 	/* Send IOCTL request to MLAN */
1954 	status = woal_request_ioctl(priv, req, MOAL_IOCTL_WAIT);
1955 
1956 	if (status != MLAN_STATUS_PENDING)
1957 		kfree(req);
1958 	phandle->is_fw_dump_timer_set = MTRUE;
1959 	woal_mod_timer(&phandle->fw_dump_timer, MOAL_TIMER_5S);
1960 
1961 done:
1962 	LEAVE();
1963 	return;
1964 }
1965 
woal_usb_get_fw_name(moal_handle * handle)1966 static mlan_status woal_usb_get_fw_name(moal_handle *handle)
1967 {
1968 	mlan_status ret = MLAN_STATUS_SUCCESS;
1969 #if defined(USB8997) || defined(USB9098) || defined(USB9097) ||                \
1970 	defined(USB8978) || defined(USBNW62X)
1971 	t_u32 revision_id = 0;
1972 	t_u32 strap = 0;
1973 #endif
1974 	struct usb_card_rec *cardp = (struct usb_card_rec *)handle->card;
1975 #if defined(USB9098)
1976 	moal_handle *ref_handle = NULL;
1977 #endif
1978 
1979 	ENTER();
1980 	if (handle->params.fw_name)
1981 		goto done;
1982 	if (cardp->boot_state == USB_FW_READY)
1983 		goto done;
1984 #ifdef USB8801
1985 	if (IS_USB8801(handle->card_type))
1986 		goto done;
1987 #endif
1988 
1989 #if defined(USB8997) || defined(USB9098) || defined(USB9097) ||                \
1990 	defined(USB8978) || defined(USBNW62X)
1991 	ret = woal_check_chip_revision(handle, &revision_id, &strap);
1992 	if (ret != MLAN_STATUS_SUCCESS) {
1993 		PRINTM(MFATAL, "Chip revision check failure!\n");
1994 		ret = MLAN_STATUS_FAILURE;
1995 		goto done;
1996 	}
1997 	PRINTM(MCMND, "revision=0x%x, strap=0x%x\n", revision_id, strap);
1998 #endif
1999 
2000 #ifdef USB8997
2001 	if (IS_USB8997(handle->card_type)) {
2002 		if (strap == CARD_TYPE_USB_UART)
2003 			strcpy(handle->card_info->fw_name,
2004 			       USBUART8997_DEFAULT_COMBO_FW_NAME);
2005 		else if (strap != 0)
2006 			strcpy(handle->card_info->fw_name,
2007 			       USBUSB8997_DEFAULT_COMBO_FW_NAME);
2008 	}
2009 #endif
2010 
2011 #ifdef USB8978
2012 	if (IS_USB8978(handle->card_type)) {
2013 		if (strap == CARD_TYPE_USB_UART)
2014 			strcpy(handle->card_info->fw_name,
2015 			       USBUART8978_DEFAULT_COMBO_FW_NAME);
2016 		else if (strap != 0)
2017 			strcpy(handle->card_info->fw_name,
2018 			       USBUSB8978_DEFAULT_COMBO_FW_NAME);
2019 	}
2020 #endif
2021 
2022 #ifdef USB9098
2023 	if (IS_USB9098(handle->card_type)) {
2024 		if (cardp->second_mac) {
2025 			ref_handle = (moal_handle *)handle->pref_mac;
2026 			if (ref_handle) {
2027 				strcpy(handle->card_info->fw_name,
2028 				       ref_handle->card_info->fw_name);
2029 				strcpy(handle->card_info->fw_name_wlan,
2030 				       ref_handle->card_info->fw_name_wlan);
2031 			}
2032 			goto done;
2033 		}
2034 		switch (revision_id) {
2035 		case USB9098_Z1Z2:
2036 			if (strap != 0) {
2037 				if (strap == CARD_TYPE_USB_UART)
2038 					strcpy(handle->card_info->fw_name,
2039 					       USBUART9098_DEFAULT_COMBO_FW_NAME);
2040 				else
2041 					strcpy(handle->card_info->fw_name,
2042 					       USBUSB9098_DEFAULT_COMBO_FW_NAME);
2043 			}
2044 			strcpy(handle->card_info->fw_name_wlan,
2045 			       USB9098_DEFAULT_WLAN_FW_NAME);
2046 			break;
2047 		case USB9098_A0:
2048 		case USB9098_A1:
2049 		case USB9098_A2:
2050 			if (strap != 0) {
2051 				if (strap == CARD_TYPE_USB_UART)
2052 					strcpy(handle->card_info->fw_name,
2053 					       USBUART9098_COMBO_V1_FW_NAME);
2054 				else
2055 					strcpy(handle->card_info->fw_name,
2056 					       USBUSB9098_COMBO_V1_FW_NAME);
2057 			}
2058 			strcpy(handle->card_info->fw_name_wlan,
2059 			       USB9098_WLAN_V1_FW_NAME);
2060 			break;
2061 		}
2062 	}
2063 #endif
2064 #ifdef USB9097
2065 	if (IS_USB9097(handle->card_type)) {
2066 		switch (revision_id) {
2067 		case USB9097_B0:
2068 		case USB9097_B1:
2069 			if (strap != 0) {
2070 				if (strap == CARD_TYPE_USB_UART)
2071 					strcpy(handle->card_info->fw_name,
2072 					       USBUART9097_COMBO_V1_FW_NAME);
2073 				else
2074 					strcpy(handle->card_info->fw_name,
2075 					       USBUSB9097_COMBO_V1_FW_NAME);
2076 			}
2077 			strcpy(handle->card_info->fw_name_wlan,
2078 			       USB9097_WLAN_V1_FW_NAME);
2079 			break;
2080 		}
2081 	}
2082 #endif
2083 #ifdef USBNW62X
2084 	if (IS_USBNW62X(handle->card_type)) {
2085 		if (strap == CARD_TYPE_USB_UART)
2086 			strcpy(handle->card_info->fw_name,
2087 			       USBUARTNW62X_COMBO_FW_NAME);
2088 		else
2089 			strcpy(handle->card_info->fw_name,
2090 			       USBUSBNW62X_COMBO_FW_NAME);
2091 	}
2092 #endif
2093 
2094 done:
2095 	PRINTM(MCMND, "combo fw:%s wlan fw:%s \n", handle->card_info->fw_name,
2096 	       handle->card_info->fw_name_wlan);
2097 	LEAVE();
2098 	return ret;
2099 }
2100 
2101 static moal_if_ops usb_ops = {
2102 	.register_dev = woal_usb_register_dev,
2103 	.unregister_dev = woal_usb_unregister_dev,
2104 	.read_data_sync = woal_usb_read_data_sync,
2105 	.write_data_sync = woal_usb_write_data_sync,
2106 	.get_fw_name = woal_usb_get_fw_name,
2107 	.dump_fw_info = woal_usb_dump_fw_info,
2108 	.is_second_mac = woal_usb_is_second_mac,
2109 };
2110