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