staging: brcm80211: remove unused type definitions from driver
[firefly-linux-kernel-4.4.55.git] / drivers / staging / brcm80211 / brcmsmac / 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 <linux/kernel.h>
20 #include <linux/etherdevice.h>
21 #include <linux/string.h>
22 #include <linux/pci_ids.h>
23 #include <bcmdefs.h>
24 #include <linux/module.h>
25 #include <linux/pci.h>
26 #include <linux/sched.h>
27 #include <osl.h>
28 #define WLC_MAXBSSCFG           1       /* single BSS configs */
29
30 #include <wlc_cfg.h>
31 #include <net/mac80211.h>
32 #include <phy_version.h>
33 #include <bcmutils.h>
34 #include <pcicfg.h>
35 #include <wlioctl.h>
36 #include <wlc_key.h>
37 #include <sbhndpio.h>
38 #include <sbhnddma.h>
39 #include <wlc_channel.h>
40 #include <wlc_pub.h>
41 #include <wlc_scb.h>
42 #include <wl_dbg.h>
43 #include <wl_export.h>
44
45 #include <wl_mac80211.h>
46 #include <linux/firmware.h>
47 #include <wl_ucode.h>
48 #include <d11ucode_ext.h>
49
50
51 static void wl_timer(unsigned long data);
52 static void _wl_timer(wl_timer_t *t);
53
54
55 static int ieee_hw_init(struct ieee80211_hw *hw);
56 static int ieee_hw_rate_init(struct ieee80211_hw *hw);
57
58 static int wl_linux_watchdog(void *ctx);
59
60 /* Flags we support */
61 #define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
62         FIF_ALLMULTI | \
63         FIF_FCSFAIL | \
64         FIF_PLCPFAIL | \
65         FIF_CONTROL | \
66         FIF_OTHER_BSS | \
67         FIF_BCN_PRBRESP_PROMISC)
68
69 static int wl_found;
70
71 #define WL_DEV_IF(dev)          ((struct wl_if *)netdev_priv(dev))
72 #define WL_INFO(dev)            ((struct wl_info *)(WL_DEV_IF(dev)->wl))
73 static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev);
74 static void wl_release_fw(struct wl_info *wl);
75
76 /* local prototypes */
77 static int wl_start(struct sk_buff *skb, struct wl_info *wl);
78 static int wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw,
79                         struct sk_buff *skb);
80 static void wl_dpc(unsigned long data);
81
82 MODULE_AUTHOR("Broadcom Corporation");
83 MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
84 MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
85 MODULE_LICENSE("Dual BSD/GPL");
86
87 /* recognized PCI IDs */
88 static struct pci_device_id wl_id_table[] = {
89         {PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},      /* 43225 2G */
90         {PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},      /* 43224 DUAL */
91         {PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},      /* 4313 DUAL */
92         {0}
93 };
94
95 MODULE_DEVICE_TABLE(pci, wl_id_table);
96 static void wl_remove(struct pci_dev *pdev);
97
98
99 #ifdef BCMDBG
100 static int msglevel = 0xdeadbeef;
101 module_param(msglevel, int, 0);
102 static int phymsglevel = 0xdeadbeef;
103 module_param(phymsglevel, int, 0);
104 #endif                          /* BCMDBG */
105
106 #define HW_TO_WL(hw)     (hw->priv)
107 #define WL_TO_HW(wl)      (wl->pub->ieee_hw)
108 static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
109 static int wl_ops_start(struct ieee80211_hw *hw);
110 static void wl_ops_stop(struct ieee80211_hw *hw);
111 static int wl_ops_add_interface(struct ieee80211_hw *hw,
112                                 struct ieee80211_vif *vif);
113 static void wl_ops_remove_interface(struct ieee80211_hw *hw,
114                                     struct ieee80211_vif *vif);
115 static int wl_ops_config(struct ieee80211_hw *hw, u32 changed);
116 static void wl_ops_bss_info_changed(struct ieee80211_hw *hw,
117                                     struct ieee80211_vif *vif,
118                                     struct ieee80211_bss_conf *info,
119                                     u32 changed);
120 static void wl_ops_configure_filter(struct ieee80211_hw *hw,
121                                     unsigned int changed_flags,
122                                     unsigned int *total_flags, u64 multicast);
123 static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
124                           bool set);
125 static void wl_ops_sw_scan_start(struct ieee80211_hw *hw);
126 static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw);
127 static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf);
128 static int wl_ops_get_stats(struct ieee80211_hw *hw,
129                             struct ieee80211_low_level_stats *stats);
130 static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
131 static void wl_ops_sta_notify(struct ieee80211_hw *hw,
132                               struct ieee80211_vif *vif,
133                               enum sta_notify_cmd cmd,
134                               struct ieee80211_sta *sta);
135 static int wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
136                           const struct ieee80211_tx_queue_params *params);
137 static u64 wl_ops_get_tsf(struct ieee80211_hw *hw);
138 static int wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
139                       struct ieee80211_sta *sta);
140 static int wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
141                          struct ieee80211_sta *sta);
142 static int wl_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
143                            enum ieee80211_ampdu_mlme_action action,
144                            struct ieee80211_sta *sta, u16 tid, u16 *ssn);
145
146 static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
147 {
148         int status;
149         struct wl_info *wl = hw->priv;
150         WL_LOCK(wl);
151         if (!wl->pub->up) {
152                 WL_ERROR("ops->tx called while down\n");
153                 status = -ENETDOWN;
154                 goto done;
155         }
156         status = wl_start(skb, wl);
157  done:
158         WL_UNLOCK(wl);
159         return status;
160 }
161
162 static int wl_ops_start(struct ieee80211_hw *hw)
163 {
164         struct wl_info *wl = hw->priv;
165         /*
166           struct ieee80211_channel *curchan = hw->conf.channel;
167           WL_NONE("%s : Initial channel: %d\n", __func__, curchan->hw_value);
168         */
169
170         WL_LOCK(wl);
171         ieee80211_wake_queues(hw);
172         WL_UNLOCK(wl);
173
174         return 0;
175 }
176
177 static void wl_ops_stop(struct ieee80211_hw *hw)
178 {
179         struct wl_info *wl = hw->priv;
180         ASSERT(wl);
181         WL_LOCK(wl);
182         wl_down(wl);
183         ieee80211_stop_queues(hw);
184         WL_UNLOCK(wl);
185
186         return;
187 }
188
189 static int
190 wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
191 {
192         struct wl_info *wl;
193         int err;
194
195         /* Just STA for now */
196         if (vif->type != NL80211_IFTYPE_AP &&
197             vif->type != NL80211_IFTYPE_MESH_POINT &&
198             vif->type != NL80211_IFTYPE_STATION &&
199             vif->type != NL80211_IFTYPE_WDS &&
200             vif->type != NL80211_IFTYPE_ADHOC) {
201                 WL_ERROR("%s: Attempt to add type %d, only STA for now\n",
202                          __func__, vif->type);
203                 return -EOPNOTSUPP;
204         }
205
206         wl = HW_TO_WL(hw);
207         WL_LOCK(wl);
208         err = wl_up(wl);
209         WL_UNLOCK(wl);
210
211         if (err != 0)
212                 WL_ERROR("%s: wl_up() returned %d\n", __func__, err);
213         return err;
214 }
215
216 static void
217 wl_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
218 {
219         return;
220 }
221
222 static int
223 ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan,
224                  enum nl80211_channel_type type)
225 {
226         struct wl_info *wl = HW_TO_WL(hw);
227         int err = 0;
228
229         switch (type) {
230         case NL80211_CHAN_HT20:
231         case NL80211_CHAN_NO_HT:
232                 WL_LOCK(wl);
233                 err = wlc_set(wl->wlc, WLC_SET_CHANNEL, chan->hw_value);
234                 WL_UNLOCK(wl);
235                 break;
236         case NL80211_CHAN_HT40MINUS:
237         case NL80211_CHAN_HT40PLUS:
238                 WL_ERROR("%s: Need to implement 40 Mhz Channels!\n", __func__);
239                 break;
240         }
241
242         if (err)
243                 return -EIO;
244         return err;
245 }
246
247 static int wl_ops_config(struct ieee80211_hw *hw, u32 changed)
248 {
249         struct ieee80211_conf *conf = &hw->conf;
250         struct wl_info *wl = HW_TO_WL(hw);
251         int err = 0;
252         int new_int;
253
254         if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
255                 WL_NONE("%s: Setting listen interval to %d\n",
256                         __func__, conf->listen_interval);
257                 if (wlc_iovar_setint
258                     (wl->wlc, "bcn_li_bcn", conf->listen_interval)) {
259                         WL_ERROR("%s: Error setting listen_interval\n",
260                                  __func__);
261                         err = -EIO;
262                         goto config_out;
263                 }
264                 wlc_iovar_getint(wl->wlc, "bcn_li_bcn", &new_int);
265                 ASSERT(new_int == conf->listen_interval);
266         }
267         if (changed & IEEE80211_CONF_CHANGE_MONITOR)
268                 WL_NONE("Need to set monitor mode\n");
269         if (changed & IEEE80211_CONF_CHANGE_PS)
270                 WL_NONE("Need to set Power-save mode\n");
271
272         if (changed & IEEE80211_CONF_CHANGE_POWER) {
273                 WL_NONE("%s: Setting tx power to %d dbm\n",
274                         __func__, conf->power_level);
275                 if (wlc_iovar_setint
276                     (wl->wlc, "qtxpower", conf->power_level * 4)) {
277                         WL_ERROR("%s: Error setting power_level\n", __func__);
278                         err = -EIO;
279                         goto config_out;
280                 }
281                 wlc_iovar_getint(wl->wlc, "qtxpower", &new_int);
282                 if (new_int != (conf->power_level * 4))
283                         WL_ERROR("%s: Power level req != actual, %d %d\n",
284                                  __func__, conf->power_level * 4, new_int);
285         }
286         if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
287                 err = ieee_set_channel(hw, conf->channel, conf->channel_type);
288         }
289         if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
290                 WL_NONE("%s: srl %d, lrl %d\n",
291                         __func__,
292                         conf->short_frame_max_tx_count,
293                         conf->long_frame_max_tx_count);
294                 if (wlc_set
295                     (wl->wlc, WLC_SET_SRL,
296                      conf->short_frame_max_tx_count) < 0) {
297                         WL_ERROR("%s: Error setting srl\n", __func__);
298                         err = -EIO;
299                         goto config_out;
300                 }
301                 if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count)
302                     < 0) {
303                         WL_ERROR("%s: Error setting lrl\n", __func__);
304                         err = -EIO;
305                         goto config_out;
306                 }
307         }
308
309  config_out:
310         return err;
311 }
312
313 static void
314 wl_ops_bss_info_changed(struct ieee80211_hw *hw,
315                         struct ieee80211_vif *vif,
316                         struct ieee80211_bss_conf *info, u32 changed)
317 {
318         struct wl_info *wl = HW_TO_WL(hw);
319         int val;
320
321
322         if (changed & BSS_CHANGED_ASSOC) {
323                 WL_ERROR("Associated:\t%s\n", info->assoc ? "True" : "False");
324                 /* association status changed (associated/disassociated)
325                  * also implies a change in the AID.
326                  */
327         }
328         if (changed & BSS_CHANGED_ERP_CTS_PROT) {
329                 WL_NONE("Use_cts_prot:\t%s Implement me\n",
330                         info->use_cts_prot ? "True" : "False");
331                 /* CTS protection changed */
332         }
333         if (changed & BSS_CHANGED_ERP_PREAMBLE) {
334                 WL_NONE("Short preamble:\t%s Implement me\n",
335                         info->use_short_preamble ? "True" : "False");
336                 /* preamble changed */
337         }
338         if (changed & BSS_CHANGED_ERP_SLOT) {
339                 WL_NONE("Changing short slot:\t%s\n",
340                         info->use_short_slot ? "True" : "False");
341                 if (info->use_short_slot)
342                         val = 1;
343                 else
344                         val = 0;
345                 wlc_set(wl->wlc, WLC_SET_SHORTSLOT_OVERRIDE, val);
346                 /* slot timing changed */
347         }
348
349         if (changed & BSS_CHANGED_HT) {
350                 WL_NONE("%s: HT mode - Implement me\n", __func__);
351                 /* 802.11n parameters changed */
352         }
353         if (changed & BSS_CHANGED_BASIC_RATES) {
354                 WL_NONE("Need to change Basic Rates:\t0x%x! Implement me\n",
355                         (u32) info->basic_rates);
356                 /* Basic rateset changed */
357         }
358         if (changed & BSS_CHANGED_BEACON_INT) {
359                 WL_NONE("Beacon Interval:\t%d Implement me\n",
360                         info->beacon_int);
361                 /* Beacon interval changed */
362         }
363         if (changed & BSS_CHANGED_BSSID) {
364                 WL_NONE("new BSSID:\taid %d  bss:%pM\n",
365                         info->aid, info->bssid);
366                 /* BSSID changed, for whatever reason (IBSS and managed mode) */
367                 /* FIXME: need to store bssid in bsscfg */
368                 wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET,
369                                   info->bssid);
370         }
371         if (changed & BSS_CHANGED_BEACON) {
372                 WL_ERROR("BSS_CHANGED_BEACON\n");
373                 /* Beacon data changed, retrieve new beacon (beaconing modes) */
374         }
375         if (changed & BSS_CHANGED_BEACON_ENABLED) {
376                 WL_ERROR("Beacon enabled:\t%s\n",
377                          info->enable_beacon ? "True" : "False");
378                 /* Beaconing should be enabled/disabled (beaconing modes) */
379         }
380         return;
381 }
382
383 static void
384 wl_ops_configure_filter(struct ieee80211_hw *hw,
385                         unsigned int changed_flags,
386                         unsigned int *total_flags, u64 multicast)
387 {
388         struct wl_info *wl = hw->priv;
389
390         changed_flags &= MAC_FILTERS;
391         *total_flags &= MAC_FILTERS;
392         if (changed_flags & FIF_PROMISC_IN_BSS)
393                 WL_ERROR("FIF_PROMISC_IN_BSS\n");
394         if (changed_flags & FIF_ALLMULTI)
395                 WL_ERROR("FIF_ALLMULTI\n");
396         if (changed_flags & FIF_FCSFAIL)
397                 WL_ERROR("FIF_FCSFAIL\n");
398         if (changed_flags & FIF_PLCPFAIL)
399                 WL_ERROR("FIF_PLCPFAIL\n");
400         if (changed_flags & FIF_CONTROL)
401                 WL_ERROR("FIF_CONTROL\n");
402         if (changed_flags & FIF_OTHER_BSS)
403                 WL_ERROR("FIF_OTHER_BSS\n");
404         if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
405                 WL_NONE("FIF_BCN_PRBRESP_PROMISC\n");
406                 WL_LOCK(wl);
407                 if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
408                         wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS;
409                         wlc_mac_bcn_promisc_change(wl->wlc, 1);
410                 } else {
411                         wlc_mac_bcn_promisc_change(wl->wlc, 0);
412                         wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS;
413                 }
414                 WL_UNLOCK(wl);
415         }
416         return;
417 }
418
419 static int
420 wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
421 {
422         WL_ERROR("%s: Enter\n", __func__);
423         return 0;
424 }
425
426 static void wl_ops_sw_scan_start(struct ieee80211_hw *hw)
427 {
428         WL_NONE("Scan Start\n");
429         return;
430 }
431
432 static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw)
433 {
434         WL_NONE("Scan Complete\n");
435         return;
436 }
437
438 static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf)
439 {
440         WL_ERROR("%s: Enter\n", __func__);
441         return;
442 }
443
444 static int
445 wl_ops_get_stats(struct ieee80211_hw *hw,
446                  struct ieee80211_low_level_stats *stats)
447 {
448         WL_ERROR("%s: Enter\n", __func__);
449         return 0;
450 }
451
452 static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
453 {
454         WL_ERROR("%s: Enter\n", __func__);
455         return 0;
456 }
457
458 static void
459 wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
460                   enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
461 {
462         WL_NONE("%s: Enter\n", __func__);
463         switch (cmd) {
464         default:
465                 WL_ERROR("%s: Unknown cmd = %d\n", __func__, cmd);
466                 break;
467         }
468         return;
469 }
470
471 static int
472 wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
473                const struct ieee80211_tx_queue_params *params)
474 {
475         struct wl_info *wl = hw->priv;
476
477         WL_NONE("%s: Enter (WME config)\n", __func__);
478         WL_NONE("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue,
479                  params->txop, params->cw_min, params->cw_max, params->aifs);
480
481         WL_LOCK(wl);
482         wlc_wme_setparams(wl->wlc, queue, (void *)params, true);
483         WL_UNLOCK(wl);
484
485         return 0;
486 }
487
488 static u64 wl_ops_get_tsf(struct ieee80211_hw *hw)
489 {
490         WL_ERROR("%s: Enter\n", __func__);
491         return 0;
492 }
493
494 static int
495 wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
496            struct ieee80211_sta *sta)
497 {
498         struct scb *scb;
499
500         int i;
501         struct wl_info *wl = hw->priv;
502
503         /* Init the scb */
504         scb = (struct scb *)sta->drv_priv;
505         memset(scb, 0, sizeof(struct scb));
506         for (i = 0; i < NUMPRIO; i++)
507                 scb->seqctl[i] = 0xFFFF;
508         scb->seqctl_nonqos = 0xFFFF;
509         scb->magic = SCB_MAGIC;
510
511         wl->pub->global_scb = scb;
512         wl->pub->global_ampdu = &(scb->scb_ampdu);
513         wl->pub->global_ampdu->scb = scb;
514         wl->pub->global_ampdu->max_pdu = 16;
515         pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID,
516                   AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT);
517
518         sta->ht_cap.ht_supported = true;
519         sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_64K;
520         sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY;
521         sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD |
522             IEEE80211_HT_CAP_SGI_20 |
523             IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT;
524
525         /* minstrel_ht initiates addBA on our behalf by calling ieee80211_start_tx_ba_session() */
526         return 0;
527 }
528
529 static int
530 wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
531               struct ieee80211_sta *sta)
532 {
533         WL_NONE("%s: Enter\n", __func__);
534         return 0;
535 }
536
537 static int
538 wl_ampdu_action(struct ieee80211_hw *hw,
539                 struct ieee80211_vif *vif,
540                 enum ieee80211_ampdu_mlme_action action,
541                 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
542 {
543 #if defined(BCMDBG)
544         struct scb *scb = (struct scb *)sta->drv_priv;
545 #endif
546         struct wl_info *wl = hw->priv;
547
548         ASSERT(scb->magic == SCB_MAGIC);
549         switch (action) {
550         case IEEE80211_AMPDU_RX_START:
551                 WL_NONE("%s: action = IEEE80211_AMPDU_RX_START\n", __func__);
552                 break;
553         case IEEE80211_AMPDU_RX_STOP:
554                 WL_NONE("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__);
555                 break;
556         case IEEE80211_AMPDU_TX_START:
557                 if (!wlc_aggregatable(wl->wlc, tid)) {
558                         /* WL_ERROR("START: tid %d is not agg' able, return FAILURE to stack\n", tid); */
559                         return -1;
560                 }
561                 /* XXX: Use the starting sequence number provided ... */
562                 *ssn = 0;
563                 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
564                 break;
565
566         case IEEE80211_AMPDU_TX_STOP:
567                 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
568                 break;
569         case IEEE80211_AMPDU_TX_OPERATIONAL:
570                 /* Not sure what to do here */
571                 /* Power save wakeup */
572                 WL_NONE("%s: action = IEEE80211_AMPDU_TX_OPERATIONAL\n",
573                         __func__);
574                 break;
575         default:
576                 WL_ERROR("%s: Invalid command, ignoring\n", __func__);
577         }
578
579         return 0;
580 }
581
582 static const struct ieee80211_ops wl_ops = {
583         .tx = wl_ops_tx,
584         .start = wl_ops_start,
585         .stop = wl_ops_stop,
586         .add_interface = wl_ops_add_interface,
587         .remove_interface = wl_ops_remove_interface,
588         .config = wl_ops_config,
589         .bss_info_changed = wl_ops_bss_info_changed,
590         .configure_filter = wl_ops_configure_filter,
591         .set_tim = wl_ops_set_tim,
592         .sw_scan_start = wl_ops_sw_scan_start,
593         .sw_scan_complete = wl_ops_sw_scan_complete,
594         .set_tsf = wl_ops_set_tsf,
595         .get_stats = wl_ops_get_stats,
596         .set_rts_threshold = wl_ops_set_rts_threshold,
597         .sta_notify = wl_ops_sta_notify,
598         .conf_tx = wl_ops_conf_tx,
599         .get_tsf = wl_ops_get_tsf,
600         .sta_add = wl_sta_add,
601         .sta_remove = wl_sta_remove,
602         .ampdu_action = wl_ampdu_action,
603 };
604
605 static int wl_set_hint(struct wl_info *wl, char *abbrev)
606 {
607         WL_ERROR("%s: Sending country code %c%c to MAC80211\n",
608                  __func__, abbrev[0], abbrev[1]);
609         return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev);
610 }
611
612 /**
613  * attach to the WL device.
614  *
615  * Attach to the WL device identified by vendor and device parameters.
616  * regs is a host accessible memory address pointing to WL device registers.
617  *
618  * wl_attach is not defined as static because in the case where no bus
619  * is defined, wl_attach will never be called, and thus, gcc will issue
620  * a warning that this function is defined but not used if we declare
621  * it as static.
622  */
623 static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs,
624                             uint bustype, void *btparam, uint irq)
625 {
626         struct wl_info *wl;
627         struct osl_info *osh;
628         int unit, err;
629
630         unsigned long base_addr;
631         struct ieee80211_hw *hw;
632         u8 perm[ETH_ALEN];
633
634         unit = wl_found;
635         err = 0;
636
637         if (unit < 0) {
638                 WL_ERROR("wl%d: unit number overflow, exiting\n", unit);
639                 return NULL;
640         }
641
642         osh = osl_attach(btparam, bustype);
643         ASSERT(osh);
644
645         /* allocate private info */
646         hw = pci_get_drvdata(btparam);  /* btparam == pdev */
647         wl = hw->priv;
648         ASSERT(wl);
649
650         wl->osh = osh;
651         atomic_set(&wl->callbacks, 0);
652
653         /* setup the bottom half handler */
654         tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl);
655
656
657
658         base_addr = regs;
659
660         if (bustype == PCI_BUS) {
661                 wl->piomode = false;
662         } else if (bustype == RPC_BUS) {
663                 /* Do nothing */
664         } else {
665                 bustype = PCI_BUS;
666                 WL_TRACE("force to PCI\n");
667         }
668         wl->bcm_bustype = bustype;
669
670         wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ);
671         if (wl->regsva == NULL) {
672                 WL_ERROR("wl%d: ioremap() failed\n", unit);
673                 goto fail;
674         }
675         spin_lock_init(&wl->lock);
676         spin_lock_init(&wl->isr_lock);
677
678         /* prepare ucode */
679         if (wl_request_fw(wl, (struct pci_dev *)btparam)) {
680                 printf("%s: Failed to find firmware usually in %s\n",
681                         KBUILD_MODNAME, "/lib/firmware/brcm");
682                 wl_release_fw(wl);
683                 wl_remove((struct pci_dev *)btparam);
684                 goto fail1;
685         }
686
687         /* common load-time initialization */
688         wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, osh,
689                              wl->regsva, wl->bcm_bustype, btparam, &err);
690         wl_release_fw(wl);
691         if (!wl->wlc) {
692                 printf("%s: wlc_attach() failed with code %d\n",
693                         KBUILD_MODNAME, err);
694                 goto fail;
695         }
696         wl->pub = wlc_pub(wl->wlc);
697
698         wl->pub->ieee_hw = hw;
699         ASSERT(wl->pub->ieee_hw);
700         ASSERT(wl->pub->ieee_hw->priv == wl);
701
702
703         if (wlc_iovar_setint(wl->wlc, "mpc", 0)) {
704                 WL_ERROR("wl%d: Error setting MPC variable to 0\n", unit);
705         }
706
707         /* register our interrupt handler */
708         if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
709                 WL_ERROR("wl%d: request_irq() failed\n", unit);
710                 goto fail;
711         }
712         wl->irq = irq;
713
714         /* register module */
715         wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog,
716                             NULL);
717
718         if (ieee_hw_init(hw)) {
719                 WL_ERROR("wl%d: %s: ieee_hw_init failed!\n", unit, __func__);
720                 goto fail;
721         }
722
723         bcopy(&wl->pub->cur_etheraddr, perm, ETH_ALEN);
724         ASSERT(is_valid_ether_addr(perm));
725         SET_IEEE80211_PERM_ADDR(hw, perm);
726
727         err = ieee80211_register_hw(hw);
728         if (err) {
729                 WL_ERROR("%s: ieee80211_register_hw failed, status %d\n",
730                          __func__, err);
731         }
732
733         if (wl->pub->srom_ccode[0])
734                 err = wl_set_hint(wl, wl->pub->srom_ccode);
735         else
736                 err = wl_set_hint(wl, "US");
737         if (err) {
738                 WL_ERROR("%s: regulatory_hint failed, status %d\n",
739                          __func__, err);
740         }
741         WL_ERROR("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver (" PHY_VERSION_STR ")",
742                  unit);
743
744 #ifdef BCMDBG
745         printf(" (Compiled at " __TIME__ " on " __DATE__ ")");
746 #endif                          /* BCMDBG */
747         printf("\n");
748
749         wl_found++;
750         return wl;
751
752  fail:
753         wl_free(wl);
754 fail1:
755         return NULL;
756 }
757
758
759
760 #define CHAN2GHZ(channel, freqency, chflags)  { \
761         .band = IEEE80211_BAND_2GHZ, \
762         .center_freq = (freqency), \
763         .hw_value = (channel), \
764         .flags = chflags, \
765         .max_antenna_gain = 0, \
766         .max_power = 19, \
767 }
768
769 static struct ieee80211_channel wl_2ghz_chantable[] = {
770         CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
771         CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS),
772         CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS),
773         CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS),
774         CHAN2GHZ(5, 2432, 0),
775         CHAN2GHZ(6, 2437, 0),
776         CHAN2GHZ(7, 2442, 0),
777         CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS),
778         CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS),
779         CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
780         CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
781         CHAN2GHZ(12, 2467,
782                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
783                  IEEE80211_CHAN_NO_HT40PLUS),
784         CHAN2GHZ(13, 2472,
785                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
786                  IEEE80211_CHAN_NO_HT40PLUS),
787         CHAN2GHZ(14, 2484,
788                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
789                  IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
790 };
791
792 #define CHAN5GHZ(channel, chflags)  { \
793         .band = IEEE80211_BAND_5GHZ, \
794         .center_freq = 5000 + 5*(channel), \
795         .hw_value = (channel), \
796         .flags = chflags, \
797         .max_antenna_gain = 0, \
798         .max_power = 21, \
799 }
800
801 static struct ieee80211_channel wl_5ghz_nphy_chantable[] = {
802         /* UNII-1 */
803         CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS),
804         CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS),
805         CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS),
806         CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
807         /* UNII-2 */
808         CHAN5GHZ(52,
809                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
810                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
811         CHAN5GHZ(56,
812                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
813                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
814         CHAN5GHZ(60,
815                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
816                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
817         CHAN5GHZ(64,
818                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
819                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
820         /* MID */
821         CHAN5GHZ(100,
822                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
823                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
824         CHAN5GHZ(104,
825                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
826                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
827         CHAN5GHZ(108,
828                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
829                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
830         CHAN5GHZ(112,
831                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
832                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
833         CHAN5GHZ(116,
834                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
835                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
836         CHAN5GHZ(120,
837                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
838                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
839         CHAN5GHZ(124,
840                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
841                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
842         CHAN5GHZ(128,
843                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
844                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
845         CHAN5GHZ(132,
846                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
847                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
848         CHAN5GHZ(136,
849                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
850                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
851         CHAN5GHZ(140,
852                  IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
853                  IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS |
854                  IEEE80211_CHAN_NO_HT40MINUS),
855         /* UNII-3 */
856         CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
857         CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS),
858         CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS),
859         CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS),
860         CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
861 };
862
863 #define RATE(rate100m, _flags) { \
864         .bitrate = (rate100m), \
865         .flags = (_flags), \
866         .hw_value = (rate100m / 5), \
867 }
868
869 static struct ieee80211_rate wl_legacy_ratetable[] = {
870         RATE(10, 0),
871         RATE(20, IEEE80211_RATE_SHORT_PREAMBLE),
872         RATE(55, IEEE80211_RATE_SHORT_PREAMBLE),
873         RATE(110, IEEE80211_RATE_SHORT_PREAMBLE),
874         RATE(60, 0),
875         RATE(90, 0),
876         RATE(120, 0),
877         RATE(180, 0),
878         RATE(240, 0),
879         RATE(360, 0),
880         RATE(480, 0),
881         RATE(540, 0),
882 };
883
884 static struct ieee80211_supported_band wl_band_2GHz_nphy = {
885         .band = IEEE80211_BAND_2GHZ,
886         .channels = wl_2ghz_chantable,
887         .n_channels = ARRAY_SIZE(wl_2ghz_chantable),
888         .bitrates = wl_legacy_ratetable,
889         .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable),
890         .ht_cap = {
891                    /* from include/linux/ieee80211.h */
892                    .cap = IEEE80211_HT_CAP_GRN_FLD |
893                    IEEE80211_HT_CAP_SGI_20 |
894                    IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT,
895                    .ht_supported = true,
896                    .ampdu_factor = AMPDU_RX_FACTOR_64K,
897                    .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
898                    .mcs = {
899                            /* placeholders for now */
900                            .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
901                            .rx_highest = 500,
902                            .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
903                    }
904 };
905
906 static struct ieee80211_supported_band wl_band_5GHz_nphy = {
907         .band = IEEE80211_BAND_5GHZ,
908         .channels = wl_5ghz_nphy_chantable,
909         .n_channels = ARRAY_SIZE(wl_5ghz_nphy_chantable),
910         .bitrates = wl_legacy_ratetable + 4,
911         .n_bitrates = ARRAY_SIZE(wl_legacy_ratetable) - 4,
912         .ht_cap = {
913                    /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */
914                    .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 */
915                    .ht_supported = true,
916                    .ampdu_factor = AMPDU_RX_FACTOR_64K,
917                    .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
918                    .mcs = {
919                            /* placeholders for now */
920                            .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
921                            .rx_highest = 500,
922                            .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
923                    }
924 };
925
926 static int ieee_hw_rate_init(struct ieee80211_hw *hw)
927 {
928         struct wl_info *wl = HW_TO_WL(hw);
929         int has_5g;
930         char phy_list[4];
931
932         has_5g = 0;
933
934         hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
935         hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
936
937         if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) {
938                 WL_ERROR("Phy list failed\n");
939         }
940         WL_NONE("%s: phylist = %c\n", __func__, phy_list[0]);
941
942         if (phy_list[0] == 'n' || phy_list[0] == 'c') {
943                 if (phy_list[0] == 'c') {
944                         /* Single stream */
945                         wl_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0;
946                         wl_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72;
947                 }
948                 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy;
949         } else {
950                 BUG();
951                 return -1;
952         }
953
954         /* Assume all bands use the same phy.  True for 11n devices. */
955         if (NBANDS_PUB(wl->pub) > 1) {
956                 has_5g++;
957                 if (phy_list[0] == 'n' || phy_list[0] == 'c') {
958                         hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
959                             &wl_band_5GHz_nphy;
960                 } else {
961                         return -1;
962                 }
963         }
964
965         WL_NONE("%s: 2ghz = %d, 5ghz = %d\n", __func__, 1, has_5g);
966
967         return 0;
968 }
969
970 static int ieee_hw_init(struct ieee80211_hw *hw)
971 {
972         hw->flags = IEEE80211_HW_SIGNAL_DBM
973             /* | IEEE80211_HW_CONNECTION_MONITOR  What is this? */
974             | IEEE80211_HW_REPORTS_TX_ACK_STATUS
975             | IEEE80211_HW_AMPDU_AGGREGATION;
976
977         hw->extra_tx_headroom = wlc_get_header_len();
978         /* FIXME: should get this from wlc->machwcap */
979         hw->queues = 4;
980         /* FIXME: this doesn't seem to be used properly in minstrel_ht.
981          * mac80211/status.c:ieee80211_tx_status() checks this value,
982          * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate()
983          * appears to always set 3 rates
984          */
985         hw->max_rates = 2;      /* Primary rate and 1 fallback rate */
986
987         hw->channel_change_time = 7 * 1000;     /* channel change time is dependant on chip and band  */
988         hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
989
990         hw->rate_control_algorithm = "minstrel_ht";
991
992         hw->sta_data_size = sizeof(struct scb);
993         return ieee_hw_rate_init(hw);
994 }
995
996 /**
997  * determines if a device is a WL device, and if so, attaches it.
998  *
999  * This function determines if a device pointed to by pdev is a WL device,
1000  * and if so, performs a wl_attach() on it.
1001  *
1002  */
1003 int __devinit
1004 wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
1005 {
1006         int rc;
1007         struct wl_info *wl;
1008         struct ieee80211_hw *hw;
1009         u32 val;
1010
1011         ASSERT(pdev);
1012
1013         WL_TRACE("%s: bus %d slot %d func %d irq %d\n",
1014                  __func__, pdev->bus->number, PCI_SLOT(pdev->devfn),
1015                  PCI_FUNC(pdev->devfn), pdev->irq);
1016
1017         if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) ||
1018             (((pdev->device & 0xff00) != 0x4300) &&
1019              ((pdev->device & 0xff00) != 0x4700) &&
1020              ((pdev->device < 43000) || (pdev->device > 43999))))
1021                 return -ENODEV;
1022
1023         rc = pci_enable_device(pdev);
1024         if (rc) {
1025                 WL_ERROR("%s: Cannot enable device %d-%d_%d\n",
1026                          __func__, pdev->bus->number, PCI_SLOT(pdev->devfn),
1027                          PCI_FUNC(pdev->devfn));
1028                 return -ENODEV;
1029         }
1030         pci_set_master(pdev);
1031
1032         pci_read_config_dword(pdev, 0x40, &val);
1033         if ((val & 0x0000ff00) != 0)
1034                 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1035
1036         hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops);
1037         if (!hw) {
1038                 WL_ERROR("%s: ieee80211_alloc_hw failed\n", __func__);
1039                 rc = -ENOMEM;
1040                 goto err_1;
1041         }
1042
1043         SET_IEEE80211_DEV(hw, &pdev->dev);
1044
1045         pci_set_drvdata(pdev, hw);
1046
1047         memset(hw->priv, 0, sizeof(*wl));
1048
1049         wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0),
1050                        PCI_BUS, pdev, pdev->irq);
1051
1052         if (!wl) {
1053                 WL_ERROR("%s: %s: wl_attach failed!\n",
1054                          KBUILD_MODNAME, __func__);
1055                 return -ENODEV;
1056         }
1057         return 0;
1058  err_1:
1059         WL_ERROR("%s: err_1: Major hoarkage\n", __func__);
1060         return 0;
1061 }
1062
1063 #ifdef LINUXSTA_PS
1064 static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
1065 {
1066         struct wl_info *wl;
1067         struct ieee80211_hw *hw;
1068
1069         WL_TRACE("wl: wl_suspend\n");
1070
1071         hw = pci_get_drvdata(pdev);
1072         wl = HW_TO_WL(hw);
1073         if (!wl) {
1074                 WL_ERROR("wl: wl_suspend: pci_get_drvdata failed\n");
1075                 return -ENODEV;
1076         }
1077
1078         WL_LOCK(wl);
1079         wl_down(wl);
1080         wl->pub->hw_up = false;
1081         WL_UNLOCK(wl);
1082         pci_save_state(pdev, wl->pci_psstate);
1083         pci_disable_device(pdev);
1084         return pci_set_power_state(pdev, PCI_D3hot);
1085 }
1086
1087 static int wl_resume(struct pci_dev *pdev)
1088 {
1089         struct wl_info *wl;
1090         struct ieee80211_hw *hw;
1091         int err = 0;
1092         u32 val;
1093
1094         WL_TRACE("wl: wl_resume\n");
1095         hw = pci_get_drvdata(pdev);
1096         wl = HW_TO_WL(hw);
1097         if (!wl) {
1098                 WL_ERROR("wl: wl_resume: pci_get_drvdata failed\n");
1099                 return -ENODEV;
1100         }
1101
1102         err = pci_set_power_state(pdev, PCI_D0);
1103         if (err)
1104                 return err;
1105
1106         pci_restore_state(pdev, wl->pci_psstate);
1107
1108         err = pci_enable_device(pdev);
1109         if (err)
1110                 return err;
1111
1112         pci_set_master(pdev);
1113
1114         pci_read_config_dword(pdev, 0x40, &val);
1115         if ((val & 0x0000ff00) != 0)
1116                 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1117
1118         WL_LOCK(wl);
1119         err = wl_up(wl);
1120         WL_UNLOCK(wl);
1121
1122         return err;
1123 }
1124 #endif                          /* LINUXSTA_PS */
1125
1126 static void wl_remove(struct pci_dev *pdev)
1127 {
1128         struct wl_info *wl;
1129         struct ieee80211_hw *hw;
1130
1131         hw = pci_get_drvdata(pdev);
1132         wl = HW_TO_WL(hw);
1133         if (!wl) {
1134                 WL_ERROR("wl: wl_remove: pci_get_drvdata failed\n");
1135                 return;
1136         }
1137         if (!wlc_chipmatch(pdev->vendor, pdev->device)) {
1138                 WL_ERROR("wl: wl_remove: wlc_chipmatch failed\n");
1139                 return;
1140         }
1141         if (wl->wlc) {
1142                 ieee80211_unregister_hw(hw);
1143                 WL_LOCK(wl);
1144                 wl_down(wl);
1145                 WL_UNLOCK(wl);
1146                 WL_NONE("%s: Down\n", __func__);
1147         }
1148         pci_disable_device(pdev);
1149
1150         wl_free(wl);
1151
1152         pci_set_drvdata(pdev, NULL);
1153         ieee80211_free_hw(hw);
1154 }
1155
1156 static struct pci_driver wl_pci_driver = {
1157         .name  = KBUILD_MODNAME,
1158         .probe = wl_pci_probe,
1159 #ifdef LINUXSTA_PS
1160         .suspend = wl_suspend,
1161         .resume  = wl_resume,
1162 #endif                          /* LINUXSTA_PS */
1163         .remove   = __devexit_p(wl_remove),
1164         .id_table = wl_id_table,
1165 };
1166
1167 /**
1168  * This is the main entry point for the WL driver.
1169  *
1170  * This function determines if a device pointed to by pdev is a WL device,
1171  * and if so, performs a wl_attach() on it.
1172  *
1173  */
1174 static int __init wl_module_init(void)
1175 {
1176         int error = -ENODEV;
1177
1178 #ifdef BCMDBG
1179         if (msglevel != 0xdeadbeef)
1180                 wl_msg_level = msglevel;
1181         else {
1182                 char *var = getvar(NULL, "wl_msglevel");
1183                 if (var)
1184                         wl_msg_level = simple_strtoul(var, NULL, 0);
1185         }
1186         {
1187                 extern u32 phyhal_msg_level;
1188
1189                 if (phymsglevel != 0xdeadbeef)
1190                         phyhal_msg_level = phymsglevel;
1191                 else {
1192                         char *var = getvar(NULL, "phy_msglevel");
1193                         if (var)
1194                                 phyhal_msg_level = simple_strtoul(var, NULL, 0);
1195                 }
1196         }
1197 #endif                          /* BCMDBG */
1198
1199         error = pci_register_driver(&wl_pci_driver);
1200         if (!error)
1201                 return 0;
1202
1203
1204
1205         return error;
1206 }
1207
1208 /**
1209  * This function unloads the WL driver from the system.
1210  *
1211  * This function unconditionally unloads the WL driver module from the
1212  * system.
1213  *
1214  */
1215 static void __exit wl_module_exit(void)
1216 {
1217         pci_unregister_driver(&wl_pci_driver);
1218
1219 }
1220
1221 module_init(wl_module_init);
1222 module_exit(wl_module_exit);
1223
1224 /**
1225  * This function frees the WL per-device resources.
1226  *
1227  * This function frees resources owned by the WL device pointed to
1228  * by the wl parameter.
1229  *
1230  */
1231 void wl_free(struct wl_info *wl)
1232 {
1233         wl_timer_t *t, *next;
1234         struct osl_info *osh;
1235
1236         ASSERT(wl);
1237         /* free ucode data */
1238         if (wl->fw.fw_cnt)
1239                 wl_ucode_data_free();
1240         if (wl->irq)
1241                 free_irq(wl->irq, wl);
1242
1243         /* kill dpc */
1244         tasklet_kill(&wl->tasklet);
1245
1246         if (wl->pub) {
1247                 wlc_module_unregister(wl->pub, "linux", wl);
1248         }
1249
1250         /* free common resources */
1251         if (wl->wlc) {
1252                 wlc_detach(wl->wlc);
1253                 wl->wlc = NULL;
1254                 wl->pub = NULL;
1255         }
1256
1257         /* virtual interface deletion is deferred so we cannot spinwait */
1258
1259         /* wait for all pending callbacks to complete */
1260         while (atomic_read(&wl->callbacks) > 0)
1261                 schedule();
1262
1263         /* free timers */
1264         for (t = wl->timers; t; t = next) {
1265                 next = t->next;
1266 #ifdef BCMDBG
1267                 if (t->name)
1268                         kfree(t->name);
1269 #endif
1270                 kfree(t);
1271         }
1272
1273         osh = wl->osh;
1274
1275         /*
1276          * unregister_netdev() calls get_stats() which may read chip registers
1277          * so we cannot unmap the chip registers until after calling unregister_netdev() .
1278          */
1279         if (wl->regsva && wl->bcm_bustype != SDIO_BUS &&
1280             wl->bcm_bustype != JTAG_BUS) {
1281                 iounmap((void *)wl->regsva);
1282         }
1283         wl->regsva = NULL;
1284
1285
1286         osl_detach(osh);
1287 }
1288
1289 /* transmit a packet */
1290 static int BCMFASTPATH wl_start(struct sk_buff *skb, struct wl_info *wl)
1291 {
1292         if (!wl)
1293                 return -ENETDOWN;
1294
1295         return wl_start_int(wl, WL_TO_HW(wl), skb);
1296 }
1297
1298 static int BCMFASTPATH
1299 wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, struct sk_buff *skb)
1300 {
1301         wlc_sendpkt_mac80211(wl->wlc, skb, hw);
1302         return NETDEV_TX_OK;
1303 }
1304
1305 void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state,
1306                       int prio)
1307 {
1308         WL_ERROR("Shouldn't be here %s\n", __func__);
1309 }
1310
1311 void wl_init(struct wl_info *wl)
1312 {
1313         WL_TRACE("wl%d: wl_init\n", wl->pub->unit);
1314
1315         wl_reset(wl);
1316
1317         wlc_init(wl->wlc);
1318 }
1319
1320 uint wl_reset(struct wl_info *wl)
1321 {
1322         WL_TRACE("wl%d: wl_reset\n", wl->pub->unit);
1323
1324         wlc_reset(wl->wlc);
1325
1326         /* dpc will not be rescheduled */
1327         wl->resched = 0;
1328
1329         return 0;
1330 }
1331
1332 /*
1333  * These are interrupt on/off entry points. Disable interrupts
1334  * during interrupt state transition.
1335  */
1336 void BCMFASTPATH wl_intrson(struct wl_info *wl)
1337 {
1338         unsigned long flags;
1339
1340         INT_LOCK(wl, flags);
1341         wlc_intrson(wl->wlc);
1342         INT_UNLOCK(wl, flags);
1343 }
1344
1345 bool wl_alloc_dma_resources(struct wl_info *wl, uint addrwidth)
1346 {
1347         return true;
1348 }
1349
1350 u32 BCMFASTPATH wl_intrsoff(struct wl_info *wl)
1351 {
1352         unsigned long flags;
1353         u32 status;
1354
1355         INT_LOCK(wl, flags);
1356         status = wlc_intrsoff(wl->wlc);
1357         INT_UNLOCK(wl, flags);
1358         return status;
1359 }
1360
1361 void wl_intrsrestore(struct wl_info *wl, u32 macintmask)
1362 {
1363         unsigned long flags;
1364
1365         INT_LOCK(wl, flags);
1366         wlc_intrsrestore(wl->wlc, macintmask);
1367         INT_UNLOCK(wl, flags);
1368 }
1369
1370 int wl_up(struct wl_info *wl)
1371 {
1372         int error = 0;
1373
1374         if (wl->pub->up)
1375                 return 0;
1376
1377         error = wlc_up(wl->wlc);
1378
1379         return error;
1380 }
1381
1382 void wl_down(struct wl_info *wl)
1383 {
1384         uint callbacks, ret_val = 0;
1385
1386         /* call common down function */
1387         ret_val = wlc_down(wl->wlc);
1388         callbacks = atomic_read(&wl->callbacks) - ret_val;
1389
1390         /* wait for down callbacks to complete */
1391         WL_UNLOCK(wl);
1392
1393         /* For HIGH_only driver, it's important to actually schedule other work,
1394          * not just spin wait since everything runs at schedule level
1395          */
1396         SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
1397
1398         WL_LOCK(wl);
1399 }
1400
1401 irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id)
1402 {
1403         struct wl_info *wl;
1404         bool ours, wantdpc;
1405         unsigned long flags;
1406
1407         wl = (struct wl_info *) dev_id;
1408
1409         WL_ISRLOCK(wl, flags);
1410
1411         /* call common first level interrupt handler */
1412         ours = wlc_isr(wl->wlc, &wantdpc);
1413         if (ours) {
1414                 /* if more to do... */
1415                 if (wantdpc) {
1416
1417                         /* ...and call the second level interrupt handler */
1418                         /* schedule dpc */
1419                         ASSERT(wl->resched == false);
1420                         tasklet_schedule(&wl->tasklet);
1421                 }
1422         }
1423
1424         WL_ISRUNLOCK(wl, flags);
1425
1426         return IRQ_RETVAL(ours);
1427 }
1428
1429 static void BCMFASTPATH wl_dpc(unsigned long data)
1430 {
1431         struct wl_info *wl;
1432
1433         wl = (struct wl_info *) data;
1434
1435         WL_LOCK(wl);
1436
1437         /* call the common second level interrupt handler */
1438         if (wl->pub->up) {
1439                 if (wl->resched) {
1440                         unsigned long flags;
1441
1442                         INT_LOCK(wl, flags);
1443                         wlc_intrsupd(wl->wlc);
1444                         INT_UNLOCK(wl, flags);
1445                 }
1446
1447                 wl->resched = wlc_dpc(wl->wlc, true);
1448         }
1449
1450         /* wlc_dpc() may bring the driver down */
1451         if (!wl->pub->up)
1452                 goto done;
1453
1454         /* re-schedule dpc */
1455         if (wl->resched)
1456                 tasklet_schedule(&wl->tasklet);
1457         else {
1458                 /* re-enable interrupts */
1459                 wl_intrson(wl);
1460         }
1461
1462  done:
1463         WL_UNLOCK(wl);
1464 }
1465
1466 static void wl_link_up(struct wl_info *wl, char *ifname)
1467 {
1468         WL_ERROR("wl%d: link up (%s)\n", wl->pub->unit, ifname);
1469 }
1470
1471 static void wl_link_down(struct wl_info *wl, char *ifname)
1472 {
1473         WL_ERROR("wl%d: link down (%s)\n", wl->pub->unit, ifname);
1474 }
1475
1476 void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e)
1477 {
1478
1479         switch (e->event.event_type) {
1480         case WLC_E_LINK:
1481         case WLC_E_NDIS_LINK:
1482                 if (e->event.flags & WLC_EVENT_MSG_LINK)
1483                         wl_link_up(wl, ifname);
1484                 else
1485                         wl_link_down(wl, ifname);
1486                 break;
1487         case WLC_E_RADIO:
1488                 break;
1489         }
1490 }
1491
1492 static void wl_timer(unsigned long data)
1493 {
1494         _wl_timer((wl_timer_t *) data);
1495 }
1496
1497 static void _wl_timer(wl_timer_t *t)
1498 {
1499         WL_LOCK(t->wl);
1500
1501         if (t->set) {
1502                 if (t->periodic) {
1503                         t->timer.expires = jiffies + t->ms * HZ / 1000;
1504                         atomic_inc(&t->wl->callbacks);
1505                         add_timer(&t->timer);
1506                         t->set = true;
1507                 } else
1508                         t->set = false;
1509
1510                 t->fn(t->arg);
1511         }
1512
1513         atomic_dec(&t->wl->callbacks);
1514
1515         WL_UNLOCK(t->wl);
1516 }
1517
1518 wl_timer_t *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), void *arg,
1519                           const char *name)
1520 {
1521         wl_timer_t *t;
1522
1523         t = kmalloc(sizeof(wl_timer_t), GFP_ATOMIC);
1524         if (!t) {
1525                 WL_ERROR("wl%d: wl_init_timer: out of memory\n", wl->pub->unit);
1526                 return 0;
1527         }
1528
1529         memset(t, 0, sizeof(wl_timer_t));
1530
1531         init_timer(&t->timer);
1532         t->timer.data = (unsigned long) t;
1533         t->timer.function = wl_timer;
1534         t->wl = wl;
1535         t->fn = fn;
1536         t->arg = arg;
1537         t->next = wl->timers;
1538         wl->timers = t;
1539
1540 #ifdef BCMDBG
1541         t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC);
1542         if (t->name)
1543                 strcpy(t->name, name);
1544 #endif
1545
1546         return t;
1547 }
1548
1549 /* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate
1550  * as well as it's easier to make it periodic
1551  */
1552 void wl_add_timer(struct wl_info *wl, wl_timer_t *t, uint ms, int periodic)
1553 {
1554 #ifdef BCMDBG
1555         if (t->set) {
1556                 WL_ERROR("%s: Already set. Name: %s, per %d\n",
1557                          __func__, t->name, periodic);
1558         }
1559 #endif
1560         ASSERT(!t->set);
1561
1562         t->ms = ms;
1563         t->periodic = (bool) periodic;
1564         t->set = true;
1565         t->timer.expires = jiffies + ms * HZ / 1000;
1566
1567         atomic_inc(&wl->callbacks);
1568         add_timer(&t->timer);
1569 }
1570
1571 /* return true if timer successfully deleted, false if still pending */
1572 bool wl_del_timer(struct wl_info *wl, wl_timer_t *t)
1573 {
1574         if (t->set) {
1575                 t->set = false;
1576                 if (!del_timer(&t->timer)) {
1577                         return false;
1578                 }
1579                 atomic_dec(&wl->callbacks);
1580         }
1581
1582         return true;
1583 }
1584
1585 void wl_free_timer(struct wl_info *wl, wl_timer_t *t)
1586 {
1587         wl_timer_t *tmp;
1588
1589         /* delete the timer in case it is active */
1590         wl_del_timer(wl, t);
1591
1592         if (wl->timers == t) {
1593                 wl->timers = wl->timers->next;
1594 #ifdef BCMDBG
1595                 if (t->name)
1596                         kfree(t->name);
1597 #endif
1598                 kfree(t);
1599                 return;
1600
1601         }
1602
1603         tmp = wl->timers;
1604         while (tmp) {
1605                 if (tmp->next == t) {
1606                         tmp->next = t->next;
1607 #ifdef BCMDBG
1608                         if (t->name)
1609                                 kfree(t->name);
1610 #endif
1611                         kfree(t);
1612                         return;
1613                 }
1614                 tmp = tmp->next;
1615         }
1616
1617 }
1618
1619 static int wl_linux_watchdog(void *ctx)
1620 {
1621         struct wl_info *wl = (struct wl_info *) ctx;
1622         struct net_device_stats *stats = NULL;
1623         uint id;
1624         /* refresh stats */
1625         if (wl->pub->up) {
1626                 ASSERT(wl->stats_id < 2);
1627
1628                 id = 1 - wl->stats_id;
1629
1630                 stats = &wl->stats_watchdog[id];
1631                 stats->rx_packets = WLCNTVAL(wl->pub->_cnt->rxframe);
1632                 stats->tx_packets = WLCNTVAL(wl->pub->_cnt->txframe);
1633                 stats->rx_bytes = WLCNTVAL(wl->pub->_cnt->rxbyte);
1634                 stats->tx_bytes = WLCNTVAL(wl->pub->_cnt->txbyte);
1635                 stats->rx_errors = WLCNTVAL(wl->pub->_cnt->rxerror);
1636                 stats->tx_errors = WLCNTVAL(wl->pub->_cnt->txerror);
1637                 stats->collisions = 0;
1638
1639                 stats->rx_length_errors = 0;
1640                 stats->rx_over_errors = WLCNTVAL(wl->pub->_cnt->rxoflo);
1641                 stats->rx_crc_errors = WLCNTVAL(wl->pub->_cnt->rxcrc);
1642                 stats->rx_frame_errors = 0;
1643                 stats->rx_fifo_errors = WLCNTVAL(wl->pub->_cnt->rxoflo);
1644                 stats->rx_missed_errors = 0;
1645
1646                 stats->tx_fifo_errors = WLCNTVAL(wl->pub->_cnt->txuflo);
1647
1648                 wl->stats_id = id;
1649
1650         }
1651
1652         return 0;
1653 }
1654
1655 struct wl_fw_hdr {
1656         u32 offset;
1657         u32 len;
1658         u32 idx;
1659 };
1660
1661 char *wl_firmwares[WL_MAX_FW] = {
1662         "brcm/bcm43xx",
1663         NULL
1664 };
1665
1666 int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx)
1667 {
1668         int i, entry;
1669         const u8 *pdata;
1670         struct wl_fw_hdr *hdr;
1671         for (i = 0; i < wl->fw.fw_cnt; i++) {
1672                 hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data;
1673                 for (entry = 0; entry < wl->fw.hdr_num_entries[i];
1674                      entry++, hdr++) {
1675                         if (hdr->idx == idx) {
1676                                 pdata = wl->fw.fw_bin[i]->data + hdr->offset;
1677                                 *pbuf = kmalloc(hdr->len, GFP_ATOMIC);
1678                                 if (*pbuf == NULL) {
1679                                         printf("fail to alloc %d bytes\n",
1680                                                hdr->len);
1681                                 }
1682                                 bcopy(pdata, *pbuf, hdr->len);
1683                                 return 0;
1684                         }
1685                 }
1686         }
1687         printf("ERROR: ucode buf tag:%d can not be found!\n", idx);
1688         *pbuf = NULL;
1689         return -1;
1690 }
1691
1692 int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx)
1693 {
1694         int i, entry;
1695         const u8 *pdata;
1696         struct wl_fw_hdr *hdr;
1697         for (i = 0; i < wl->fw.fw_cnt; i++) {
1698                 hdr = (struct wl_fw_hdr *)wl->fw.fw_hdr[i]->data;
1699                 for (entry = 0; entry < wl->fw.hdr_num_entries[i];
1700                      entry++, hdr++) {
1701                         if (hdr->idx == idx) {
1702                                 pdata = wl->fw.fw_bin[i]->data + hdr->offset;
1703                                 ASSERT(hdr->len == 4);
1704                                 *data = *((u32 *) pdata);
1705                                 return 0;
1706                         }
1707                 }
1708         }
1709         printf("ERROR: ucode tag:%d can not be found!\n", idx);
1710         return -1;
1711 }
1712
1713 static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev)
1714 {
1715         int status;
1716         struct device *device = &pdev->dev;
1717         char fw_name[100];
1718         int i;
1719
1720         memset((void *)&wl->fw, 0, sizeof(struct wl_firmware));
1721         for (i = 0; i < WL_MAX_FW; i++) {
1722                 if (wl_firmwares[i] == NULL)
1723                         break;
1724                 sprintf(fw_name, "%s-%d.fw", wl_firmwares[i],
1725                         UCODE_LOADER_API_VER);
1726                 WL_NONE("request fw %s\n", fw_name);
1727                 status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
1728                 if (status) {
1729                         printf("%s: fail to load firmware %s\n",
1730                                 KBUILD_MODNAME, fw_name);
1731                         wl_release_fw(wl);
1732                         return status;
1733                 }
1734                 WL_NONE("request fw %s\n", fw_name);
1735                 sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i],
1736                         UCODE_LOADER_API_VER);
1737                 status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
1738                 if (status) {
1739                         printf("%s: fail to load firmware %s\n",
1740                                 KBUILD_MODNAME, fw_name);
1741                         wl_release_fw(wl);
1742                         return status;
1743                 }
1744                 wl->fw.hdr_num_entries[i] =
1745                     wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr));
1746                 WL_NONE("request fw %s find: %d entries\n",
1747                         fw_name, wl->fw.hdr_num_entries[i]);
1748         }
1749         wl->fw.fw_cnt = i;
1750         return wl_ucode_data_init(wl);
1751 }
1752
1753 void wl_ucode_free_buf(void *p)
1754 {
1755         kfree(p);
1756 }
1757
1758 static void wl_release_fw(struct wl_info *wl)
1759 {
1760         int i;
1761         for (i = 0; i < WL_MAX_FW; i++) {
1762                 release_firmware(wl->fw.fw_bin[i]);
1763                 release_firmware(wl->fw.fw_hdr[i]);
1764         }
1765 }
1766
1767
1768 /*
1769  * checks validity of all firmware images loaded from user space
1770  */
1771 int wl_check_firmwares(struct wl_info *wl)
1772 {
1773         int i;
1774         int entry;
1775         int rc = 0;
1776         const struct firmware *fw;
1777         const struct firmware *fw_hdr;
1778         struct wl_fw_hdr *ucode_hdr;
1779         for (i = 0; i < WL_MAX_FW && rc == 0; i++) {
1780                 fw =  wl->fw.fw_bin[i];
1781                 fw_hdr = wl->fw.fw_hdr[i];
1782                 if (fw == NULL && fw_hdr == NULL) {
1783                         break;
1784                 } else if (fw == NULL || fw_hdr == NULL) {
1785                         WL_ERROR("%s: invalid bin/hdr fw\n", __func__);
1786                         rc = -EBADF;
1787                 } else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) {
1788                         WL_ERROR("%s: non integral fw hdr file size %d/%zu\n",
1789                                  __func__, fw_hdr->size,
1790                                  sizeof(struct wl_fw_hdr));
1791                         rc = -EBADF;
1792                 } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) {
1793                         WL_ERROR("%s: out of bounds fw file size %d\n",
1794                                  __func__, fw->size);
1795                         rc = -EBADF;
1796                 } else {
1797                         /* check if ucode section overruns firmware image */
1798                         ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data;
1799                         for (entry = 0; entry < wl->fw.hdr_num_entries[i] && rc;
1800                              entry++, ucode_hdr++) {
1801                                 if (ucode_hdr->offset + ucode_hdr->len >
1802                                     fw->size) {
1803                                         WL_ERROR("%s: conflicting bin/hdr\n",
1804                                                  __func__);
1805                                         rc = -EBADF;
1806                                 }
1807                         }
1808                 }
1809         }
1810         if (rc == 0 && wl->fw.fw_cnt != i) {
1811                 WL_ERROR("%s: invalid fw_cnt=%d\n", __func__, wl->fw.fw_cnt);
1812                 rc = -EBADF;
1813         }
1814         return rc;
1815 }
1816