Staging: brcm80211: remove some more macros from linuxver.h
[pandora-kernel.git] / drivers / staging / brcm80211 / sys / wl_mac80211.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #define __UNDEF_NO_VERSION__
18
19 #include <typedefs.h>
20 #include <linuxver.h>
21 #include <osl.h>
22 #include <linux/kernel.h>
23 #include <linux/etherdevice.h>
24 #include <linux/string.h>
25 #include <linux/pci_ids.h>
26 #define WLC_MAXBSSCFG           1       /* single BSS configs */
27
28 #include <wlc_cfg.h>
29 #include <net/mac80211.h>
30 #include <epivers.h>
31 #ifndef WLC_HIGH_ONLY
32 #include <phy_version.h>
33 #endif
34 #include <bcmutils.h>
35 #include <pcicfg.h>
36 #include <wlioctl.h>
37 #include <wlc_key.h>
38 #include <wlc_channel.h>
39 #include <wlc_pub.h>
40 #include <wlc_scb.h>
41 #include <wl_dbg.h>
42 #ifdef BCMSDIO
43 #include <bcmsdh.h>
44 #endif
45 #include <wl_export.h>
46 #ifdef WLC_HIGH_ONLY
47 #include "dbus.h"
48 #include "bcm_rpc_tp.h"
49 #include "bcm_rpc.h"
50 #include "bcm_xdr.h"
51 #include "wlc_rpc.h"
52 #endif
53
54 #include <wl_mac80211.h>
55 #include <linux/firmware.h>
56 #ifndef WLC_HIGH_ONLY
57 #include <wl_ucode.h>
58 #include <d11ucode_ext.h>
59 #endif
60
61 #ifdef BCMSDIO
62 extern struct device *sdiommc_dev;
63 #endif
64
65 extern void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg,
66                               bool suspend);
67 bool wlc_sendpkt_mac80211(wlc_info_t *wlc, void *sdu, struct ieee80211_hw *hw);
68 void wlc_mac_bcn_promisc_change(wlc_info_t *wlc, bool promisc);
69 void wlc_set_addrmatch(wlc_info_t *wlc, int match_reg_offset,
70                        const struct ether_addr *addr);
71
72 static void wl_timer(unsigned long data);
73 static void _wl_timer(wl_timer_t *t);
74
75 #ifdef WLC_HIGH_ONLY
76 #define RPCQ_LOCK(_wl, _flags) spin_lock_irqsave(&(_wl)->rpcq_lock, (_flags))
77 #define RPCQ_UNLOCK(_wl, _flags)  spin_unlock_irqrestore(&(_wl)->rpcq_lock, (_flags))
78 #define TXQ_LOCK(_wl, _flags) spin_lock_irqsave(&(_wl)->txq_lock, (_flags))
79 #define TXQ_UNLOCK(_wl, _flags)  spin_unlock_irqrestore(&(_wl)->txq_lock, (_flags))
80 static void wl_rpc_down(void *wlh);
81 static void wl_rpcq_free(wl_info_t *wl);
82 static void wl_rpcq_dispatch(struct wl_task *task);
83 static void wl_rpc_dispatch_schedule(void *ctx, struct rpc_buf *buf);
84 static void wl_start_txqwork(struct wl_task *task);
85 static void wl_txq_free(wl_info_t *wl);
86 static void wl_timer_task(wl_task_t *task);
87 static int wl_schedule_task(wl_info_t *wl, void (*fn) (struct wl_task *),
88                             void *context);
89 #endif                          /* WLC_HIGH_ONLY */
90
91 static int ieee_hw_init(struct ieee80211_hw *hw);
92 static int ieee_hw_rate_init(struct ieee80211_hw *hw);
93
94 static int wl_linux_watchdog(void *ctx);
95
96 /* Flags we support */
97 #define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
98         FIF_ALLMULTI | \
99         FIF_FCSFAIL | \
100         FIF_PLCPFAIL | \
101         FIF_CONTROL | \
102         FIF_OTHER_BSS | \
103         FIF_BCN_PRBRESP_PROMISC)
104
105 static int wl_found;
106
107 struct ieee80211_tkip_data {
108 #define TKIP_KEY_LEN 32
109         u8 key[TKIP_KEY_LEN];
110         int key_set;
111
112         u32 tx_iv32;
113         u16 tx_iv16;
114         u16 tx_ttak[5];
115         int tx_phase1_done;
116
117         u32 rx_iv32;
118         u16 rx_iv16;
119         u16 rx_ttak[5];
120         int rx_phase1_done;
121         u32 rx_iv32_new;
122         u16 rx_iv16_new;
123
124         u32 dot11RSNAStatsTKIPReplays;
125         u32 dot11RSNAStatsTKIPICVErrors;
126         u32 dot11RSNAStatsTKIPLocalMICFailures;
127
128         int key_idx;
129
130         struct crypto_tfm *tfm_arc4;
131         struct crypto_tfm *tfm_michael;
132
133         /* scratch buffers for virt_to_page() (crypto API) */
134         u8 rx_hdr[16], tx_hdr[16];
135 };
136
137 #ifndef WLC_HIGH_ONLY
138 #define WL_DEV_IF(dev)          ((wl_if_t *)netdev_priv(dev))
139 #define WL_INFO(dev)            ((wl_info_t *)(WL_DEV_IF(dev)->wl))     /* points to wl */
140 static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev);
141 static void wl_release_fw(wl_info_t *wl);
142 #endif
143
144 /* local prototypes */
145 static int wl_start(struct sk_buff *skb, wl_info_t *wl);
146 static int wl_start_int(wl_info_t *wl, struct ieee80211_hw *hw,
147                         struct sk_buff *skb);
148 static void wl_dpc(unsigned long data);
149
150 MODULE_AUTHOR("Broadcom Corporation");
151 MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
152 MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
153 MODULE_LICENSE("Dual BSD/GPL");
154
155 #ifndef BCMSDIO
156 /* recognized PCI IDs */
157 static struct pci_device_id wl_id_table[] = {
158         {PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},      /* 43225 2G */
159         {PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},      /* 43224 DUAL */
160         {PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},      /* 4313 DUAL */
161         {0}
162 };
163
164 MODULE_DEVICE_TABLE(pci, wl_id_table);
165 static void wl_remove(struct pci_dev *pdev);
166 #endif                          /* !BCMSDIO */
167
168 #ifdef BCMSDIO
169 static uint sd_drivestrength = 6;
170 module_param(sd_drivestrength, uint, 0);
171 #endif
172
173 #ifdef BCMDBG
174 static int msglevel = 0xdeadbeef;
175 module_param(msglevel, int, 0);
176 #ifndef WLC_HIGH_ONLY
177 static int phymsglevel = 0xdeadbeef;
178 module_param(phymsglevel, int, 0);
179 #endif                          /* WLC_HIGH_ONLY */
180 #endif                          /* BCMDBG */
181
182 static int oneonly;
183 module_param(oneonly, int, 0);
184
185 static int piomode;
186 module_param(piomode, int, 0);
187
188 static int instance_base;       /* Starting instance number */
189 module_param(instance_base, int, 0);
190
191 #if defined(BCMDBG)
192 static char *macaddr;
193 module_param(macaddr, charp, S_IRUGO);
194 #endif
195
196 static int nompc = 1;
197 module_param(nompc, int, 0);
198
199 static char name[IFNAMSIZ] = "eth%d";
200 module_param_string(name, name, IFNAMSIZ, 0);
201
202 #ifndef SRCBASE
203 #define SRCBASE "."
204 #endif
205
206 #define WL_MAGIC        0xdeadbeef
207
208 #define HW_TO_WL(hw)     (hw->priv)
209 #define WL_TO_HW(wl)      (wl->pub->ieee_hw)
210 #ifdef WLC_HIGH_ONLY
211 static int wl_ops_tx_nl(struct ieee80211_hw *hw, struct sk_buff *skb);
212 #else
213 static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
214 #endif
215 static int wl_ops_start(struct ieee80211_hw *hw);
216 static void wl_ops_stop(struct ieee80211_hw *hw);
217 static int wl_ops_add_interface(struct ieee80211_hw *hw,
218                                 struct ieee80211_vif *vif);
219 static void wl_ops_remove_interface(struct ieee80211_hw *hw,
220                                     struct ieee80211_vif *vif);
221 static int wl_ops_config(struct ieee80211_hw *hw, u32 changed);
222 static void wl_ops_bss_info_changed(struct ieee80211_hw *hw,
223                                     struct ieee80211_vif *vif,
224                                     struct ieee80211_bss_conf *info,
225                                     u32 changed);
226 static void wl_ops_configure_filter(struct ieee80211_hw *hw,
227                                     unsigned int changed_flags,
228                                     unsigned int *total_flags, u64 multicast);
229 static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
230                           bool set);
231 static void wl_ops_sw_scan_start(struct ieee80211_hw *hw);
232 static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw);
233 static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf);
234 static int wl_ops_get_stats(struct ieee80211_hw *hw,
235                             struct ieee80211_low_level_stats *stats);
236 static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
237 static void wl_ops_sta_notify(struct ieee80211_hw *hw,
238                               struct ieee80211_vif *vif,
239                               enum sta_notify_cmd cmd,
240                               struct ieee80211_sta *sta);
241 static int wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
242                           const struct ieee80211_tx_queue_params *params);
243 static u64 wl_ops_get_tsf(struct ieee80211_hw *hw);
244 static int wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
245                       struct ieee80211_sta *sta);
246 static int wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
247                          struct ieee80211_sta *sta);
248 static int wl_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
249                            enum ieee80211_ampdu_mlme_action action,
250                            struct ieee80211_sta *sta, u16 tid, u16 *ssn);
251
252 #ifdef WLC_HIGH_ONLY
253 static int wl_ops_tx_nl(struct ieee80211_hw *hw, struct sk_buff *skb)
254 {
255         int status;
256         wl_info_t *wl = hw->priv;
257         if (!wl->pub->up) {
258                 WL_ERROR(("ops->tx called while down\n"));
259                 status = -ENETDOWN;
260                 goto done;
261         }
262         status = wl_start(skb, wl);
263  done:
264         return status;
265 }
266 #else
267 static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
268 {
269         int status;
270         wl_info_t *wl = hw->priv;
271         WL_LOCK(wl);
272         if (!wl->pub->up) {
273                 WL_ERROR(("ops->tx called while down\n"));
274                 status = -ENETDOWN;
275                 goto done;
276         }
277         status = wl_start(skb, wl);
278  done:
279         WL_UNLOCK(wl);
280         return status;
281 }
282 #endif                          /* WLC_HIGH_ONLY */
283
284 static int wl_ops_start(struct ieee80211_hw *hw)
285 {
286         wl_info_t *wl = hw->priv;
287         /* struct ieee80211_channel *curchan = hw->conf.channel; */
288         WL_NONE(("%s : Initial channel: %d\n", __func__, curchan->hw_value));
289
290         WL_LOCK(wl);
291         ieee80211_wake_queues(hw);
292         WL_UNLOCK(wl);
293
294         return 0;
295 }
296
297 static void wl_ops_stop(struct ieee80211_hw *hw)
298 {
299         wl_info_t *wl = hw->priv;
300         ASSERT(wl);
301         WL_LOCK(wl);
302         wl_down(wl);
303         ieee80211_stop_queues(hw);
304         WL_UNLOCK(wl);
305
306         return;
307 }
308
309 static int
310 wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
311 {
312         wl_info_t *wl;
313         int err;
314
315         /* Just STA for now */
316         if (vif->type != NL80211_IFTYPE_AP &&
317             vif->type != NL80211_IFTYPE_MESH_POINT &&
318             vif->type != NL80211_IFTYPE_STATION &&
319             vif->type != NL80211_IFTYPE_WDS &&
320             vif->type != NL80211_IFTYPE_ADHOC) {
321                 WL_ERROR(("%s: Attempt to add type %d, only STA for now\n",
322                           __func__, vif->type));
323                 return -EOPNOTSUPP;
324         }
325
326         wl = HW_TO_WL(hw);
327         WL_LOCK(wl);
328         err = wl_up(wl);
329         WL_UNLOCK(wl);
330
331         if (err != 0)
332                 WL_ERROR(("%s: wl_up() returned %d\n", __func__, err));
333         return err;
334 }
335
336 static void
337 wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
338 {
339         return;
340 }
341
342 static int
343 ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan,
344                  enum nl80211_channel_type type)
345 {
346         wl_info_t *wl = HW_TO_WL(hw);
347         int err = 0;
348
349         switch (type) {
350         case NL80211_CHAN_HT20:
351         case NL80211_CHAN_NO_HT:
352                 WL_LOCK(wl);
353                 err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value);
354                 WL_UNLOCK(wl);
355                 break;
356         case NL80211_CHAN_HT40MINUS:
357         case NL80211_CHAN_HT40PLUS:
358                 WL_ERROR(("%s: Need to implement 40 Mhz Channels!\n",
359                           __func__));
360                 break;
361         }
362
363         if (err)
364                 return -EIO;
365         return err;
366 }
367
368 static int wl_ops_config(struct ieee80211_hw *hw, u32 changed)
369 {
370         struct ieee80211_conf *conf = &hw->conf;
371         wl_info_t *wl = HW_TO_WL(hw);
372         int err = 0;
373         int new_int;
374
375         if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
376                 WL_NONE(("%s: Setting listen interval to %d\n",
377                          __func__, conf->listen_interval));
378                 if (wlc_iovar_setint
379                     (wl->wlc, "bcn_li_bcn", conf->listen_interval)) {
380                         WL_ERROR(("%s: Error setting listen_interval\n",
381                                   __func__));
382                         err = -EIO;
383                         goto config_out;
384                 }
385                 wlc_iovar_getint(wl->wlc, "bcn_li_bcn", &new_int);
386                 ASSERT(new_int == conf->listen_interval);
387         }
388         if (changed & IEEE80211_CONF_CHANGE_MONITOR)
389                 WL_NONE(("Need to set monitor mode\n"));
390         if (changed & IEEE80211_CONF_CHANGE_PS)
391                 WL_NONE(("Need to set Power-save mode\n"));
392
393         if (changed & IEEE80211_CONF_CHANGE_POWER) {
394                 WL_NONE(("%s: Setting tx power to %d dbm\n", __func__,
395                          conf->power_level));
396                 if (wlc_iovar_setint
397                     (wl->wlc, "qtxpower", conf->power_level * 4)) {
398                         WL_ERROR(("%s: Error setting power_level\n", __func__));
399                         err = -EIO;
400                         goto config_out;
401                 }
402                 wlc_iovar_getint(wl->wlc, "qtxpower", &new_int);
403                 if (new_int != (conf->power_level * 4))
404                         WL_ERROR(("%s: Power level req != actual, %d %d\n",
405                                   __func__, conf->power_level * 4, new_int));
406         }
407         if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
408                 err = ieee_set_channel(hw, conf->channel, conf->channel_type);
409         }
410         if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
411                 WL_NONE(("%s: srl %d, lrl %d\n", __func__,
412                          conf->short_frame_max_tx_count,
413                          conf->long_frame_max_tx_count));
414                 if (wlc_set
415                     (wl->wlc, WLC_SET_SRL,
416                      conf->short_frame_max_tx_count) < 0) {
417                         WL_ERROR(("%s: Error setting srl\n", __func__));
418                         err = -EIO;
419                         goto config_out;
420                 }
421                 if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count)
422                     < 0) {
423                         WL_ERROR(("%s: Error setting lrl\n", __func__));
424                         err = -EIO;
425                         goto config_out;
426                 }
427         }
428
429  config_out:
430         return err;
431 }
432
433 static void
434 wl_ops_bss_info_changed(struct ieee80211_hw *hw,
435                         struct ieee80211_vif *vif,
436                         struct ieee80211_bss_conf *info, u32 changed)
437 {
438         wl_info_t *wl = HW_TO_WL(hw);
439         int val;
440
441 #ifdef WLC_HIGH_ONLY
442         WL_LOCK(wl);
443 #endif
444
445         if (changed & BSS_CHANGED_ASSOC) {
446                 WL_ERROR(("Associated:\t%s\n", info->assoc ? "True" : "False"));
447                 /* association status changed (associated/disassociated)
448                  * also implies a change in the AID.
449                  */
450         }
451         if (changed & BSS_CHANGED_ERP_CTS_PROT) {
452                 WL_NONE(("Use_cts_prot:\t%s Implement me\n",
453                          info->use_cts_prot ? "True" : "False"));
454                 /* CTS protection changed */
455         }
456         if (changed & BSS_CHANGED_ERP_PREAMBLE) {
457                 WL_NONE(("Short preamble:\t%s Implement me\n",
458                          info->use_short_preamble ? "True" : "False"));
459                 /* preamble changed */
460         }
461         if (changed & BSS_CHANGED_ERP_SLOT) {
462                 WL_NONE(("Changing short slot:\t%s\n",
463                          info->use_short_slot ? "True" : "False"));
464                 if (info->use_short_slot)
465                         val = 1;
466                 else
467                         val = 0;
468                 wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val);
469                 /* slot timing changed */
470         }
471
472         if (changed & BSS_CHANGED_HT) {
473                 WL_NONE(("%s: HT mode - Implement me\n", __func__));
474                 /* 802.11n parameters changed */
475         }
476         if (changed & BSS_CHANGED_BASIC_RATES) {
477                 WL_NONE(("Need to change Basic Rates:\t0x%x! Implement me\n",
478                          (uint32) info->basic_rates));
479                 /* Basic rateset changed */
480         }
481         if (changed & BSS_CHANGED_BEACON_INT) {
482                 WL_NONE(("Beacon Interval:\t%d Implement me\n",
483                          info->beacon_int));
484                 /* Beacon interval changed */
485         }
486         if (changed & BSS_CHANGED_BSSID) {
487                 /* char eabuf[ETHER_ADDR_STR_LEN]; */
488                 WL_NONE(("new BSSID:\taid %d  bss:%s\n",
489                          info->aid,
490                          bcm_ether_ntoa((struct ether_addr *)info->bssid,
491                                         eabuf)));
492                 /* BSSID changed, for whatever reason (IBSS and managed mode) */
493                 /* FIXME: need to store bssid in bsscfg */
494                 wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET,
495                                   (struct ether_addr *)info->bssid);
496         }
497         if (changed & BSS_CHANGED_BEACON) {
498                 WL_ERROR(("BSS_CHANGED_BEACON\n"));
499                 /* Beacon data changed, retrieve new beacon (beaconing modes) */
500         }
501         if (changed & BSS_CHANGED_BEACON_ENABLED) {
502                 WL_ERROR(("Beacon enabled:\t%s\n",
503                           info->enable_beacon ? "True" : "False"));
504                 /* Beaconing should be enabled/disabled (beaconing modes) */
505         }
506 #ifdef WLC_HIGH_ONLY
507         WL_UNLOCK(wl);
508 #endif
509         return;
510 }
511
512 static void
513 wl_ops_configure_filter(struct ieee80211_hw *hw,
514                         unsigned int changed_flags,
515                         unsigned int *total_flags, u64 multicast)
516 {
517 #ifndef WLC_HIGH_ONLY
518         wl_info_t *wl = hw->priv;
519 #endif
520
521         changed_flags &= MAC_FILTERS;
522         *total_flags &= MAC_FILTERS;
523         if (changed_flags & FIF_PROMISC_IN_BSS)
524                 WL_ERROR(("FIF_PROMISC_IN_BSS\n"));
525         if (changed_flags & FIF_ALLMULTI)
526                 WL_ERROR(("FIF_ALLMULTI\n"));
527         if (changed_flags & FIF_FCSFAIL)
528                 WL_ERROR(("FIF_FCSFAIL\n"));
529         if (changed_flags & FIF_PLCPFAIL)
530                 WL_ERROR(("FIF_PLCPFAIL\n"));
531         if (changed_flags & FIF_CONTROL)
532                 WL_ERROR(("FIF_CONTROL\n"));
533         if (changed_flags & FIF_OTHER_BSS)
534                 WL_ERROR(("FIF_OTHER_BSS\n"));
535         if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
536                 WL_NONE(("FIF_BCN_PRBRESP_PROMISC\n"));
537 #ifndef WLC_HIGH_ONLY
538                 WL_LOCK(wl);
539                 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
540                         wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS;
541                         wlc_mac_bcn_promisc_change(wl->wlc, 1);
542                 } else {
543                         wlc_mac_bcn_promisc_change(wl->wlc, 0);
544                         wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS;
545                 }
546                 WL_UNLOCK(wl);
547 #endif
548         }
549         return;
550 }
551
552 static int
553 wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
554 {
555         WL_ERROR(("%s: Enter\n", __func__));
556         return 0;
557 }
558
559 static void wl_ops_sw_scan_start(struct ieee80211_hw *hw)
560 {
561         WL_NONE(("Scan Start\n"));
562         return;
563 }
564
565 static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw)
566 {
567         WL_NONE(("Scan Complete\n"));
568         return;
569 }
570
571 static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf)
572 {
573         WL_ERROR(("%s: Enter\n", __func__));
574         return;
575 }
576
577 static int
578 wl_ops_get_stats(struct ieee80211_hw *hw,
579                  struct ieee80211_low_level_stats *stats)
580 {
581         WL_ERROR(("%s: Enter\n", __func__));
582         return 0;
583 }
584
585 static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
586 {
587         WL_ERROR(("%s: Enter\n", __func__));
588         return 0;
589 }
590
591 static void
592 wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
593                   enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
594 {
595         WL_NONE(("%s: Enter\n", __func__));
596         switch (cmd) {
597         default:
598                 WL_ERROR(("%s: Uknown cmd = %d\n", __func__, cmd));
599                 break;
600         }
601         return;
602 }
603
604 static int
605 wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
606                const struct ieee80211_tx_queue_params *params)
607 {
608         wl_info_t *wl = hw->priv;
609
610         WL_NONE(("%s: Enter (WME config)\n", __func__));
611         WL_NONE(("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue,
612                  params->txop, params->cw_min, params->cw_max, params->aifs));
613
614         WL_LOCK(wl);
615         wlc_wme_setparams(wl->wlc, queue, (void *)params, TRUE);
616         WL_UNLOCK(wl);
617
618         return 0;
619 }
620
621 static u64 wl_ops_get_tsf(struct ieee80211_hw *hw)
622 {
623         WL_ERROR(("%s: Enter\n", __func__));
624         return 0;
625 }
626
627 static int
628 wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
629            struct ieee80211_sta *sta)
630 {
631         struct scb *scb;
632
633         int i;
634         wl_info_t *wl = hw->priv;
635
636         /* Init the scb */
637         scb = (struct scb *)sta->drv_priv;
638         bzero(scb, sizeof(struct scb));
639         for (i = 0; i < NUMPRIO; i++)
640                 scb->seqctl[i] = 0xFFFF;
641         scb->seqctl_nonqos = 0xFFFF;
642         scb->magic = SCB_MAGIC;
643
644         wl->pub->global_scb = scb;
645         wl->pub->global_ampdu = &(scb->scb_ampdu);
646         wl->pub->global_ampdu->scb = scb;
647 #ifdef WLC_HIGH_ONLY
648         wl->pub->global_ampdu->max_pdu = AMPDU_NUM_MPDU;
649 #else
650         wl->pub->global_ampdu->max_pdu = 16;
651 #endif
652         pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID,
653                   AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT);
654
655         sta->ht_cap.ht_supported = TRUE;
656 #ifdef WLC_HIGH_ONLY
657         sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_16K;
658 #else
659         sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_64K;
660 #endif
661         sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY;
662         sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD |
663             IEEE80211_HT_CAP_SGI_20 |
664             IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT;
665
666         /* minstrel_ht initiates addBA on our behalf by calling ieee80211_start_tx_ba_session() */
667         return 0;
668 }
669
670 static int
671 wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
672               struct ieee80211_sta *sta)
673 {
674         WL_NONE(("%s: Enter\n", __func__));
675         return 0;
676 }
677
678 static int
679 wl_ampdu_action(struct ieee80211_hw *hw,
680                 struct ieee80211_vif *vif,
681                 enum ieee80211_ampdu_mlme_action action,
682                 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
683 {
684 #if defined(BCMDBG)
685         struct scb *scb = (struct scb *)sta->drv_priv;
686 #endif
687         wl_info_t *wl = hw->priv;
688
689         ASSERT(scb->magic == SCB_MAGIC);
690         switch (action) {
691         case IEEE80211_AMPDU_RX_START:
692                 WL_NONE(("%s: action = IEEE80211_AMPDU_RX_START\n", __func__));
693                 break;
694         case IEEE80211_AMPDU_RX_STOP:
695                 WL_NONE(("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__));
696                 break;
697         case IEEE80211_AMPDU_TX_START:
698                 if (!wlc_aggregatable(wl->wlc, tid)) {
699                         /* WL_ERROR(("START: tid %d is not agg' able, return FAILURE to stack\n", tid)); */
700                         return -1;
701                 }
702                 /* XXX: Use the starting sequence number provided ... */
703                 *ssn = 0;
704                 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
705                 break;
706
707         case IEEE80211_AMPDU_TX_STOP:
708                 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
709                 break;
710         case IEEE80211_AMPDU_TX_OPERATIONAL:
711                 /* Not sure what to do here */
712                 /* Power save wakeup */
713                 WL_NONE(("%s: action = IEEE80211_AMPDU_TX_OPERATIONAL\n",
714                          __func__));
715                 break;
716         default:
717                 WL_ERROR(("%s: Invalid command, ignoring\n", __func__));
718         }
719
720         return 0;
721 }
722
723 static const struct ieee80211_ops wl_ops = {
724 #ifdef WLC_HIGH_ONLY
725         .tx = wl_ops_tx_nl,
726 #else
727         .tx = wl_ops_tx,
728 #endif
729         .start = wl_ops_start,
730         .stop = wl_ops_stop,
731         .add_interface = wl_ops_add_interface,
732         .remove_interface = wl_ops_remove_interface,
733         .config = wl_ops_config,
734         .bss_info_changed = wl_ops_bss_info_changed,
735         .configure_filter = wl_ops_configure_filter,
736         .set_tim = wl_ops_set_tim,
737         .sw_scan_start = wl_ops_sw_scan_start,
738         .sw_scan_complete = wl_ops_sw_scan_complete,
739         .set_tsf = wl_ops_set_tsf,
740         .get_stats = wl_ops_get_stats,
741         .set_rts_threshold = wl_ops_set_rts_threshold,
742         .sta_notify = wl_ops_sta_notify,
743         .conf_tx = wl_ops_conf_tx,
744         .get_tsf = wl_ops_get_tsf,
745         .sta_add = wl_sta_add,
746         .sta_remove = wl_sta_remove,
747         .ampdu_action = wl_ampdu_action,
748 };
749
750 static int wl_set_hint(wl_info_t *wl, char *abbrev)
751 {
752         WL_ERROR(("%s: Sending country code %c%c to MAC80211\n", __func__,
753                   abbrev[0], abbrev[1]));
754         return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev);
755 }
756
757 /**
758  * attach to the WL device.
759  *
760  * Attach to the WL device identified by vendor and device parameters.
761  * regs is a host accessible memory address pointing to WL device registers.
762  *
763  * wl_attach is not defined as static because in the case where no bus
764  * is defined, wl_attach will never be called, and thus, gcc will issue
765  * a warning that this function is defined but not used if we declare
766  * it as static.
767  */
768 static wl_info_t *wl_attach(uint16 vendor, uint16 device, unsigned long regs,
769                             uint bustype, void *btparam, uint irq)
770 {
771         wl_info_t *wl;
772         osl_t *osh;
773         int unit, err;
774
775         unsigned long base_addr;
776         struct ieee80211_hw *hw;
777         u8 perm[ETH_ALEN];
778
779         unit = wl_found + instance_base;
780         err = 0;
781
782         if (unit < 0) {
783                 WL_ERROR(("wl%d: unit number overflow, exiting\n", unit));
784                 return NULL;
785         }
786
787         if (oneonly && (unit != instance_base)) {
788                 WL_ERROR(("wl%d: wl_attach: oneonly is set, exiting\n", unit));
789                 return NULL;
790         }
791
792         /* Requires pkttag feature */
793         osh = osl_attach(btparam, bustype, TRUE);
794         ASSERT(osh);
795
796 #ifdef WLC_HIGH_ONLY
797         hw = ieee80211_alloc_hw(sizeof(wl_info_t), &wl_ops);
798         if (!hw) {
799                 WL_ERROR(("%s: ieee80211_alloc_hw failed\n", __func__));
800                 ASSERT(0);
801         }
802
803         bzero(hw->priv, sizeof(*wl));
804         wl = hw->priv;
805 #else
806         /* allocate private info */
807         hw = pci_get_drvdata(btparam);  /* btparam == pdev */
808         wl = hw->priv;
809 #endif
810         ASSERT(wl);
811
812         wl->magic = WL_MAGIC;
813         wl->osh = osh;
814         atomic_set(&wl->callbacks, 0);
815
816         /* setup the bottom half handler */
817         tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl);
818
819 #ifdef WLC_HIGH_ONLY
820         wl->rpc_th = bcm_rpc_tp_attach(osh, NULL);
821         if (wl->rpc_th == NULL) {
822                 WL_ERROR(("wl%d: %s: bcm_rpc_tp_attach failed!\n", unit,
823                           __func__));
824                 goto fail;
825         }
826
827         wl->rpc = bcm_rpc_attach(NULL, osh, wl->rpc_th);
828         if (wl->rpc == NULL) {
829                 WL_ERROR(("wl%d: %s: bcm_rpc_attach failed!\n", unit,
830                           __func__));
831                 goto fail;
832         }
833
834         /* init tx work queue for wl_start/send pkt; no need to destroy workitem  */
835         INIT_WORK(&wl->txq_task.work, (work_func_t) wl_start_txqwork);
836         wl->txq_task.context = wl;
837 #endif                          /* WLC_HIGH_ONLY */
838
839 #ifdef BCMSDIO
840         SET_IEEE80211_DEV(hw, sdiommc_dev);
841 #endif
842
843         base_addr = regs;
844
845         if (bustype == PCI_BUS) {
846                 /* piomode can be overwritten by command argument */
847                 wl->piomode = piomode;
848                 WL_TRACE(("PCI/%s\n", wl->piomode ? "PIO" : "DMA"));
849         } else if (bustype == RPC_BUS) {
850                 /* Do nothing */
851         } else {
852                 bustype = PCI_BUS;
853                 WL_TRACE(("force to PCI\n"));
854         }
855         wl->bcm_bustype = bustype;
856
857 #ifdef WLC_HIGH_ONLY
858         if (wl->bcm_bustype == RPC_BUS) {
859                 wl->regsva = (void *)0;
860                 btparam = wl->rpc;
861         } else
862 #endif
863         wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ);
864         if (wl->regsva == NULL) {
865                 WL_ERROR(("wl%d: ioremap() failed\n", unit));
866                 goto fail;
867         }
868 #ifdef WLC_HIGH_ONLY
869         spin_lock_init(&wl->rpcq_lock);
870         spin_lock_init(&wl->txq_lock);
871
872         init_MUTEX(&wl->sem);
873 #else
874         spin_lock_init(&wl->lock);
875         spin_lock_init(&wl->isr_lock);
876 #endif
877
878 #ifndef WLC_HIGH_ONLY
879         /* prepare ucode */
880         if (wl_request_fw(wl, (struct pci_dev *)btparam)) {
881                 printf("%s: Failed to find firmware usually in %s\n",
882                         KBUILD_MODNAME, "/lib/firmware/brcm");
883                 wl_release_fw(wl);
884                 wl_remove((struct pci_dev *)btparam);
885                 goto fail1;
886         }
887 #endif
888
889         /* common load-time initialization */
890         wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, osh,
891                              wl->regsva, wl->bcm_bustype, btparam, &err);
892 #ifndef WLC_HIGH_ONLY
893         wl_release_fw(wl);
894 #endif
895         if (!wl->wlc) {
896                 printf("%s: %s wlc_attach() failed with code %d\n",
897                         KBUILD_MODNAME, EPI_VERSION_STR, err);
898                 goto fail;
899         }
900         wl->pub = wlc_pub(wl->wlc);
901
902         wl->pub->ieee_hw = hw;
903         ASSERT(wl->pub->ieee_hw);
904         ASSERT(wl->pub->ieee_hw->priv == wl);
905
906 #ifdef WLC_HIGH_ONLY
907         REGOPSSET(osh, (osl_rreg_fn_t) wlc_reg_read,
908                   (osl_wreg_fn_t) wlc_reg_write, wl->wlc);
909         wl->rpc_dispatch_ctx.rpc = wl->rpc;
910         wl->rpc_dispatch_ctx.wlc = wl->wlc;
911         bcm_rpc_rxcb_init(wl->rpc, wl, wl_rpc_dispatch_schedule, wl,
912                           wl_rpc_down, NULL, NULL);
913 #endif                          /* WLC_HIGH_ONLY */
914
915         if (nompc) {
916                 if (wlc_iovar_setint(wl->wlc, "mpc", 0)) {
917                         WL_ERROR(("wl%d: Error setting MPC variable to 0\n",
918                                   unit));
919                 }
920         }
921 #ifdef BCMSDIO
922         /* Set SDIO drive strength */
923         wlc_iovar_setint(wl->wlc, "sd_drivestrength", sd_drivestrength);
924 #endif
925
926 #ifdef WLC_LOW
927         /* register our interrupt handler */
928         if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
929                 WL_ERROR(("wl%d: request_irq() failed\n", unit));
930                 goto fail;
931         }
932         wl->irq = irq;
933 #endif                          /* WLC_LOW */
934
935         /* register module */
936         wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog,
937                             NULL);
938
939         if (ieee_hw_init(hw)) {
940                 WL_ERROR(("wl%d: %s: ieee_hw_init failed!\n", unit, __func__));
941                 goto fail;
942         }
943
944         bcopy(&wl->pub->cur_etheraddr, perm, ETHER_ADDR_LEN);
945         ASSERT(is_valid_ether_addr(perm));
946         SET_IEEE80211_PERM_ADDR(hw, perm);
947
948         err = ieee80211_register_hw(hw);
949         if (err) {
950                 WL_ERROR(("%s: ieee80211_register_hw failed, status %d\n",
951                           __func__, err));
952         }
953
954         if (wl->pub->srom_ccode[0])
955                 err = wl_set_hint(wl, wl->pub->srom_ccode);
956         else
957                 err = wl_set_hint(wl, "US");
958         if (err) {
959                 WL_ERROR(("%s: regulatory_hint failed, status %d\n", __func__,
960                           err));
961         }
962 #ifndef WLC_HIGH_ONLY
963         WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver "
964                   EPI_VERSION_STR " (" PHY_VERSION_STR ")", unit));
965 #else
966         WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver "
967                   EPI_VERSION_STR, unit));
968 #endif
969
970 #ifdef BCMDBG
971         printf(" (Compiled in " SRCBASE " at " __TIME__ " on " __DATE__ ")");
972 #endif                          /* BCMDBG */
973         printf("\n");
974
975         wl_found++;
976         return wl;
977
978  fail:
979         wl_free(wl);
980 fail1:
981         return NULL;
982 }
983
984 #ifdef WLC_HIGH_ONLY
985 static void *wl_dbus_probe_cb(void *arg, const char *desc, uint32 bustype,
986                               uint32 hdrlen)
987 {
988         wl_info_t *wl;
989         WL_ERROR(("%s:\n", __func__));
990
991         wl = wl_attach(BCM_DNGL_VID, BCM_DNGL_BDC_PID, (unsigned long) NULL, RPC_BUS,
992                 NULL, 0);
993         if (!wl) {
994                 WL_ERROR(("%s: wl_attach failed\n", __func__));
995         }
996
997         /* This is later passed to wl_dbus_disconnect_cb */
998         return wl;
999 }
1000
1001 static void wl_dbus_disconnect_cb(void *arg)
1002 {
1003         wl_info_t *wl = arg;
1004
1005         WL_ERROR(("%s:\n", __func__));
1006
1007         if (wl) {
1008 #ifdef WLC_HIGH_ONLY
1009                 if (wl->pub->ieee_hw) {
1010                         ieee80211_unregister_hw(wl->pub->ieee_hw);
1011                         WL_ERROR(("%s: Back from down\n", __func__));
1012                 }
1013                 wlc_device_removed(wl->wlc);
1014                 wlc_bmac_dngl_reboot(wl->rpc);
1015                 bcm_rpc_down(wl->rpc);
1016 #endif
1017                 WL_LOCK(wl);
1018                 wl_down(wl);
1019                 WL_UNLOCK(wl);
1020 #ifdef WLC_HIGH_ONLY
1021                 if (wl->pub->ieee_hw) {
1022                         ieee80211_free_hw(wl->pub->ieee_hw);
1023                         WL_ERROR(("%s: Back from ieee80211_free_hw\n",
1024                                   __func__));
1025                         wl->pub->ieee_hw = NULL;
1026                 }
1027 #endif
1028                 wl_free(wl);
1029         }
1030 }
1031 #endif                          /* WLC_HIGH_ONLY */
1032
1033
1034 #define CHAN2GHZ(channel, freqency, chflags)  { \
1035         .band = IEEE80211_BAND_2GHZ, \
1036         .center_freq = (freqency), \
1037         .hw_value = (channel), \
1038         .flags = chflags, \
1039         .max_antenna_gain = 0, \
1040         .max_power = 19, \
1041 }
1042
1043 static struct ieee80211_channel wl_2ghz_chantable[] = {
1044         CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
1045         CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS),
1046         CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS),
1047         CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS),
1048         CHAN2GHZ(5, 2432, 0),
1049         CHAN2GHZ(6, 2437, 0),
1050         CHAN2GHZ(7, 2442, 0),
1051         CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS),
1052         CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS),
1053         CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
1054         CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
1055         CHAN2GHZ(12, 2467,
1056                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
1057                  IEEE80211_CHAN_NO_HT40PLUS),
1058         CHAN2GHZ(13, 2472,
1059                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
1060                  IEEE80211_CHAN_NO_HT40PLUS),
1061         CHAN2GHZ(14, 2484,
1062                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
1063                  IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
1064 };
1065
1066 #define CHAN5GHZ(channel, chflags)  { \
1067         .band = IEEE80211_BAND_5GHZ, \
1068         .center_freq = 5000 + 5*(channel), \
1069         .hw_value = (channel), \
1070         .flags = chflags, \
1071         .max_antenna_gain = 0, \
1072         .max_power = 21, \
1073 }
1074
1075 static struct ieee80211_channel wl_5ghz_nphy_chantable[] = {
1076         /* UNII-1 */
1077         CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS),
1078         CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS),
1079         CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS),
1080         CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
1081         /* UNII-2 */
1082         CHAN5GHZ(52,
1083                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1084                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
1085         CHAN5GHZ(56,
1086                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1087                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
1088         CHAN5GHZ(60,
1089                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1090                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
1091         CHAN5GHZ(64,
1092                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1093                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
1094         /* MID */
1095         CHAN5GHZ(100,
1096                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1097                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
1098         CHAN5GHZ(104,
1099                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1100                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
1101         CHAN5GHZ(108,
1102                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1103                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
1104         CHAN5GHZ(112,
1105                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1106                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
1107         CHAN5GHZ(116,
1108                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1109                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
1110         CHAN5GHZ(120,
1111                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1112                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
1113         CHAN5GHZ(124,
1114                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1115                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
1116         CHAN5GHZ(128,
1117                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1118                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
1119         CHAN5GHZ(132,
1120                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1121                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
1122         CHAN5GHZ(136,
1123                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1124                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
1125         CHAN5GHZ(140,
1126                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
1127                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS |
1128                  IEEE80211_CHAN_NO_HT40MINUS),
1129         /* UNII-3 */
1130         CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
1131         CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS),
1132         CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS),
1133         CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS),
1134         CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
1135 };
1136
1137 #define RATE(rate100m, _flags) { \
1138         .bitrate = (rate100m), \
1139         .flags = (_flags), \
1140         .hw_value = (rate100m / 5), \
1141 }
1142
1143 static struct ieee80211_rate wl_legacy_ratetable[] = {
1144         RATE(10, 0),
1145         RATE(20, IEEE80211_RATE_SHORT_PREAMBLE),
1146         RATE(55, IEEE80211_RATE_SHORT_PREAMBLE),
1147         RATE(110, IEEE80211_RATE_SHORT_PREAMBLE),
1148         RATE(60, 0),
1149         RATE(90, 0),
1150         RATE(120, 0),
1151         RATE(180, 0),
1152         RATE(240, 0),
1153         RATE(360, 0),
1154         RATE(480, 0),
1155         RATE(540, 0),
1156 };
1157
1158 static struct ieee80211_supported_band wl_band_2GHz_nphy = {
1159         .band = IEEE80211_BAND_2GHZ,
1160         .channels = wl_2ghz_chantable,
1161         .n_channels = ARRAY_SIZE(wl_2ghz_chantable),
1162         .bitrates = wl_legacy_ratetable,
1163         .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable),
1164         .ht_cap = {
1165                    /* from include/linux/ieee80211.h */
1166                    .cap = IEEE80211_HT_CAP_GRN_FLD |
1167                    IEEE80211_HT_CAP_SGI_20 |
1168                    IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT,
1169 #ifdef WLC_HIGH_ONLY
1170                    .ht_supported = true,
1171                    .ampdu_factor = AMPDU_RX_FACTOR_16K,
1172 #else
1173                    .ht_supported = true,
1174                    .ampdu_factor = AMPDU_RX_FACTOR_64K,
1175 #endif
1176                    .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
1177                    .mcs = {
1178                            /* placeholders for now */
1179 #ifdef WLC_HIGH_ONLY
1180                            /*
1181                             * rx_mask[0] = 0xff by default
1182                             * rx_mask[1] = 0xff if number of rx chain >=2
1183                             * rx_mask[2] = 0xff if number of rx chain >=3
1184                             * rx_mask[4] = 1 if 40Mhz is supported
1185                             */
1186                            .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},
1187                            .rx_highest = 72,    /* max rate of single stream */
1188 #else
1189                            .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
1190                            .rx_highest = 500,
1191 #endif
1192                            .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
1193                    }
1194 };
1195
1196 static struct ieee80211_supported_band wl_band_5GHz_nphy = {
1197         .band = IEEE80211_BAND_5GHZ,
1198         .channels = wl_5ghz_nphy_chantable,
1199         .n_channels = ARRAY_SIZE(wl_5ghz_nphy_chantable),
1200         .bitrates = wl_legacy_ratetable + 4,
1201         .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable) - 4,
1202         .ht_cap = {
1203                    /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */
1204                    .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT,     /* No 40 mhz yet */
1205                    .ht_supported = true,
1206                    .ampdu_factor = AMPDU_RX_FACTOR_64K,
1207                    .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
1208                    .mcs = {
1209                            /* placeholders for now */
1210                            .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
1211                            .rx_highest = 500,
1212                            .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
1213                    }
1214 };
1215
1216 static int ieee_hw_rate_init(struct ieee80211_hw *hw)
1217 {
1218         wl_info_t *wl = HW_TO_WL(hw);
1219         int has_5g;
1220         char phy_list[4];
1221
1222         has_5g = 0;
1223
1224         hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
1225         hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
1226
1227         if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) {
1228                 WL_ERROR(("Phy list failed\n"));
1229         }
1230         WL_NONE(("%s: phylist = %c\n", __func__, phy_list[0]));
1231
1232 #ifndef WLC_HIGH_ONLY
1233         if (phy_list[0] == 'n' || phy_list[0] == 'c') {
1234                 if (phy_list[0] == 'c') {
1235                         /* Single stream */
1236                         wl_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0;
1237                         wl_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72;
1238                 }
1239 #else
1240         if (phy_list[0] == 's') {
1241 #endif
1242                 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy;
1243         } else {
1244                 BUG();
1245                 return -1;
1246         }
1247
1248         /* Assume all bands use the same phy.  True for 11n devices. */
1249         if (NBANDS_PUB(wl->pub) > 1) {
1250                 has_5g++;
1251 #ifndef WLC_HIGH_ONLY
1252                 if (phy_list[0] == 'n' || phy_list[0] == 'c') {
1253 #else
1254                 if (phy_list[0] == 's') {
1255 #endif
1256                         hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
1257                             &wl_band_5GHz_nphy;
1258                 } else {
1259                         return -1;
1260                 }
1261         }
1262
1263         WL_NONE(("%s: 2ghz = %d, 5ghz = %d\n", __func__, 1, has_5g));
1264
1265         return 0;
1266 }
1267
1268 static int ieee_hw_init(struct ieee80211_hw *hw)
1269 {
1270         hw->flags = IEEE80211_HW_SIGNAL_DBM
1271             /* | IEEE80211_HW_CONNECTION_MONITOR  What is this? */
1272             | IEEE80211_HW_REPORTS_TX_ACK_STATUS
1273             | IEEE80211_HW_AMPDU_AGGREGATION;
1274
1275         hw->extra_tx_headroom = wlc_get_header_len();
1276         /* FIXME: should get this from wlc->machwcap */
1277         hw->queues = 4;
1278         /* FIXME: this doesn't seem to be used properly in minstrel_ht.
1279          * mac80211/status.c:ieee80211_tx_status() checks this value,
1280          * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate()
1281          * appears to always set 3 rates
1282          */
1283         hw->max_rates = 2;      /* Primary rate and 1 fallback rate */
1284
1285         hw->channel_change_time = 7 * 1000;     /* channel change time is dependant on chip and band  */
1286         hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1287
1288         hw->rate_control_algorithm = "minstrel_ht";
1289
1290         hw->sta_data_size = sizeof(struct scb);
1291         return ieee_hw_rate_init(hw);
1292 }
1293
1294 #ifndef BCMSDIO
1295 /**
1296  * determines if a device is a WL device, and if so, attaches it.
1297  *
1298  * This function determines if a device pointed to by pdev is a WL device,
1299  * and if so, performs a wl_attach() on it.
1300  *
1301  */
1302 int __devinit
1303 wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1304 {
1305         int rc;
1306         wl_info_t *wl;
1307         struct ieee80211_hw *hw;
1308         uint32 val;
1309
1310         ASSERT(pdev);
1311
1312         WL_TRACE(("%s: bus %d slot %d func %d irq %d\n", __func__,
1313                   pdev->bus->number, PCI_SLOT(pdev->devfn),
1314                   PCI_FUNC(pdev->devfn), pdev->irq));
1315
1316         if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) ||
1317             (((pdev->device & 0xff00) != 0x4300) &&
1318              ((pdev->device & 0xff00) != 0x4700) &&
1319              ((pdev->device < 43000) || (pdev->device > 43999))))
1320                 return -ENODEV;
1321
1322         rc = pci_enable_device(pdev);
1323         if (rc) {
1324                 WL_ERROR(("%s: Cannot enable device %d-%d_%d\n", __func__,
1325                           pdev->bus->number, PCI_SLOT(pdev->devfn),
1326                           PCI_FUNC(pdev->devfn)));
1327                 return -ENODEV;
1328         }
1329         pci_set_master(pdev);
1330
1331         pci_read_config_dword(pdev, 0x40, &val);
1332         if ((val & 0x0000ff00) != 0)
1333                 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1334
1335         hw = ieee80211_alloc_hw(sizeof(wl_info_t), &wl_ops);
1336         if (!hw) {
1337                 WL_ERROR(("%s: ieee80211_alloc_hw failed\n", __func__));
1338                 rc = -ENOMEM;
1339                 goto err_1;
1340         }
1341
1342         SET_IEEE80211_DEV(hw, &pdev->dev);
1343
1344         pci_set_drvdata(pdev, hw);
1345
1346         bzero(hw->priv, sizeof(*wl));
1347
1348         wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0),
1349                        PCI_BUS, pdev, pdev->irq);
1350
1351         if (!wl) {
1352                 WL_ERROR(("%s: %s: wl_attach failed!\n",
1353                         KBUILD_MODNAME, __func__));
1354                 return -ENODEV;
1355         }
1356         return 0;
1357  err_1:
1358         WL_ERROR(("%s: err_1: Major hoarkage\n", __func__));
1359         return 0;
1360 }
1361
1362 #ifdef LINUXSTA_PS
1363 static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
1364 {
1365         wl_info_t *wl;
1366         struct ieee80211_hw *hw;
1367
1368         WL_TRACE(("wl: wl_suspend\n"));
1369
1370         hw = pci_get_drvdata(pdev);
1371         wl = HW_TO_WL(hw);
1372         if (!wl) {
1373                 WL_ERROR(("wl: wl_suspend: pci_get_drvdata failed\n"));
1374                 return -ENODEV;
1375         }
1376
1377         WL_LOCK(wl);
1378         wl_down(wl);
1379         wl->pub->hw_up = FALSE;
1380         WL_UNLOCK(wl);
1381         pci_save_state(pdev, wl->pci_psstate);
1382         pci_disable_device(pdev);
1383         return pci_set_power_state(pdev, PCI_D3hot);
1384 }
1385
1386 static int wl_resume(struct pci_dev *pdev)
1387 {
1388         wl_info_t *wl;
1389         struct ieee80211_hw *hw;
1390         int err = 0;
1391         uint32 val;
1392
1393         WL_TRACE(("wl: wl_resume\n"));
1394         hw = pci_get_drvdata(pdev);
1395         wl = HW_TO_WL(hw);
1396         if (!wl) {
1397                 WL_ERROR(("wl: wl_resume: pci_get_drvdata failed\n"));
1398                 return -ENODEV;
1399         }
1400
1401         err = pci_set_power_state(pdev, PCI_D0);
1402         if (err)
1403                 return err;
1404
1405         pci_restore_state(pdev, wl->pci_psstate);
1406
1407         err = pci_enable_device(pdev);
1408         if (err)
1409                 return err;
1410
1411         pci_set_master(pdev);
1412
1413         pci_read_config_dword(pdev, 0x40, &val);
1414         if ((val & 0x0000ff00) != 0)
1415                 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1416
1417         WL_LOCK(wl);
1418         err = wl_up(wl);
1419         WL_UNLOCK(wl);
1420
1421         return err;
1422 }
1423 #endif                          /* LINUXSTA_PS */
1424
1425 static void wl_remove(struct pci_dev *pdev)
1426 {
1427         wl_info_t *wl;
1428         struct ieee80211_hw *hw;
1429
1430         hw = pci_get_drvdata(pdev);
1431         wl = HW_TO_WL(hw);
1432         if (!wl) {
1433                 WL_ERROR(("wl: wl_remove: pci_get_drvdata failed\n"));
1434                 return;
1435         }
1436         if (!wlc_chipmatch(pdev->vendor, pdev->device)) {
1437                 WL_ERROR(("wl: wl_remove: wlc_chipmatch failed\n"));
1438                 return;
1439         }
1440         if (wl->wlc) {
1441                 ieee80211_unregister_hw(hw);
1442                 WL_LOCK(wl);
1443                 wl_down(wl);
1444                 WL_UNLOCK(wl);
1445                 WL_NONE(("%s: Down\n", __func__));
1446         }
1447         pci_disable_device(pdev);
1448
1449         wl_free(wl);
1450
1451         pci_set_drvdata(pdev, NULL);
1452         ieee80211_free_hw(hw);
1453 }
1454
1455 static struct pci_driver wl_pci_driver = {
1456  .name  = "brcm80211",
1457  .probe = wl_pci_probe,
1458 #ifdef LINUXSTA_PS
1459  .suspend = wl_suspend,
1460  .resume  = wl_resume,
1461 #endif                          /* LINUXSTA_PS */
1462  .remove   = __devexit_p(wl_remove),
1463  .id_table = wl_id_table,
1464 };
1465 #endif                          /* !BCMSDIO */
1466
1467 /**
1468  * This is the main entry point for the WL driver.
1469  *
1470  * This function determines if a device pointed to by pdev is a WL device,
1471  * and if so, performs a wl_attach() on it.
1472  *
1473  */
1474 static int __init wl_module_init(void)
1475 {
1476         int error = -ENODEV;
1477
1478 #ifdef BCMDBG
1479         if (msglevel != 0xdeadbeef)
1480                 wl_msg_level = msglevel;
1481         else {
1482                 char *var = getvar(NULL, "wl_msglevel");
1483                 if (var)
1484                         wl_msg_level = simple_strtoul(var, NULL, 0);
1485         }
1486 #ifndef WLC_HIGH_ONLY
1487         {
1488                 extern uint32 phyhal_msg_level;
1489
1490                 if (phymsglevel != 0xdeadbeef)
1491                         phyhal_msg_level = phymsglevel;
1492                 else {
1493                         char *var = getvar(NULL, "phy_msglevel");
1494                         if (var)
1495                                 phyhal_msg_level = simple_strtoul(var, NULL, 0);
1496                 }
1497         }
1498 #endif                          /* WLC_HIGH_ONLY */
1499 #endif                          /* BCMDBG */
1500
1501 #ifndef BCMSDIO
1502         error = pci_register_driver(&wl_pci_driver);
1503         if (!error)
1504                 return 0;
1505
1506 #endif                          /* !BCMSDIO */
1507
1508 #ifdef WLC_HIGH_ONLY
1509         /* BMAC_NOTE: define hardcode number, why NODEVICE is ok ? */
1510         error =
1511             dbus_register(BCM_DNGL_VID, 0, wl_dbus_probe_cb,
1512                           wl_dbus_disconnect_cb, NULL, NULL, NULL);
1513         if (error == DBUS_ERR_NODEVICE) {
1514                 error = DBUS_OK;
1515         }
1516 #endif                          /* WLC_HIGH_ONLY */
1517
1518         return error;
1519 }
1520
1521 /**
1522  * This function unloads the WL driver from the system.
1523  *
1524  * This function unconditionally unloads the WL driver module from the
1525  * system.
1526  *
1527  */
1528 static void __exit wl_module_exit(void)
1529 {
1530 #ifndef BCMSDIO
1531         pci_unregister_driver(&wl_pci_driver);
1532 #endif                          /* !BCMSDIO */
1533
1534 #ifdef WLC_HIGH_ONLY
1535         dbus_deregister();
1536 #endif                          /* WLC_HIGH_ONLY */
1537 }
1538
1539 module_init(wl_module_init);
1540 module_exit(wl_module_exit);
1541
1542 /**
1543  * This function frees the WL per-device resources.
1544  *
1545  * This function frees resources owned by the WL device pointed to
1546  * by the wl parameter.
1547  *
1548  */
1549 void wl_free(wl_info_t *wl)
1550 {
1551         wl_timer_t *t, *next;
1552         osl_t *osh;
1553
1554         ASSERT(wl);
1555 #ifndef WLC_HIGH_ONLY
1556         /* free ucode data */
1557         if (wl->fw.fw_cnt)
1558                 wl_ucode_data_free();
1559         if (wl->irq)
1560                 free_irq(wl->irq, wl);
1561 #endif
1562
1563         /* kill dpc */
1564         tasklet_kill(&wl->tasklet);
1565
1566         if (wl->pub) {
1567                 wlc_module_unregister(wl->pub, "linux", wl);
1568         }
1569
1570         /* free common resources */
1571         if (wl->wlc) {
1572                 wlc_detach(wl->wlc);
1573                 wl->wlc = NULL;
1574                 wl->pub = NULL;
1575         }
1576
1577         /* virtual interface deletion is deferred so we cannot spinwait */
1578
1579         /* wait for all pending callbacks to complete */
1580         while (atomic_read(&wl->callbacks) > 0)
1581                 schedule();
1582
1583         /* free timers */
1584         for (t = wl->timers; t; t = next) {
1585                 next = t->next;
1586 #ifdef BCMDBG
1587                 if (t->name)
1588                         MFREE(wl->osh, t->name, strlen(t->name) + 1);
1589 #endif
1590                 MFREE(wl->osh, t, sizeof(wl_timer_t));
1591         }
1592
1593         osh = wl->osh;
1594
1595         /*
1596          * unregister_netdev() calls get_stats() which may read chip registers
1597          * so we cannot unmap the chip registers until after calling unregister_netdev() .
1598          */
1599         if (wl->regsva && BUSTYPE(wl->bcm_bustype) != SDIO_BUS &&
1600             BUSTYPE(wl->bcm_bustype) != JTAG_BUS) {
1601                 iounmap((void *)wl->regsva);
1602         }
1603         wl->regsva = NULL;
1604
1605 #ifdef WLC_HIGH_ONLY
1606         wl_rpcq_free(wl);
1607
1608         wl_txq_free(wl);
1609
1610         if (wl->rpc) {
1611                 bcm_rpc_detach(wl->rpc);
1612                 wl->rpc = NULL;
1613         }
1614
1615         if (wl->rpc_th) {
1616                 bcm_rpc_tp_detach(wl->rpc_th);
1617                 wl->rpc_th = NULL;
1618         }
1619 #endif                          /* WLC_HIGH_ONLY */
1620
1621         if (osl_malloced(osh)) {
1622                 printf("****   Memory leak of bytes %d\n", osl_malloced(osh));
1623                 ASSERT(0 && "Memory Leak");
1624         }
1625
1626         osl_detach(osh);
1627 }
1628
1629 #ifdef WLC_LOW
1630 /* transmit a packet */
1631 static int BCMFASTPATH wl_start(struct sk_buff *skb, wl_info_t *wl)
1632 {
1633         if (!wl)
1634                 return -ENETDOWN;
1635
1636         return wl_start_int(wl, WL_TO_HW(wl), skb);
1637 }
1638 #endif                          /* WLC_LOW */
1639
1640 static int BCMFASTPATH
1641 wl_start_int(wl_info_t *wl, struct ieee80211_hw *hw, struct sk_buff *skb)
1642 {
1643 #ifdef WLC_HIGH_ONLY
1644         WL_LOCK(wl);
1645 #endif
1646         wlc_sendpkt_mac80211(wl->wlc, skb, hw);
1647 #ifdef WLC_HIGH_ONLY
1648         WL_UNLOCK(wl);
1649 #endif
1650         return NETDEV_TX_OK;
1651 }
1652
1653 void wl_txflowcontrol(wl_info_t *wl, struct wl_if *wlif, bool state, int prio)
1654 {
1655         WL_ERROR(("Shouldn't be here %s\n", __func__));
1656 }
1657
1658 #if defined(WLC_HIGH_ONLY)
1659 /* Schedule a completion handler to run at safe time */
1660 static int
1661 wl_schedule_task(wl_info_t *wl, void (*fn) (struct wl_task *task),
1662                  void *context)
1663 {
1664         wl_task_t *task;
1665
1666         WL_TRACE(("wl%d: wl_schedule_task\n", wl->pub->unit));
1667
1668         task = osl_malloc(wl->osh, sizeof(wl_task_t));
1669         if (!task) {
1670                 WL_ERROR(("wl%d: wl_schedule_task: out of memory, malloced %d bytes\n", wl->pub->unit, osl_malloced(wl->osh)));
1671                 return -ENOMEM;
1672         }
1673
1674         INIT_WORK(&task->work, (work_func_t) fn);
1675         task->context = context;
1676
1677         if (!schedule_work(&task->work)) {
1678                 WL_ERROR(("wl%d: schedule_work() failed\n", wl->pub->unit));
1679                 MFREE(wl->osh, task, sizeof(wl_task_t));
1680                 return -ENOMEM;
1681         }
1682
1683         atomic_inc(&wl->callbacks);
1684
1685         return 0;
1686 }
1687 #endif                          /* defined(WLC_HIGH_ONLY) */
1688
1689 void wl_init(wl_info_t *wl)
1690 {
1691         WL_TRACE(("wl%d: wl_init\n", wl->pub->unit));
1692
1693         wl_reset(wl);
1694
1695         wlc_init(wl->wlc);
1696 }
1697
1698 uint wl_reset(wl_info_t *wl)
1699 {
1700         WL_TRACE(("wl%d: wl_reset\n", wl->pub->unit));
1701
1702         wlc_reset(wl->wlc);
1703
1704         /* dpc will not be rescheduled */
1705         wl->resched = 0;
1706
1707         return 0;
1708 }
1709
1710 /*
1711  * These are interrupt on/off entry points. Disable interrupts
1712  * during interrupt state transition.
1713  */
1714 void BCMFASTPATH wl_intrson(wl_info_t *wl)
1715 {
1716 #if defined(WLC_LOW)
1717         unsigned long flags;
1718
1719         INT_LOCK(wl, flags);
1720         wlc_intrson(wl->wlc);
1721         INT_UNLOCK(wl, flags);
1722 #endif                          /* WLC_LOW */
1723 }
1724
1725 bool wl_alloc_dma_resources(wl_info_t *wl, uint addrwidth)
1726 {
1727         return TRUE;
1728 }
1729
1730 uint32 BCMFASTPATH wl_intrsoff(wl_info_t *wl)
1731 {
1732 #if defined(WLC_LOW)
1733         unsigned long flags;
1734         uint32 status;
1735
1736         INT_LOCK(wl, flags);
1737         status = wlc_intrsoff(wl->wlc);
1738         INT_UNLOCK(wl, flags);
1739         return status;
1740 #else
1741         return 0;
1742 #endif                          /* WLC_LOW */
1743 }
1744
1745 void wl_intrsrestore(wl_info_t *wl, uint32 macintmask)
1746 {
1747 #if defined(WLC_LOW)
1748         unsigned long flags;
1749
1750         INT_LOCK(wl, flags);
1751         wlc_intrsrestore(wl->wlc, macintmask);
1752         INT_UNLOCK(wl, flags);
1753 #endif                          /* WLC_LOW */
1754 }
1755
1756 int wl_up(wl_info_t *wl)
1757 {
1758         int error = 0;
1759
1760         if (wl->pub->up)
1761                 return 0;
1762
1763         error = wlc_up(wl->wlc);
1764
1765         return error;
1766 }
1767
1768 void wl_down(wl_info_t *wl)
1769 {
1770         uint callbacks, ret_val = 0;
1771
1772         /* call common down function */
1773         ret_val = wlc_down(wl->wlc);
1774         callbacks = atomic_read(&wl->callbacks) - ret_val;
1775
1776         /* wait for down callbacks to complete */
1777         WL_UNLOCK(wl);
1778
1779 #ifndef WLC_HIGH_ONLY
1780         /* For HIGH_only driver, it's important to actually schedule other work,
1781          * not just spin wait since everything runs at schedule level
1782          */
1783         SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
1784 #endif                          /* WLC_HIGH_ONLY */
1785
1786         WL_LOCK(wl);
1787 }
1788
1789 irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id)
1790 {
1791 #if defined(WLC_LOW)
1792         wl_info_t *wl;
1793         bool ours, wantdpc;
1794         unsigned long flags;
1795
1796         wl = (wl_info_t *) dev_id;
1797
1798         WL_ISRLOCK(wl, flags);
1799
1800         /* call common first level interrupt handler */
1801         ours = wlc_isr(wl->wlc, &wantdpc);
1802         if (ours) {
1803                 /* if more to do... */
1804                 if (wantdpc) {
1805
1806                         /* ...and call the second level interrupt handler */
1807                         /* schedule dpc */
1808                         ASSERT(wl->resched == FALSE);
1809                         tasklet_schedule(&wl->tasklet);
1810                 }
1811         }
1812
1813         WL_ISRUNLOCK(wl, flags);
1814
1815         return IRQ_RETVAL(ours);
1816 #else
1817         return IRQ_RETVAL(0);
1818 #endif                          /* WLC_LOW */
1819 }
1820
1821 static void BCMFASTPATH wl_dpc(unsigned long data)
1822 {
1823 #ifdef WLC_LOW
1824         wl_info_t *wl;
1825
1826         wl = (wl_info_t *) data;
1827
1828         WL_LOCK(wl);
1829
1830         /* call the common second level interrupt handler */
1831         if (wl->pub->up) {
1832                 if (wl->resched) {
1833                         unsigned long flags;
1834
1835                         INT_LOCK(wl, flags);
1836                         wlc_intrsupd(wl->wlc);
1837                         INT_UNLOCK(wl, flags);
1838                 }
1839
1840                 wl->resched = wlc_dpc(wl->wlc, TRUE);
1841         }
1842
1843         /* wlc_dpc() may bring the driver down */
1844         if (!wl->pub->up)
1845                 goto done;
1846
1847         /* re-schedule dpc */
1848         if (wl->resched)
1849                 tasklet_schedule(&wl->tasklet);
1850         else {
1851                 /* re-enable interrupts */
1852                 wl_intrson(wl);
1853         }
1854
1855  done:
1856         WL_UNLOCK(wl);
1857 #endif                          /* WLC_LOW */
1858 }
1859
1860 static void wl_link_up(wl_info_t *wl, char *ifname)
1861 {
1862         WL_ERROR(("wl%d: link up (%s)\n", wl->pub->unit, ifname));
1863 }
1864
1865 static void wl_link_down(wl_info_t *wl, char *ifname)
1866 {
1867         WL_ERROR(("wl%d: link down (%s)\n", wl->pub->unit, ifname));
1868 }
1869
1870 void wl_event(wl_info_t *wl, char *ifname, wlc_event_t *e)
1871 {
1872
1873         switch (e->event.event_type) {
1874         case WLC_E_LINK:
1875         case WLC_E_NDIS_LINK:
1876                 if (e->event.flags & WLC_EVENT_MSG_LINK)
1877                         wl_link_up(wl, ifname);
1878                 else
1879                         wl_link_down(wl, ifname);
1880                 break;
1881         case WLC_E_RADIO:
1882                 break;
1883         }
1884 }
1885
1886 static void wl_timer(unsigned long data)
1887 {
1888 #ifndef WLC_HIGH_ONLY
1889         _wl_timer((wl_timer_t *) data);
1890 #else
1891         wl_timer_t *t = (wl_timer_t *) data;
1892         wl_schedule_task(t->wl, wl_timer_task, t);
1893 #endif                          /* WLC_HIGH_ONLY */
1894 }
1895
1896 static void _wl_timer(wl_timer_t *t)
1897 {
1898         WL_LOCK(t->wl);
1899
1900         if (t->set) {
1901                 if (t->periodic) {
1902                         t->timer.expires = jiffies + t->ms * HZ / 1000;
1903                         atomic_inc(&t->wl->callbacks);
1904                         add_timer(&t->timer);
1905                         t->set = TRUE;
1906                 } else
1907                         t->set = FALSE;
1908
1909                 t->fn(t->arg);
1910         }
1911
1912         atomic_dec(&t->wl->callbacks);
1913
1914         WL_UNLOCK(t->wl);
1915 }
1916
1917 wl_timer_t *wl_init_timer(wl_info_t *wl, void (*fn) (void *arg), void *arg,
1918                           const char *name)
1919 {
1920         wl_timer_t *t;
1921
1922         t = osl_malloc(wl->osh, sizeof(wl_timer_t));
1923         if (!t) {
1924                 WL_ERROR(("wl%d: wl_init_timer: out of memory, malloced %d bytes\n", wl->pub->unit, osl_malloced(wl->osh)));
1925                 return 0;
1926         }
1927
1928         bzero(t, sizeof(wl_timer_t));
1929
1930         init_timer(&t->timer);
1931         t->timer.data = (unsigned long) t;
1932         t->timer.function = wl_timer;
1933         t->wl = wl;
1934         t->fn = fn;
1935         t->arg = arg;
1936         t->next = wl->timers;
1937         wl->timers = t;
1938
1939 #ifdef BCMDBG
1940         t->name = osl_malloc(wl->osh, strlen(name) + 1);
1941         if (t->name)
1942                 strcpy(t->name, name);
1943 #endif
1944
1945         return t;
1946 }
1947
1948 /* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate
1949  * as well as it's easier to make it periodic
1950  */
1951 void wl_add_timer(wl_info_t *wl, wl_timer_t *t, uint ms, int periodic)
1952 {
1953 #ifdef BCMDBG
1954         if (t->set) {
1955                 WL_ERROR(("%s: Already set. Name: %s, per %d\n",
1956                           __func__, t->name, periodic));
1957         }
1958 #endif
1959         ASSERT(!t->set);
1960
1961         t->ms = ms;
1962         t->periodic = (bool) periodic;
1963         t->set = TRUE;
1964         t->timer.expires = jiffies + ms * HZ / 1000;
1965
1966         atomic_inc(&wl->callbacks);
1967         add_timer(&t->timer);
1968 }
1969
1970 /* return TRUE if timer successfully deleted, FALSE if still pending */
1971 bool wl_del_timer(wl_info_t *wl, wl_timer_t *t)
1972 {
1973         if (t->set) {
1974                 t->set = FALSE;
1975                 if (!del_timer(&t->timer)) {
1976                         return FALSE;
1977                 }
1978                 atomic_dec(&wl->callbacks);
1979         }
1980
1981         return TRUE;
1982 }
1983
1984 void wl_free_timer(wl_info_t *wl, wl_timer_t *t)
1985 {
1986         wl_timer_t *tmp;
1987
1988         /* delete the timer in case it is active */
1989         wl_del_timer(wl, t);
1990
1991         if (wl->timers == t) {
1992                 wl->timers = wl->timers->next;
1993 #ifdef BCMDBG
1994                 if (t->name)
1995                         MFREE(wl->osh, t->name, strlen(t->name) + 1);
1996 #endif
1997                 MFREE(wl->osh, t, sizeof(wl_timer_t));
1998                 return;
1999
2000         }
2001
2002         tmp = wl->timers;
2003         while (tmp) {
2004                 if (tmp->next == t) {
2005                         tmp->next = t->next;
2006 #ifdef BCMDBG
2007                         if (t->name)
2008                                 MFREE(wl->osh, t->name, strlen(t->name) + 1);
2009 #endif
2010                         MFREE(wl->osh, t, sizeof(wl_timer_t));
2011                         return;
2012                 }
2013                 tmp = tmp->next;
2014         }
2015
2016 }
2017
2018 static int wl_linux_watchdog(void *ctx)
2019 {
2020         wl_info_t *wl = (wl_info_t *) ctx;
2021         struct net_device_stats *stats = NULL;
2022         uint id;
2023         /* refresh stats */
2024         if (wl->pub->up) {
2025                 ASSERT(wl->stats_id < 2);
2026
2027                 id = 1 - wl->stats_id;
2028
2029                 stats = &wl->stats_watchdog[id];
2030                 stats->rx_packets = WLCNTVAL(wl->pub->_cnt->rxframe);
2031                 stats->tx_packets = WLCNTVAL(wl->pub->_cnt->txframe);
2032                 stats->rx_bytes = WLCNTVAL(wl->pub->_cnt->rxbyte);
2033                 stats->tx_bytes = WLCNTVAL(wl->pub->_cnt->txbyte);
2034                 stats->rx_errors = WLCNTVAL(wl->pub->_cnt->rxerror);
2035                 stats->tx_errors = WLCNTVAL(wl->pub->_cnt->txerror);
2036                 stats->collisions = 0;
2037
2038                 stats->rx_length_errors = 0;
2039                 stats->rx_over_errors = WLCNTVAL(wl->pub->_cnt->rxoflo);
2040                 stats->rx_crc_errors = WLCNTVAL(wl->pub->_cnt->rxcrc);
2041                 stats->rx_frame_errors = 0;
2042                 stats->rx_fifo_errors = WLCNTVAL(wl->pub->_cnt->rxoflo);
2043                 stats->rx_missed_errors = 0;
2044
2045                 stats->tx_fifo_errors = WLCNTVAL(wl->pub->_cnt->txuflo);
2046
2047                 wl->stats_id = id;
2048
2049         }
2050
2051         return 0;
2052 }
2053
2054 struct wl_fw_hdr {
2055         uint32 offset;
2056         uint32 len;
2057         uint32 idx;
2058 };
2059
2060 #ifdef WLC_HIGH_ONLY
2061 static void wl_rpc_down(void *wlh)
2062 {
2063         wl_info_t *wl = (wl_info_t *) (wlh);
2064
2065         wlc_device_removed(wl->wlc);
2066
2067         wl_rpcq_free(wl);
2068 }
2069
2070 static int BCMFASTPATH wl_start(struct sk_buff *skb, wl_info_t *wl)
2071 {
2072
2073         unsigned long flags;
2074
2075         skb->prev = NULL;
2076
2077         /* Lock the queue as tasklet could be running at this time */
2078         TXQ_LOCK(wl, flags);
2079         if (wl->txq_head == NULL)
2080                 wl->txq_head = skb;
2081         else {
2082                 wl->txq_tail->prev = skb;
2083         }
2084         wl->txq_tail = skb;
2085
2086         if (wl->txq_dispatched == FALSE) {
2087                 wl->txq_dispatched = TRUE;
2088
2089                 if (schedule_work(&wl->txq_task.work)) {
2090                         atomic_inc(&wl->callbacks);
2091                 } else {
2092                         WL_ERROR(("wl%d: wl_start/schedule_work failed\n",
2093                                   wl->pub->unit));
2094                 }
2095         }
2096
2097         TXQ_UNLOCK(wl, flags);
2098
2099         return 0;
2100
2101 }
2102
2103 static void wl_start_txqwork(struct wl_task *task)
2104 {
2105         wl_info_t *wl = (wl_info_t *) task->context;
2106         struct sk_buff *skb;
2107         unsigned long flags;
2108         uint count = 0;
2109
2110         WL_TRACE(("wl%d: wl_start_txqwork\n", wl->pub->unit));
2111
2112         /* First remove an entry then go for execution */
2113         TXQ_LOCK(wl, flags);
2114         while (wl->txq_head) {
2115                 skb = wl->txq_head;
2116                 wl->txq_head = skb->prev;
2117                 skb->prev = NULL;
2118                 if (wl->txq_head == NULL)
2119                         wl->txq_tail = NULL;
2120                 TXQ_UNLOCK(wl, flags);
2121
2122                 /* it has WL_LOCK/WL_UNLOCK inside */
2123                 wl_start_int(wl, WL_TO_HW(wl), skb);
2124
2125                 /* bounded our execution, reshedule ourself next */
2126                 if (++count >= 10)
2127                         break;
2128
2129                 TXQ_LOCK(wl, flags);
2130         }
2131
2132         if (count >= 10) {
2133                 if (!schedule_work(&wl->txq_task.work)) {
2134                         WL_ERROR(("wl%d: wl_start/schedule_work failed\n",
2135                                   wl->pub->unit));
2136                         atomic_dec(&wl->callbacks);
2137                 }
2138         } else {
2139                 wl->txq_dispatched = FALSE;
2140                 TXQ_UNLOCK(wl, flags);
2141                 atomic_dec(&wl->callbacks);
2142         }
2143
2144         return;
2145 }
2146
2147 static void wl_txq_free(wl_info_t *wl)
2148 {
2149         struct sk_buff *skb;
2150
2151         if (wl->txq_head == NULL) {
2152                 ASSERT(wl->txq_tail == NULL);
2153                 return;
2154         }
2155
2156         while (wl->txq_head) {
2157                 skb = wl->txq_head;
2158                 wl->txq_head = skb->prev;
2159                 PKTFREE(wl->osh, skb, TRUE);
2160         }
2161
2162         wl->txq_tail = NULL;
2163 }
2164
2165 static void wl_rpcq_free(wl_info_t *wl)
2166 {
2167         rpc_buf_t *buf;
2168
2169         if (wl->rpcq_head == NULL) {
2170                 ASSERT(wl->rpcq_tail == NULL);
2171                 return;
2172         }
2173
2174         while (wl->rpcq_head) {
2175                 buf = wl->rpcq_head;
2176                 wl->rpcq_head = bcm_rpc_buf_next_get(wl->rpc_th, buf);
2177                 bcm_rpc_buf_free(wl->rpc_dispatch_ctx.rpc, buf);
2178         }
2179
2180         wl->rpcq_tail = NULL;
2181 }
2182
2183 static void wl_rpcq_dispatch(struct wl_task *task)
2184 {
2185         wl_info_t *wl = (wl_info_t *) task->context;
2186         rpc_buf_t *buf;
2187         unsigned long flags;
2188
2189         /* First remove an entry then go for execution */
2190         RPCQ_LOCK(wl, flags);
2191         while (wl->rpcq_head) {
2192                 buf = wl->rpcq_head;
2193                 wl->rpcq_head = bcm_rpc_buf_next_get(wl->rpc_th, buf);
2194
2195                 if (wl->rpcq_head == NULL)
2196                         wl->rpcq_tail = NULL;
2197                 RPCQ_UNLOCK(wl, flags);
2198
2199                 WL_LOCK(wl);
2200                 wlc_rpc_high_dispatch(&wl->rpc_dispatch_ctx, buf);
2201                 WL_UNLOCK(wl);
2202
2203                 RPCQ_LOCK(wl, flags);
2204         }
2205
2206         wl->rpcq_dispatched = FALSE;
2207
2208         RPCQ_UNLOCK(wl, flags);
2209
2210         MFREE(wl->osh, task, sizeof(wl_task_t));
2211         atomic_dec(&wl->callbacks);
2212 }
2213
2214 static void wl_rpcq_add(wl_info_t *wl, rpc_buf_t *buf)
2215 {
2216         unsigned long flags;
2217
2218         bcm_rpc_buf_next_set(wl->rpc_th, buf, NULL);
2219
2220         /* Lock the queue as tasklet could be running at this time */
2221         RPCQ_LOCK(wl, flags);
2222         if (wl->rpcq_head == NULL)
2223                 wl->rpcq_head = buf;
2224         else
2225                 bcm_rpc_buf_next_set(wl->rpc_th, wl->rpcq_tail, buf);
2226
2227         wl->rpcq_tail = buf;
2228
2229         if (wl->rpcq_dispatched == FALSE) {
2230                 wl->rpcq_dispatched = TRUE;
2231                 wl_schedule_task(wl, wl_rpcq_dispatch, wl);
2232         }
2233
2234         RPCQ_UNLOCK(wl, flags);
2235 }
2236
2237 #if defined(BCMDBG)
2238 static const struct name_entry rpc_name_tbl[] = RPC_ID_TABLE;
2239 #endif                          /* BCMDBG */
2240
2241 /* dongle-side rpc dispatch routine */
2242 static void wl_rpc_dispatch_schedule(void *ctx, struct rpc_buf *buf)
2243 {
2244         bcm_xdr_buf_t b;
2245         wl_info_t *wl = (wl_info_t *) ctx;
2246         wlc_rpc_id_t rpc_id;
2247         int err;
2248
2249         bcm_xdr_buf_init(&b, bcm_rpc_buf_data(wl->rpc_th, buf),
2250                          bcm_rpc_buf_len_get(wl->rpc_th, buf));
2251
2252         err = bcm_xdr_unpack_uint32(&b, &rpc_id);
2253         ASSERT(!err);
2254         WL_TRACE(("%s: Dispatch id %s\n", __func__,
2255                   WLC_RPC_ID_LOOKUP(rpc_name_tbl, rpc_id)));
2256
2257         /* Handle few emergency ones */
2258         switch (rpc_id) {
2259         default:
2260                 wl_rpcq_add(wl, buf);
2261                 break;
2262         }
2263 }
2264
2265 static void wl_timer_task(wl_task_t *task)
2266 {
2267         wl_timer_t *t = (wl_timer_t *) task->context;
2268
2269         _wl_timer(t);
2270         MFREE(t->wl->osh, task, sizeof(wl_task_t));
2271
2272         /* This dec is for the task_schedule. The timer related
2273          * callback is decremented in _wl_timer
2274          */
2275         atomic_dec(&t->wl->callbacks);
2276 }
2277 #endif                          /* WLC_HIGH_ONLY */
2278
2279 #ifndef WLC_HIGH_ONLY
2280 char *wl_firmwares[WL_MAX_FW] = {
2281         "brcm/bcm43xx",
2282         NULL
2283 };
2284
2285 #ifdef WLC_LOW
2286 int wl_ucode_init_buf(wl_info_t *wl, void **pbuf, uint32 idx)
2287 {
2288         int i, entry;
2289         const u8 *pdata;
2290         struct wl_fw_hdr *hdr;
2291         for (i = 0; i < wl->fw.fw_cnt; i++) {
2292                 hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data;
2293                 for (entry = 0; entry < wl->fw.hdr_num_entries[i];
2294                      entry++, hdr++) {
2295                         if (hdr->idx == idx) {
2296                                 pdata = wl->fw.fw_bin[i]->data + hdr->offset;
2297                                 *pbuf = kmalloc(hdr->len, GFP_ATOMIC);
2298                                 if (*pbuf == NULL) {
2299                                         printf("fail to alloc %d bytes\n",
2300                                                hdr->len);
2301                                 }
2302                                 bcopy(pdata, *pbuf, hdr->len);
2303                                 return 0;
2304                         }
2305                 }
2306         }
2307         printf("ERROR: ucode buf tag:%d can not be found!\n", idx);
2308         *pbuf = NULL;
2309         return -1;
2310 }
2311
2312 int wl_ucode_init_uint(wl_info_t *wl, uint32 *data, uint32 idx)
2313 {
2314         int i, entry;
2315         const u8 *pdata;
2316         struct wl_fw_hdr *hdr;
2317         for (i = 0; i < wl->fw.fw_cnt; i++) {
2318                 hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data;
2319                 for (entry = 0; entry < wl->fw.hdr_num_entries[i];
2320                      entry++, hdr++) {
2321                         if (hdr->idx == idx) {
2322                                 pdata = wl->fw.fw_bin[i]->data + hdr->offset;
2323                                 ASSERT(hdr->len == 4);
2324                                 *data = *((uint32 *) pdata);
2325                                 return 0;
2326                         }
2327                 }
2328         }
2329         printf("ERROR: ucode tag:%d can not be found!\n", idx);
2330         return -1;
2331 }
2332 #endif                          /* WLC_LOW */
2333
2334 static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev)
2335 {
2336         int status;
2337         struct device *device = &pdev->dev;
2338         char fw_name[100];
2339         int i;
2340
2341         bzero((void *)&wl->fw, sizeof(struct wl_firmware));
2342         for (i = 0; i < WL_MAX_FW; i++) {
2343                 if (wl_firmwares[i] == NULL)
2344                         break;
2345                 sprintf(fw_name, "%s-%d.fw", wl_firmwares[i],
2346                         UCODE_LOADER_API_VER);
2347                 WL_NONE(("request fw %s\n", fw_name));
2348                 status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
2349                 if (status) {
2350                         printf("%s: fail to load firmware %s\n",
2351                                 KBUILD_MODNAME, fw_name);
2352                         wl_release_fw(wl);
2353                         return status;
2354                 }
2355                 WL_NONE(("request fw %s\n", fw_name));
2356                 sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i],
2357                         UCODE_LOADER_API_VER);
2358                 status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
2359                 if (status) {
2360                         printf("%s: fail to load firmware %s\n",
2361                                 KBUILD_MODNAME, fw_name);
2362                         wl_release_fw(wl);
2363                         return status;
2364                 }
2365                 wl->fw.hdr_num_entries[i] =
2366                     wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr));
2367                 WL_NONE(("request fw %s find: %d entries\n", fw_name,
2368                          wl->fw.hdr_num_entries[i]));
2369         }
2370         wl->fw.fw_cnt = i;
2371         wl_ucode_data_init(wl);
2372         return 0;
2373 }
2374
2375 #ifdef WLC_LOW
2376 void wl_ucode_free_buf(void *p)
2377 {
2378         kfree(p);
2379 }
2380 #endif                          /* WLC_LOW */
2381
2382 static void wl_release_fw(wl_info_t *wl)
2383 {
2384         int i;
2385         for (i = 0; i < WL_MAX_FW; i++) {
2386                 release_firmware(wl->fw.fw_bin[i]);
2387                 release_firmware(wl->fw.fw_hdr[i]);
2388         }
2389 }
2390 #endif                          /* WLC_HIGH_ONLY */