mac80211: move TX station pointer and restructure TX
[deliverable/linux.git] / drivers / net / wireless / brcm80211 / brcmsmac / mac80211_if.c
CommitLineData
5b435de0
AS
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__
02f77195 18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
5b435de0
AS
19
20#include <linux/etherdevice.h>
5b435de0
AS
21#include <linux/sched.h>
22#include <linux/firmware.h>
23#include <linux/interrupt.h>
45296236 24#include <linux/module.h>
2e756560 25#include <linux/bcma/bcma.h>
5b435de0
AS
26#include <net/mac80211.h>
27#include <defs.h>
5b435de0
AS
28#include "phy/phy_int.h"
29#include "d11.h"
30#include "channel.h"
31#include "scb.h"
32#include "pub.h"
33#include "ucode_loader.h"
34#include "mac80211_if.h"
35#include "main.h"
36
37#define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */
38
39/* Flags we support */
40#define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
41 FIF_ALLMULTI | \
42 FIF_FCSFAIL | \
5b435de0
AS
43 FIF_CONTROL | \
44 FIF_OTHER_BSS | \
be667669
AB
45 FIF_BCN_PRBRESP_PROMISC | \
46 FIF_PSPOLL)
5b435de0
AS
47
48#define CHAN2GHZ(channel, freqency, chflags) { \
49 .band = IEEE80211_BAND_2GHZ, \
50 .center_freq = (freqency), \
51 .hw_value = (channel), \
52 .flags = chflags, \
53 .max_antenna_gain = 0, \
54 .max_power = 19, \
55}
56
57#define CHAN5GHZ(channel, chflags) { \
58 .band = IEEE80211_BAND_5GHZ, \
59 .center_freq = 5000 + 5*(channel), \
60 .hw_value = (channel), \
61 .flags = chflags, \
62 .max_antenna_gain = 0, \
63 .max_power = 21, \
64}
65
66#define RATE(rate100m, _flags) { \
67 .bitrate = (rate100m), \
68 .flags = (_flags), \
69 .hw_value = (rate100m / 5), \
70}
71
72struct firmware_hdr {
73 __le32 offset;
74 __le32 len;
75 __le32 idx;
76};
77
78static const char * const brcms_firmwares[MAX_FW_IMAGES] = {
79 "brcm/bcm43xx",
80 NULL
81};
82
83static int n_adapters_found;
84
85MODULE_AUTHOR("Broadcom Corporation");
86MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
87MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
88MODULE_LICENSE("Dual BSD/GPL");
89
5b435de0 90
2e756560
AS
91/* recognized BCMA Core IDs */
92static struct bcma_device_id brcms_coreid_table[] = {
eb032f03
AS
93 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 23, BCMA_ANY_CLASS),
94 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 24, BCMA_ANY_CLASS),
2e756560
AS
95 BCMA_CORETABLE_END
96};
97MODULE_DEVICE_TABLE(bcma, brcms_coreid_table);
5b435de0 98
8ae74654 99#ifdef DEBUG
5b435de0
AS
100static int msglevel = 0xdeadbeef;
101module_param(msglevel, int, 0);
8ae74654 102#endif /* DEBUG */
5b435de0
AS
103
104static struct ieee80211_channel brcms_2ghz_chantable[] = {
105 CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS),
106 CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS),
107 CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS),
108 CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS),
109 CHAN2GHZ(5, 2432, 0),
110 CHAN2GHZ(6, 2437, 0),
111 CHAN2GHZ(7, 2442, 0),
112 CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS),
113 CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS),
114 CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS),
115 CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS),
116 CHAN2GHZ(12, 2467,
117 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
118 IEEE80211_CHAN_NO_HT40PLUS),
119 CHAN2GHZ(13, 2472,
120 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
121 IEEE80211_CHAN_NO_HT40PLUS),
122 CHAN2GHZ(14, 2484,
123 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS |
124 IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
125};
126
127static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = {
128 /* UNII-1 */
129 CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS),
130 CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS),
131 CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS),
132 CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS),
133 /* UNII-2 */
134 CHAN5GHZ(52,
135 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
136 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
137 CHAN5GHZ(56,
138 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
139 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
140 CHAN5GHZ(60,
141 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
142 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
143 CHAN5GHZ(64,
144 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
145 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
146 /* MID */
147 CHAN5GHZ(100,
148 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
149 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
150 CHAN5GHZ(104,
151 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
152 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
153 CHAN5GHZ(108,
154 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
155 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
156 CHAN5GHZ(112,
157 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
158 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
159 CHAN5GHZ(116,
160 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
161 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
162 CHAN5GHZ(120,
163 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
164 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
165 CHAN5GHZ(124,
166 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
167 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
168 CHAN5GHZ(128,
169 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
170 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
171 CHAN5GHZ(132,
172 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
173 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS),
174 CHAN5GHZ(136,
175 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
176 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS),
177 CHAN5GHZ(140,
178 IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS |
179 IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS |
180 IEEE80211_CHAN_NO_HT40MINUS),
181 /* UNII-3 */
182 CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS),
183 CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS),
184 CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS),
185 CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS),
186 CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)
187};
188
189/*
190 * The rate table is used for both 2.4G and 5G rates. The
191 * latter being a subset as it does not support CCK rates.
192 */
193static struct ieee80211_rate legacy_ratetable[] = {
194 RATE(10, 0),
195 RATE(20, IEEE80211_RATE_SHORT_PREAMBLE),
196 RATE(55, IEEE80211_RATE_SHORT_PREAMBLE),
197 RATE(110, IEEE80211_RATE_SHORT_PREAMBLE),
198 RATE(60, 0),
199 RATE(90, 0),
200 RATE(120, 0),
201 RATE(180, 0),
202 RATE(240, 0),
203 RATE(360, 0),
204 RATE(480, 0),
205 RATE(540, 0),
206};
207
208static const struct ieee80211_supported_band brcms_band_2GHz_nphy_template = {
209 .band = IEEE80211_BAND_2GHZ,
210 .channels = brcms_2ghz_chantable,
211 .n_channels = ARRAY_SIZE(brcms_2ghz_chantable),
212 .bitrates = legacy_ratetable,
213 .n_bitrates = ARRAY_SIZE(legacy_ratetable),
214 .ht_cap = {
215 /* from include/linux/ieee80211.h */
216 .cap = IEEE80211_HT_CAP_GRN_FLD |
6b1a89af 217 IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40,
5b435de0
AS
218 .ht_supported = true,
219 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
220 .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
221 .mcs = {
222 /* placeholders for now */
223 .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
224 .rx_highest = cpu_to_le16(500),
225 .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
226 }
227};
228
229static const struct ieee80211_supported_band brcms_band_5GHz_nphy_template = {
230 .band = IEEE80211_BAND_5GHZ,
231 .channels = brcms_5ghz_nphy_chantable,
232 .n_channels = ARRAY_SIZE(brcms_5ghz_nphy_chantable),
233 .bitrates = legacy_ratetable + BRCMS_LEGACY_5G_RATE_OFFSET,
234 .n_bitrates = ARRAY_SIZE(legacy_ratetable) -
235 BRCMS_LEGACY_5G_RATE_OFFSET,
236 .ht_cap = {
237 .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
6b1a89af 238 IEEE80211_HT_CAP_SGI_40,
5b435de0
AS
239 .ht_supported = true,
240 .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K,
241 .ampdu_density = AMPDU_DEF_MPDU_DENSITY,
242 .mcs = {
243 /* placeholders for now */
244 .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
245 .rx_highest = cpu_to_le16(500),
246 .tx_params = IEEE80211_HT_MCS_TX_DEFINED}
247 }
248};
249
250/* flags the given rate in rateset as requested */
251static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br)
252{
253 u32 i;
254
255 for (i = 0; i < rs->count; i++) {
256 if (rate != (rs->rates[i] & 0x7f))
257 continue;
258
259 if (is_br)
260 rs->rates[i] |= BRCMS_RATE_FLAG;
261 else
262 rs->rates[i] &= BRCMS_RATE_MASK;
263 return;
264 }
265}
266
36323f81
TH
267static void brcms_ops_tx(struct ieee80211_hw *hw,
268 struct ieee80211_tx_control *control,
269 struct sk_buff *skb)
5b435de0
AS
270{
271 struct brcms_info *wl = hw->priv;
644e8c07 272 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
5b435de0
AS
273
274 spin_lock_bh(&wl->lock);
275 if (!wl->pub->up) {
276 wiphy_err(wl->wiphy, "ops->tx called while down\n");
277 kfree_skb(skb);
278 goto done;
279 }
280 brcms_c_sendpkt_mac80211(wl->wlc, skb, hw);
36323f81 281 tx_info->rate_driver_data[0] = control->sta;
5b435de0
AS
282 done:
283 spin_unlock_bh(&wl->lock);
284}
285
286static int brcms_ops_start(struct ieee80211_hw *hw)
287{
288 struct brcms_info *wl = hw->priv;
289 bool blocked;
2646c46d 290 int err;
5b435de0
AS
291
292 ieee80211_wake_queues(hw);
293 spin_lock_bh(&wl->lock);
294 blocked = brcms_rfkill_set_hw_state(wl);
295 spin_unlock_bh(&wl->lock);
296 if (!blocked)
297 wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
298
2646c46d 299 spin_lock_bh(&wl->lock);
dc460127
RV
300 /* avoid acknowledging frames before a non-monitor device is added */
301 wl->mute_tx = true;
302
2646c46d
RV
303 if (!wl->pub->up)
304 err = brcms_up(wl);
305 else
306 err = -ENODEV;
307 spin_unlock_bh(&wl->lock);
308
309 if (err != 0)
310 wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__,
311 err);
312 return err;
5b435de0
AS
313}
314
315static void brcms_ops_stop(struct ieee80211_hw *hw)
316{
2646c46d
RV
317 struct brcms_info *wl = hw->priv;
318 int status;
319
5b435de0 320 ieee80211_stop_queues(hw);
2646c46d
RV
321
322 if (wl->wlc == NULL)
323 return;
324
325 spin_lock_bh(&wl->lock);
cacaa64b 326 status = brcms_c_chipmatch(wl->wlc->hw->d11core);
2646c46d
RV
327 spin_unlock_bh(&wl->lock);
328 if (!status) {
329 wiphy_err(wl->wiphy,
330 "wl: brcms_ops_stop: chipmatch failed\n");
331 return;
332 }
333
334 /* put driver in down state */
335 spin_lock_bh(&wl->lock);
336 brcms_down(wl);
337 spin_unlock_bh(&wl->lock);
5b435de0
AS
338}
339
340static int
341brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
342{
dc460127
RV
343 struct brcms_info *wl = hw->priv;
344
5b435de0 345 /* Just STA for now */
1525662a 346 if (vif->type != NL80211_IFTYPE_STATION) {
5b435de0
AS
347 wiphy_err(hw->wiphy, "%s: Attempt to add type %d, only"
348 " STA for now\n", __func__, vif->type);
349 return -EOPNOTSUPP;
350 }
351
dc460127
RV
352 wl->mute_tx = false;
353 brcms_c_mute(wl->wlc, false);
354
2646c46d 355 return 0;
5b435de0
AS
356}
357
358static void
359brcms_ops_remove_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
360{
5b435de0
AS
361}
362
363static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed)
364{
365 struct ieee80211_conf *conf = &hw->conf;
366 struct brcms_info *wl = hw->priv;
367 int err = 0;
368 int new_int;
369 struct wiphy *wiphy = hw->wiphy;
370
371 spin_lock_bh(&wl->lock);
372 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
373 brcms_c_set_beacon_listen_interval(wl->wlc,
374 conf->listen_interval);
375 }
376 if (changed & IEEE80211_CONF_CHANGE_MONITOR)
be667669 377 wiphy_dbg(wiphy, "%s: change monitor mode: %s\n",
5b435de0
AS
378 __func__, conf->flags & IEEE80211_CONF_MONITOR ?
379 "true" : "false");
380 if (changed & IEEE80211_CONF_CHANGE_PS)
381 wiphy_err(wiphy, "%s: change power-save mode: %s (implement)\n",
382 __func__, conf->flags & IEEE80211_CONF_PS ?
383 "true" : "false");
384
385 if (changed & IEEE80211_CONF_CHANGE_POWER) {
386 err = brcms_c_set_tx_power(wl->wlc, conf->power_level);
387 if (err < 0) {
388 wiphy_err(wiphy, "%s: Error setting power_level\n",
389 __func__);
390 goto config_out;
391 }
392 new_int = brcms_c_get_tx_power(wl->wlc);
393 if (new_int != conf->power_level)
394 wiphy_err(wiphy, "%s: Power level req != actual, %d %d"
395 "\n", __func__, conf->power_level,
396 new_int);
397 }
398 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
399 if (conf->channel_type == NL80211_CHAN_HT20 ||
400 conf->channel_type == NL80211_CHAN_NO_HT)
401 err = brcms_c_set_channel(wl->wlc,
402 conf->channel->hw_value);
403 else
404 err = -ENOTSUPP;
405 }
406 if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS)
407 err = brcms_c_set_rate_limit(wl->wlc,
408 conf->short_frame_max_tx_count,
409 conf->long_frame_max_tx_count);
410
411 config_out:
412 spin_unlock_bh(&wl->lock);
413 return err;
414}
415
416static void
417brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
418 struct ieee80211_vif *vif,
419 struct ieee80211_bss_conf *info, u32 changed)
420{
421 struct brcms_info *wl = hw->priv;
422 struct wiphy *wiphy = hw->wiphy;
423
424 if (changed & BSS_CHANGED_ASSOC) {
425 /* association status changed (associated/disassociated)
426 * also implies a change in the AID.
427 */
428 wiphy_err(wiphy, "%s: %s: %sassociated\n", KBUILD_MODNAME,
429 __func__, info->assoc ? "" : "dis");
430 spin_lock_bh(&wl->lock);
431 brcms_c_associate_upd(wl->wlc, info->assoc);
432 spin_unlock_bh(&wl->lock);
433 }
434 if (changed & BSS_CHANGED_ERP_SLOT) {
435 s8 val;
436
437 /* slot timing changed */
438 if (info->use_short_slot)
439 val = 1;
440 else
441 val = 0;
442 spin_lock_bh(&wl->lock);
443 brcms_c_set_shortslot_override(wl->wlc, val);
444 spin_unlock_bh(&wl->lock);
445 }
446
447 if (changed & BSS_CHANGED_HT) {
448 /* 802.11n parameters changed */
449 u16 mode = info->ht_operation_mode;
450
451 spin_lock_bh(&wl->lock);
452 brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_CFG,
453 mode & IEEE80211_HT_OP_MODE_PROTECTION);
454 brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_NONGF,
455 mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT);
456 brcms_c_protection_upd(wl->wlc, BRCMS_PROT_N_OBSS,
457 mode & IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT);
458 spin_unlock_bh(&wl->lock);
459 }
460 if (changed & BSS_CHANGED_BASIC_RATES) {
461 struct ieee80211_supported_band *bi;
462 u32 br_mask, i;
463 u16 rate;
464 struct brcm_rateset rs;
465 int error;
466
467 /* retrieve the current rates */
468 spin_lock_bh(&wl->lock);
469 brcms_c_get_current_rateset(wl->wlc, &rs);
470 spin_unlock_bh(&wl->lock);
471
472 br_mask = info->basic_rates;
473 bi = hw->wiphy->bands[brcms_c_get_curband(wl->wlc)];
474 for (i = 0; i < bi->n_bitrates; i++) {
475 /* convert to internal rate value */
476 rate = (bi->bitrates[i].bitrate << 1) / 10;
477
478 /* set/clear basic rate flag */
479 brcms_set_basic_rate(&rs, rate, br_mask & 1);
480 br_mask >>= 1;
481 }
482
483 /* update the rate set */
484 spin_lock_bh(&wl->lock);
485 error = brcms_c_set_rateset(wl->wlc, &rs);
486 spin_unlock_bh(&wl->lock);
487 if (error)
488 wiphy_err(wiphy, "changing basic rates failed: %d\n",
489 error);
490 }
491 if (changed & BSS_CHANGED_BEACON_INT) {
492 /* Beacon interval changed */
493 spin_lock_bh(&wl->lock);
494 brcms_c_set_beacon_period(wl->wlc, info->beacon_int);
495 spin_unlock_bh(&wl->lock);
496 }
497 if (changed & BSS_CHANGED_BSSID) {
498 /* BSSID changed, for whatever reason (IBSS and managed mode) */
499 spin_lock_bh(&wl->lock);
500 brcms_c_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, info->bssid);
501 spin_unlock_bh(&wl->lock);
502 }
503 if (changed & BSS_CHANGED_BEACON)
504 /* Beacon data changed, retrieve new beacon (beaconing modes) */
505 wiphy_err(wiphy, "%s: beacon changed\n", __func__);
506
507 if (changed & BSS_CHANGED_BEACON_ENABLED) {
508 /* Beaconing should be enabled/disabled (beaconing modes) */
509 wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__,
510 info->enable_beacon ? "true" : "false");
511 }
512
513 if (changed & BSS_CHANGED_CQM) {
514 /* Connection quality monitor config changed */
515 wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d "
516 " (implement)\n", __func__, info->cqm_rssi_thold,
517 info->cqm_rssi_hyst);
518 }
519
520 if (changed & BSS_CHANGED_IBSS) {
521 /* IBSS join status changed */
522 wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__,
523 info->ibss_joined ? "true" : "false");
524 }
525
526 if (changed & BSS_CHANGED_ARP_FILTER) {
527 /* Hardware ARP filter address list or state changed */
528 wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d"
529 " (implement)\n", __func__, info->arp_filter_enabled ?
530 "true" : "false", info->arp_addr_cnt);
531 }
532
533 if (changed & BSS_CHANGED_QOS) {
534 /*
535 * QoS for this association was enabled/disabled.
536 * Note that it is only ever disabled for station mode.
537 */
538 wiphy_err(wiphy, "%s: qos enabled: %s (implement)\n", __func__,
539 info->qos ? "true" : "false");
540 }
541 return;
542}
543
544static void
545brcms_ops_configure_filter(struct ieee80211_hw *hw,
546 unsigned int changed_flags,
547 unsigned int *total_flags, u64 multicast)
548{
549 struct brcms_info *wl = hw->priv;
550 struct wiphy *wiphy = hw->wiphy;
551
552 changed_flags &= MAC_FILTERS;
553 *total_flags &= MAC_FILTERS;
be667669 554
5b435de0 555 if (changed_flags & FIF_PROMISC_IN_BSS)
be667669 556 wiphy_dbg(wiphy, "FIF_PROMISC_IN_BSS\n");
5b435de0 557 if (changed_flags & FIF_ALLMULTI)
be667669 558 wiphy_dbg(wiphy, "FIF_ALLMULTI\n");
5b435de0 559 if (changed_flags & FIF_FCSFAIL)
be667669 560 wiphy_dbg(wiphy, "FIF_FCSFAIL\n");
5b435de0 561 if (changed_flags & FIF_CONTROL)
be667669 562 wiphy_dbg(wiphy, "FIF_CONTROL\n");
5b435de0 563 if (changed_flags & FIF_OTHER_BSS)
be667669
AB
564 wiphy_dbg(wiphy, "FIF_OTHER_BSS\n");
565 if (changed_flags & FIF_PSPOLL)
566 wiphy_dbg(wiphy, "FIF_PSPOLL\n");
567 if (changed_flags & FIF_BCN_PRBRESP_PROMISC)
568 wiphy_dbg(wiphy, "FIF_BCN_PRBRESP_PROMISC\n");
569
570 spin_lock_bh(&wl->lock);
571 brcms_c_mac_promisc(wl->wlc, *total_flags);
572 spin_unlock_bh(&wl->lock);
5b435de0
AS
573 return;
574}
575
576static void brcms_ops_sw_scan_start(struct ieee80211_hw *hw)
577{
578 struct brcms_info *wl = hw->priv;
579 spin_lock_bh(&wl->lock);
580 brcms_c_scan_start(wl->wlc);
581 spin_unlock_bh(&wl->lock);
582 return;
583}
584
585static void brcms_ops_sw_scan_complete(struct ieee80211_hw *hw)
586{
587 struct brcms_info *wl = hw->priv;
588 spin_lock_bh(&wl->lock);
589 brcms_c_scan_stop(wl->wlc);
590 spin_unlock_bh(&wl->lock);
591 return;
592}
593
594static int
595brcms_ops_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue,
596 const struct ieee80211_tx_queue_params *params)
597{
598 struct brcms_info *wl = hw->priv;
599
600 spin_lock_bh(&wl->lock);
601 brcms_c_wme_setparams(wl->wlc, queue, params, true);
602 spin_unlock_bh(&wl->lock);
603
604 return 0;
605}
606
607static int
608brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
609 struct ieee80211_sta *sta)
610{
611 struct brcms_info *wl = hw->priv;
612 struct scb *scb = &wl->wlc->pri_scb;
613
614 brcms_c_init_scb(scb);
615
616 wl->pub->global_ampdu = &(scb->scb_ampdu);
617 wl->pub->global_ampdu->scb = scb;
618 wl->pub->global_ampdu->max_pdu = 16;
619
5b435de0
AS
620 /*
621 * minstrel_ht initiates addBA on our behalf by calling
622 * ieee80211_start_tx_ba_session()
623 */
624 return 0;
625}
626
627static int
628brcms_ops_ampdu_action(struct ieee80211_hw *hw,
629 struct ieee80211_vif *vif,
630 enum ieee80211_ampdu_mlme_action action,
631 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
632 u8 buf_size)
633{
634 struct brcms_info *wl = hw->priv;
635 struct scb *scb = &wl->wlc->pri_scb;
636 int status;
637
638 if (WARN_ON(scb->magic != SCB_MAGIC))
639 return -EIDRM;
640 switch (action) {
641 case IEEE80211_AMPDU_RX_START:
642 break;
643 case IEEE80211_AMPDU_RX_STOP:
644 break;
645 case IEEE80211_AMPDU_TX_START:
646 spin_lock_bh(&wl->lock);
647 status = brcms_c_aggregatable(wl->wlc, tid);
648 spin_unlock_bh(&wl->lock);
649 if (!status) {
650 wiphy_err(wl->wiphy, "START: tid %d is not agg\'able\n",
651 tid);
652 return -EINVAL;
653 }
654 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
655 break;
656
657 case IEEE80211_AMPDU_TX_STOP:
658 spin_lock_bh(&wl->lock);
659 brcms_c_ampdu_flush(wl->wlc, sta, tid);
660 spin_unlock_bh(&wl->lock);
661 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
662 break;
663 case IEEE80211_AMPDU_TX_OPERATIONAL:
664 /*
665 * BA window size from ADDBA response ('buf_size') defines how
666 * many outstanding MPDUs are allowed for the BA stream by
667 * recipient and traffic class. 'ampdu_factor' gives maximum
668 * AMPDU size.
669 */
670 spin_lock_bh(&wl->lock);
671 brcms_c_ampdu_tx_operational(wl->wlc, tid, buf_size,
672 (1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
673 sta->ht_cap.ampdu_factor)) - 1);
674 spin_unlock_bh(&wl->lock);
675 /* Power save wakeup */
676 break;
677 default:
678 wiphy_err(wl->wiphy, "%s: Invalid command, ignoring\n",
679 __func__);
680 }
681
682 return 0;
683}
684
685static void brcms_ops_rfkill_poll(struct ieee80211_hw *hw)
686{
687 struct brcms_info *wl = hw->priv;
688 bool blocked;
689
690 spin_lock_bh(&wl->lock);
691 blocked = brcms_c_check_radio_disabled(wl->wlc);
692 spin_unlock_bh(&wl->lock);
693
694 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
695}
696
697static void brcms_ops_flush(struct ieee80211_hw *hw, bool drop)
698{
699 struct brcms_info *wl = hw->priv;
700
701 no_printk("%s: drop = %s\n", __func__, drop ? "true" : "false");
702
703 /* wait for packet queue and dma fifos to run empty */
704 spin_lock_bh(&wl->lock);
705 brcms_c_wait_for_tx_completion(wl->wlc, drop);
706 spin_unlock_bh(&wl->lock);
707}
708
709static const struct ieee80211_ops brcms_ops = {
710 .tx = brcms_ops_tx,
711 .start = brcms_ops_start,
712 .stop = brcms_ops_stop,
713 .add_interface = brcms_ops_add_interface,
714 .remove_interface = brcms_ops_remove_interface,
715 .config = brcms_ops_config,
716 .bss_info_changed = brcms_ops_bss_info_changed,
717 .configure_filter = brcms_ops_configure_filter,
718 .sw_scan_start = brcms_ops_sw_scan_start,
719 .sw_scan_complete = brcms_ops_sw_scan_complete,
720 .conf_tx = brcms_ops_conf_tx,
721 .sta_add = brcms_ops_sta_add,
722 .ampdu_action = brcms_ops_ampdu_action,
723 .rfkill_poll = brcms_ops_rfkill_poll,
724 .flush = brcms_ops_flush,
725};
726
5b435de0
AS
727void brcms_dpc(unsigned long data)
728{
729 struct brcms_info *wl;
730
731 wl = (struct brcms_info *) data;
732
733 spin_lock_bh(&wl->lock);
734
735 /* call the common second level interrupt handler */
736 if (wl->pub->up) {
737 if (wl->resched) {
738 unsigned long flags;
739
740 spin_lock_irqsave(&wl->isr_lock, flags);
741 brcms_c_intrsupd(wl->wlc);
742 spin_unlock_irqrestore(&wl->isr_lock, flags);
743 }
744
745 wl->resched = brcms_c_dpc(wl->wlc, true);
746 }
747
748 /* brcms_c_dpc() may bring the driver down */
749 if (!wl->pub->up)
750 goto done;
751
752 /* re-schedule dpc */
753 if (wl->resched)
754 tasklet_schedule(&wl->tasklet);
755 else
756 /* re-enable interrupts */
757 brcms_intrson(wl);
758
759 done:
760 spin_unlock_bh(&wl->lock);
761}
762
763/*
764 * Precondition: Since this function is called in brcms_pci_probe() context,
765 * no locking is required.
766 */
00bcda40 767static int brcms_request_fw(struct brcms_info *wl, struct bcma_device *pdev)
5b435de0
AS
768{
769 int status;
770 struct device *device = &pdev->dev;
771 char fw_name[100];
772 int i;
773
774 memset(&wl->fw, 0, sizeof(struct brcms_firmware));
775 for (i = 0; i < MAX_FW_IMAGES; i++) {
776 if (brcms_firmwares[i] == NULL)
777 break;
778 sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i],
779 UCODE_LOADER_API_VER);
780 status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
781 if (status) {
782 wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
783 KBUILD_MODNAME, fw_name);
784 return status;
785 }
786 sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i],
787 UCODE_LOADER_API_VER);
788 status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
789 if (status) {
790 wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n",
791 KBUILD_MODNAME, fw_name);
792 return status;
793 }
794 wl->fw.hdr_num_entries[i] =
795 wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr));
796 }
797 wl->fw.fw_cnt = i;
798 return brcms_ucode_data_init(wl, &wl->ucode);
799}
800
801/*
802 * Precondition: Since this function is called in brcms_pci_probe() context,
803 * no locking is required.
804 */
805static void brcms_release_fw(struct brcms_info *wl)
806{
807 int i;
808 for (i = 0; i < MAX_FW_IMAGES; i++) {
809 release_firmware(wl->fw.fw_bin[i]);
810 release_firmware(wl->fw.fw_hdr[i]);
811 }
812}
813
814/**
815 * This function frees the WL per-device resources.
816 *
817 * This function frees resources owned by the WL device pointed to
818 * by the wl parameter.
819 *
820 * precondition: can both be called locked and unlocked
821 *
822 */
823static void brcms_free(struct brcms_info *wl)
824{
825 struct brcms_timer *t, *next;
826
827 /* free ucode data */
828 if (wl->fw.fw_cnt)
829 brcms_ucode_data_free(&wl->ucode);
830 if (wl->irq)
831 free_irq(wl->irq, wl);
832
833 /* kill dpc */
834 tasklet_kill(&wl->tasklet);
835
836 if (wl->pub)
837 brcms_c_module_unregister(wl->pub, "linux", wl);
838
839 /* free common resources */
840 if (wl->wlc) {
841 brcms_c_detach(wl->wlc);
842 wl->wlc = NULL;
843 wl->pub = NULL;
844 }
845
846 /* virtual interface deletion is deferred so we cannot spinwait */
847
848 /* wait for all pending callbacks to complete */
849 while (atomic_read(&wl->callbacks) > 0)
850 schedule();
851
852 /* free timers */
853 for (t = wl->timers; t; t = next) {
854 next = t->next;
8ae74654 855#ifdef DEBUG
5b435de0
AS
856 kfree(t->name);
857#endif
858 kfree(t);
859 }
5b435de0
AS
860}
861
862/*
2646c46d 863* called from both kernel as from this kernel module (error flow on attach)
5b435de0
AS
864* precondition: perimeter lock is not acquired.
865*/
2e756560 866static void brcms_remove(struct bcma_device *pdev)
5b435de0 867{
2e756560 868 struct ieee80211_hw *hw = bcma_get_drvdata(pdev);
2646c46d 869 struct brcms_info *wl = hw->priv;
5b435de0 870
5b435de0
AS
871 if (wl->wlc) {
872 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, false);
873 wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy);
874 ieee80211_unregister_hw(hw);
5b435de0 875 }
5b435de0
AS
876
877 brcms_free(wl);
878
2e756560 879 bcma_set_drvdata(pdev, NULL);
5b435de0
AS
880 ieee80211_free_hw(hw);
881}
882
883static irqreturn_t brcms_isr(int irq, void *dev_id)
884{
885 struct brcms_info *wl;
886 bool ours, wantdpc;
887
888 wl = (struct brcms_info *) dev_id;
889
890 spin_lock(&wl->isr_lock);
891
892 /* call common first level interrupt handler */
893 ours = brcms_c_isr(wl->wlc, &wantdpc);
894 if (ours) {
895 /* if more to do... */
896 if (wantdpc) {
897
898 /* ...and call the second level interrupt handler */
899 /* schedule dpc */
900 tasklet_schedule(&wl->tasklet);
901 }
902 }
903
904 spin_unlock(&wl->isr_lock);
905
906 return IRQ_RETVAL(ours);
907}
908
909/*
910 * is called in brcms_pci_probe() context, therefore no locking required.
911 */
912static int ieee_hw_rate_init(struct ieee80211_hw *hw)
913{
914 struct brcms_info *wl = hw->priv;
915 struct brcms_c_info *wlc = wl->wlc;
916 struct ieee80211_supported_band *band;
917 int has_5g = 0;
918 u16 phy_type;
919
920 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = NULL;
921 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
922
923 phy_type = brcms_c_get_phy_type(wl->wlc, 0);
924 if (phy_type == PHY_TYPE_N || phy_type == PHY_TYPE_LCN) {
925 band = &wlc->bandstate[BAND_2G_INDEX]->band;
926 *band = brcms_band_2GHz_nphy_template;
927 if (phy_type == PHY_TYPE_LCN) {
928 /* Single stream */
929 band->ht_cap.mcs.rx_mask[1] = 0;
df4492f8 930 band->ht_cap.mcs.rx_highest = cpu_to_le16(72);
5b435de0
AS
931 }
932 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band;
933 } else {
934 return -EPERM;
935 }
936
937 /* Assume all bands use the same phy. True for 11n devices. */
938 if (wl->pub->_nbands > 1) {
939 has_5g++;
940 if (phy_type == PHY_TYPE_N || phy_type == PHY_TYPE_LCN) {
941 band = &wlc->bandstate[BAND_5G_INDEX]->band;
942 *band = brcms_band_5GHz_nphy_template;
943 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = band;
944 } else {
945 return -EPERM;
946 }
947 }
948 return 0;
949}
950
951/*
952 * is called in brcms_pci_probe() context, therefore no locking required.
953 */
954static int ieee_hw_init(struct ieee80211_hw *hw)
955{
956 hw->flags = IEEE80211_HW_SIGNAL_DBM
957 /* | IEEE80211_HW_CONNECTION_MONITOR What is this? */
958 | IEEE80211_HW_REPORTS_TX_ACK_STATUS
959 | IEEE80211_HW_AMPDU_AGGREGATION;
960
961 hw->extra_tx_headroom = brcms_c_get_header_len();
962 hw->queues = N_TX_QUEUES;
963 hw->max_rates = 2; /* Primary rate and 1 fallback rate */
964
965 /* channel change time is dependent on chip and band */
966 hw->channel_change_time = 7 * 1000;
967 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
968
969 hw->rate_control_algorithm = "minstrel_ht";
970
971 hw->sta_data_size = 0;
972 return ieee_hw_rate_init(hw);
973}
974
975/**
976 * attach to the WL device.
977 *
978 * Attach to the WL device identified by vendor and device parameters.
979 * regs is a host accessible memory address pointing to WL device registers.
980 *
981 * brcms_attach is not defined as static because in the case where no bus
982 * is defined, wl_attach will never be called, and thus, gcc will issue
983 * a warning that this function is defined but not used if we declare
984 * it as static.
985 *
986 *
2e756560 987 * is called in brcms_bcma_probe() context, therefore no locking required.
5b435de0 988 */
2e756560 989static struct brcms_info *brcms_attach(struct bcma_device *pdev)
5b435de0
AS
990{
991 struct brcms_info *wl = NULL;
992 int unit, err;
993 struct ieee80211_hw *hw;
994 u8 perm[ETH_ALEN];
995
996 unit = n_adapters_found;
997 err = 0;
998
999 if (unit < 0)
1000 return NULL;
1001
1002 /* allocate private info */
2e756560 1003 hw = bcma_get_drvdata(pdev);
5b435de0
AS
1004 if (hw != NULL)
1005 wl = hw->priv;
1006 if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL))
1007 return NULL;
1008 wl->wiphy = hw->wiphy;
1009
1010 atomic_set(&wl->callbacks, 0);
1011
1012 /* setup the bottom half handler */
1013 tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl);
1014
5b435de0
AS
1015 spin_lock_init(&wl->lock);
1016 spin_lock_init(&wl->isr_lock);
1017
1018 /* prepare ucode */
00bcda40 1019 if (brcms_request_fw(wl, pdev) < 0) {
5b435de0
AS
1020 wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in "
1021 "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm");
1022 brcms_release_fw(wl);
2e756560 1023 brcms_remove(pdev);
5b435de0
AS
1024 return NULL;
1025 }
1026
1027 /* common load-time initialization */
b63337a0 1028 wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err);
5b435de0
AS
1029 brcms_release_fw(wl);
1030 if (!wl->wlc) {
1031 wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n",
1032 KBUILD_MODNAME, err);
1033 goto fail;
1034 }
1035 wl->pub = brcms_c_pub(wl->wlc);
1036
1037 wl->pub->ieee_hw = hw;
1038
5b435de0 1039 /* register our interrupt handler */
00bcda40 1040 if (request_irq(pdev->irq, brcms_isr,
2e756560 1041 IRQF_SHARED, KBUILD_MODNAME, wl)) {
5b435de0
AS
1042 wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
1043 goto fail;
1044 }
00bcda40 1045 wl->irq = pdev->irq;
5b435de0
AS
1046
1047 /* register module */
1048 brcms_c_module_register(wl->pub, "linux", wl, NULL);
1049
1050 if (ieee_hw_init(hw)) {
1051 wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit,
1052 __func__);
1053 goto fail;
1054 }
1055
cf03c5da
SF
1056 brcms_c_regd_init(wl->wlc);
1057
5b435de0
AS
1058 memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN);
1059 if (WARN_ON(!is_valid_ether_addr(perm)))
1060 goto fail;
1061 SET_IEEE80211_PERM_ADDR(hw, perm);
1062
1063 err = ieee80211_register_hw(hw);
1064 if (err)
1065 wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status"
1066 "%d\n", __func__, err);
1067
d597ee7e
AS
1068 if (wl->pub->srom_ccode[0] &&
1069 regulatory_hint(wl->wiphy, wl->pub->srom_ccode))
1070 wiphy_err(wl->wiphy, "%s: regulatory hint failed\n", __func__);
5b435de0
AS
1071
1072 n_adapters_found++;
1073 return wl;
1074
1075fail:
1076 brcms_free(wl);
1077 return NULL;
1078}
1079
1080
1081
1082/**
1083 * determines if a device is a WL device, and if so, attaches it.
1084 *
1085 * This function determines if a device pointed to by pdev is a WL device,
1086 * and if so, performs a brcms_attach() on it.
1087 *
1088 * Perimeter lock is initialized in the course of this function.
1089 */
2e756560 1090static int __devinit brcms_bcma_probe(struct bcma_device *pdev)
5b435de0 1091{
5b435de0
AS
1092 struct brcms_info *wl;
1093 struct ieee80211_hw *hw;
5b435de0 1094
2e756560
AS
1095 dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n",
1096 pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class,
00bcda40 1097 pdev->irq);
5b435de0 1098
2e756560
AS
1099 if ((pdev->id.manuf != BCMA_MANUF_BCM) ||
1100 (pdev->id.id != BCMA_CORE_80211))
5b435de0 1101 return -ENODEV;
5b435de0
AS
1102
1103 hw = ieee80211_alloc_hw(sizeof(struct brcms_info), &brcms_ops);
1104 if (!hw) {
1105 pr_err("%s: ieee80211_alloc_hw failed\n", __func__);
1106 return -ENOMEM;
1107 }
1108
1109 SET_IEEE80211_DEV(hw, &pdev->dev);
1110
2e756560 1111 bcma_set_drvdata(pdev, hw);
5b435de0
AS
1112
1113 memset(hw->priv, 0, sizeof(*wl));
1114
2e756560 1115 wl = brcms_attach(pdev);
5b435de0 1116 if (!wl) {
02f77195 1117 pr_err("%s: brcms_attach failed!\n", __func__);
5b435de0
AS
1118 return -ENODEV;
1119 }
1120 return 0;
1121}
1122
7d5869e7 1123static int brcms_suspend(struct bcma_device *pdev)
5b435de0
AS
1124{
1125 struct brcms_info *wl;
1126 struct ieee80211_hw *hw;
1127
2e756560 1128 hw = bcma_get_drvdata(pdev);
5b435de0
AS
1129 wl = hw->priv;
1130 if (!wl) {
137dabed
AS
1131 pr_err("%s: %s: no driver private struct!\n", KBUILD_MODNAME,
1132 __func__);
5b435de0
AS
1133 return -ENODEV;
1134 }
1135
1136 /* only need to flag hw is down for proper resume */
1137 spin_lock_bh(&wl->lock);
1138 wl->pub->hw_up = false;
1139 spin_unlock_bh(&wl->lock);
1140
7e9e7fa4 1141 pr_debug("brcms_suspend ok\n");
5b435de0 1142
2e756560
AS
1143 return 0;
1144}
1145
1146static int brcms_resume(struct bcma_device *pdev)
1147{
7e9e7fa4
LT
1148 pr_debug("brcms_resume ok\n");
1149 return 0;
5b435de0
AS
1150}
1151
2e756560 1152static struct bcma_driver brcms_bcma_driver = {
5b435de0 1153 .name = KBUILD_MODNAME,
2e756560 1154 .probe = brcms_bcma_probe,
5b435de0
AS
1155 .suspend = brcms_suspend,
1156 .resume = brcms_resume,
1157 .remove = __devexit_p(brcms_remove),
2e756560 1158 .id_table = brcms_coreid_table,
5b435de0
AS
1159};
1160
1161/**
2e756560 1162 * This is the main entry point for the brcmsmac driver.
5b435de0 1163 *
b0c359b2
AS
1164 * This function is scheduled upon module initialization and
1165 * does the driver registration, which result in brcms_bcma_probe()
1166 * call resulting in the driver bringup.
5b435de0 1167 */
b0c359b2 1168static void brcms_driver_init(struct work_struct *work)
5b435de0 1169{
b0c359b2
AS
1170 int error;
1171
1172 error = bcma_driver_register(&brcms_bcma_driver);
1173 if (error)
1174 pr_err("%s: register returned %d\n", __func__, error);
1175}
1176
1177static DECLARE_WORK(brcms_driver_work, brcms_driver_init);
5b435de0 1178
b0c359b2
AS
1179static int __init brcms_module_init(void)
1180{
8ae74654 1181#ifdef DEBUG
5b435de0
AS
1182 if (msglevel != 0xdeadbeef)
1183 brcm_msg_level = msglevel;
b0c359b2
AS
1184#endif
1185 if (!schedule_work(&brcms_driver_work))
1186 return -EBUSY;
5b435de0 1187
b0c359b2 1188 return 0;
5b435de0
AS
1189}
1190
1191/**
2e756560 1192 * This function unloads the brcmsmac driver from the system.
5b435de0 1193 *
2e756560 1194 * This function unconditionally unloads the brcmsmac driver module from the
5b435de0
AS
1195 * system.
1196 *
1197 */
1198static void __exit brcms_module_exit(void)
1199{
b0c359b2 1200 cancel_work_sync(&brcms_driver_work);
2e756560 1201 bcma_driver_unregister(&brcms_bcma_driver);
5b435de0
AS
1202}
1203
1204module_init(brcms_module_init);
1205module_exit(brcms_module_exit);
1206
1207/*
1208 * precondition: perimeter lock has been acquired
1209 */
1210void brcms_txflowcontrol(struct brcms_info *wl, struct brcms_if *wlif,
1211 bool state, int prio)
1212{
1213 wiphy_err(wl->wiphy, "Shouldn't be here %s\n", __func__);
1214}
1215
1216/*
1217 * precondition: perimeter lock has been acquired
1218 */
1219void brcms_init(struct brcms_info *wl)
1220{
1221 BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit);
1222 brcms_reset(wl);
dc460127 1223 brcms_c_init(wl->wlc, wl->mute_tx);
5b435de0
AS
1224}
1225
1226/*
1227 * precondition: perimeter lock has been acquired
1228 */
1229uint brcms_reset(struct brcms_info *wl)
1230{
1231 BCMMSG(wl->pub->ieee_hw->wiphy, "wl%d\n", wl->pub->unit);
1232 brcms_c_reset(wl->wlc);
1233
1234 /* dpc will not be rescheduled */
3db1cd5c 1235 wl->resched = false;
5b435de0
AS
1236
1237 return 0;
1238}
1239
c261bdf8
RV
1240void brcms_fatal_error(struct brcms_info *wl)
1241{
1242 wiphy_err(wl->wlc->wiphy, "wl%d: fatal error, reinitializing\n",
1243 wl->wlc->pub->unit);
1244 brcms_reset(wl);
1245 ieee80211_restart_hw(wl->pub->ieee_hw);
1246}
1247
5b435de0
AS
1248/*
1249 * These are interrupt on/off entry points. Disable interrupts
1250 * during interrupt state transition.
1251 */
1252void brcms_intrson(struct brcms_info *wl)
1253{
1254 unsigned long flags;
1255
1256 spin_lock_irqsave(&wl->isr_lock, flags);
1257 brcms_c_intrson(wl->wlc);
1258 spin_unlock_irqrestore(&wl->isr_lock, flags);
1259}
1260
1261u32 brcms_intrsoff(struct brcms_info *wl)
1262{
1263 unsigned long flags;
1264 u32 status;
1265
1266 spin_lock_irqsave(&wl->isr_lock, flags);
1267 status = brcms_c_intrsoff(wl->wlc);
1268 spin_unlock_irqrestore(&wl->isr_lock, flags);
1269 return status;
1270}
1271
1272void brcms_intrsrestore(struct brcms_info *wl, u32 macintmask)
1273{
1274 unsigned long flags;
1275
1276 spin_lock_irqsave(&wl->isr_lock, flags);
1277 brcms_c_intrsrestore(wl->wlc, macintmask);
1278 spin_unlock_irqrestore(&wl->isr_lock, flags);
1279}
1280
1281/*
1282 * precondition: perimeter lock has been acquired
1283 */
1284int brcms_up(struct brcms_info *wl)
1285{
1286 int error = 0;
1287
1288 if (wl->pub->up)
1289 return 0;
1290
1291 error = brcms_c_up(wl->wlc);
1292
1293 return error;
1294}
1295
1296/*
1297 * precondition: perimeter lock has been acquired
1298 */
1299void brcms_down(struct brcms_info *wl)
1300{
1301 uint callbacks, ret_val = 0;
1302
1303 /* call common down function */
1304 ret_val = brcms_c_down(wl->wlc);
1305 callbacks = atomic_read(&wl->callbacks) - ret_val;
1306
1307 /* wait for down callbacks to complete */
1308 spin_unlock_bh(&wl->lock);
1309
1310 /* For HIGH_only driver, it's important to actually schedule other work,
1311 * not just spin wait since everything runs at schedule level
1312 */
1313 SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
1314
1315 spin_lock_bh(&wl->lock);
1316}
1317
1318/*
1319* precondition: perimeter lock is not acquired
1320 */
2a7fc5b1 1321static void _brcms_timer(struct work_struct *work)
5b435de0 1322{
2a7fc5b1
RV
1323 struct brcms_timer *t = container_of(work, struct brcms_timer,
1324 dly_wrk.work);
1325
5b435de0
AS
1326 spin_lock_bh(&t->wl->lock);
1327
1328 if (t->set) {
1329 if (t->periodic) {
5b435de0 1330 atomic_inc(&t->wl->callbacks);
2a7fc5b1
RV
1331 ieee80211_queue_delayed_work(t->wl->pub->ieee_hw,
1332 &t->dly_wrk,
1333 msecs_to_jiffies(t->ms));
1334 } else {
5b435de0 1335 t->set = false;
2a7fc5b1 1336 }
5b435de0
AS
1337
1338 t->fn(t->arg);
1339 }
1340
1341 atomic_dec(&t->wl->callbacks);
1342
1343 spin_unlock_bh(&t->wl->lock);
1344}
1345
5b435de0
AS
1346/*
1347 * Adds a timer to the list. Caller supplies a timer function.
1348 * Is called from wlc.
1349 *
1350 * precondition: perimeter lock has been acquired
1351 */
1352struct brcms_timer *brcms_init_timer(struct brcms_info *wl,
1353 void (*fn) (void *arg),
1354 void *arg, const char *name)
1355{
1356 struct brcms_timer *t;
1357
1358 t = kzalloc(sizeof(struct brcms_timer), GFP_ATOMIC);
1359 if (!t)
1360 return NULL;
1361
2a7fc5b1 1362 INIT_DELAYED_WORK(&t->dly_wrk, _brcms_timer);
5b435de0
AS
1363 t->wl = wl;
1364 t->fn = fn;
1365 t->arg = arg;
1366 t->next = wl->timers;
1367 wl->timers = t;
1368
8ae74654 1369#ifdef DEBUG
5b435de0
AS
1370 t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC);
1371 if (t->name)
1372 strcpy(t->name, name);
1373#endif
1374
1375 return t;
1376}
1377
1378/*
1379 * adds only the kernel timer since it's going to be more accurate
1380 * as well as it's easier to make it periodic
1381 *
1382 * precondition: perimeter lock has been acquired
1383 */
2a7fc5b1 1384void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
5b435de0 1385{
2a7fc5b1
RV
1386 struct ieee80211_hw *hw = t->wl->pub->ieee_hw;
1387
8ae74654 1388#ifdef DEBUG
5b435de0 1389 if (t->set)
2a7fc5b1 1390 wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n",
5b435de0 1391 __func__, t->name, periodic);
5b435de0
AS
1392#endif
1393 t->ms = ms;
1394 t->periodic = (bool) periodic;
1395 t->set = true;
5b435de0 1396
be69c4ef 1397 atomic_inc(&t->wl->callbacks);
2a7fc5b1
RV
1398
1399 ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
5b435de0
AS
1400}
1401
1402/*
1403 * return true if timer successfully deleted, false if still pending
1404 *
1405 * precondition: perimeter lock has been acquired
1406 */
be69c4ef 1407bool brcms_del_timer(struct brcms_timer *t)
5b435de0
AS
1408{
1409 if (t->set) {
1410 t->set = false;
2a7fc5b1 1411 if (!cancel_delayed_work(&t->dly_wrk))
5b435de0
AS
1412 return false;
1413
be69c4ef 1414 atomic_dec(&t->wl->callbacks);
5b435de0
AS
1415 }
1416
1417 return true;
1418}
1419
1420/*
1421 * precondition: perimeter lock has been acquired
1422 */
be69c4ef 1423void brcms_free_timer(struct brcms_timer *t)
5b435de0 1424{
be69c4ef 1425 struct brcms_info *wl = t->wl;
5b435de0
AS
1426 struct brcms_timer *tmp;
1427
1428 /* delete the timer in case it is active */
be69c4ef 1429 brcms_del_timer(t);
5b435de0
AS
1430
1431 if (wl->timers == t) {
1432 wl->timers = wl->timers->next;
8ae74654 1433#ifdef DEBUG
5b435de0
AS
1434 kfree(t->name);
1435#endif
1436 kfree(t);
1437 return;
1438
1439 }
1440
1441 tmp = wl->timers;
1442 while (tmp) {
1443 if (tmp->next == t) {
1444 tmp->next = t->next;
8ae74654 1445#ifdef DEBUG
5b435de0
AS
1446 kfree(t->name);
1447#endif
1448 kfree(t);
1449 return;
1450 }
1451 tmp = tmp->next;
1452 }
1453
1454}
1455
1456/*
1457 * precondition: perimeter lock has been acquired
1458 */
1459int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx)
1460{
1461 int i, entry;
1462 const u8 *pdata;
1463 struct firmware_hdr *hdr;
1464 for (i = 0; i < wl->fw.fw_cnt; i++) {
1465 hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data;
1466 for (entry = 0; entry < wl->fw.hdr_num_entries[i];
1467 entry++, hdr++) {
1468 u32 len = le32_to_cpu(hdr->len);
1469 if (le32_to_cpu(hdr->idx) == idx) {
1470 pdata = wl->fw.fw_bin[i]->data +
1471 le32_to_cpu(hdr->offset);
1f1d5289 1472 *pbuf = kmemdup(pdata, len, GFP_ATOMIC);
5b435de0
AS
1473 if (*pbuf == NULL)
1474 goto fail;
1475
5b435de0
AS
1476 return 0;
1477 }
1478 }
1479 }
1480 wiphy_err(wl->wiphy, "ERROR: ucode buf tag:%d can not be found!\n",
1481 idx);
1482 *pbuf = NULL;
1483fail:
1484 return -ENODATA;
1485}
1486
1487/*
2e756560 1488 * Precondition: Since this function is called in brcms_bcma_probe() context,
5b435de0
AS
1489 * no locking is required.
1490 */
1491int brcms_ucode_init_uint(struct brcms_info *wl, size_t *n_bytes, u32 idx)
1492{
1493 int i, entry;
1494 const u8 *pdata;
1495 struct firmware_hdr *hdr;
1496 for (i = 0; i < wl->fw.fw_cnt; i++) {
1497 hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data;
1498 for (entry = 0; entry < wl->fw.hdr_num_entries[i];
1499 entry++, hdr++) {
1500 if (le32_to_cpu(hdr->idx) == idx) {
1501 pdata = wl->fw.fw_bin[i]->data +
1502 le32_to_cpu(hdr->offset);
1503 if (le32_to_cpu(hdr->len) != 4) {
1504 wiphy_err(wl->wiphy,
1505 "ERROR: fw hdr len\n");
1506 return -ENOMSG;
1507 }
1508 *n_bytes = le32_to_cpu(*((__le32 *) pdata));
1509 return 0;
1510 }
1511 }
1512 }
1513 wiphy_err(wl->wiphy, "ERROR: ucode tag:%d can not be found!\n", idx);
1514 return -ENOMSG;
1515}
1516
1517/*
1518 * precondition: can both be called locked and unlocked
1519 */
1520void brcms_ucode_free_buf(void *p)
1521{
1522 kfree(p);
1523}
1524
1525/*
1526 * checks validity of all firmware images loaded from user space
1527 *
2e756560 1528 * Precondition: Since this function is called in brcms_bcma_probe() context,
5b435de0
AS
1529 * no locking is required.
1530 */
1531int brcms_check_firmwares(struct brcms_info *wl)
1532{
1533 int i;
1534 int entry;
1535 int rc = 0;
1536 const struct firmware *fw;
1537 const struct firmware *fw_hdr;
1538 struct firmware_hdr *ucode_hdr;
1539 for (i = 0; i < MAX_FW_IMAGES && rc == 0; i++) {
1540 fw = wl->fw.fw_bin[i];
1541 fw_hdr = wl->fw.fw_hdr[i];
1542 if (fw == NULL && fw_hdr == NULL) {
1543 break;
1544 } else if (fw == NULL || fw_hdr == NULL) {
1545 wiphy_err(wl->wiphy, "%s: invalid bin/hdr fw\n",
1546 __func__);
1547 rc = -EBADF;
1548 } else if (fw_hdr->size % sizeof(struct firmware_hdr)) {
1549 wiphy_err(wl->wiphy, "%s: non integral fw hdr file "
1550 "size %zu/%zu\n", __func__, fw_hdr->size,
1551 sizeof(struct firmware_hdr));
1552 rc = -EBADF;
1553 } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) {
1554 wiphy_err(wl->wiphy, "%s: out of bounds fw file size "
1555 "%zu\n", __func__, fw->size);
1556 rc = -EBADF;
1557 } else {
1558 /* check if ucode section overruns firmware image */
1559 ucode_hdr = (struct firmware_hdr *)fw_hdr->data;
1560 for (entry = 0; entry < wl->fw.hdr_num_entries[i] &&
1561 !rc; entry++, ucode_hdr++) {
1562 if (le32_to_cpu(ucode_hdr->offset) +
1563 le32_to_cpu(ucode_hdr->len) >
1564 fw->size) {
1565 wiphy_err(wl->wiphy,
1566 "%s: conflicting bin/hdr\n",
1567 __func__);
1568 rc = -EBADF;
1569 }
1570 }
1571 }
1572 }
1573 if (rc == 0 && wl->fw.fw_cnt != i) {
1574 wiphy_err(wl->wiphy, "%s: invalid fw_cnt=%d\n", __func__,
1575 wl->fw.fw_cnt);
1576 rc = -EBADF;
1577 }
1578 return rc;
1579}
1580
1581/*
1582 * precondition: perimeter lock has been acquired
1583 */
1584bool brcms_rfkill_set_hw_state(struct brcms_info *wl)
1585{
1586 bool blocked = brcms_c_check_radio_disabled(wl->wlc);
1587
1588 spin_unlock_bh(&wl->lock);
1589 wiphy_rfkill_set_hw_state(wl->pub->ieee_hw->wiphy, blocked);
1590 if (blocked)
1591 wiphy_rfkill_start_polling(wl->pub->ieee_hw->wiphy);
1592 spin_lock_bh(&wl->lock);
1593 return blocked;
1594}
1595
1596/*
1597 * precondition: perimeter lock has been acquired
1598 */
1599void brcms_msleep(struct brcms_info *wl, uint ms)
1600{
1601 spin_unlock_bh(&wl->lock);
1602 msleep(ms);
1603 spin_lock_bh(&wl->lock);
1604}
This page took 0.172409 seconds and 5 git commands to generate.