aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2007-08-20 11:43:25 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:50:34 -0400
commit954ee164f4f4598afc172c0ec3865d0352e55a0b (patch)
tree51aae73210d22c0a91282a52b5198cfa1ad068b4 /drivers
parentb1b1907dceadddc7d7317f8ae85a5efec44125d8 (diff)
[PATCH] libertas: reorganize and simplify init sequence
This patch moves all firmware load responsibility into the interface-specific code and gets rid of the firmware pointer in the generic card structure. It also removes 3 fairly unecessary callbacks: hw_register_dev, hw_unregister_dev, and hw_prog_firmware. It also makes the init sequence from interface probe functions more logical, as there are paired add/remove and start/stop calls into generic libertas code. Because the USB driver code uses the same TX URB callback for both firmware upload (where the generic libertas structure isn't initialized yet) and for normal operation (where it is), some bits of USB code have to deal with 'priv' being NULL. All USB firmware upload bits have been changed to not require 'priv' at all, but simply the USB card structure. Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
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