aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/libertas/decl.h3
-rw-r--r--drivers/net/wireless/libertas/dev.h4
-rw-r--r--drivers/net/wireless/libertas/if_cs.c54
-rw-r--r--drivers/net/wireless/libertas/if_usb.c365
-rw-r--r--drivers/net/wireless/libertas/if_usb.h4
-rw-r--r--drivers/net/wireless/libertas/main.c405
6 files changed, 334 insertions, 501 deletions
diff --git a/drivers/net/wireless/libertas/decl.h b/drivers/net/wireless/libertas/decl.h
index 095edf6a4c29..87fea9d5b90a 100644
--- a/drivers/net/wireless/libertas/decl.h
+++ b/drivers/net/wireless/libertas/decl.h
@@ -72,8 +72,9 @@ void libertas_send_iwevcustom_event(wlan_private * priv, s8 * str);
72struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band, 72struct chan_freq_power *libertas_get_region_cfp_table(u8 region, u8 band,
73 int *cfp_no); 73 int *cfp_no);
74wlan_private *libertas_add_card(void *card, struct device *dmdev); 74wlan_private *libertas_add_card(void *card, struct device *dmdev);
75int libertas_activate_card(wlan_private *priv);
76int libertas_remove_card(wlan_private *priv); 75int libertas_remove_card(wlan_private *priv);
76int libertas_start_card(wlan_private *priv);
77int libertas_stop_card(wlan_private *priv);
77int libertas_add_mesh(wlan_private *priv, struct device *dev); 78int libertas_add_mesh(wlan_private *priv, struct device *dev);
78void libertas_remove_mesh(wlan_private *priv); 79void libertas_remove_mesh(wlan_private *priv);
79int libertas_reset_device(wlan_private *priv); 80int libertas_reset_device(wlan_private *priv);
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index a3c94d7388ab..1fb807aa91b9 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -143,7 +143,6 @@ struct _wlan_private {
143 all other bits reserved 0 */ 143 all other bits reserved 0 */
144 u8 dnld_sent; 144 u8 dnld_sent;
145 145
146 const struct firmware *firmware;
147 struct device *hotplug_device; 146 struct device *hotplug_device;
148 147
149 /** thread to service interrupts */ 148 /** thread to service interrupts */
@@ -156,9 +155,6 @@ struct _wlan_private {
156 struct work_struct sync_channel; 155 struct work_struct sync_channel;
157 156
158 /** Hardware access */ 157 /** Hardware access */
159 int (*hw_register_dev) (wlan_private * priv);
160 int (*hw_unregister_dev) (wlan_private *);
161 int (*hw_prog_firmware) (wlan_private *);
162 int (*hw_host_to_card) (wlan_private * priv, u8 type, u8 * payload, u16 nb); 158 int (*hw_host_to_card) (wlan_private * priv, u8 type, u8 * payload, u16 nb);
163 int (*hw_get_int_status) (wlan_private * priv, u8 *); 159 int (*hw_get_int_status) (wlan_private * priv, u8 *);
164 int (*hw_read_event_cause) (wlan_private *); 160 int (*hw_read_event_cause) (wlan_private *);
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 888f023a74e1..4dffc5cc0d1a 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -608,51 +608,6 @@ done:
608/* Callback functions for libertas.ko */ 608/* Callback functions for libertas.ko */
609/********************************************************************/ 609/********************************************************************/
610 610
611static int if_cs_register_dev(wlan_private *priv)
612{
613 struct if_cs_card *card = (struct if_cs_card *)priv->card;
614
615 lbs_deb_enter(LBS_DEB_CS);
616
617 card->priv = priv;
618
619 return 0;
620}
621
622
623static int if_cs_unregister_dev(wlan_private *priv)
624{
625 lbs_deb_enter(LBS_DEB_CS);
626
627 /*
628 * Nothing special here. Because the device's power gets turned off
629 * anyway, there's no need to send a RESET command like in if_usb.c
630 */
631
632 return 0;
633}
634
635
636/*
637 * This callback is a dummy. The reason is that the USB code needs
638 * to have various things set up in order to be able to download the
639 * firmware. That's not needed in our case.
640 *
641 * On the contrary, if libertas_add_card() has been called and we're
642 * then later called via libertas_activate_card(), but without a valid
643 * firmware, then it's quite tedious to tear down the half-installed
644 * card. Therefore, we download the firmware before calling adding/
645 * activating the card in the first place. If that doesn't work, we
646 * won't call into libertas.ko at all.
647 */
648
649static int if_cs_prog_firmware(wlan_private *priv)
650{
651 priv->adapter->fw_ready = 1;
652 return 0;
653}
654
655
656/* Send commands or data packets to the card */ 611/* Send commands or data packets to the card */
657static int if_cs_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 nb) 612static int if_cs_host_to_card(wlan_private *priv, u8 type, u8 *buf, u16 nb)
658{ 613{
@@ -902,14 +857,14 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
902 } 857 }
903 858
904 /* Store pointers to our call-back functions */ 859 /* Store pointers to our call-back functions */
860 card->priv = priv;
905 priv->card = card; 861 priv->card = card;
906 priv->hw_register_dev = if_cs_register_dev;
907 priv->hw_unregister_dev = if_cs_unregister_dev;
908 priv->hw_prog_firmware = if_cs_prog_firmware;
909 priv->hw_host_to_card = if_cs_host_to_card; 862 priv->hw_host_to_card = if_cs_host_to_card;
910 priv->hw_get_int_status = if_cs_get_int_status; 863 priv->hw_get_int_status = if_cs_get_int_status;
911 priv->hw_read_event_cause = if_cs_read_event_cause; 864 priv->hw_read_event_cause = if_cs_read_event_cause;
912 865
866 priv->adapter->fw_ready = 1;
867
913 /* Now actually get the IRQ */ 868 /* Now actually get the IRQ */
914 ret = request_irq(p_dev->irq.AssignedIRQ, if_cs_interrupt, 869 ret = request_irq(p_dev->irq.AssignedIRQ, if_cs_interrupt,
915 IRQF_SHARED, DRV_NAME, card); 870 IRQF_SHARED, DRV_NAME, card);
@@ -919,7 +874,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
919 } 874 }
920 875
921 /* And finally bring the card up */ 876 /* And finally bring the card up */
922 if (libertas_activate_card(priv) != 0) { 877 if (libertas_start_card(priv) != 0) {
923 lbs_pr_err("could not activate card\n"); 878 lbs_pr_err("could not activate card\n");
924 goto out3; 879 goto out3;
925 } 880 }
@@ -951,6 +906,7 @@ static void if_cs_detach(struct pcmcia_device *p_dev)
951 906
952 lbs_deb_enter(LBS_DEB_CS); 907 lbs_deb_enter(LBS_DEB_CS);
953 908
909 libertas_stop_card(card->priv);
954 libertas_remove_card(card->priv); 910 libertas_remove_card(card->priv);
955 if_cs_release(p_dev); 911 if_cs_release(p_dev);
956 kfree(card); 912 kfree(card);
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 364eae374b93..105a00a7025d 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -45,14 +45,14 @@ MODULE_DEVICE_TABLE(usb, if_usb_table);
45 45
46static void if_usb_receive(struct urb *urb); 46static void if_usb_receive(struct urb *urb);
47static void if_usb_receive_fwload(struct urb *urb); 47static void if_usb_receive_fwload(struct urb *urb);
48static int if_usb_register_dev(wlan_private * priv); 48static int if_usb_prog_firmware(struct usb_card_rec *cardp);
49static int if_usb_unregister_dev(wlan_private *);
50static int if_usb_prog_firmware(wlan_private *);
51static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb); 49static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 nb);
52static int if_usb_get_int_status(wlan_private * priv, u8 *); 50static int if_usb_get_int_status(wlan_private * priv, u8 *);
53static int if_usb_read_event_cause(wlan_private *); 51static int if_usb_read_event_cause(wlan_private *);
54static int usb_tx_block(wlan_private *priv, u8 *payload, u16 nb); 52static int usb_tx_block(struct usb_card_rec *cardp, u8 *payload, u16 nb);
55static void if_usb_free(struct usb_card_rec *cardp); 53static void if_usb_free(struct usb_card_rec *cardp);
54static int if_usb_submit_rx_urb(struct usb_card_rec *cardp);
55static int if_usb_reset_device(struct usb_card_rec *cardp);
56 56
57/** 57/**
58 * @brief call back function to handle the status of the URB 58 * @brief call back function to handle the status of the URB
@@ -61,29 +61,40 @@ static void if_usb_free(struct usb_card_rec *cardp);
61 */ 61 */
62static void if_usb_write_bulk_callback(struct urb *urb) 62static void if_usb_write_bulk_callback(struct urb *urb)
63{ 63{
64 wlan_private *priv = (wlan_private *) (urb->context); 64 struct usb_card_rec *cardp = (struct usb_card_rec *) urb->context;
65 wlan_adapter *adapter = priv->adapter;
66 struct net_device *dev = priv->dev;
67 65
68 /* handle the transmission complete validations */ 66 /* handle the transmission complete validations */
69 67
70 if (urb->status != 0) { 68 if (urb->status == 0) {
71 /* print the failure status number for debug */ 69 wlan_private *priv = cardp->priv;
72 lbs_pr_info("URB in failure status: %d\n", urb->status); 70
73 } else {
74 /* 71 /*
75 lbs_deb_usbd(&urb->dev->dev, "URB status is successfull\n"); 72 lbs_deb_usbd(&urb->dev->dev, "URB status is successfull\n");
76 lbs_deb_usbd(&urb->dev->dev, "Actual length transmitted %d\n", 73 lbs_deb_usbd(&urb->dev->dev, "Actual length transmitted %d\n",
77 urb->actual_length); 74 urb->actual_length);
78 */ 75 */
79 priv->dnld_sent = DNLD_RES_RECEIVED; 76
80 /* Wake main thread if commands are pending */ 77 /* Used for both firmware TX and regular TX. priv isn't
81 if (!adapter->cur_cmd) 78 * valid at firmware load time.
82 wake_up_interruptible(&priv->waitq); 79 */
83 if ((adapter->connect_status == LIBERTAS_CONNECTED)) { 80 if (priv) {
84 netif_wake_queue(dev); 81 wlan_adapter *adapter = priv->adapter;
85 netif_wake_queue(priv->mesh_dev); 82 struct net_device *dev = priv->dev;
83
84 priv->dnld_sent = DNLD_RES_RECEIVED;
85
86 /* Wake main thread if commands are pending */
87 if (!adapter->cur_cmd)
88 wake_up_interruptible(&priv->waitq);
89
90 if ((adapter->connect_status == LIBERTAS_CONNECTED)) {
91 netif_wake_queue(dev);
92 netif_wake_queue(priv->mesh_dev);
93 }
86 } 94 }
95 } else {
96 /* print the failure status number for debug */
97 lbs_pr_info("URB in failure status: %d\n", urb->status);
87 } 98 }
88 99
89 return; 100 return;
@@ -205,24 +216,35 @@ static int if_usb_probe(struct usb_interface *intf,
205 } 216 }
206 } 217 }
207 218
219 /* Upload firmware */
220 cardp->rinfo.cardp = cardp;
221 if (if_usb_prog_firmware(cardp)) {
222 lbs_deb_usbd(&udev->dev, "FW upload failed");
223 goto err_prog_firmware;
224 }
225
208 if (!(priv = libertas_add_card(cardp, &udev->dev))) 226 if (!(priv = libertas_add_card(cardp, &udev->dev)))
209 goto dealloc; 227 goto err_prog_firmware;
210 228
211 udev->dev.driver_data = priv; 229 cardp->priv = priv;
212 230
213 if (libertas_add_mesh(priv, &udev->dev)) 231 if (libertas_add_mesh(priv, &udev->dev))
214 goto err_add_mesh; 232 goto err_add_mesh;
215 233
216 priv->hw_register_dev = if_usb_register_dev; 234 cardp->eth_dev = priv->dev;
217 priv->hw_unregister_dev = if_usb_unregister_dev; 235
218 priv->hw_prog_firmware = if_usb_prog_firmware;
219 priv->hw_host_to_card = if_usb_host_to_card; 236 priv->hw_host_to_card = if_usb_host_to_card;
220 priv->hw_get_int_status = if_usb_get_int_status; 237 priv->hw_get_int_status = if_usb_get_int_status;
221 priv->hw_read_event_cause = if_usb_read_event_cause; 238 priv->hw_read_event_cause = if_usb_read_event_cause;
222 priv->boot2_version = udev->descriptor.bcdDevice; 239 priv->boot2_version = udev->descriptor.bcdDevice;
223 240
224 if (libertas_activate_card(priv)) 241 /* Delay 200 ms to waiting for the FW ready */
225 goto err_activate_card; 242 if_usb_submit_rx_urb(cardp);
243 msleep_interruptible(200);
244 priv->adapter->fw_ready = 1;
245
246 if (libertas_start_card(priv))
247 goto err_start_card;
226 248
227 list_add_tail(&cardp->list, &usb_devices); 249 list_add_tail(&cardp->list, &usb_devices);
228 250
@@ -231,11 +253,12 @@ static int if_usb_probe(struct usb_interface *intf,
231 253
232 return 0; 254 return 0;
233 255
234err_activate_card: 256err_start_card:
235 libertas_remove_mesh(priv); 257 libertas_remove_mesh(priv);
236err_add_mesh: 258err_add_mesh:
237 free_netdev(priv->dev); 259 libertas_remove_card(priv);
238 kfree(priv->adapter); 260err_prog_firmware:
261 if_usb_reset_device(cardp);
239dealloc: 262dealloc:
240 if_usb_free(cardp); 263 if_usb_free(cardp);
241 264
@@ -252,21 +275,22 @@ static void if_usb_disconnect(struct usb_interface *intf)
252{ 275{
253 struct usb_card_rec *cardp = usb_get_intfdata(intf); 276 struct usb_card_rec *cardp = usb_get_intfdata(intf);
254 wlan_private *priv = (wlan_private *) cardp->priv; 277 wlan_private *priv = (wlan_private *) cardp->priv;
255 wlan_adapter *adapter = NULL;
256 278
257 adapter = priv->adapter; 279 lbs_deb_enter(LBS_DEB_MAIN);
258 280
259 /* 281 /* Update Surprise removed to TRUE */
260 * Update Surprise removed to TRUE 282 cardp->surprise_removed = 1;
261 */
262 adapter->surpriseremoved = 1;
263 283
264 list_del(&cardp->list); 284 list_del(&cardp->list);
265 285
266 /* card is removed and we can call wlan_remove_card */ 286 if (priv) {
267 lbs_deb_usbd(&cardp->udev->dev, "call remove card\n"); 287 wlan_adapter *adapter = priv->adapter;
268 libertas_remove_mesh(priv); 288
269 libertas_remove_card(priv); 289 adapter->surpriseremoved = 1;
290 libertas_stop_card(priv);
291 libertas_remove_mesh(priv);
292 libertas_remove_card(priv);
293 }
270 294
271 /* Unlink and free urb */ 295 /* Unlink and free urb */
272 if_usb_free(cardp); 296 if_usb_free(cardp);
@@ -274,7 +298,7 @@ static void if_usb_disconnect(struct usb_interface *intf)
274 usb_set_intfdata(intf, NULL); 298 usb_set_intfdata(intf, NULL);
275 usb_put_dev(interface_to_usbdev(intf)); 299 usb_put_dev(interface_to_usbdev(intf));
276 300
277 return; 301 lbs_deb_leave(LBS_DEB_MAIN);
278} 302}
279 303
280/** 304/**
@@ -282,12 +306,11 @@ static void if_usb_disconnect(struct usb_interface *intf)
282 * @param priv pointer to wlan_private 306 * @param priv pointer to wlan_private
283 * @return 0 307 * @return 0
284 */ 308 */
285static int if_prog_firmware(wlan_private * priv) 309static int if_prog_firmware(struct usb_card_rec *cardp)
286{ 310{
287 struct usb_card_rec *cardp = priv->card;
288 struct FWData *fwdata; 311 struct FWData *fwdata;
289 struct fwheader *fwheader; 312 struct fwheader *fwheader;
290 u8 *firmware = priv->firmware->data; 313 u8 *firmware = cardp->fw->data;
291 314
292 fwdata = kmalloc(sizeof(struct FWData), GFP_ATOMIC); 315 fwdata = kmalloc(sizeof(struct FWData), GFP_ATOMIC);
293 316
@@ -335,7 +358,7 @@ static int if_prog_firmware(wlan_private * priv)
335 cardp->totalbytes); 358 cardp->totalbytes);
336 */ 359 */
337 memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE); 360 memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
338 usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE); 361 usb_tx_block(cardp, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
339 362
340 } else if (fwdata->fwheader.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) { 363 } else if (fwdata->fwheader.dnldcmd == cpu_to_le32(FW_HAS_LAST_BLOCK)) {
341 /* 364 /*
@@ -345,7 +368,7 @@ static int if_prog_firmware(wlan_private * priv)
345 "Donwloading FW JUMP BLOCK\n"); 368 "Donwloading FW JUMP BLOCK\n");
346 */ 369 */
347 memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE); 370 memcpy(cardp->bulk_out_buffer, fwheader, FW_DATA_XMIT_SIZE);
348 usb_tx_block(priv, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE); 371 usb_tx_block(cardp, cardp->bulk_out_buffer, FW_DATA_XMIT_SIZE);
349 cardp->fwfinalblk = 1; 372 cardp->fwfinalblk = 1;
350 } 373 }
351 374
@@ -360,10 +383,10 @@ static int if_prog_firmware(wlan_private * priv)
360 return 0; 383 return 0;
361} 384}
362 385
363static int if_usb_reset_device(wlan_private *priv) 386static int if_usb_reset_device(struct usb_card_rec *cardp)
364{ 387{
365 int ret; 388 int ret;
366 struct usb_card_rec *cardp = priv->card; 389 wlan_private * priv = cardp->priv;
367 390
368 lbs_deb_enter(LBS_DEB_USB); 391 lbs_deb_enter(LBS_DEB_USB);
369 392
@@ -371,7 +394,7 @@ static int if_usb_reset_device(wlan_private *priv)
371 * command to the firmware. 394 * command to the firmware.
372 */ 395 */
373 ret = usb_reset_device(cardp->udev); 396 ret = usb_reset_device(cardp->udev);
374 if (!ret) { 397 if (!ret && priv) {
375 msleep(10); 398 msleep(10);
376 ret = libertas_reset_device(priv); 399 ret = libertas_reset_device(priv);
377 msleep(10); 400 msleep(10);
@@ -389,14 +412,12 @@ static int if_usb_reset_device(wlan_private *priv)
389 * @param nb data length 412 * @param nb data length
390 * @return 0 or -1 413 * @return 0 or -1
391 */ 414 */
392static int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb) 415static int usb_tx_block(struct usb_card_rec *cardp, u8 * payload, u16 nb)
393{ 416{
394 /* pointer to card structure */
395 struct usb_card_rec *cardp = priv->card;
396 int ret = -1; 417 int ret = -1;
397 418
398 /* check if device is removed */ 419 /* check if device is removed */
399 if (priv->adapter->surpriseremoved) { 420 if (cardp->surprise_removed) {
400 lbs_deb_usbd(&cardp->udev->dev, "Device removed\n"); 421 lbs_deb_usbd(&cardp->udev->dev, "Device removed\n");
401 goto tx_ret; 422 goto tx_ret;
402 } 423 }
@@ -404,7 +425,7 @@ static int usb_tx_block(wlan_private * priv, u8 * payload, u16 nb)
404 usb_fill_bulk_urb(cardp->tx_urb, cardp->udev, 425 usb_fill_bulk_urb(cardp->tx_urb, cardp->udev,
405 usb_sndbulkpipe(cardp->udev, 426 usb_sndbulkpipe(cardp->udev,
406 cardp->bulk_out_endpointAddr), 427 cardp->bulk_out_endpointAddr),
407 payload, nb, if_usb_write_bulk_callback, priv); 428 payload, nb, if_usb_write_bulk_callback, cardp);
408 429
409 cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET; 430 cardp->tx_urb->transfer_flags |= URB_ZERO_PACKET;
410 431
@@ -421,11 +442,9 @@ tx_ret:
421 return ret; 442 return ret;
422} 443}
423 444
424static int __if_usb_submit_rx_urb(wlan_private * priv, 445static int __if_usb_submit_rx_urb(struct usb_card_rec *cardp,
425 void (*callbackfn) 446 void (*callbackfn)(struct urb *urb))
426 (struct urb *urb))
427{ 447{
428 struct usb_card_rec *cardp = priv->card;
429 struct sk_buff *skb; 448 struct sk_buff *skb;
430 struct read_cb_info *rinfo = &cardp->rinfo; 449 struct read_cb_info *rinfo = &cardp->rinfo;
431 int ret = -1; 450 int ret = -1;
@@ -461,22 +480,21 @@ rx_ret:
461 return ret; 480 return ret;
462} 481}
463 482
464static inline int if_usb_submit_rx_urb_fwload(wlan_private * priv) 483static int if_usb_submit_rx_urb_fwload(struct usb_card_rec *cardp)
465{ 484{
466 return __if_usb_submit_rx_urb(priv, &if_usb_receive_fwload); 485 return __if_usb_submit_rx_urb(cardp, &if_usb_receive_fwload);
467} 486}
468 487
469static inline int if_usb_submit_rx_urb(wlan_private * priv) 488static int if_usb_submit_rx_urb(struct usb_card_rec *cardp)
470{ 489{
471 return __if_usb_submit_rx_urb(priv, &if_usb_receive); 490 return __if_usb_submit_rx_urb(cardp, &if_usb_receive);
472} 491}
473 492
474static void if_usb_receive_fwload(struct urb *urb) 493static void if_usb_receive_fwload(struct urb *urb)
475{ 494{
476 struct read_cb_info *rinfo = (struct read_cb_info *)urb->context; 495 struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
477 wlan_private *priv = rinfo->priv;
478 struct sk_buff *skb = rinfo->skb; 496 struct sk_buff *skb = rinfo->skb;
479 struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card; 497 struct usb_card_rec *cardp = (struct usb_card_rec *)rinfo->cardp;
480 struct fwsyncheader *syncfwheader; 498 struct fwsyncheader *syncfwheader;
481 struct bootcmdrespStr bootcmdresp; 499 struct bootcmdrespStr bootcmdresp;
482 500
@@ -492,7 +510,7 @@ static void if_usb_receive_fwload(struct urb *urb)
492 sizeof(bootcmdresp)); 510 sizeof(bootcmdresp));
493 if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) { 511 if (le16_to_cpu(cardp->udev->descriptor.bcdDevice) < 0x3106) {
494 kfree_skb(skb); 512 kfree_skb(skb);
495 if_usb_submit_rx_urb_fwload(priv); 513 if_usb_submit_rx_urb_fwload(cardp);
496 cardp->bootcmdresp = 1; 514 cardp->bootcmdresp = 1;
497 lbs_deb_usbd(&cardp->udev->dev, 515 lbs_deb_usbd(&cardp->udev->dev,
498 "Received valid boot command response\n"); 516 "Received valid boot command response\n");
@@ -516,7 +534,7 @@ static void if_usb_receive_fwload(struct urb *urb)
516 "Received valid boot command response\n"); 534 "Received valid boot command response\n");
517 } 535 }
518 kfree_skb(skb); 536 kfree_skb(skb);
519 if_usb_submit_rx_urb_fwload(priv); 537 if_usb_submit_rx_urb_fwload(cardp);
520 return; 538 return;
521 } 539 }
522 540
@@ -552,9 +570,9 @@ static void if_usb_receive_fwload(struct urb *urb)
552 goto exit; 570 goto exit;
553 } 571 }
554 572
555 if_prog_firmware(priv); 573 if_prog_firmware(cardp);
556 574
557 if_usb_submit_rx_urb_fwload(priv); 575 if_usb_submit_rx_urb_fwload(cardp);
558exit: 576exit:
559 kfree(syncfwheader); 577 kfree(syncfwheader);
560 578
@@ -633,9 +651,9 @@ static inline void process_cmdrequest(int recvlength, u8 *recvbuff,
633static void if_usb_receive(struct urb *urb) 651static void if_usb_receive(struct urb *urb)
634{ 652{
635 struct read_cb_info *rinfo = (struct read_cb_info *)urb->context; 653 struct read_cb_info *rinfo = (struct read_cb_info *)urb->context;
636 wlan_private *priv = rinfo->priv;
637 struct sk_buff *skb = rinfo->skb; 654 struct sk_buff *skb = rinfo->skb;
638 struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card; 655 struct usb_card_rec *cardp = (struct usb_card_rec *) rinfo->cardp;
656 wlan_private * priv = cardp->priv;
639 657
640 int recvlength = urb->actual_length; 658 int recvlength = urb->actual_length;
641 u8 *recvbuff = NULL; 659 u8 *recvbuff = NULL;
@@ -696,7 +714,7 @@ static void if_usb_receive(struct urb *urb)
696 } 714 }
697 715
698setup_for_next: 716setup_for_next:
699 if_usb_submit_rx_urb(priv); 717 if_usb_submit_rx_urb(cardp);
700rx_exit: 718rx_exit:
701 lbs_deb_leave(LBS_DEB_USB); 719 lbs_deb_leave(LBS_DEB_USB);
702} 720}
@@ -731,7 +749,7 @@ static int if_usb_host_to_card(wlan_private * priv, u8 type, u8 * payload, u16 n
731 749
732 memcpy((cardp->bulk_out_buffer + MESSAGE_HEADER_LEN), payload, nb); 750 memcpy((cardp->bulk_out_buffer + MESSAGE_HEADER_LEN), payload, nb);
733 751
734 return usb_tx_block(priv, cardp->bulk_out_buffer, 752 return usb_tx_block(cardp, cardp->bulk_out_buffer,
735 nb + MESSAGE_HEADER_LEN); 753 nb + MESSAGE_HEADER_LEN);
736} 754}
737 755
@@ -751,46 +769,10 @@ static int if_usb_get_int_status(wlan_private * priv, u8 * ireg)
751static int if_usb_read_event_cause(wlan_private * priv) 769static int if_usb_read_event_cause(wlan_private * priv)
752{ 770{
753 struct usb_card_rec *cardp = priv->card; 771 struct usb_card_rec *cardp = priv->card;
772
754 priv->adapter->eventcause = cardp->usb_event_cause; 773 priv->adapter->eventcause = cardp->usb_event_cause;
755 /* Re-submit rx urb here to avoid event lost issue */ 774 /* Re-submit rx urb here to avoid event lost issue */
756 if_usb_submit_rx_urb(priv); 775 if_usb_submit_rx_urb(cardp);
757 return 0;
758}
759
760static int if_usb_unregister_dev(wlan_private * priv)
761{
762 int ret = 0;
763
764 /* Need to send a Reset command to device before USB resources freed
765 * and wlan_remove_card() called, then device can handle FW download
766 * again.
767 */
768 if (priv)
769 libertas_reset_device(priv);
770
771 return ret;
772}
773
774
775/**
776 * @brief This function register usb device and initialize parameter
777 * @param priv pointer to wlan_private
778 * @return 0 or -1
779 */
780static int if_usb_register_dev(wlan_private * priv)
781{
782 struct usb_card_rec *cardp = (struct usb_card_rec *)priv->card;
783
784 lbs_deb_enter(LBS_DEB_USB);
785
786 cardp->priv = priv;
787 cardp->eth_dev = priv->dev;
788 priv->hotplug_device = &(cardp->udev->dev);
789
790 lbs_deb_usbd(&cardp->udev->dev, "udev pointer is at %p\n",
791 cardp->udev);
792
793 lbs_deb_leave(LBS_DEB_USB);
794 return 0; 776 return 0;
795} 777}
796 778
@@ -800,10 +782,9 @@ static int if_usb_register_dev(wlan_private * priv)
800 * 2:Boot from FW in EEPROM 782 * 2:Boot from FW in EEPROM
801 * @return 0 783 * @return 0
802 */ 784 */
803static int if_usb_issue_boot_command(wlan_private *priv, int ivalue) 785static int if_usb_issue_boot_command(struct usb_card_rec *cardp, int ivalue)
804{ 786{
805 struct usb_card_rec *cardp = priv->card; 787 struct bootcmdstr sbootcmd;
806 struct bootcmdstr sbootcmd;
807 int i; 788 int i;
808 789
809 /* Prepare command */ 790 /* Prepare command */
@@ -814,28 +795,83 @@ static int if_usb_issue_boot_command(wlan_private *priv, int ivalue)
814 memcpy(cardp->bulk_out_buffer, &sbootcmd, sizeof(struct bootcmdstr)); 795 memcpy(cardp->bulk_out_buffer, &sbootcmd, sizeof(struct bootcmdstr));
815 796
816 /* Issue command */ 797 /* Issue command */
817 usb_tx_block(priv, cardp->bulk_out_buffer, sizeof(struct bootcmdstr)); 798 usb_tx_block(cardp, cardp->bulk_out_buffer, sizeof(struct bootcmdstr));
818 799
819 return 0; 800 return 0;
820} 801}
821 802
822 803
823static int if_usb_do_prog_firmware(wlan_private * priv) 804/**
805 * @brief This function checks the validity of Boot2/FW image.
806 *
807 * @param data pointer to image
808 * len image length
809 * @return 0 or -1
810 */
811static int check_fwfile_format(u8 *data, u32 totlen)
812{
813 u32 bincmd, exit;
814 u32 blksize, offset, len;
815 int ret;
816
817 ret = 1;
818 exit = len = 0;
819
820 do {
821 struct fwheader *fwh = (void *)data;
822
823 bincmd = le32_to_cpu(fwh->dnldcmd);
824 blksize = le32_to_cpu(fwh->datalength);
825 switch (bincmd) {
826 case FW_HAS_DATA_TO_RECV:
827 offset = sizeof(struct fwheader) + blksize;
828 data += offset;
829 len += offset;
830 if (len >= totlen)
831 exit = 1;
832 break;
833 case FW_HAS_LAST_BLOCK:
834 exit = 1;
835 ret = 0;
836 break;
837 default:
838 exit = 1;
839 break;
840 }
841 } while (!exit);
842
843 if (ret)
844 lbs_pr_err("firmware file format check FAIL\n");
845 else
846 lbs_deb_fw("firmware file format check PASS\n");
847
848 return ret;
849}
850
851
852static int if_usb_prog_firmware(struct usb_card_rec *cardp)
824{ 853{
825 struct usb_card_rec *cardp = priv->card;
826 int i = 0; 854 int i = 0;
827 static int reset_count = 10; 855 static int reset_count = 10;
828 int ret = 0; 856 int ret = 0;
829 857
830 lbs_deb_enter(LBS_DEB_USB); 858 lbs_deb_enter(LBS_DEB_USB);
831 859
832 cardp->rinfo.priv = priv; 860 if ((ret = request_firmware(&cardp->fw, libertas_fw_name,
861 &cardp->udev->dev)) < 0) {
862 lbs_pr_err("request_firmware() failed with %#x\n", ret);
863 lbs_pr_err("firmware %s not found\n", libertas_fw_name);
864 goto done;
865 }
866
867 if (check_fwfile_format(cardp->fw->data, cardp->fw->size))
868 goto release_fw;
833 869
834restart: 870restart:
835 if (if_usb_submit_rx_urb_fwload(priv) < 0) { 871 if (if_usb_submit_rx_urb_fwload(cardp) < 0) {
836 lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n"); 872 lbs_deb_usbd(&cardp->udev->dev, "URB submission is failed\n");
837 ret = -1; 873 ret = -1;
838 goto done; 874 goto release_fw;
839 } 875 }
840 876
841 cardp->bootcmdresp = 0; 877 cardp->bootcmdresp = 0;
@@ -843,7 +879,7 @@ restart:
843 int j = 0; 879 int j = 0;
844 i++; 880 i++;
845 /* Issue Boot command = 1, Boot from Download-FW */ 881 /* Issue Boot command = 1, Boot from Download-FW */
846 if_usb_issue_boot_command(priv, BOOT_CMD_FW_BY_USB); 882 if_usb_issue_boot_command(cardp, BOOT_CMD_FW_BY_USB);
847 /* wait for command response */ 883 /* wait for command response */
848 do { 884 do {
849 j++; 885 j++;
@@ -853,14 +889,13 @@ restart:
853 889
854 if (cardp->bootcmdresp == 0) { 890 if (cardp->bootcmdresp == 0) {
855 if (--reset_count >= 0) { 891 if (--reset_count >= 0) {
856 if_usb_reset_device(priv); 892 if_usb_reset_device(cardp);
857 goto restart; 893 goto restart;
858 } 894 }
859 return -1; 895 return -1;
860 } 896 }
861 897
862 i = 0; 898 i = 0;
863 priv->adapter->fw_ready = 0;
864 899
865 cardp->totalbytes = 0; 900 cardp->totalbytes = 0;
866 cardp->fwlastblksent = 0; 901 cardp->fwlastblksent = 0;
@@ -870,113 +905,37 @@ restart:
870 cardp->totalbytes = 0; 905 cardp->totalbytes = 0;
871 cardp->fwfinalblk = 0; 906 cardp->fwfinalblk = 0;
872 907
873 if_prog_firmware(priv); 908 if_prog_firmware(cardp);
874 909
875 do { 910 do {
876 lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n"); 911 lbs_deb_usbd(&cardp->udev->dev,"Wlan sched timeout\n");
877 i++; 912 i++;
878 msleep_interruptible(100); 913 msleep_interruptible(100);
879 if (priv->adapter->surpriseremoved || i >= 20) 914 if (cardp->surprise_removed || i >= 20)
880 break; 915 break;
881 } while (!cardp->fwdnldover); 916 } while (!cardp->fwdnldover);
882 917
883 if (!cardp->fwdnldover) { 918 if (!cardp->fwdnldover) {
884 lbs_pr_info("failed to load fw, resetting device!\n"); 919 lbs_pr_info("failed to load fw, resetting device!\n");
885 if (--reset_count >= 0) { 920 if (--reset_count >= 0) {
886 if_usb_reset_device(priv); 921 if_usb_reset_device(cardp);
887 goto restart; 922 goto restart;
888 } 923 }
889 924
890 lbs_pr_info("FW download failure, time = %d ms\n", i * 100); 925 lbs_pr_info("FW download failure, time = %d ms\n", i * 100);
891 ret = -1; 926 ret = -1;
892 goto done; 927 goto release_fw;
893 } 928 }
894 929
895 if_usb_submit_rx_urb(priv); 930release_fw:
896 931 release_firmware(cardp->fw);
897 /* Delay 200 ms to waiting for the FW ready */ 932 cardp->fw = NULL;
898 msleep_interruptible(200);
899
900 priv->adapter->fw_ready = 1;
901 933
902done: 934done:
903 lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret); 935 lbs_deb_leave_args(LBS_DEB_USB, "ret %d", ret);
904 return ret; 936 return ret;
905} 937}
906 938
907/**
908 * @brief This function checks the validity of Boot2/FW image.
909 *
910 * @param data pointer to image
911 * len image length
912 * @return 0 or -1
913 */
914static int check_fwfile_format(u8 *data, u32 totlen)
915{
916 u32 bincmd, exit;
917 u32 blksize, offset, len;
918 int ret;
919
920 ret = 1;
921 exit = len = 0;
922
923 do {
924 struct fwheader *fwh = (void *)data;
925
926 bincmd = le32_to_cpu(fwh->dnldcmd);
927 blksize = le32_to_cpu(fwh->datalength);
928 switch (bincmd) {
929 case FW_HAS_DATA_TO_RECV:
930 offset = sizeof(struct fwheader) + blksize;
931 data += offset;
932 len += offset;
933 if (len >= totlen)
934 exit = 1;
935 break;
936 case FW_HAS_LAST_BLOCK:
937 exit = 1;
938 ret = 0;
939 break;
940 default:
941 exit = 1;
942 break;
943 }
944 } while (!exit);
945
946 if (ret)
947 lbs_pr_err("firmware file format check FAIL\n");
948 else
949 lbs_deb_fw("firmware file format check PASS\n");
950
951 return ret;
952}
953
954
955static int if_usb_prog_firmware(wlan_private *priv)
956{
957 int ret = -1;
958
959 lbs_deb_enter(LBS_DEB_FW);
960
961 if ((ret = request_firmware(&priv->firmware, libertas_fw_name,
962 priv->hotplug_device)) < 0) {
963 lbs_pr_err("request_firmware() failed with %#x\n", ret);
964 lbs_pr_err("firmware %s not found\n", libertas_fw_name);
965 goto done;
966 }
967
968 if (check_fwfile_format(priv->firmware->data, priv->firmware->size)) {
969 release_firmware(priv->firmware);
970 goto done;
971 }
972
973 ret = if_usb_do_prog_firmware(priv);
974
975 release_firmware(priv->firmware);
976done:
977 return ret;
978}
979
980 939
981#ifdef CONFIG_PM 940#ifdef CONFIG_PM
982static int if_usb_suspend(struct usb_interface *intf, pm_message_t message) 941static int if_usb_suspend(struct usb_interface *intf, pm_message_t message)
diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h
index 8b3b4f1e47f6..e07a10ed28b5 100644
--- a/drivers/net/wireless/libertas/if_usb.h
+++ b/drivers/net/wireless/libertas/if_usb.h
@@ -38,7 +38,7 @@ struct bootcmdrespStr
38 38
39/* read callback private data */ 39/* read callback private data */
40struct read_cb_info { 40struct read_cb_info {
41 wlan_private *priv; 41 struct usb_card_rec *cardp;
42 struct sk_buff *skb; 42 struct sk_buff *skb;
43}; 43};
44 44
@@ -58,6 +58,7 @@ struct usb_card_rec {
58 int bulk_out_size; 58 int bulk_out_size;
59 u8 bulk_out_endpointAddr; 59 u8 bulk_out_endpointAddr;
60 60
61 const struct firmware *fw;
61 u8 CRC_OK; 62 u8 CRC_OK;
62 u32 fwseqnum; 63 u32 fwseqnum;
63 u32 lastseqnum; 64 u32 lastseqnum;
@@ -65,6 +66,7 @@ struct usb_card_rec {
65 u32 fwlastblksent; 66 u32 fwlastblksent;
66 u8 fwdnldover; 67 u8 fwdnldover;
67 u8 fwfinalblk; 68 u8 fwfinalblk;
69 u8 surprise_removed;
68 70
69 u32 usb_event_cause; 71 u32 usb_event_cause;
70 u8 usb_int_cause; 72 u8 usb_int_cause;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index ce1c18ee6280..6304bd97d399 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -791,7 +791,6 @@ static int libertas_thread(void *data)
791 } else 791 } else
792 spin_unlock_irq(&adapter->driver_lock); 792 spin_unlock_irq(&adapter->driver_lock);
793 793
794
795 lbs_deb_thread( 794 lbs_deb_thread(
796 "main-thread 222 (waking up): intcounter=%d currenttxskb=%p " 795 "main-thread 222 (waking up): intcounter=%d currenttxskb=%p "
797 "dnld_sent=%d\n", adapter->intcounter, 796 "dnld_sent=%d\n", adapter->intcounter,
@@ -926,7 +925,7 @@ static int libertas_thread(void *data)
926 * @param priv A pointer to wlan_private structure 925 * @param priv A pointer to wlan_private structure
927 * @return 0 or -1 926 * @return 0 or -1
928 */ 927 */
929static int wlan_setup_station_hw(wlan_private * priv) 928static int wlan_setup_firmware(wlan_private * priv)
930{ 929{
931 int ret = -1; 930 int ret = -1;
932 wlan_adapter *adapter = priv->adapter; 931 wlan_adapter *adapter = priv->adapter;
@@ -934,14 +933,6 @@ static int wlan_setup_station_hw(wlan_private * priv)
934 933
935 lbs_deb_enter(LBS_DEB_FW); 934 lbs_deb_enter(LBS_DEB_FW);
936 935
937 ret = priv->hw_prog_firmware(priv);
938
939 if (ret) {
940 lbs_deb_fw("bootloader in invalid state\n");
941 ret = -1;
942 goto done;
943 }
944
945 /* 936 /*
946 * Read MAC address from HW 937 * Read MAC address from HW
947 */ 938 */
@@ -992,8 +983,6 @@ done:
992 return ret; 983 return ret;
993} 984}
994 985
995static void command_timer_fn(unsigned long data);
996
997/** 986/**
998 * This function handles the timeout of command sending. 987 * This function handles the timeout of command sending.
999 * It will re-send the same command again. 988 * It will re-send the same command again.
@@ -1035,155 +1024,99 @@ static void command_timer_fn(unsigned long data)
1035 return; 1024 return;
1036} 1025}
1037 1026
1038static void libertas_free_adapter(wlan_private * priv) 1027static int libertas_init_adapter(wlan_private * priv)
1039{ 1028{
1040 wlan_adapter *adapter = priv->adapter; 1029 wlan_adapter *adapter = priv->adapter;
1041
1042 if (!adapter) {
1043 lbs_deb_fw("why double free adapter?\n");
1044 return;
1045 }
1046
1047 lbs_deb_fw("free command buffer\n");
1048 libertas_free_cmd_buffer(priv);
1049
1050 lbs_deb_fw("free command_timer\n");
1051 del_timer(&adapter->command_timer);
1052
1053 lbs_deb_fw("free scan results table\n");
1054 kfree(adapter->networks);
1055 adapter->networks = NULL;
1056
1057 /* Free the adapter object itself */
1058 lbs_deb_fw("free adapter\n");
1059 kfree(adapter);
1060 priv->adapter = NULL;
1061}
1062
1063static int wlan_allocate_adapter(wlan_private * priv)
1064{
1065 size_t bufsize; 1030 size_t bufsize;
1066 wlan_adapter *adapter = priv->adapter; 1031 int i, ret = 0;
1067 1032
1068 /* Allocate buffer to store the BSSID list */ 1033 /* Allocate buffer to store the BSSID list */
1069 bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor); 1034 bufsize = MAX_NETWORK_COUNT * sizeof(struct bss_descriptor);
1070 adapter->networks = kzalloc(bufsize, GFP_KERNEL); 1035 adapter->networks = kzalloc(bufsize, GFP_KERNEL);
1071 if (!adapter->networks) { 1036 if (!adapter->networks) {
1072 lbs_pr_err("Out of memory allocating beacons\n"); 1037 lbs_pr_err("Out of memory allocating beacons\n");
1073 libertas_free_adapter(priv); 1038 ret = -1;
1074 return -ENOMEM; 1039 goto out;
1075 } 1040 }
1076 1041
1077 /* Allocate the command buffers */ 1042 /* Initialize scan result lists */
1078 libertas_allocate_cmd_buffer(priv); 1043 INIT_LIST_HEAD(&adapter->network_free_list);
1044 INIT_LIST_HEAD(&adapter->network_list);
1045 for (i = 0; i < MAX_NETWORK_COUNT; i++) {
1046 list_add_tail(&adapter->networks[i].list,
1047 &adapter->network_free_list);
1048 }
1079 1049
1080 memset(&adapter->libertas_ps_confirm_sleep, 0, sizeof(struct PS_CMD_ConfirmSleep));
1081 adapter->libertas_ps_confirm_sleep.seqnum = cpu_to_le16(++adapter->seqnum); 1050 adapter->libertas_ps_confirm_sleep.seqnum = cpu_to_le16(++adapter->seqnum);
1082 adapter->libertas_ps_confirm_sleep.command = 1051 adapter->libertas_ps_confirm_sleep.command =
1083 cpu_to_le16(CMD_802_11_PS_MODE); 1052 cpu_to_le16(CMD_802_11_PS_MODE);
1084 adapter->libertas_ps_confirm_sleep.size = 1053 adapter->libertas_ps_confirm_sleep.size =
1085 cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep)); 1054 cpu_to_le16(sizeof(struct PS_CMD_ConfirmSleep));
1086 adapter->libertas_ps_confirm_sleep.result = 0;
1087 adapter->libertas_ps_confirm_sleep.action = 1055 adapter->libertas_ps_confirm_sleep.action =
1088 cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED); 1056 cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED);
1089 1057
1090 return 0;
1091}
1092
1093static void wlan_init_adapter(wlan_private * priv)
1094{
1095 wlan_adapter *adapter = priv->adapter;
1096 int i;
1097
1098 adapter->connect_status = LIBERTAS_DISCONNECTED;
1099 memset(adapter->current_addr, 0xff, ETH_ALEN); 1058 memset(adapter->current_addr, 0xff, ETH_ALEN);
1100 1059
1101 /* 802.11 specific */ 1060 adapter->connect_status = LIBERTAS_DISCONNECTED;
1102 adapter->secinfo.wep_enabled = 0;
1103 for (i = 0; i < sizeof(adapter->wep_keys) / sizeof(adapter->wep_keys[0]);
1104 i++)
1105 memset(&adapter->wep_keys[i], 0, sizeof(struct enc_key));
1106 adapter->wep_tx_keyidx = 0;
1107 adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 1061 adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1108 adapter->mode = IW_MODE_INFRA; 1062 adapter->mode = IW_MODE_INFRA;
1109
1110 adapter->pending_assoc_req = NULL;
1111 adapter->in_progress_assoc_req = NULL;
1112
1113 /* Initialize scan result lists */
1114 INIT_LIST_HEAD(&adapter->network_free_list);
1115 INIT_LIST_HEAD(&adapter->network_list);
1116 for (i = 0; i < MAX_NETWORK_COUNT; i++) {
1117 list_add_tail(&adapter->networks[i].list,
1118 &adapter->network_free_list);
1119 }
1120
1121 mutex_init(&adapter->lock);
1122
1123 memset(&adapter->curbssparams, 0, sizeof(adapter->curbssparams));
1124 adapter->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL; 1063 adapter->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
1125 1064 adapter->currentpacketfilter = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
1126 /* PnP and power profile */
1127 adapter->surpriseremoved = 0;
1128
1129 adapter->currentpacketfilter =
1130 CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
1131
1132 adapter->radioon = RADIO_ON; 1065 adapter->radioon = RADIO_ON;
1133
1134 adapter->auto_rate = 1; 1066 adapter->auto_rate = 1;
1135 adapter->cur_rate = 0;
1136
1137 // set default capabilities
1138 adapter->capability = WLAN_CAPABILITY_SHORT_PREAMBLE; 1067 adapter->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
1139
1140 adapter->psmode = WLAN802_11POWERMODECAM; 1068 adapter->psmode = WLAN802_11POWERMODECAM;
1141
1142 adapter->psstate = PS_STATE_FULL_POWER; 1069 adapter->psstate = PS_STATE_FULL_POWER;
1143 adapter->needtowakeup = 0;
1144 1070
1145 adapter->intcounter = 0; 1071 mutex_init(&adapter->lock);
1146
1147 adapter->currenttxskb = NULL;
1148 1072
1149 memset(&adapter->tx_queue_ps, 0, NR_TX_QUEUE*sizeof(struct sk_buff*)); 1073 memset(&adapter->tx_queue_ps, 0, NR_TX_QUEUE*sizeof(struct sk_buff*));
1150 adapter->tx_queue_idx = 0; 1074 adapter->tx_queue_idx = 0;
1151 spin_lock_init(&adapter->txqueue_lock); 1075 spin_lock_init(&adapter->txqueue_lock);
1152 1076
1153 return; 1077 setup_timer(&adapter->command_timer, command_timer_fn,
1154} 1078 (unsigned long)priv);
1155 1079
1156static int libertas_init_fw(wlan_private * priv) 1080 INIT_LIST_HEAD(&adapter->cmdfreeq);
1157{ 1081 INIT_LIST_HEAD(&adapter->cmdpendingq);
1158 int ret = -1;
1159 wlan_adapter *adapter = priv->adapter;
1160 1082
1161 lbs_deb_enter(LBS_DEB_FW); 1083 spin_lock_init(&adapter->driver_lock);
1084 init_waitqueue_head(&adapter->cmd_pending);
1085 adapter->nr_cmd_pending = 0;
1162 1086
1163 /* Allocate adapter structure */ 1087 /* Allocate the command buffers */
1164 if ((ret = wlan_allocate_adapter(priv)) != 0) 1088 if (libertas_allocate_cmd_buffer(priv)) {
1165 goto done; 1089 lbs_pr_err("Out of memory allocating command buffers\n");
1090 ret = -1;
1091 }
1166 1092
1167 /* init adapter structure */ 1093out:
1168 wlan_init_adapter(priv); 1094 return ret;
1095}
1169 1096
1170 /* init timer etc. */ 1097static void libertas_free_adapter(wlan_private * priv)
1171 setup_timer(&adapter->command_timer, command_timer_fn, 1098{
1172 (unsigned long)priv); 1099 wlan_adapter *adapter = priv->adapter;
1173 1100
1174 /* download fimrware etc. */ 1101 if (!adapter) {
1175 if ((ret = wlan_setup_station_hw(priv)) != 0) { 1102 lbs_deb_fw("why double free adapter?\n");
1176 del_timer_sync(&adapter->command_timer); 1103 return;
1177 goto done;
1178 } 1104 }
1179 1105
1180 /* init 802.11d */ 1106 lbs_deb_fw("free command buffer\n");
1181 libertas_init_11d(priv); 1107 libertas_free_cmd_buffer(priv);
1182 1108
1183 ret = 0; 1109 lbs_deb_fw("free command_timer\n");
1184done: 1110 del_timer(&adapter->command_timer);
1185 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); 1111
1186 return ret; 1112 lbs_deb_fw("free scan results table\n");
1113 kfree(adapter->networks);
1114 adapter->networks = NULL;
1115
1116 /* Free the adapter object itself */
1117 lbs_deb_fw("free adapter\n");
1118 kfree(adapter);
1119 priv->adapter = NULL;
1187} 1120}
1188 1121
1189/** 1122/**
@@ -1203,9 +1136,9 @@ wlan_private *libertas_add_card(void *card, struct device *dmdev)
1203 /* Allocate an Ethernet device and register it */ 1136 /* Allocate an Ethernet device and register it */
1204 if (!(dev = alloc_etherdev(sizeof(wlan_private)))) { 1137 if (!(dev = alloc_etherdev(sizeof(wlan_private)))) {
1205 lbs_pr_err("init ethX device failed\n"); 1138 lbs_pr_err("init ethX device failed\n");
1206 return NULL; 1139 goto done;
1207 } 1140 }
1208 priv = dev->priv; 1141 dmdev->driver_data = priv = dev->priv;
1209 1142
1210 /* allocate buffer for wlan_adapter */ 1143 /* allocate buffer for wlan_adapter */
1211 if (!(priv->adapter = kzalloc(sizeof(wlan_adapter), GFP_KERNEL))) { 1144 if (!(priv->adapter = kzalloc(sizeof(wlan_adapter), GFP_KERNEL))) {
@@ -1213,10 +1146,16 @@ wlan_private *libertas_add_card(void *card, struct device *dmdev)
1213 goto err_kzalloc; 1146 goto err_kzalloc;
1214 } 1147 }
1215 1148
1149 if (libertas_init_adapter(priv)) {
1150 lbs_pr_err("failed to initialize adapter structure.\n");
1151 goto err_init_adapter;
1152 }
1153
1216 priv->dev = dev; 1154 priv->dev = dev;
1217 priv->card = card; 1155 priv->card = card;
1218 priv->mesh_open = 0; 1156 priv->mesh_open = 0;
1219 priv->infra_open = 0; 1157 priv->infra_open = 0;
1158 priv->hotplug_device = dmdev;
1220 1159
1221 SET_MODULE_OWNER(dev); 1160 SET_MODULE_OWNER(dev);
1222 1161
@@ -1239,87 +1178,144 @@ wlan_private *libertas_add_card(void *card, struct device *dmdev)
1239 1178
1240 SET_NETDEV_DEV(dev, dmdev); 1179 SET_NETDEV_DEV(dev, dmdev);
1241 1180
1242 INIT_LIST_HEAD(&priv->adapter->cmdfreeq);
1243 INIT_LIST_HEAD(&priv->adapter->cmdpendingq);
1244
1245 spin_lock_init(&priv->adapter->driver_lock);
1246 init_waitqueue_head(&priv->adapter->cmd_pending);
1247 priv->adapter->nr_cmd_pending = 0;
1248 priv->rtap_net_dev = NULL; 1181 priv->rtap_net_dev = NULL;
1249 if (device_create_file(dmdev, &dev_attr_libertas_rtap)) 1182 if (device_create_file(dmdev, &dev_attr_libertas_rtap))
1250 goto err_kzalloc; 1183 goto err_init_adapter;
1184
1185 lbs_deb_thread("Starting main thread...\n");
1186 init_waitqueue_head(&priv->waitq);
1187 priv->main_thread = kthread_run(libertas_thread, dev, "libertas_main");
1188 if (IS_ERR(priv->main_thread)) {
1189 lbs_deb_thread("Error creating main thread.\n");
1190 goto err_kthread_run;
1191 }
1192
1193 priv->work_thread = create_singlethread_workqueue("libertas_worker");
1194 INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker);
1195 INIT_DELAYED_WORK(&priv->scan_work, libertas_scan_worker);
1196 INIT_WORK(&priv->sync_channel, libertas_sync_channel);
1197
1251 goto done; 1198 goto done;
1252 1199
1200err_kthread_run:
1201 device_remove_file(dmdev, &dev_attr_libertas_rtap);
1202
1203err_init_adapter:
1204 libertas_free_adapter(priv);
1205
1253err_kzalloc: 1206err_kzalloc:
1254 free_netdev(dev); 1207 free_netdev(dev);
1255 priv = NULL; 1208 priv = NULL;
1209
1256done: 1210done:
1257 lbs_deb_leave_args(LBS_DEB_NET, "priv %p", priv); 1211 lbs_deb_leave_args(LBS_DEB_NET, "priv %p", priv);
1258 return priv; 1212 return priv;
1259} 1213}
1260EXPORT_SYMBOL_GPL(libertas_add_card); 1214EXPORT_SYMBOL_GPL(libertas_add_card);
1261 1215
1262int libertas_activate_card(wlan_private *priv) 1216
1217int libertas_remove_card(wlan_private *priv)
1263{ 1218{
1219 wlan_adapter *adapter = priv->adapter;
1264 struct net_device *dev = priv->dev; 1220 struct net_device *dev = priv->dev;
1265 int ret = -1; 1221 union iwreq_data wrqu;
1266 1222
1267 lbs_deb_enter(LBS_DEB_MAIN); 1223 lbs_deb_enter(LBS_DEB_MAIN);
1268 1224
1269 lbs_deb_thread("Starting main thread...\n"); 1225 libertas_remove_rtap(priv);
1270 init_waitqueue_head(&priv->waitq);
1271 priv->main_thread = kthread_run(libertas_thread, dev, "libertas_main");
1272 if (IS_ERR(priv->main_thread)) {
1273 lbs_deb_thread("Error creating main thread.\n");
1274 goto done;
1275 }
1276 1226
1277 priv->work_thread = create_singlethread_workqueue("libertas_worker"); 1227 dev = priv->dev;
1278 INIT_DELAYED_WORK(&priv->assoc_work, libertas_association_worker); 1228 device_remove_file(priv->hotplug_device, &dev_attr_libertas_rtap);
1279 INIT_DELAYED_WORK(&priv->scan_work, libertas_scan_worker);
1280 1229
1281 INIT_WORK(&priv->sync_channel, libertas_sync_channel); 1230 cancel_delayed_work(&priv->scan_work);
1231 cancel_delayed_work(&priv->assoc_work);
1232 destroy_workqueue(priv->work_thread);
1282 1233
1283 /* 1234 if (adapter->psmode == WLAN802_11POWERMODEMAX_PSP) {
1284 * Register the device. Fillup the private data structure with 1235 adapter->psmode = WLAN802_11POWERMODECAM;
1285 * relevant information from the card and request for the required 1236 libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
1286 * IRQ.
1287 */
1288 if (priv->hw_register_dev(priv) < 0) {
1289 lbs_pr_err("failed to register WLAN device\n");
1290 goto err_registerdev;
1291 } 1237 }
1292 1238
1293 /* init FW and HW */ 1239 memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
1294 if (libertas_init_fw(priv)) { 1240 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1295 lbs_pr_err("firmware init failed\n"); 1241 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1296 goto err_registerdev; 1242
1297 } 1243 /* Stop the thread servicing the interrupts */
1244 adapter->surpriseremoved = 1;
1245 kthread_stop(priv->main_thread);
1246
1247 libertas_free_adapter(priv);
1248
1249 priv->dev = NULL;
1250 free_netdev(dev);
1251
1252 lbs_deb_leave(LBS_DEB_MAIN);
1253 return 0;
1254}
1255EXPORT_SYMBOL_GPL(libertas_remove_card);
1256
1257
1258int libertas_start_card(wlan_private *priv)
1259{
1260 struct net_device *dev = priv->dev;
1261 int ret = -1;
1262
1263 lbs_deb_enter(LBS_DEB_MAIN);
1264
1265 /* poke the firmware */
1266 ret = wlan_setup_firmware(priv);
1267 if (ret)
1268 goto done;
1269
1270 /* init 802.11d */
1271 libertas_init_11d(priv);
1298 1272
1299 if (register_netdev(dev)) { 1273 if (register_netdev(dev)) {
1300 lbs_pr_err("cannot register ethX device\n"); 1274 lbs_pr_err("cannot register ethX device\n");
1301 goto err_init_fw; 1275 goto done;
1302 } 1276 }
1303 1277
1304 lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
1305
1306 libertas_debugfs_init_one(priv, dev); 1278 libertas_debugfs_init_one(priv, dev);
1307 1279
1280 lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name);
1281
1308 ret = 0; 1282 ret = 0;
1309 goto done;
1310 1283
1311err_init_fw:
1312 priv->hw_unregister_dev(priv);
1313err_registerdev:
1314 destroy_workqueue(priv->work_thread);
1315 /* Stop the thread servicing the interrupts */
1316 wake_up_interruptible(&priv->waitq);
1317 kthread_stop(priv->main_thread);
1318done: 1284done:
1319 lbs_deb_leave_args(LBS_DEB_NET, "ret %d", ret); 1285 lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
1320 return ret; 1286 return ret;
1321} 1287}
1322EXPORT_SYMBOL_GPL(libertas_activate_card); 1288EXPORT_SYMBOL_GPL(libertas_start_card);
1289
1290
1291int libertas_stop_card(wlan_private *priv)
1292{
1293 struct net_device *dev = priv->dev;
1294 int ret = -1;
1295 struct cmd_ctrl_node *cmdnode;
1296 unsigned long flags;
1297
1298 lbs_deb_enter(LBS_DEB_MAIN);
1299
1300 netif_stop_queue(priv->dev);
1301 netif_carrier_off(priv->dev);
1302
1303 libertas_debugfs_remove_one(priv);
1304
1305 /* Flush pending command nodes */
1306 spin_lock_irqsave(&priv->adapter->driver_lock, flags);
1307 list_for_each_entry(cmdnode, &priv->adapter->cmdpendingq, list) {
1308 cmdnode->cmdwaitqwoken = 1;
1309 wake_up_interruptible(&cmdnode->cmdwait_q);
1310 }
1311 spin_unlock_irqrestore(&priv->adapter->driver_lock, flags);
1312
1313 unregister_netdev(dev);
1314
1315 lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
1316 return ret;
1317}
1318EXPORT_SYMBOL_GPL(libertas_stop_card);
1323 1319
1324 1320
1325/** 1321/**
@@ -1389,89 +1385,12 @@ done:
1389} 1385}
1390EXPORT_SYMBOL_GPL(libertas_add_mesh); 1386EXPORT_SYMBOL_GPL(libertas_add_mesh);
1391 1387
1392static void wake_pending_cmdnodes(wlan_private *priv)
1393{
1394 struct cmd_ctrl_node *cmdnode;
1395 unsigned long flags;
1396
1397 lbs_deb_enter(LBS_DEB_HOST);
1398
1399 spin_lock_irqsave(&priv->adapter->driver_lock, flags);
1400 list_for_each_entry(cmdnode, &priv->adapter->cmdpendingq, list) {
1401 cmdnode->cmdwaitqwoken = 1;
1402 wake_up_interruptible(&cmdnode->cmdwait_q);
1403 }
1404 spin_unlock_irqrestore(&priv->adapter->driver_lock, flags);
1405}
1406
1407
1408int libertas_remove_card(wlan_private *priv)
1409{
1410 wlan_adapter *adapter;
1411 struct net_device *dev;
1412 union iwreq_data wrqu;
1413
1414 lbs_deb_enter(LBS_DEB_NET);
1415
1416 libertas_remove_rtap(priv);
1417 if (!priv)
1418 goto out;
1419
1420 adapter = priv->adapter;
1421
1422 if (!adapter)
1423 goto out;
1424
1425 dev = priv->dev;
1426 device_remove_file(priv->hotplug_device, &dev_attr_libertas_rtap);
1427
1428 netif_stop_queue(priv->dev);
1429 netif_carrier_off(priv->dev);
1430
1431 wake_pending_cmdnodes(priv);
1432
1433 unregister_netdev(dev);
1434
1435 cancel_delayed_work(&priv->scan_work);
1436 cancel_delayed_work(&priv->assoc_work);
1437 destroy_workqueue(priv->work_thread);
1438
1439 if (adapter->psmode == WLAN802_11POWERMODEMAX_PSP) {
1440 adapter->psmode = WLAN802_11POWERMODECAM;
1441 libertas_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
1442 }
1443
1444 memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN);
1445 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1446 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL);
1447
1448 adapter->surpriseremoved = 1;
1449
1450 /* Stop the thread servicing the interrupts */
1451 kthread_stop(priv->main_thread);
1452
1453 libertas_debugfs_remove_one(priv);
1454
1455 lbs_deb_net("free adapter\n");
1456 libertas_free_adapter(priv);
1457
1458 lbs_deb_net("unregister finish\n");
1459
1460 priv->dev = NULL;
1461 free_netdev(dev);
1462
1463out:
1464 lbs_deb_leave(LBS_DEB_NET);
1465 return 0;
1466}
1467EXPORT_SYMBOL_GPL(libertas_remove_card);
1468
1469 1388
1470void libertas_remove_mesh(wlan_private *priv) 1389void libertas_remove_mesh(wlan_private *priv)
1471{ 1390{
1472 struct net_device *mesh_dev; 1391 struct net_device *mesh_dev;
1473 1392
1474 lbs_deb_enter(LBS_DEB_NET); 1393 lbs_deb_enter(LBS_DEB_MAIN);
1475 1394
1476 if (!priv) 1395 if (!priv)
1477 goto out; 1396 goto out;
@@ -1488,7 +1407,7 @@ void libertas_remove_mesh(wlan_private *priv)
1488 free_netdev(mesh_dev); 1407 free_netdev(mesh_dev);
1489 1408
1490out: 1409out:
1491 lbs_deb_leave(LBS_DEB_NET); 1410 lbs_deb_leave(LBS_DEB_MAIN);
1492} 1411}
1493EXPORT_SYMBOL_GPL(libertas_remove_mesh); 1412EXPORT_SYMBOL_GPL(libertas_remove_mesh);
1494 1413