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