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.c795
1 files changed, 188 insertions, 607 deletions
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 87b4e497faa2..598080414b17 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -13,12 +13,15 @@
13#include <linux/kfifo.h> 13#include <linux/kfifo.h>
14#include <linux/stddef.h> 14#include <linux/stddef.h>
15#include <linux/ieee80211.h> 15#include <linux/ieee80211.h>
16#include <linux/slab.h>
16#include <net/iw_handler.h> 17#include <net/iw_handler.h>
18#include <net/cfg80211.h>
17 19
18#include "host.h" 20#include "host.h"
19#include "decl.h" 21#include "decl.h"
20#include "dev.h" 22#include "dev.h"
21#include "wext.h" 23#include "wext.h"
24#include "cfg.h"
22#include "debugfs.h" 25#include "debugfs.h"
23#include "scan.h" 26#include "scan.h"
24#include "assoc.h" 27#include "assoc.h"
@@ -43,119 +46,6 @@ module_param_named(libertas_debug, lbs_debug, int, 0644);
43struct cmd_confirm_sleep confirm_sleep; 46struct cmd_confirm_sleep confirm_sleep;
44 47
45 48
46#define LBS_TX_PWR_DEFAULT 20 /*100mW */
47#define LBS_TX_PWR_US_DEFAULT 20 /*100mW */
48#define LBS_TX_PWR_JP_DEFAULT 16 /*50mW */
49#define LBS_TX_PWR_FR_DEFAULT 20 /*100mW */
50#define LBS_TX_PWR_EMEA_DEFAULT 20 /*100mW */
51
52/* Format { channel, frequency (MHz), maxtxpower } */
53/* band: 'B/G', region: USA FCC/Canada IC */
54static struct chan_freq_power channel_freq_power_US_BG[] = {
55 {1, 2412, LBS_TX_PWR_US_DEFAULT},
56 {2, 2417, LBS_TX_PWR_US_DEFAULT},
57 {3, 2422, LBS_TX_PWR_US_DEFAULT},
58 {4, 2427, LBS_TX_PWR_US_DEFAULT},
59 {5, 2432, LBS_TX_PWR_US_DEFAULT},
60 {6, 2437, LBS_TX_PWR_US_DEFAULT},
61 {7, 2442, LBS_TX_PWR_US_DEFAULT},
62 {8, 2447, LBS_TX_PWR_US_DEFAULT},
63 {9, 2452, LBS_TX_PWR_US_DEFAULT},
64 {10, 2457, LBS_TX_PWR_US_DEFAULT},
65 {11, 2462, LBS_TX_PWR_US_DEFAULT}
66};
67
68/* band: 'B/G', region: Europe ETSI */
69static struct chan_freq_power channel_freq_power_EU_BG[] = {
70 {1, 2412, LBS_TX_PWR_EMEA_DEFAULT},
71 {2, 2417, LBS_TX_PWR_EMEA_DEFAULT},
72 {3, 2422, LBS_TX_PWR_EMEA_DEFAULT},
73 {4, 2427, LBS_TX_PWR_EMEA_DEFAULT},
74 {5, 2432, LBS_TX_PWR_EMEA_DEFAULT},
75 {6, 2437, LBS_TX_PWR_EMEA_DEFAULT},
76 {7, 2442, LBS_TX_PWR_EMEA_DEFAULT},
77 {8, 2447, LBS_TX_PWR_EMEA_DEFAULT},
78 {9, 2452, LBS_TX_PWR_EMEA_DEFAULT},
79 {10, 2457, LBS_TX_PWR_EMEA_DEFAULT},
80 {11, 2462, LBS_TX_PWR_EMEA_DEFAULT},
81 {12, 2467, LBS_TX_PWR_EMEA_DEFAULT},
82 {13, 2472, LBS_TX_PWR_EMEA_DEFAULT}
83};
84
85/* band: 'B/G', region: Spain */
86static struct chan_freq_power channel_freq_power_SPN_BG[] = {
87 {10, 2457, LBS_TX_PWR_DEFAULT},
88 {11, 2462, LBS_TX_PWR_DEFAULT}
89};
90
91/* band: 'B/G', region: France */
92static struct chan_freq_power channel_freq_power_FR_BG[] = {
93 {10, 2457, LBS_TX_PWR_FR_DEFAULT},
94 {11, 2462, LBS_TX_PWR_FR_DEFAULT},
95 {12, 2467, LBS_TX_PWR_FR_DEFAULT},
96 {13, 2472, LBS_TX_PWR_FR_DEFAULT}
97};
98
99/* band: 'B/G', region: Japan */
100static struct chan_freq_power channel_freq_power_JPN_BG[] = {
101 {1, 2412, LBS_TX_PWR_JP_DEFAULT},
102 {2, 2417, LBS_TX_PWR_JP_DEFAULT},
103 {3, 2422, LBS_TX_PWR_JP_DEFAULT},
104 {4, 2427, LBS_TX_PWR_JP_DEFAULT},
105 {5, 2432, LBS_TX_PWR_JP_DEFAULT},
106 {6, 2437, LBS_TX_PWR_JP_DEFAULT},
107 {7, 2442, LBS_TX_PWR_JP_DEFAULT},
108 {8, 2447, LBS_TX_PWR_JP_DEFAULT},
109 {9, 2452, LBS_TX_PWR_JP_DEFAULT},
110 {10, 2457, LBS_TX_PWR_JP_DEFAULT},
111 {11, 2462, LBS_TX_PWR_JP_DEFAULT},
112 {12, 2467, LBS_TX_PWR_JP_DEFAULT},
113 {13, 2472, LBS_TX_PWR_JP_DEFAULT},
114 {14, 2484, LBS_TX_PWR_JP_DEFAULT}
115};
116
117/**
118 * the structure for channel, frequency and power
119 */
120struct region_cfp_table {
121 u8 region;
122 struct chan_freq_power *cfp_BG;
123 int cfp_no_BG;
124};
125
126/**
127 * the structure for the mapping between region and CFP
128 */
129static struct region_cfp_table region_cfp_table[] = {
130 {0x10, /*US FCC */
131 channel_freq_power_US_BG,
132 ARRAY_SIZE(channel_freq_power_US_BG),
133 }
134 ,
135 {0x20, /*CANADA IC */
136 channel_freq_power_US_BG,
137 ARRAY_SIZE(channel_freq_power_US_BG),
138 }
139 ,
140 {0x30, /*EU*/ channel_freq_power_EU_BG,
141 ARRAY_SIZE(channel_freq_power_EU_BG),
142 }
143 ,
144 {0x31, /*SPAIN*/ channel_freq_power_SPN_BG,
145 ARRAY_SIZE(channel_freq_power_SPN_BG),
146 }
147 ,
148 {0x32, /*FRANCE*/ channel_freq_power_FR_BG,
149 ARRAY_SIZE(channel_freq_power_FR_BG),
150 }
151 ,
152 {0x40, /*JAPAN*/ channel_freq_power_JPN_BG,
153 ARRAY_SIZE(channel_freq_power_JPN_BG),
154 }
155 ,
156/*Add new region here */
157};
158
159/** 49/**
160 * the table to keep region code 50 * the table to keep region code
161 */ 51 */
@@ -163,13 +53,6 @@ u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] =
163 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 }; 53 { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 };
164 54
165/** 55/**
166 * 802.11b/g supported bitrates (in 500Kb/s units)
167 */
168u8 lbs_bg_rates[MAX_RATES] =
169 { 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
1700x00, 0x00 };
171
172/**
173 * FW rate table. FW refers to rates by their index in this table, not by the 56 * FW rate table. FW refers to rates by their index in this table, not by the
174 * rate value itself. Values of 0x00 are 57 * rate value itself. Values of 0x00 are
175 * reserved positions. 58 * reserved positions.
@@ -212,107 +95,9 @@ u8 lbs_data_rate_to_fw_index(u32 rate)
212 return 0; 95 return 0;
213} 96}
214 97
215/**
216 * Attributes exported through sysfs
217 */
218
219/**
220 * @brief Get function for sysfs attribute anycast_mask
221 */
222static ssize_t lbs_anycast_get(struct device *dev,
223 struct device_attribute *attr, char * buf)
224{
225 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
226 struct cmd_ds_mesh_access mesh_access;
227 int ret;
228
229 memset(&mesh_access, 0, sizeof(mesh_access));
230
231 ret = lbs_mesh_access(priv, CMD_ACT_MESH_GET_ANYCAST, &mesh_access);
232 if (ret)
233 return ret;
234
235 return snprintf(buf, 12, "0x%X\n", le32_to_cpu(mesh_access.data[0]));
236}
237
238/**
239 * @brief Set function for sysfs attribute anycast_mask
240 */
241static ssize_t lbs_anycast_set(struct device *dev,
242 struct device_attribute *attr, const char * buf, size_t count)
243{
244 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
245 struct cmd_ds_mesh_access mesh_access;
246 uint32_t datum;
247 int ret;
248
249 memset(&mesh_access, 0, sizeof(mesh_access));
250 sscanf(buf, "%x", &datum);
251 mesh_access.data[0] = cpu_to_le32(datum);
252
253 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_ANYCAST, &mesh_access);
254 if (ret)
255 return ret;
256
257 return strlen(buf);
258}
259
260/**
261 * @brief Get function for sysfs attribute prb_rsp_limit
262 */
263static ssize_t lbs_prb_rsp_limit_get(struct device *dev,
264 struct device_attribute *attr, char *buf)
265{
266 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
267 struct cmd_ds_mesh_access mesh_access;
268 int ret;
269 u32 retry_limit;
270
271 memset(&mesh_access, 0, sizeof(mesh_access));
272 mesh_access.data[0] = cpu_to_le32(CMD_ACT_GET);
273
274 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
275 &mesh_access);
276 if (ret)
277 return ret;
278
279 retry_limit = le32_to_cpu(mesh_access.data[1]);
280 return snprintf(buf, 10, "%d\n", retry_limit);
281}
282
283/**
284 * @brief Set function for sysfs attribute prb_rsp_limit
285 */
286static ssize_t lbs_prb_rsp_limit_set(struct device *dev,
287 struct device_attribute *attr, const char *buf, size_t count)
288{
289 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
290 struct cmd_ds_mesh_access mesh_access;
291 int ret;
292 unsigned long retry_limit;
293
294 memset(&mesh_access, 0, sizeof(mesh_access));
295 mesh_access.data[0] = cpu_to_le32(CMD_ACT_SET);
296
297 if (!strict_strtoul(buf, 10, &retry_limit))
298 return -ENOTSUPP;
299 if (retry_limit > 15)
300 return -ENOTSUPP;
301
302 mesh_access.data[1] = cpu_to_le32(retry_limit);
303
304 ret = lbs_mesh_access(priv, CMD_ACT_MESH_SET_GET_PRB_RSP_LIMIT,
305 &mesh_access);
306 if (ret)
307 return ret;
308
309 return strlen(buf);
310}
311 98
312static int lbs_add_rtap(struct lbs_private *priv); 99static int lbs_add_rtap(struct lbs_private *priv);
313static void lbs_remove_rtap(struct lbs_private *priv); 100static void lbs_remove_rtap(struct lbs_private *priv);
314static int lbs_add_mesh(struct lbs_private *priv);
315static void lbs_remove_mesh(struct lbs_private *priv);
316 101
317 102
318/** 103/**
@@ -339,7 +124,7 @@ static ssize_t lbs_rtap_set(struct device *dev,
339 if (priv->monitormode == monitor_mode) 124 if (priv->monitormode == monitor_mode)
340 return strlen(buf); 125 return strlen(buf);
341 if (!priv->monitormode) { 126 if (!priv->monitormode) {
342 if (priv->infra_open || priv->mesh_open) 127 if (priv->infra_open || lbs_mesh_open(priv))
343 return -EBUSY; 128 return -EBUSY;
344 if (priv->mode == IW_MODE_INFRA) 129 if (priv->mode == IW_MODE_INFRA)
345 lbs_cmd_80211_deauthenticate(priv, 130 lbs_cmd_80211_deauthenticate(priv,
@@ -378,74 +163,7 @@ static ssize_t lbs_rtap_set(struct device *dev,
378static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set ); 163static DEVICE_ATTR(lbs_rtap, 0644, lbs_rtap_get, lbs_rtap_set );
379 164
380/** 165/**
381 * Get function for sysfs attribute mesh 166 * @brief This function opens the ethX interface
382 */
383static ssize_t lbs_mesh_get(struct device *dev,
384 struct device_attribute *attr, char * buf)
385{
386 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
387 return snprintf(buf, 5, "0x%X\n", !!priv->mesh_dev);
388}
389
390/**
391 * Set function for sysfs attribute mesh
392 */
393static ssize_t lbs_mesh_set(struct device *dev,
394 struct device_attribute *attr, const char * buf, size_t count)
395{
396 struct lbs_private *priv = to_net_dev(dev)->ml_priv;
397 int enable;
398 int ret, action = CMD_ACT_MESH_CONFIG_STOP;
399
400 sscanf(buf, "%x", &enable);
401 enable = !!enable;
402 if (enable == !!priv->mesh_dev)
403 return count;
404 if (enable)
405 action = CMD_ACT_MESH_CONFIG_START;
406 ret = lbs_mesh_config(priv, action, priv->curbssparams.channel);
407 if (ret)
408 return ret;
409
410 if (enable)
411 lbs_add_mesh(priv);
412 else
413 lbs_remove_mesh(priv);
414
415 return count;
416}
417
418/**
419 * lbs_mesh attribute to be exported per ethX interface
420 * through sysfs (/sys/class/net/ethX/lbs_mesh)
421 */
422static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set);
423
424/**
425 * anycast_mask attribute to be exported per mshX interface
426 * through sysfs (/sys/class/net/mshX/anycast_mask)
427 */
428static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set);
429
430/**
431 * prb_rsp_limit attribute to be exported per mshX interface
432 * through sysfs (/sys/class/net/mshX/prb_rsp_limit)
433 */
434static DEVICE_ATTR(prb_rsp_limit, 0644, lbs_prb_rsp_limit_get,
435 lbs_prb_rsp_limit_set);
436
437static struct attribute *lbs_mesh_sysfs_entries[] = {
438 &dev_attr_anycast_mask.attr,
439 &dev_attr_prb_rsp_limit.attr,
440 NULL,
441};
442
443static struct attribute_group lbs_mesh_attr_group = {
444 .attrs = lbs_mesh_sysfs_entries,
445};
446
447/**
448 * @brief This function opens the ethX or mshX interface
449 * 167 *
450 * @param dev A pointer to net_device structure 168 * @param dev A pointer to net_device structure
451 * @return 0 or -EBUSY if monitor mode active 169 * @return 0 or -EBUSY if monitor mode active
@@ -464,18 +182,12 @@ static int lbs_dev_open(struct net_device *dev)
464 goto out; 182 goto out;
465 } 183 }
466 184
467 if (dev == priv->mesh_dev) { 185 priv->infra_open = 1;
468 priv->mesh_open = 1;
469 priv->mesh_connect_status = LBS_CONNECTED;
470 netif_carrier_on(dev);
471 } else {
472 priv->infra_open = 1;
473 186
474 if (priv->connect_status == LBS_CONNECTED) 187 if (priv->connect_status == LBS_CONNECTED)
475 netif_carrier_on(dev); 188 netif_carrier_on(dev);
476 else 189 else
477 netif_carrier_off(dev); 190 netif_carrier_off(dev);
478 }
479 191
480 if (!priv->tx_pending_len) 192 if (!priv->tx_pending_len)
481 netif_wake_queue(dev); 193 netif_wake_queue(dev);
@@ -487,33 +199,6 @@ static int lbs_dev_open(struct net_device *dev)
487} 199}
488 200
489/** 201/**
490 * @brief This function closes the mshX interface
491 *
492 * @param dev A pointer to net_device structure
493 * @return 0
494 */
495static int lbs_mesh_stop(struct net_device *dev)
496{
497 struct lbs_private *priv = dev->ml_priv;
498
499 lbs_deb_enter(LBS_DEB_MESH);
500 spin_lock_irq(&priv->driver_lock);
501
502 priv->mesh_open = 0;
503 priv->mesh_connect_status = LBS_DISCONNECTED;
504
505 netif_stop_queue(dev);
506 netif_carrier_off(dev);
507
508 spin_unlock_irq(&priv->driver_lock);
509
510 schedule_work(&priv->mcast_work);
511
512 lbs_deb_leave(LBS_DEB_MESH);
513 return 0;
514}
515
516/**
517 * @brief This function closes the ethX interface 202 * @brief This function closes the ethX interface
518 * 203 *
519 * @param dev A pointer to net_device structure 204 * @param dev A pointer to net_device structure
@@ -574,15 +259,17 @@ void lbs_host_to_card_done(struct lbs_private *priv)
574 priv->dnld_sent = DNLD_RES_RECEIVED; 259 priv->dnld_sent = DNLD_RES_RECEIVED;
575 260
576 /* Wake main thread if commands are pending */ 261 /* Wake main thread if commands are pending */
577 if (!priv->cur_cmd || priv->tx_pending_len > 0) 262 if (!priv->cur_cmd || priv->tx_pending_len > 0) {
578 wake_up_interruptible(&priv->waitq); 263 if (!priv->wakeup_dev_required)
264 wake_up_interruptible(&priv->waitq);
265 }
579 266
580 spin_unlock_irqrestore(&priv->driver_lock, flags); 267 spin_unlock_irqrestore(&priv->driver_lock, flags);
581 lbs_deb_leave(LBS_DEB_THREAD); 268 lbs_deb_leave(LBS_DEB_THREAD);
582} 269}
583EXPORT_SYMBOL_GPL(lbs_host_to_card_done); 270EXPORT_SYMBOL_GPL(lbs_host_to_card_done);
584 271
585static int lbs_set_mac_address(struct net_device *dev, void *addr) 272int lbs_set_mac_address(struct net_device *dev, void *addr)
586{ 273{
587 int ret = 0; 274 int ret = 0;
588 struct lbs_private *priv = dev->ml_priv; 275 struct lbs_private *priv = dev->ml_priv;
@@ -633,15 +320,18 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
633{ 320{
634 int i = nr_addrs; 321 int i = nr_addrs;
635 struct dev_mc_list *mc_list; 322 struct dev_mc_list *mc_list;
323 int cnt;
636 324
637 if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST)) 325 if ((dev->flags & (IFF_UP|IFF_MULTICAST)) != (IFF_UP|IFF_MULTICAST))
638 return nr_addrs; 326 return nr_addrs;
639 327
640 netif_addr_lock_bh(dev); 328 netif_addr_lock_bh(dev);
641 for (mc_list = dev->mc_list; mc_list; mc_list = mc_list->next) { 329 cnt = netdev_mc_count(dev);
330 netdev_for_each_mc_addr(mc_list, dev) {
642 if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) { 331 if (mac_in_list(cmd->maclist, nr_addrs, mc_list->dmi_addr)) {
643 lbs_deb_net("mcast address %s:%pM skipped\n", dev->name, 332 lbs_deb_net("mcast address %s:%pM skipped\n", dev->name,
644 mc_list->dmi_addr); 333 mc_list->dmi_addr);
334 cnt--;
645 continue; 335 continue;
646 } 336 }
647 337
@@ -651,9 +341,10 @@ static int lbs_add_mcast_addrs(struct cmd_ds_mac_multicast_adr *cmd,
651 lbs_deb_net("mcast address %s:%pM added to filter\n", dev->name, 341 lbs_deb_net("mcast address %s:%pM added to filter\n", dev->name,
652 mc_list->dmi_addr); 342 mc_list->dmi_addr);
653 i++; 343 i++;
344 cnt--;
654 } 345 }
655 netif_addr_unlock_bh(dev); 346 netif_addr_unlock_bh(dev);
656 if (mc_list) 347 if (cnt)
657 return -EOVERFLOW; 348 return -EOVERFLOW;
658 349
659 return i; 350 return i;
@@ -716,7 +407,7 @@ static void lbs_set_mcast_worker(struct work_struct *work)
716 lbs_deb_leave(LBS_DEB_NET); 407 lbs_deb_leave(LBS_DEB_NET);
717} 408}
718 409
719static void lbs_set_multicast_list(struct net_device *dev) 410void lbs_set_multicast_list(struct net_device *dev)
720{ 411{
721 struct lbs_private *priv = dev->ml_priv; 412 struct lbs_private *priv = dev->ml_priv;
722 413
@@ -770,9 +461,10 @@ static int lbs_thread(void *data)
770 shouldsleep = 0; /* We have a command response */ 461 shouldsleep = 0; /* We have a command response */
771 else if (priv->cur_cmd) 462 else if (priv->cur_cmd)
772 shouldsleep = 1; /* Can't send a command; one already running */ 463 shouldsleep = 1; /* Can't send a command; one already running */
773 else if (!list_empty(&priv->cmdpendingq)) 464 else if (!list_empty(&priv->cmdpendingq) &&
465 !(priv->wakeup_dev_required))
774 shouldsleep = 0; /* We have a command to send */ 466 shouldsleep = 0; /* We have a command to send */
775 else if (__kfifo_len(priv->event_fifo)) 467 else if (kfifo_len(&priv->event_fifo))
776 shouldsleep = 0; /* We have an event to process */ 468 shouldsleep = 0; /* We have an event to process */
777 else 469 else
778 shouldsleep = 1; /* No command */ 470 shouldsleep = 1; /* No command */
@@ -822,46 +514,41 @@ static int lbs_thread(void *data)
822 } 514 }
823 spin_unlock_irq(&priv->driver_lock); 515 spin_unlock_irq(&priv->driver_lock);
824 516
825 /* command timeout stuff */
826 if (priv->cmd_timed_out && priv->cur_cmd) {
827 struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
828
829 if (++priv->nr_retries > 3) {
830 lbs_pr_info("Excessive timeouts submitting "
831 "command 0x%04x\n",
832 le16_to_cpu(cmdnode->cmdbuf->command));
833 lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
834 priv->nr_retries = 0;
835 if (priv->reset_card)
836 priv->reset_card(priv);
837 } else {
838 priv->cur_cmd = NULL;
839 priv->dnld_sent = DNLD_RES_RECEIVED;
840 lbs_pr_info("requeueing command 0x%04x due "
841 "to timeout (#%d)\n",
842 le16_to_cpu(cmdnode->cmdbuf->command),
843 priv->nr_retries);
844
845 /* Stick it back at the _top_ of the pending queue
846 for immediate resubmission */
847 list_add(&cmdnode->list, &priv->cmdpendingq);
848 }
849 }
850 priv->cmd_timed_out = 0;
851
852 /* Process hardware events, e.g. card removed, link lost */ 517 /* Process hardware events, e.g. card removed, link lost */
853 spin_lock_irq(&priv->driver_lock); 518 spin_lock_irq(&priv->driver_lock);
854 while (__kfifo_len(priv->event_fifo)) { 519 while (kfifo_len(&priv->event_fifo)) {
855 u32 event; 520 u32 event;
856 521
857 __kfifo_get(priv->event_fifo, (unsigned char *) &event, 522 if (kfifo_out(&priv->event_fifo,
858 sizeof(event)); 523 (unsigned char *) &event, sizeof(event)) !=
524 sizeof(event))
525 break;
859 spin_unlock_irq(&priv->driver_lock); 526 spin_unlock_irq(&priv->driver_lock);
860 lbs_process_event(priv, event); 527 lbs_process_event(priv, event);
861 spin_lock_irq(&priv->driver_lock); 528 spin_lock_irq(&priv->driver_lock);
862 } 529 }
863 spin_unlock_irq(&priv->driver_lock); 530 spin_unlock_irq(&priv->driver_lock);
864 531
532 if (priv->wakeup_dev_required) {
533 lbs_deb_thread("Waking up device...\n");
534 /* Wake up device */
535 if (priv->exit_deep_sleep(priv))
536 lbs_deb_thread("Wakeup device failed\n");
537 continue;
538 }
539
540 /* command timeout stuff */
541 if (priv->cmd_timed_out && priv->cur_cmd) {
542 struct cmd_ctrl_node *cmdnode = priv->cur_cmd;
543
544 lbs_pr_info("Timeout submitting command 0x%04x\n",
545 le16_to_cpu(cmdnode->cmdbuf->command));
546 lbs_complete_command(priv, cmdnode, -ETIMEDOUT);
547 if (priv->reset_card)
548 priv->reset_card(priv);
549 }
550 priv->cmd_timed_out = 0;
551
865 if (!priv->fw_ready) 552 if (!priv->fw_ready)
866 continue; 553 continue;
867 554
@@ -894,6 +581,9 @@ static int lbs_thread(void *data)
894 (priv->psstate == PS_STATE_PRE_SLEEP)) 581 (priv->psstate == PS_STATE_PRE_SLEEP))
895 continue; 582 continue;
896 583
584 if (priv->is_deep_sleep)
585 continue;
586
897 /* Execute the next command */ 587 /* Execute the next command */
898 if (!priv->dnld_sent && !priv->cur_cmd) 588 if (!priv->dnld_sent && !priv->cur_cmd)
899 lbs_execute_next_command(priv); 589 lbs_execute_next_command(priv);
@@ -920,7 +610,7 @@ static int lbs_thread(void *data)
920 if (priv->connect_status == LBS_CONNECTED) 610 if (priv->connect_status == LBS_CONNECTED)
921 netif_wake_queue(priv->dev); 611 netif_wake_queue(priv->dev);
922 if (priv->mesh_dev && 612 if (priv->mesh_dev &&
923 priv->mesh_connect_status == LBS_CONNECTED) 613 lbs_mesh_connected(priv))
924 netif_wake_queue(priv->mesh_dev); 614 netif_wake_queue(priv->mesh_dev);
925 } 615 }
926 } 616 }
@@ -928,6 +618,7 @@ static int lbs_thread(void *data)
928 } 618 }
929 619
930 del_timer(&priv->command_timer); 620 del_timer(&priv->command_timer);
621 del_timer(&priv->auto_deepsleep_timer);
931 wake_up_all(&priv->cmd_pending); 622 wake_up_all(&priv->cmd_pending);
932 623
933 lbs_deb_leave(LBS_DEB_THREAD); 624 lbs_deb_leave(LBS_DEB_THREAD);
@@ -1029,7 +720,7 @@ done:
1029 * This function handles the timeout of command sending. 720 * This function handles the timeout of command sending.
1030 * It will re-send the same command again. 721 * It will re-send the same command again.
1031 */ 722 */
1032static void command_timer_fn(unsigned long data) 723static void lbs_cmd_timeout_handler(unsigned long data)
1033{ 724{
1034 struct lbs_private *priv = (struct lbs_private *)data; 725 struct lbs_private *priv = (struct lbs_private *)data;
1035 unsigned long flags; 726 unsigned long flags;
@@ -1050,17 +741,61 @@ out:
1050 lbs_deb_leave(LBS_DEB_CMD); 741 lbs_deb_leave(LBS_DEB_CMD);
1051} 742}
1052 743
1053static void lbs_sync_channel_worker(struct work_struct *work) 744/**
745 * This function put the device back to deep sleep mode when timer expires
746 * and no activity (command, event, data etc.) is detected.
747 */
748static void auto_deepsleep_timer_fn(unsigned long data)
1054{ 749{
1055 struct lbs_private *priv = container_of(work, struct lbs_private, 750 struct lbs_private *priv = (struct lbs_private *)data;
1056 sync_channel); 751 int ret;
1057 752
1058 lbs_deb_enter(LBS_DEB_MAIN); 753 lbs_deb_enter(LBS_DEB_CMD);
1059 if (lbs_update_channel(priv)) 754
1060 lbs_pr_info("Channel synchronization failed."); 755 if (priv->is_activity_detected) {
1061 lbs_deb_leave(LBS_DEB_MAIN); 756 priv->is_activity_detected = 0;
757 } else {
758 if (priv->is_auto_deep_sleep_enabled &&
759 (!priv->wakeup_dev_required) &&
760 (priv->connect_status != LBS_CONNECTED)) {
761 lbs_deb_main("Entering auto deep sleep mode...\n");
762 ret = lbs_prepare_and_send_command(priv,
763 CMD_802_11_DEEP_SLEEP, 0,
764 0, 0, NULL);
765 if (ret)
766 lbs_pr_err("Enter Deep Sleep command failed\n");
767 }
768 }
769 mod_timer(&priv->auto_deepsleep_timer , jiffies +
770 (priv->auto_deep_sleep_timeout * HZ)/1000);
771 lbs_deb_leave(LBS_DEB_CMD);
772}
773
774int lbs_enter_auto_deep_sleep(struct lbs_private *priv)
775{
776 lbs_deb_enter(LBS_DEB_SDIO);
777
778 priv->is_auto_deep_sleep_enabled = 1;
779 if (priv->is_deep_sleep)
780 priv->wakeup_dev_required = 1;
781 mod_timer(&priv->auto_deepsleep_timer ,
782 jiffies + (priv->auto_deep_sleep_timeout * HZ)/1000);
783
784 lbs_deb_leave(LBS_DEB_SDIO);
785 return 0;
1062} 786}
1063 787
788int lbs_exit_auto_deep_sleep(struct lbs_private *priv)
789{
790 lbs_deb_enter(LBS_DEB_SDIO);
791
792 priv->is_auto_deep_sleep_enabled = 0;
793 priv->auto_deep_sleep_timeout = 0;
794 del_timer(&priv->auto_deepsleep_timer);
795
796 lbs_deb_leave(LBS_DEB_SDIO);
797 return 0;
798}
1064 799
1065static int lbs_init_adapter(struct lbs_private *priv) 800static int lbs_init_adapter(struct lbs_private *priv)
1066{ 801{
@@ -1089,21 +824,25 @@ static int lbs_init_adapter(struct lbs_private *priv)
1089 memset(priv->current_addr, 0xff, ETH_ALEN); 824 memset(priv->current_addr, 0xff, ETH_ALEN);
1090 825
1091 priv->connect_status = LBS_DISCONNECTED; 826 priv->connect_status = LBS_DISCONNECTED;
1092 priv->mesh_connect_status = LBS_DISCONNECTED;
1093 priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM; 827 priv->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
1094 priv->mode = IW_MODE_INFRA; 828 priv->mode = IW_MODE_INFRA;
1095 priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL; 829 priv->channel = DEFAULT_AD_HOC_CHANNEL;
1096 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON; 830 priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
1097 priv->radio_on = 1; 831 priv->radio_on = 1;
1098 priv->enablehwauto = 1; 832 priv->enablehwauto = 1;
1099 priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
1100 priv->psmode = LBS802_11POWERMODECAM; 833 priv->psmode = LBS802_11POWERMODECAM;
1101 priv->psstate = PS_STATE_FULL_POWER; 834 priv->psstate = PS_STATE_FULL_POWER;
835 priv->is_deep_sleep = 0;
836 priv->is_auto_deep_sleep_enabled = 0;
837 priv->wakeup_dev_required = 0;
838 init_waitqueue_head(&priv->ds_awake_q);
1102 839
1103 mutex_init(&priv->lock); 840 mutex_init(&priv->lock);
1104 841
1105 setup_timer(&priv->command_timer, command_timer_fn, 842 setup_timer(&priv->command_timer, lbs_cmd_timeout_handler,
1106 (unsigned long)priv); 843 (unsigned long)priv);
844 setup_timer(&priv->auto_deepsleep_timer, auto_deepsleep_timer_fn,
845 (unsigned long)priv);
1107 846
1108 INIT_LIST_HEAD(&priv->cmdfreeq); 847 INIT_LIST_HEAD(&priv->cmdfreeq);
1109 INIT_LIST_HEAD(&priv->cmdpendingq); 848 INIT_LIST_HEAD(&priv->cmdpendingq);
@@ -1121,10 +860,9 @@ static int lbs_init_adapter(struct lbs_private *priv)
1121 priv->resp_len[0] = priv->resp_len[1] = 0; 860 priv->resp_len[0] = priv->resp_len[1] = 0;
1122 861
1123 /* Create the event FIFO */ 862 /* Create the event FIFO */
1124 priv->event_fifo = kfifo_alloc(sizeof(u32) * 16, GFP_KERNEL, NULL); 863 ret = kfifo_alloc(&priv->event_fifo, sizeof(u32) * 16, GFP_KERNEL);
1125 if (IS_ERR(priv->event_fifo)) { 864 if (ret) {
1126 lbs_pr_err("Out of memory allocating event FIFO buffer\n"); 865 lbs_pr_err("Out of memory allocating event FIFO buffer\n");
1127 ret = -ENOMEM;
1128 goto out; 866 goto out;
1129 } 867 }
1130 868
@@ -1139,9 +877,9 @@ static void lbs_free_adapter(struct lbs_private *priv)
1139 lbs_deb_enter(LBS_DEB_MAIN); 877 lbs_deb_enter(LBS_DEB_MAIN);
1140 878
1141 lbs_free_cmd_buffer(priv); 879 lbs_free_cmd_buffer(priv);
1142 if (priv->event_fifo) 880 kfifo_free(&priv->event_fifo);
1143 kfifo_free(priv->event_fifo);
1144 del_timer(&priv->command_timer); 881 del_timer(&priv->command_timer);
882 del_timer(&priv->auto_deepsleep_timer);
1145 kfree(priv->networks); 883 kfree(priv->networks);
1146 priv->networks = NULL; 884 priv->networks = NULL;
1147 885
@@ -1168,31 +906,41 @@ static const struct net_device_ops lbs_netdev_ops = {
1168 */ 906 */
1169struct lbs_private *lbs_add_card(void *card, struct device *dmdev) 907struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
1170{ 908{
1171 struct net_device *dev = NULL; 909 struct net_device *dev;
910 struct wireless_dev *wdev;
1172 struct lbs_private *priv = NULL; 911 struct lbs_private *priv = NULL;
1173 912
1174 lbs_deb_enter(LBS_DEB_MAIN); 913 lbs_deb_enter(LBS_DEB_MAIN);
1175 914
1176 /* Allocate an Ethernet device and register it */ 915 /* Allocate an Ethernet device and register it */
1177 dev = alloc_etherdev(sizeof(struct lbs_private)); 916 wdev = lbs_cfg_alloc(dmdev);
1178 if (!dev) { 917 if (IS_ERR(wdev)) {
1179 lbs_pr_err("init wlanX device failed\n"); 918 lbs_pr_err("cfg80211 init failed\n");
1180 goto done; 919 goto done;
1181 } 920 }
1182 priv = netdev_priv(dev); 921 /* TODO? */
1183 dev->ml_priv = priv; 922 wdev->iftype = NL80211_IFTYPE_STATION;
923 priv = wdev_priv(wdev);
924 priv->wdev = wdev;
1184 925
1185 if (lbs_init_adapter(priv)) { 926 if (lbs_init_adapter(priv)) {
1186 lbs_pr_err("failed to initialize adapter structure.\n"); 927 lbs_pr_err("failed to initialize adapter structure.\n");
1187 goto err_init_adapter; 928 goto err_wdev;
1188 } 929 }
1189 930
931 //TODO? dev = alloc_netdev_mq(0, "wlan%d", ether_setup, IWM_TX_QUEUES);
932 dev = alloc_netdev(0, "wlan%d", ether_setup);
933 if (!dev) {
934 dev_err(dmdev, "no memory for network device instance\n");
935 goto err_adapter;
936 }
937
938 dev->ieee80211_ptr = wdev;
939 dev->ml_priv = priv;
940 SET_NETDEV_DEV(dev, dmdev);
941 wdev->netdev = dev;
1190 priv->dev = dev; 942 priv->dev = dev;
1191 priv->card = card;
1192 priv->mesh_open = 0;
1193 priv->infra_open = 0;
1194 943
1195 /* Setup the OS Interface to our functions */
1196 dev->netdev_ops = &lbs_netdev_ops; 944 dev->netdev_ops = &lbs_netdev_ops;
1197 dev->watchdog_timeo = 5 * HZ; 945 dev->watchdog_timeo = 5 * HZ;
1198 dev->ethtool_ops = &lbs_ethtool_ops; 946 dev->ethtool_ops = &lbs_ethtool_ops;
@@ -1201,7 +949,13 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
1201#endif 949#endif
1202 dev->flags |= IFF_BROADCAST | IFF_MULTICAST; 950 dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
1203 951
1204 SET_NETDEV_DEV(dev, dmdev); 952
953 // TODO: kzalloc + iwm_init_default_profile(iwm, iwm->umac_profile); ??
954
955
956 priv->card = card;
957 priv->infra_open = 0;
958
1205 959
1206 priv->rtap_net_dev = NULL; 960 priv->rtap_net_dev = NULL;
1207 strcpy(dev->name, "wlan%d"); 961 strcpy(dev->name, "wlan%d");
@@ -1211,26 +965,28 @@ struct lbs_private *lbs_add_card(void *card, struct device *dmdev)
1211 priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main"); 965 priv->main_thread = kthread_run(lbs_thread, dev, "lbs_main");
1212 if (IS_ERR(priv->main_thread)) { 966 if (IS_ERR(priv->main_thread)) {
1213 lbs_deb_thread("Error creating main thread.\n"); 967 lbs_deb_thread("Error creating main thread.\n");
1214 goto err_init_adapter; 968 goto err_ndev;
1215 } 969 }
1216 970
1217 priv->work_thread = create_singlethread_workqueue("lbs_worker"); 971 priv->work_thread = create_singlethread_workqueue("lbs_worker");
1218 INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker); 972 INIT_DELAYED_WORK(&priv->assoc_work, lbs_association_worker);
1219 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker); 973 INIT_DELAYED_WORK(&priv->scan_work, lbs_scan_worker);
1220 INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker); 974 INIT_WORK(&priv->mcast_work, lbs_set_mcast_worker);
1221 INIT_WORK(&priv->sync_channel, lbs_sync_channel_worker);
1222
1223 sprintf(priv->mesh_ssid, "mesh");
1224 priv->mesh_ssid_len = 4;
1225 975
1226 priv->wol_criteria = 0xffffffff; 976 priv->wol_criteria = 0xffffffff;
1227 priv->wol_gpio = 0xff; 977 priv->wol_gpio = 0xff;
1228 978
1229 goto done; 979 goto done;
1230 980
1231err_init_adapter: 981 err_ndev:
1232 lbs_free_adapter(priv);
1233 free_netdev(dev); 982 free_netdev(dev);
983
984 err_adapter:
985 lbs_free_adapter(priv);
986
987 err_wdev:
988 lbs_cfg_free(priv);
989
1234 priv = NULL; 990 priv = NULL;
1235 991
1236done: 992done:
@@ -1243,7 +999,6 @@ EXPORT_SYMBOL_GPL(lbs_add_card);
1243void lbs_remove_card(struct lbs_private *priv) 999void lbs_remove_card(struct lbs_private *priv)
1244{ 1000{
1245 struct net_device *dev = priv->dev; 1001 struct net_device *dev = priv->dev;
1246 union iwreq_data wrqu;
1247 1002
1248 lbs_deb_enter(LBS_DEB_MAIN); 1003 lbs_deb_enter(LBS_DEB_MAIN);
1249 1004
@@ -1268,15 +1023,19 @@ void lbs_remove_card(struct lbs_private *priv)
1268 lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP); 1023 lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
1269 } 1024 }
1270 1025
1271 memset(wrqu.ap_addr.sa_data, 0xaa, ETH_ALEN); 1026 lbs_send_disconnect_notification(priv);
1272 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 1027
1273 wireless_send_event(priv->dev, SIOCGIWAP, &wrqu, NULL); 1028 if (priv->is_deep_sleep) {
1029 priv->is_deep_sleep = 0;
1030 wake_up_interruptible(&priv->ds_awake_q);
1031 }
1274 1032
1275 /* Stop the thread servicing the interrupts */ 1033 /* Stop the thread servicing the interrupts */
1276 priv->surpriseremoved = 1; 1034 priv->surpriseremoved = 1;
1277 kthread_stop(priv->main_thread); 1035 kthread_stop(priv->main_thread);
1278 1036
1279 lbs_free_adapter(priv); 1037 lbs_free_adapter(priv);
1038 lbs_cfg_free(priv);
1280 1039
1281 priv->dev = NULL; 1040 priv->dev = NULL;
1282 free_netdev(dev); 1041 free_netdev(dev);
@@ -1286,6 +1045,17 @@ void lbs_remove_card(struct lbs_private *priv)
1286EXPORT_SYMBOL_GPL(lbs_remove_card); 1045EXPORT_SYMBOL_GPL(lbs_remove_card);
1287 1046
1288 1047
1048static int lbs_rtap_supported(struct lbs_private *priv)
1049{
1050 if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V5)
1051 return 1;
1052
1053 /* newer firmware use a capability mask */
1054 return ((MRVL_FW_MAJOR_REV(priv->fwrelease) >= MRVL_FW_V10) &&
1055 (priv->fwcapinfo & MESH_CAPINFO_ENABLE_MASK));
1056}
1057
1058
1289int lbs_start_card(struct lbs_private *priv) 1059int lbs_start_card(struct lbs_private *priv)
1290{ 1060{
1291 struct net_device *dev = priv->dev; 1061 struct net_device *dev = priv->dev;
@@ -1298,60 +1068,21 @@ int lbs_start_card(struct lbs_private *priv)
1298 if (ret) 1068 if (ret)
1299 goto done; 1069 goto done;
1300 1070
1301 /* init 802.11d */ 1071 if (lbs_cfg_register(priv)) {
1302 lbs_init_11d(priv); 1072 lbs_pr_err("cannot register device\n");
1303
1304 if (register_netdev(dev)) {
1305 lbs_pr_err("cannot register ethX device\n");
1306 goto done; 1073 goto done;
1307 } 1074 }
1308 1075
1309 lbs_update_channel(priv); 1076 lbs_update_channel(priv);
1310 1077
1311 /* Check mesh FW version and appropriately send the mesh start 1078 lbs_init_mesh(priv);
1312 * command
1313 */
1314 if (priv->mesh_fw_ver == MESH_FW_OLD) {
1315 /* Enable mesh, if supported, and work out which TLV it uses.
1316 0x100 + 291 is an unofficial value used in 5.110.20.pXX
1317 0x100 + 37 is the official value used in 5.110.21.pXX
1318 but we check them in that order because 20.pXX doesn't
1319 give an error -- it just silently fails. */
1320
1321 /* 5.110.20.pXX firmware will fail the command if the channel
1322 doesn't match the existing channel. But only if the TLV
1323 is correct. If the channel is wrong, _BOTH_ versions will
1324 give an error to 0x100+291, and allow 0x100+37 to succeed.
1325 It's just that 5.110.20.pXX will not have done anything
1326 useful */
1327
1328 priv->mesh_tlv = TLV_TYPE_OLD_MESH_ID;
1329 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
1330 priv->curbssparams.channel)) {
1331 priv->mesh_tlv = TLV_TYPE_MESH_ID;
1332 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
1333 priv->curbssparams.channel))
1334 priv->mesh_tlv = 0;
1335 }
1336 } else if (priv->mesh_fw_ver == MESH_FW_NEW) {
1337 /* 10.0.0.pXX new firmwares should succeed with TLV
1338 * 0x100+37; Do not invoke command with old TLV.
1339 */
1340 priv->mesh_tlv = TLV_TYPE_MESH_ID;
1341 if (lbs_mesh_config(priv, CMD_ACT_MESH_CONFIG_START,
1342 priv->curbssparams.channel))
1343 priv->mesh_tlv = 0;
1344 }
1345 if (priv->mesh_tlv) {
1346 lbs_add_mesh(priv);
1347
1348 if (device_create_file(&dev->dev, &dev_attr_lbs_mesh))
1349 lbs_pr_err("cannot register lbs_mesh attribute\n");
1350 1079
1351 /* While rtap isn't related to mesh, only mesh-enabled 1080 /*
1352 * firmware implements the rtap functionality via 1081 * While rtap isn't related to mesh, only mesh-enabled
1353 * CMD_802_11_MONITOR_MODE. 1082 * firmware implements the rtap functionality via
1354 */ 1083 * CMD_802_11_MONITOR_MODE.
1084 */
1085 if (lbs_rtap_supported(priv)) {
1355 if (device_create_file(&dev->dev, &dev_attr_lbs_rtap)) 1086 if (device_create_file(&dev->dev, &dev_attr_lbs_rtap))
1356 lbs_pr_err("cannot register lbs_rtap attribute\n"); 1087 lbs_pr_err("cannot register lbs_rtap attribute\n");
1357 } 1088 }
@@ -1385,13 +1116,14 @@ void lbs_stop_card(struct lbs_private *priv)
1385 netif_carrier_off(dev); 1116 netif_carrier_off(dev);
1386 1117
1387 lbs_debugfs_remove_one(priv); 1118 lbs_debugfs_remove_one(priv);
1388 if (priv->mesh_tlv) { 1119 lbs_deinit_mesh(priv);
1389 device_remove_file(&dev->dev, &dev_attr_lbs_mesh); 1120
1121 if (lbs_rtap_supported(priv))
1390 device_remove_file(&dev->dev, &dev_attr_lbs_rtap); 1122 device_remove_file(&dev->dev, &dev_attr_lbs_rtap);
1391 }
1392 1123
1393 /* Delete the timeout of the currently processing command */ 1124 /* Delete the timeout of the currently processing command */
1394 del_timer_sync(&priv->command_timer); 1125 del_timer_sync(&priv->command_timer);
1126 del_timer_sync(&priv->auto_deepsleep_timer);
1395 1127
1396 /* Flush pending command nodes */ 1128 /* Flush pending command nodes */
1397 spin_lock_irqsave(&priv->driver_lock, flags); 1129 spin_lock_irqsave(&priv->driver_lock, flags);
@@ -1420,157 +1152,6 @@ out:
1420EXPORT_SYMBOL_GPL(lbs_stop_card); 1152EXPORT_SYMBOL_GPL(lbs_stop_card);
1421 1153
1422 1154
1423static const struct net_device_ops mesh_netdev_ops = {
1424 .ndo_open = lbs_dev_open,
1425 .ndo_stop = lbs_mesh_stop,
1426 .ndo_start_xmit = lbs_hard_start_xmit,
1427 .ndo_set_mac_address = lbs_set_mac_address,
1428 .ndo_set_multicast_list = lbs_set_multicast_list,
1429};
1430
1431/**
1432 * @brief This function adds mshX interface
1433 *
1434 * @param priv A pointer to the struct lbs_private structure
1435 * @return 0 if successful, -X otherwise
1436 */
1437static int lbs_add_mesh(struct lbs_private *priv)
1438{
1439 struct net_device *mesh_dev = NULL;
1440 int ret = 0;
1441
1442 lbs_deb_enter(LBS_DEB_MESH);
1443
1444 /* Allocate a virtual mesh device */
1445 if (!(mesh_dev = alloc_netdev(0, "msh%d", ether_setup))) {
1446 lbs_deb_mesh("init mshX device failed\n");
1447 ret = -ENOMEM;
1448 goto done;
1449 }
1450 mesh_dev->ml_priv = priv;
1451 priv->mesh_dev = mesh_dev;
1452
1453 mesh_dev->netdev_ops = &mesh_netdev_ops;
1454 mesh_dev->ethtool_ops = &lbs_ethtool_ops;
1455 memcpy(mesh_dev->dev_addr, priv->dev->dev_addr,
1456 sizeof(priv->dev->dev_addr));
1457
1458 SET_NETDEV_DEV(priv->mesh_dev, priv->dev->dev.parent);
1459
1460#ifdef WIRELESS_EXT
1461 mesh_dev->wireless_handlers = (struct iw_handler_def *)&mesh_handler_def;
1462#endif
1463 mesh_dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
1464 /* Register virtual mesh interface */
1465 ret = register_netdev(mesh_dev);
1466 if (ret) {
1467 lbs_pr_err("cannot register mshX virtual interface\n");
1468 goto err_free;
1469 }
1470
1471 ret = sysfs_create_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
1472 if (ret)
1473 goto err_unregister;
1474
1475 lbs_persist_config_init(mesh_dev);
1476
1477 /* Everything successful */
1478 ret = 0;
1479 goto done;
1480
1481err_unregister:
1482 unregister_netdev(mesh_dev);
1483
1484err_free:
1485 free_netdev(mesh_dev);
1486
1487done:
1488 lbs_deb_leave_args(LBS_DEB_MESH, "ret %d", ret);
1489 return ret;
1490}
1491
1492static void lbs_remove_mesh(struct lbs_private *priv)
1493{
1494 struct net_device *mesh_dev;
1495
1496
1497 mesh_dev = priv->mesh_dev;
1498 if (!mesh_dev)
1499 return;
1500
1501 lbs_deb_enter(LBS_DEB_MESH);
1502 netif_stop_queue(mesh_dev);
1503 netif_carrier_off(mesh_dev);
1504 sysfs_remove_group(&(mesh_dev->dev.kobj), &lbs_mesh_attr_group);
1505 lbs_persist_config_remove(mesh_dev);
1506 unregister_netdev(mesh_dev);
1507 priv->mesh_dev = NULL;
1508 free_netdev(mesh_dev);
1509 lbs_deb_leave(LBS_DEB_MESH);
1510}
1511
1512/**
1513 * @brief This function finds the CFP in
1514 * region_cfp_table based on region and band parameter.
1515 *
1516 * @param region The region code
1517 * @param band The band
1518 * @param cfp_no A pointer to CFP number
1519 * @return A pointer to CFP
1520 */
1521struct chan_freq_power *lbs_get_region_cfp_table(u8 region, int *cfp_no)
1522{
1523 int i, end;
1524
1525 lbs_deb_enter(LBS_DEB_MAIN);
1526
1527 end = ARRAY_SIZE(region_cfp_table);
1528
1529 for (i = 0; i < end ; i++) {
1530 lbs_deb_main("region_cfp_table[i].region=%d\n",
1531 region_cfp_table[i].region);
1532 if (region_cfp_table[i].region == region) {
1533 *cfp_no = region_cfp_table[i].cfp_no_BG;
1534 lbs_deb_leave(LBS_DEB_MAIN);
1535 return region_cfp_table[i].cfp_BG;
1536 }
1537 }
1538
1539 lbs_deb_leave_args(LBS_DEB_MAIN, "ret NULL");
1540 return NULL;
1541}
1542
1543int lbs_set_regiontable(struct lbs_private *priv, u8 region, u8 band)
1544{
1545 int ret = 0;
1546 int i = 0;
1547
1548 struct chan_freq_power *cfp;
1549 int cfp_no;
1550
1551 lbs_deb_enter(LBS_DEB_MAIN);
1552
1553 memset(priv->region_channel, 0, sizeof(priv->region_channel));
1554
1555 cfp = lbs_get_region_cfp_table(region, &cfp_no);
1556 if (cfp != NULL) {
1557 priv->region_channel[i].nrcfp = cfp_no;
1558 priv->region_channel[i].CFP = cfp;
1559 } else {
1560 lbs_deb_main("wrong region code %#x in band B/G\n",
1561 region);
1562 ret = -1;
1563 goto out;
1564 }
1565 priv->region_channel[i].valid = 1;
1566 priv->region_channel[i].region = region;
1567 priv->region_channel[i].band = band;
1568 i++;
1569out:
1570 lbs_deb_leave_args(LBS_DEB_MAIN, "ret %d", ret);
1571 return ret;
1572}
1573
1574void lbs_queue_event(struct lbs_private *priv, u32 event) 1155void lbs_queue_event(struct lbs_private *priv, u32 event)
1575{ 1156{
1576 unsigned long flags; 1157 unsigned long flags;
@@ -1581,7 +1162,7 @@ void lbs_queue_event(struct lbs_private *priv, u32 event)
1581 if (priv->psstate == PS_STATE_SLEEP) 1162 if (priv->psstate == PS_STATE_SLEEP)
1582 priv->psstate = PS_STATE_AWAKE; 1163 priv->psstate = PS_STATE_AWAKE;
1583 1164
1584 __kfifo_put(priv->event_fifo, (unsigned char *) &event, sizeof(u32)); 1165 kfifo_in(&priv->event_fifo, (unsigned char *) &event, sizeof(u32));
1585 1166
1586 wake_up_interruptible(&priv->waitq); 1167 wake_up_interruptible(&priv->waitq);
1587 1168