aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/libertas/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/libertas/main.c')
-rw-r--r--drivers/net/wireless/libertas/main.c325
1 files changed, 217 insertions, 108 deletions
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 24958a86747b..8c40949cb076 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1,8 +1,10 @@
1/** 1/*
2 * This file contains the major functions in WLAN 2 * This file contains the major functions in WLAN
3 * driver. It includes init, exit, open, close and main 3 * driver. It includes init, exit, open, close and main
4 * thread etc.. 4 * thread etc..
5 */ 5 */
6
7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
6 8
7#include <linux/moduleparam.h> 9#include <linux/moduleparam.h>
8#include <linux/delay.h> 10#include <linux/delay.h>
@@ -34,19 +36,25 @@ unsigned int lbs_debug;
34EXPORT_SYMBOL_GPL(lbs_debug); 36EXPORT_SYMBOL_GPL(lbs_debug);
35module_param_named(libertas_debug, lbs_debug, int, 0644); 37module_param_named(libertas_debug, lbs_debug, int, 0644);
36 38
39unsigned int lbs_disablemesh;
40EXPORT_SYMBOL_GPL(lbs_disablemesh);
41module_param_named(libertas_disablemesh, lbs_disablemesh, int, 0644);
42
37 43
38/* This global structure is used to send the confirm_sleep command as 44/*
39 * fast as possible down to the firmware. */ 45 * This global structure is used to send the confirm_sleep command as
46 * fast as possible down to the firmware.
47 */
40struct cmd_confirm_sleep confirm_sleep; 48struct cmd_confirm_sleep confirm_sleep;
41 49
42 50
43/** 51/*
44 * the table to keep region code 52 * the table to keep region code
45 */ 53 */
46u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] = 54u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
47 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 }; 55 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
48 56
49/** 57/*
50 * FW rate table. FW refers to rates by their index in this table, not by the 58 * FW rate table. FW refers to rates by their index in this table, not by the
51 * rate value itself. Values of 0x00 are 59 * rate value itself. Values of 0x00 are
52 * reserved positions. 60 * reserved positions.
@@ -57,10 +65,10 @@ static u8 fw_data_rates[MAX_RATES] =
57}; 65};
58 66
59/** 67/**
60 * @brief use index to get the data rate 68 * lbs_fw_index_to_data_rate - use index to get the data rate
61 * 69 *
62 * @param idx The index of data rate 70 * @idx: The index of data rate
63 * @return data rate or 0 71 * returns: data rate or 0
64 */ 72 */
65u32 lbs_fw_index_to_data_rate(u8 idx) 73u32 lbs_fw_index_to_data_rate(u8 idx)
66{ 74{
@@ -70,10 +78,10 @@ u32 lbs_fw_index_to_data_rate(u8 idx)
70} 78}
71 79
72/** 80/**
73 * @brief use rate to get the index 81 * lbs_data_rate_to_fw_index - use rate to get the index
74 * 82 *
75 * @param rate data rate 83 * @rate: data rate
76 * @return index or 0 84 * returns: index or 0
77 */ 85 */
78u8 lbs_data_rate_to_fw_index(u32 rate) 86u8 lbs_data_rate_to_fw_index(u32 rate)
79{ 87{
@@ -91,10 +99,10 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
91 99
92 100
93/** 101/**
94 * @brief This function opens the ethX interface 102 * lbs_dev_open - open the ethX interface
95 * 103 *
96 * @param dev A pointer to net_device structure 104 * @dev: A pointer to &net_device structure
97 * @return 0 or -EBUSY if monitor mode active 105 * returns: 0 or -EBUSY if monitor mode active
98 */ 106 */
99static int lbs_dev_open(struct net_device *dev) 107static int lbs_dev_open(struct net_device *dev)
100{ 108{
@@ -104,6 +112,7 @@ static int lbs_dev_open(struct net_device *dev)
104 lbs_deb_enter(LBS_DEB_NET); 112 lbs_deb_enter(LBS_DEB_NET);
105 113
106 spin_lock_irq(&priv->driver_lock); 114 spin_lock_irq(&priv->driver_lock);
115 priv->stopping = false;
107 116
108 if (priv->connect_status == LBS_CONNECTED) 117 if (priv->connect_status == LBS_CONNECTED)
109 netif_carrier_on(dev); 118 netif_carrier_on(dev);
@@ -119,10 +128,10 @@ static int lbs_dev_open(struct net_device *dev)
119} 128}
120 129
121/** 130/**
122 * @brief This function closes the ethX interface 131 * lbs_eth_stop - close the ethX interface
123 * 132 *
124 * @param dev A pointer to net_device structure 133 * @dev: A pointer to &net_device structure
125 * @return 0 134 * returns: 0
126 */ 135 */
127static int lbs_eth_stop(struct net_device *dev) 136static int lbs_eth_stop(struct net_device *dev)
128{ 137{
@@ -131,37 +140,21 @@ static int lbs_eth_stop(struct net_device *dev)
131 lbs_deb_enter(LBS_DEB_NET); 140 lbs_deb_enter(LBS_DEB_NET);
132 141
133 spin_lock_irq(&priv->driver_lock); 142 spin_lock_irq(&priv->driver_lock);
143 priv->stopping = true;
134 netif_stop_queue(dev); 144 netif_stop_queue(dev);
135 spin_unlock_irq(&priv->driver_lock); 145 spin_unlock_irq(&priv->driver_lock);
136 146
137 schedule_work(&priv->mcast_work); 147 schedule_work(&priv->mcast_work);
148 cancel_delayed_work_sync(&priv->scan_work);
149 if (priv->scan_req) {
150 cfg80211_scan_done(priv->scan_req, false);
151 priv->scan_req = NULL;
152 }
138 153
139 lbs_deb_leave(LBS_DEB_NET); 154 lbs_deb_leave(LBS_DEB_NET);
140 return 0; 155 return 0;
141} 156}
142 157
143static void lbs_tx_timeout(struct net_device *dev)
144{
145 struct lbs_private *priv = dev->ml_priv;
146
147 lbs_deb_enter(LBS_DEB_TX);
148
149 lbs_pr_err("tx watch dog timeout\n");
150
151 dev->trans_start = jiffies; /* prevent tx timeout */
152
153 if (priv->currenttxskb)
154 lbs_send_tx_feedback(priv, 0);
155
156 /* XX: Shouldn't we also call into the hw-specific driver
157 to kick it somehow? */
158 lbs_host_to_card_done(priv);
159
160 /* FIXME: reset the card */
161
162 lbs_deb_leave(LBS_DEB_TX);
163}
164
165void lbs_host_to_card_done(struct lbs_private *priv) 158void lbs_host_to_card_done(struct lbs_private *priv)
166{ 159{
167 unsigned long flags; 160 unsigned long flags;
@@ -329,12 +322,12 @@ void lbs_set_multicast_list(struct net_device *dev)
329} 322}
330 323
331/** 324/**
332 * @brief This function handles the major jobs in the LBS driver. 325 * lbs_thread - handles the major jobs in the LBS driver.
333 * It handles all events generated by firmware, RX data received 326 * It handles all events generated by firmware, RX data received
334 * from firmware and TX data sent from kernel. 327 * from firmware and TX data sent from kernel.
335 * 328 *
336 * @param data A pointer to lbs_thread structure 329 * @data: A pointer to &lbs_thread structure
337 * @return 0 330 * returns: 0
338 */ 331 */
339static int lbs_thread(void *data) 332static int lbs_thread(void *data)
340{ 333{
@@ -455,8 +448,8 @@ static int lbs_thread(void *data)
455 if (priv->cmd_timed_out && priv->cur_cmd) { 448 if (priv->cmd_timed_out && priv->cur_cmd) {
456 struct cmd_ctrl_node *cmdnode = priv->cur_cmd; 449 struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
457 450
458 lbs_pr_info("Timeout submitting command 0x%04x\n", 451 netdev_info(dev, "Timeout submitting command 0x%04x\n",
459 le16_to_cpu(cmdnode->cmdbuf->command)); 452 le16_to_cpu(cmdnode->cmdbuf->command));
460 lbs_complete_command(priv, cmdnode, -ETIMEDOUT); 453 lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
461 if (priv->reset_card) 454 if (priv->reset_card)
462 priv->reset_card(priv); 455 priv->reset_card(priv);
@@ -483,8 +476,8 @@ static int lbs_thread(void *data)
483 * after firmware fixes it 476 * after firmware fixes it
484 */ 477 */
485 priv->psstate = PS_STATE_AWAKE; 478 priv->psstate = PS_STATE_AWAKE;
486 lbs_pr_alert("ignore PS_SleepConfirm in " 479 netdev_alert(dev,
487 "non-connected state\n"); 480 "ignore PS_SleepConfirm in non-connected state\n");
488 } 481 }
489 } 482 }
490 483
@@ -532,6 +525,43 @@ static int lbs_thread(void *data)
532 return 0; 525 return 0;
533} 526}
534 527
528/**
529 * lbs_setup_firmware - gets the HW spec from the firmware and sets
530 * some basic parameters
531 *
532 * @priv: A pointer to &struct lbs_private structure
533 * returns: 0 or -1
534 */
535static int lbs_setup_firmware(struct lbs_private *priv)
536{
537 int ret = -1;
538 s16 curlevel = 0, minlevel = 0, maxlevel = 0;
539
540 lbs_deb_enter(LBS_DEB_FW);
541
542 /* Read MAC address from firmware */
543 memset(priv->current_addr, 0xff, ETH_ALEN);
544 ret = lbs_update_hw_spec(priv);
545 if (ret)
546 goto done;
547
548 /* Read power levels if available */
549 ret = lbs_get_tx_power(priv, &curlevel, &minlevel, &maxlevel);
550 if (ret == 0) {
551 priv->txpower_cur = curlevel;
552 priv->txpower_min = minlevel;
553 priv->txpower_max = maxlevel;
554 }
555
556 /* Send cmd to FW to enable 11D function */
557 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_11D_ENABLE, 1);
558
559 lbs_set_mac_control(priv);
560done:
561 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
562 return ret;
563}
564
535int lbs_suspend(struct lbs_private *priv) 565int lbs_suspend(struct lbs_private *priv)
536{ 566{
537 int ret; 567 int ret;
@@ -541,7 +571,8 @@ int lbs_suspend(struct lbs_private *priv)
541 if (priv->is_deep_sleep) { 571 if (priv->is_deep_sleep) {
542 ret = lbs_set_deep_sleep(priv, 0); 572 ret = lbs_set_deep_sleep(priv, 0);
543 if (ret) { 573 if (ret) {
544 lbs_pr_err("deep sleep cancellation failed: %d\n", ret); 574 netdev_err(priv->dev,
575 "deep sleep cancellation failed: %d\n", ret);
545 return ret; 576 return ret;
546 } 577 }
547 priv->deep_sleep_required = 1; 578 priv->deep_sleep_required = 1;
@@ -574,54 +605,23 @@ int lbs_resume(struct lbs_private *priv)
574 priv->deep_sleep_required = 0; 605 priv->deep_sleep_required = 0;
575 ret = lbs_set_deep_sleep(priv, 1); 606 ret = lbs_set_deep_sleep(priv, 1);
576 if (ret) 607 if (ret)
577 lbs_pr_err("deep sleep activation failed: %d\n", ret); 608 netdev_err(priv->dev,
609 "deep sleep activation failed: %d\n", ret);
578 } 610 }
579 611
612 if (priv->setup_fw_on_resume)
613 ret = lbs_setup_firmware(priv);
614
580 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret); 615 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
581 return ret; 616 return ret;
582} 617}
583EXPORT_SYMBOL_GPL(lbs_resume); 618EXPORT_SYMBOL_GPL(lbs_resume);
584 619
585/** 620/**
586 * @brief This function gets the HW spec from the firmware and sets 621 * lbs_cmd_timeout_handler - handles the timeout of command sending.
587 * some basic parameters. 622 * It will re-send the same command again.
588 * 623 *
589 * @param priv A pointer to struct lbs_private structure 624 * @data: &struct lbs_private pointer
590 * @return 0 or -1
591 */
592static int lbs_setup_firmware(struct lbs_private *priv)
593{
594 int ret = -1;
595 s16 curlevel = 0, minlevel = 0, maxlevel = 0;
596
597 lbs_deb_enter(LBS_DEB_FW);
598
599 /* Read MAC address from firmware */
600 memset(priv->current_addr, 0xff, ETH_ALEN);
601 ret = lbs_update_hw_spec(priv);
602 if (ret)
603 goto done;
604
605 /* Read power levels if available */
606 ret = lbs_get_tx_power(priv, &curlevel, &minlevel, &maxlevel);
607 if (ret == 0) {
608 priv->txpower_cur = curlevel;
609 priv->txpower_min = minlevel;
610 priv->txpower_max = maxlevel;
611 }
612
613 /* Send cmd to FW to enable 11D function */
614 ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_11D_ENABLE, 1);
615
616 lbs_set_mac_control(priv);
617done:
618 lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
619 return ret;
620}
621
622/**
623 * This function handles the timeout of command sending.
624 * It will re-send the same command again.
625 */ 625 */
626static void lbs_cmd_timeout_handler(unsigned long data) 626static void lbs_cmd_timeout_handler(unsigned long data)
627{ 627{
@@ -634,8 +634,8 @@ static void lbs_cmd_timeout_handler(unsigned long data)
634 if (!priv->cur_cmd) 634 if (!priv->cur_cmd)
635 goto out; 635 goto out;
636 636
637 lbs_pr_info("command 0x%04x timed out\n", 637 netdev_info(priv->dev, "command 0x%04x timed out\n",
638 le16_to_cpu(priv->cur_cmd->cmdbuf->command)); 638 le16_to_cpu(priv->cur_cmd->cmdbuf->command));
639 639
640 priv->cmd_timed_out = 1; 640 priv->cmd_timed_out = 1;
641 wake_up_interruptible(&priv->waitq); 641 wake_up_interruptible(&priv->waitq);
@@ -645,8 +645,10 @@ out:
645} 645}
646 646
647/** 647/**
648 * This function put the device back to deep sleep mode when timer expires 648 * auto_deepsleep_timer_fn - put the device back to deep sleep mode when
649 * and no activity (command, event, data etc.) is detected. 649 * timer expires and no activity (command, event, data etc.) is detected.
650 * @data: &struct lbs_private pointer
651 * returns: N/A
650 */ 652 */
651static void auto_deepsleep_timer_fn(unsigned long data) 653static void auto_deepsleep_timer_fn(unsigned long data)
652{ 654{
@@ -738,7 +740,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
738 740
739 /* Allocate the command buffers */ 741 /* Allocate the command buffers */
740 if (lbs_allocate_cmd_buffer(priv)) { 742 if (lbs_allocate_cmd_buffer(priv)) {
741 lbs_pr_err("Out of memory allocating command buffers\n"); 743 pr_err("Out of memory allocating command buffers\n");
742 ret = -ENOMEM; 744 ret = -ENOMEM;
743 goto out; 745 goto out;
744 } 746 }
@@ -748,7 +750,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
748 /* Create the event FIFO */ 750 /* Create the event FIFO */
749 ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL); 751 ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
750 if (ret) { 752 if (ret) {
751 lbs_pr_err("Out of memory allocating event FIFO buffer\n"); 753 pr_err("Out of memory allocating event FIFO buffer\n");
752 goto out; 754 goto out;
753 } 755 }
754 756
@@ -775,18 +777,18 @@ static const struct net_device_ops lbs_netdev_ops = {
775 .ndo_stop = lbs_eth_stop, 777 .ndo_stop = lbs_eth_stop,
776 .ndo_start_xmit = lbs_hard_start_xmit, 778 .ndo_start_xmit = lbs_hard_start_xmit,
777 .ndo_set_mac_address = lbs_set_mac_address, 779 .ndo_set_mac_address = lbs_set_mac_address,
778 .ndo_tx_timeout = lbs_tx_timeout,
779 .ndo_set_multicast_list = lbs_set_multicast_list, 780 .ndo_set_multicast_list = lbs_set_multicast_list,
780 .ndo_change_mtu = eth_change_mtu, 781 .ndo_change_mtu = eth_change_mtu,
781 .ndo_validate_addr = eth_validate_addr, 782 .ndo_validate_addr = eth_validate_addr,
782}; 783};
783 784
784/** 785/**
785 * @brief This function adds the card. it will probe the 786 * lbs_add_card - adds the card. It will probe the
786 * card, allocate the lbs_priv and initialize the device. 787 * card, allocate the lbs_priv and initialize the device.
787 * 788 *
788 * @param card A pointer to card 789 * @card: A pointer to card
789 * @return A pointer to struct lbs_private structure 790 * @dmdev: A pointer to &struct device
791 * returns: A pointer to &struct lbs_private structure
790 */ 792 */
791struct lbs_private *lbs_add_card(void *card, struct device *dmdev) 793struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
792{ 794{
@@ -799,7 +801,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
799 /* Allocate an Ethernet device and register it */ 801 /* Allocate an Ethernet device and register it */
800 wdev = lbs_cfg_alloc(dmdev); 802 wdev = lbs_cfg_alloc(dmdev);
801 if (IS_ERR(wdev)) { 803 if (IS_ERR(wdev)) {
802 lbs_pr_err("cfg80211 init failed\n"); 804 pr_err("cfg80211 init failed\n");
803 goto done; 805 goto done;
804 } 806 }
805 807
@@ -808,7 +810,7 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
808 priv->wdev = wdev; 810 priv->wdev = wdev;
809 811
810 if (lbs_init_adapter(priv)) { 812 if (lbs_init_adapter(priv)) {
811 lbs_pr_err("failed to initialize adapter structure.\n"); 813 pr_err("failed to initialize adapter structure\n");
812 goto err_wdev; 814 goto err_wdev;
813 } 815 }
814 816
@@ -844,9 +846,10 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
844 priv->work_thread = create_singlethread_workqueue("lbs_worker"); 846 priv->work_thread = create_singlethread_workqueue("lbs_worker");
845 INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker); 847 INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
846 848
847 priv->wol_criteria = 0xffffffff; 849 priv->wol_criteria = EHS_REMOVE_WAKEUP;
848 priv->wol_gpio = 0xff; 850 priv->wol_gpio = 0xff;
849 priv->wol_gap = 20; 851 priv->wol_gap = 20;
852 priv->ehs_remove_supported = true;
850 853
851 goto done; 854 goto done;
852 855
@@ -908,8 +911,6 @@ void lbs_remove_card(struct lbs_private *priv)
908 911
909 lbs_free_adapter(priv); 912 lbs_free_adapter(priv);
910 lbs_cfg_free(priv); 913 lbs_cfg_free(priv);
911
912 priv->dev = NULL;
913 free_netdev(dev); 914 free_netdev(dev);
914 915
915 lbs_deb_leave(LBS_DEB_MAIN); 916 lbs_deb_leave(LBS_DEB_MAIN);
@@ -941,17 +942,20 @@ int lbs_start_card(struct lbs_private *priv)
941 goto done; 942 goto done;
942 943
943 if (lbs_cfg_register(priv)) { 944 if (lbs_cfg_register(priv)) {
944 lbs_pr_err("cannot register device\n"); 945 pr_err("cannot register device\n");
945 goto done; 946 goto done;
946 } 947 }
947 948
948 lbs_update_channel(priv); 949 lbs_update_channel(priv);
949 950
950 lbs_init_mesh(priv); 951 if (!lbs_disablemesh)
952 lbs_init_mesh(priv);
953 else
954 pr_info("%s: mesh disabled\n", dev->name);
951 955
952 lbs_debugfs_init_one(priv, dev); 956 lbs_debugfs_init_one(priv, dev);
953 957
954 lbs_pr_info("%s: Marvell WLAN 802.11 adapter\n", dev->name); 958 netdev_info(dev, "Marvell WLAN 802.11 adapter\n");
955 959
956 ret = 0; 960 ret = 0;
957 961
@@ -1047,6 +1051,111 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx)
1047} 1051}
1048EXPORT_SYMBOL_GPL(lbs_notify_command_response); 1052EXPORT_SYMBOL_GPL(lbs_notify_command_response);
1049 1053
1054/**
1055 * lbs_get_firmware - Retrieves two-stage firmware
1056 *
1057 * @dev: A pointer to &device structure
1058 * @user_helper: User-defined helper firmware file
1059 * @user_mainfw: User-defined main firmware file
1060 * @card_model: Bus-specific card model ID used to filter firmware table
1061 * elements
1062 * @fw_table: Table of firmware file names and device model numbers
1063 * terminated by an entry with a NULL helper name
1064 * @helper: On success, the helper firmware; caller must free
1065 * @mainfw: On success, the main firmware; caller must free
1066 *
1067 * returns: 0 on success, non-zero on failure
1068 */
1069int lbs_get_firmware(struct device *dev, const char *user_helper,
1070 const char *user_mainfw, u32 card_model,
1071 const struct lbs_fw_table *fw_table,
1072 const struct firmware **helper,
1073 const struct firmware **mainfw)
1074{
1075 const struct lbs_fw_table *iter;
1076 int ret;
1077
1078 BUG_ON(helper == NULL);
1079 BUG_ON(mainfw == NULL);
1080
1081 /* Try user-specified firmware first */
1082 if (user_helper) {
1083 ret = request_firmware(helper, user_helper, dev);
1084 if (ret) {
1085 dev_err(dev, "couldn't find helper firmware %s\n",
1086 user_helper);
1087 goto fail;
1088 }
1089 }
1090 if (user_mainfw) {
1091 ret = request_firmware(mainfw, user_mainfw, dev);
1092 if (ret) {
1093 dev_err(dev, "couldn't find main firmware %s\n",
1094 user_mainfw);
1095 goto fail;
1096 }
1097 }
1098
1099 if (*helper && *mainfw)
1100 return 0;
1101
1102 /* Otherwise search for firmware to use. If neither the helper or
1103 * the main firmware were specified by the user, then we need to
1104 * make sure that found helper & main are from the same entry in
1105 * fw_table.
1106 */
1107 iter = fw_table;
1108 while (iter && iter->helper) {
1109 if (iter->model != card_model)
1110 goto next;
1111
1112 if (*helper == NULL) {
1113 ret = request_firmware(helper, iter->helper, dev);
1114 if (ret)
1115 goto next;
1116
1117 /* If the device has one-stage firmware (ie cf8305) and
1118 * we've got it then we don't need to bother with the
1119 * main firmware.
1120 */
1121 if (iter->fwname == NULL)
1122 return 0;
1123 }
1124
1125 if (*mainfw == NULL) {
1126 ret = request_firmware(mainfw, iter->fwname, dev);
1127 if (ret && !user_helper) {
1128 /* Clear the helper if it wasn't user-specified
1129 * and the main firmware load failed, to ensure
1130 * we don't have mismatched firmware pairs.
1131 */
1132 release_firmware(*helper);
1133 *helper = NULL;
1134 }
1135 }
1136
1137 if (*helper && *mainfw)
1138 return 0;
1139
1140 next:
1141 iter++;
1142 }
1143
1144 fail:
1145 /* Failed */
1146 if (*helper) {
1147 release_firmware(*helper);
1148 *helper = NULL;
1149 }
1150 if (*mainfw) {
1151 release_firmware(*mainfw);
1152 *mainfw = NULL;
1153 }
1154
1155 return -ENOENT;
1156}
1157EXPORT_SYMBOL_GPL(lbs_get_firmware);
1158
1050static int __init lbs_init_module(void) 1159static int __init lbs_init_module(void)
1051{ 1160{
1052 lbs_deb_enter(LBS_DEB_MAIN); 1161 lbs_deb_enter(LBS_DEB_MAIN);