2 * Copyright (c) 2010 Broadcom Corporation
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.
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.
17 #define __UNDEF_NO_VERSION__
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>
29 #include <proto/802.11.h>
38 #include "phy/wlc_phy_int.h"
40 #include "wlc_types.h"
42 #include "phy/phy_version.h"
44 #include "wlc_channel.h"
48 #include "wl_export.h"
50 #include "wl_mac80211.h"
52 #define N_TX_QUEUES 4 /* #tx queues on mac80211<->driver interface */
54 static void wl_timer(unsigned long data
);
55 static void _wl_timer(struct wl_timer
*t
);
58 static int ieee_hw_init(struct ieee80211_hw
*hw
);
59 static int ieee_hw_rate_init(struct ieee80211_hw
*hw
);
61 static int wl_linux_watchdog(void *ctx
);
63 /* Flags we support */
64 #define MAC_FILTERS (FIF_PROMISC_IN_BSS | \
70 FIF_BCN_PRBRESP_PROMISC)
74 #define WL_DEV_IF(dev) ((struct wl_if *)netdev_priv(dev))
75 #define WL_INFO(dev) ((struct wl_info *)(WL_DEV_IF(dev)->wl))
76 static int wl_request_fw(struct wl_info
*wl
, struct pci_dev
*pdev
);
77 static void wl_release_fw(struct wl_info
*wl
);
79 /* local prototypes */
80 static void wl_dpc(unsigned long data
);
81 static irqreturn_t
wl_isr(int irq
, void *dev_id
);
83 static int __devinit
wl_pci_probe(struct pci_dev
*pdev
,
84 const struct pci_device_id
*ent
);
85 static void wl_remove(struct pci_dev
*pdev
);
86 static void wl_free(struct wl_info
*wl
);
87 static void wl_set_basic_rate(struct wl_rateset
*rs
, u16 rate
, bool is_br
);
89 MODULE_AUTHOR("Broadcom Corporation");
90 MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
91 MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
92 MODULE_LICENSE("Dual BSD/GPL");
94 /* recognized PCI IDs */
95 static struct pci_device_id wl_id_table
[] = {
96 {PCI_VENDOR_ID_BROADCOM
, 0x4357, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, /* 43225 2G */
97 {PCI_VENDOR_ID_BROADCOM
, 0x4353, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, /* 43224 DUAL */
98 {PCI_VENDOR_ID_BROADCOM
, 0x4727, PCI_ANY_ID
, PCI_ANY_ID
, 0, 0, 0}, /* 4313 DUAL */
102 MODULE_DEVICE_TABLE(pci
, wl_id_table
);
105 static int msglevel
= 0xdeadbeef;
106 module_param(msglevel
, int, 0);
107 static int phymsglevel
= 0xdeadbeef;
108 module_param(phymsglevel
, int, 0);
111 #define HW_TO_WL(hw) (hw->priv)
112 #define WL_TO_HW(wl) (wl->pub->ieee_hw)
114 /* MAC80211 callback functions */
115 static int wl_ops_start(struct ieee80211_hw
*hw
);
116 static void wl_ops_stop(struct ieee80211_hw
*hw
);
117 static int wl_ops_add_interface(struct ieee80211_hw
*hw
,
118 struct ieee80211_vif
*vif
);
119 static void wl_ops_remove_interface(struct ieee80211_hw
*hw
,
120 struct ieee80211_vif
*vif
);
121 static int wl_ops_config(struct ieee80211_hw
*hw
, u32 changed
);
122 static void wl_ops_bss_info_changed(struct ieee80211_hw
*hw
,
123 struct ieee80211_vif
*vif
,
124 struct ieee80211_bss_conf
*info
,
126 static void wl_ops_configure_filter(struct ieee80211_hw
*hw
,
127 unsigned int changed_flags
,
128 unsigned int *total_flags
, u64 multicast
);
129 static int wl_ops_set_tim(struct ieee80211_hw
*hw
, struct ieee80211_sta
*sta
,
131 static void wl_ops_sw_scan_start(struct ieee80211_hw
*hw
);
132 static void wl_ops_sw_scan_complete(struct ieee80211_hw
*hw
);
133 static void wl_ops_set_tsf(struct ieee80211_hw
*hw
, u64 tsf
);
134 static int wl_ops_get_stats(struct ieee80211_hw
*hw
,
135 struct ieee80211_low_level_stats
*stats
);
136 static void wl_ops_sta_notify(struct ieee80211_hw
*hw
,
137 struct ieee80211_vif
*vif
,
138 enum sta_notify_cmd cmd
,
139 struct ieee80211_sta
*sta
);
140 static int wl_ops_conf_tx(struct ieee80211_hw
*hw
, u16 queue
,
141 const struct ieee80211_tx_queue_params
*params
);
142 static u64
wl_ops_get_tsf(struct ieee80211_hw
*hw
);
143 static int wl_ops_sta_add(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
144 struct ieee80211_sta
*sta
);
145 static int wl_ops_sta_remove(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
146 struct ieee80211_sta
*sta
);
147 static int wl_ops_ampdu_action(struct ieee80211_hw
*hw
,
148 struct ieee80211_vif
*vif
,
149 enum ieee80211_ampdu_mlme_action action
,
150 struct ieee80211_sta
*sta
, u16 tid
, u16
*ssn
,
152 static void wl_ops_rfkill_poll(struct ieee80211_hw
*hw
);
153 static void wl_ops_flush(struct ieee80211_hw
*hw
, bool drop
);
155 static void wl_ops_tx(struct ieee80211_hw
*hw
, struct sk_buff
*skb
)
157 struct wl_info
*wl
= hw
->priv
;
161 wiphy_err(wl
->wiphy
, "ops->tx called while down\n");
165 wlc_sendpkt_mac80211(wl
->wlc
, skb
, hw
);
170 static int wl_ops_start(struct ieee80211_hw
*hw
)
172 struct wl_info
*wl
= hw
->priv
;
175 struct ieee80211_channel *curchan = hw->conf.channel;
178 ieee80211_wake_queues(hw
);
180 blocked
= wl_rfkill_set_hw_state(wl
);
183 wiphy_rfkill_stop_polling(wl
->pub
->ieee_hw
->wiphy
);
188 static void wl_ops_stop(struct ieee80211_hw
*hw
)
190 ieee80211_stop_queues(hw
);
194 wl_ops_add_interface(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
)
199 /* Just STA for now */
200 if (vif
->type
!= NL80211_IFTYPE_AP
&&
201 vif
->type
!= NL80211_IFTYPE_MESH_POINT
&&
202 vif
->type
!= NL80211_IFTYPE_STATION
&&
203 vif
->type
!= NL80211_IFTYPE_WDS
&&
204 vif
->type
!= NL80211_IFTYPE_ADHOC
) {
205 wiphy_err(hw
->wiphy
, "%s: Attempt to add type %d, only"
206 " STA for now\n", __func__
, vif
->type
);
216 wiphy_err(hw
->wiphy
, "%s: wl_up() returned %d\n", __func__
,
223 wl_ops_remove_interface(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
)
229 /* put driver in down state */
236 * precondition: perimeter lock has been acquired
239 ieee_set_channel(struct ieee80211_hw
*hw
, struct ieee80211_channel
*chan
,
240 enum nl80211_channel_type type
)
242 struct wl_info
*wl
= HW_TO_WL(hw
);
246 case NL80211_CHAN_HT20
:
247 case NL80211_CHAN_NO_HT
:
248 err
= wlc_set(wl
->wlc
, WLC_SET_CHANNEL
, chan
->hw_value
);
250 case NL80211_CHAN_HT40MINUS
:
251 case NL80211_CHAN_HT40PLUS
:
253 "%s: Need to implement 40 Mhz Channels!\n", __func__
);
263 static int wl_ops_config(struct ieee80211_hw
*hw
, u32 changed
)
265 struct ieee80211_conf
*conf
= &hw
->conf
;
266 struct wl_info
*wl
= HW_TO_WL(hw
);
269 struct wiphy
*wiphy
= hw
->wiphy
;
272 if (changed
& IEEE80211_CONF_CHANGE_LISTEN_INTERVAL
) {
274 (wl
->wlc
, "bcn_li_bcn", conf
->listen_interval
)) {
275 wiphy_err(wiphy
, "%s: Error setting listen_interval\n",
280 wlc_iovar_getint(wl
->wlc
, "bcn_li_bcn", &new_int
);
282 if (changed
& IEEE80211_CONF_CHANGE_MONITOR
)
283 wiphy_err(wiphy
, "%s: change monitor mode: %s (implement)\n",
284 __func__
, conf
->flags
& IEEE80211_CONF_MONITOR
?
286 if (changed
& IEEE80211_CONF_CHANGE_PS
)
287 wiphy_err(wiphy
, "%s: change power-save mode: %s (implement)\n",
288 __func__
, conf
->flags
& IEEE80211_CONF_PS
?
291 if (changed
& IEEE80211_CONF_CHANGE_POWER
) {
293 (wl
->wlc
, "qtxpower", conf
->power_level
* 4)) {
294 wiphy_err(wiphy
, "%s: Error setting power_level\n",
299 wlc_iovar_getint(wl
->wlc
, "qtxpower", &new_int
);
300 if (new_int
!= (conf
->power_level
* 4))
301 wiphy_err(wiphy
, "%s: Power level req != actual, %d %d"
302 "\n", __func__
, conf
->power_level
* 4,
305 if (changed
& IEEE80211_CONF_CHANGE_CHANNEL
) {
306 err
= ieee_set_channel(hw
, conf
->channel
, conf
->channel_type
);
308 if (changed
& IEEE80211_CONF_CHANGE_RETRY_LIMITS
) {
310 (wl
->wlc
, WLC_SET_SRL
,
311 conf
->short_frame_max_tx_count
) < 0) {
312 wiphy_err(wiphy
, "%s: Error setting srl\n", __func__
);
316 if (wlc_set(wl
->wlc
, WLC_SET_LRL
, conf
->long_frame_max_tx_count
)
318 wiphy_err(wiphy
, "%s: Error setting lrl\n", __func__
);
330 wl_ops_bss_info_changed(struct ieee80211_hw
*hw
,
331 struct ieee80211_vif
*vif
,
332 struct ieee80211_bss_conf
*info
, u32 changed
)
334 struct wl_info
*wl
= HW_TO_WL(hw
);
335 struct wiphy
*wiphy
= hw
->wiphy
;
338 if (changed
& BSS_CHANGED_ASSOC
) {
339 /* association status changed (associated/disassociated)
340 * also implies a change in the AID.
342 wiphy_err(wiphy
, "%s: %s: %sassociated\n", KBUILD_MODNAME
,
343 __func__
, info
->assoc
? "" : "dis");
345 wlc_associate_upd(wl
->wlc
, info
->assoc
);
348 if (changed
& BSS_CHANGED_ERP_SLOT
) {
349 /* slot timing changed */
350 if (info
->use_short_slot
)
355 wlc_set(wl
->wlc
, WLC_SET_SHORTSLOT_OVERRIDE
, val
);
359 if (changed
& BSS_CHANGED_HT
) {
360 /* 802.11n parameters changed */
361 u16 mode
= info
->ht_operation_mode
;
364 wlc_protection_upd(wl
->wlc
, WLC_PROT_N_CFG
,
365 mode
& IEEE80211_HT_OP_MODE_PROTECTION
);
366 wlc_protection_upd(wl
->wlc
, WLC_PROT_N_NONGF
,
367 mode
& IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT
);
368 wlc_protection_upd(wl
->wlc
, WLC_PROT_N_OBSS
,
369 mode
& IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT
);
372 if (changed
& BSS_CHANGED_BASIC_RATES
) {
373 struct ieee80211_supported_band
*bi
;
376 struct wl_rateset rs
;
379 /* retrieve the current rates */
381 error
= wlc_ioctl(wl
->wlc
, WLC_GET_CURR_RATESET
,
382 &rs
, sizeof(rs
), NULL
);
385 wiphy_err(wiphy
, "%s: retrieve rateset failed: %d\n",
389 br_mask
= info
->basic_rates
;
390 bi
= hw
->wiphy
->bands
[wlc_get_curband(wl
->wlc
)];
391 for (i
= 0; i
< bi
->n_bitrates
; i
++) {
392 /* convert to internal rate value */
393 rate
= (bi
->bitrates
[i
].bitrate
<< 1) / 10;
395 /* set/clear basic rate flag */
396 wl_set_basic_rate(&rs
, rate
, br_mask
& 1);
400 /* update the rate set */
402 wlc_ioctl(wl
->wlc
, WLC_SET_RATESET
, &rs
, sizeof(rs
), NULL
);
405 if (changed
& BSS_CHANGED_BEACON_INT
) {
406 /* Beacon interval changed */
408 wlc_set(wl
->wlc
, WLC_SET_BCNPRD
, info
->beacon_int
);
411 if (changed
& BSS_CHANGED_BSSID
) {
412 /* BSSID changed, for whatever reason (IBSS and managed mode) */
414 wlc_set_addrmatch(wl
->wlc
, RCM_BSSID_OFFSET
,
418 if (changed
& BSS_CHANGED_BEACON
) {
419 /* Beacon data changed, retrieve new beacon (beaconing modes) */
420 wiphy_err(wiphy
, "%s: beacon changed\n", __func__
);
422 if (changed
& BSS_CHANGED_BEACON_ENABLED
) {
423 /* Beaconing should be enabled/disabled (beaconing modes) */
424 wiphy_err(wiphy
, "%s: Beacon enabled: %s\n", __func__
,
425 info
->enable_beacon
? "true" : "false");
427 if (changed
& BSS_CHANGED_CQM
) {
428 /* Connection quality monitor config changed */
429 wiphy_err(wiphy
, "%s: cqm change: threshold %d, hys %d "
430 " (implement)\n", __func__
, info
->cqm_rssi_thold
,
431 info
->cqm_rssi_hyst
);
433 if (changed
& BSS_CHANGED_IBSS
) {
434 /* IBSS join status changed */
435 wiphy_err(wiphy
, "%s: IBSS joined: %s (implement)\n", __func__
,
436 info
->ibss_joined
? "true" : "false");
438 if (changed
& BSS_CHANGED_ARP_FILTER
) {
439 /* Hardware ARP filter address list or state changed */
440 wiphy_err(wiphy
, "%s: arp filtering: enabled %s, count %d"
441 " (implement)\n", __func__
, info
->arp_filter_enabled
?
442 "true" : "false", info
->arp_addr_cnt
);
444 if (changed
& BSS_CHANGED_QOS
) {
446 * QoS for this association was enabled/disabled.
447 * Note that it is only ever disabled for station mode.
449 wiphy_err(wiphy
, "%s: qos enabled: %s (implement)\n", __func__
,
450 info
->qos
? "true" : "false");
452 if (changed
& BSS_CHANGED_IDLE
) {
453 /* Idle changed for this BSS/interface */
454 wiphy_err(wiphy
, "%s: BSS idle: %s (implement)\n", __func__
,
455 info
->idle
? "true" : "false");
461 wl_ops_configure_filter(struct ieee80211_hw
*hw
,
462 unsigned int changed_flags
,
463 unsigned int *total_flags
, u64 multicast
)
465 struct wl_info
*wl
= hw
->priv
;
466 struct wiphy
*wiphy
= hw
->wiphy
;
468 changed_flags
&= MAC_FILTERS
;
469 *total_flags
&= MAC_FILTERS
;
470 if (changed_flags
& FIF_PROMISC_IN_BSS
)
471 wiphy_err(wiphy
, "FIF_PROMISC_IN_BSS\n");
472 if (changed_flags
& FIF_ALLMULTI
)
473 wiphy_err(wiphy
, "FIF_ALLMULTI\n");
474 if (changed_flags
& FIF_FCSFAIL
)
475 wiphy_err(wiphy
, "FIF_FCSFAIL\n");
476 if (changed_flags
& FIF_PLCPFAIL
)
477 wiphy_err(wiphy
, "FIF_PLCPFAIL\n");
478 if (changed_flags
& FIF_CONTROL
)
479 wiphy_err(wiphy
, "FIF_CONTROL\n");
480 if (changed_flags
& FIF_OTHER_BSS
)
481 wiphy_err(wiphy
, "FIF_OTHER_BSS\n");
482 if (changed_flags
& FIF_BCN_PRBRESP_PROMISC
) {
484 if (*total_flags
& FIF_BCN_PRBRESP_PROMISC
) {
485 wl
->pub
->mac80211_state
|= MAC80211_PROMISC_BCNS
;
486 wlc_mac_bcn_promisc_change(wl
->wlc
, 1);
488 wlc_mac_bcn_promisc_change(wl
->wlc
, 0);
489 wl
->pub
->mac80211_state
&= ~MAC80211_PROMISC_BCNS
;
497 wl_ops_set_tim(struct ieee80211_hw
*hw
, struct ieee80211_sta
*sta
, bool set
)
502 static void wl_ops_sw_scan_start(struct ieee80211_hw
*hw
)
504 struct wl_info
*wl
= hw
->priv
;
506 wlc_scan_start(wl
->wlc
);
511 static void wl_ops_sw_scan_complete(struct ieee80211_hw
*hw
)
513 struct wl_info
*wl
= hw
->priv
;
515 wlc_scan_stop(wl
->wlc
);
520 static void wl_ops_set_tsf(struct ieee80211_hw
*hw
, u64 tsf
)
522 wiphy_err(hw
->wiphy
, "%s: Enter\n", __func__
);
527 wl_ops_get_stats(struct ieee80211_hw
*hw
,
528 struct ieee80211_low_level_stats
*stats
)
530 struct wl_info
*wl
= hw
->priv
;
535 stats
->dot11ACKFailureCount
= 0;
536 stats
->dot11RTSFailureCount
= 0;
537 stats
->dot11FCSErrorCount
= 0;
538 stats
->dot11RTSSuccessCount
= 0;
544 wl_ops_sta_notify(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
545 enum sta_notify_cmd cmd
, struct ieee80211_sta
*sta
)
549 wiphy_err(hw
->wiphy
, "%s: Unknown cmd = %d\n", __func__
,
557 wl_ops_conf_tx(struct ieee80211_hw
*hw
, u16 queue
,
558 const struct ieee80211_tx_queue_params
*params
)
560 struct wl_info
*wl
= hw
->priv
;
563 wlc_wme_setparams(wl
->wlc
, queue
, params
, true);
569 static u64
wl_ops_get_tsf(struct ieee80211_hw
*hw
)
571 wiphy_err(hw
->wiphy
, "%s: Enter\n", __func__
);
576 wl_ops_sta_add(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
577 struct ieee80211_sta
*sta
)
582 struct wl_info
*wl
= hw
->priv
;
585 scb
= (struct scb
*)sta
->drv_priv
;
586 memset(scb
, 0, sizeof(struct scb
));
587 for (i
= 0; i
< NUMPRIO
; i
++)
588 scb
->seqctl
[i
] = 0xFFFF;
589 scb
->seqctl_nonqos
= 0xFFFF;
590 scb
->magic
= SCB_MAGIC
;
592 wl
->pub
->global_scb
= scb
;
593 wl
->pub
->global_ampdu
= &(scb
->scb_ampdu
);
594 wl
->pub
->global_ampdu
->scb
= scb
;
595 wl
->pub
->global_ampdu
->max_pdu
= 16;
596 bcm_pktq_init(&scb
->scb_ampdu
.txq
, AMPDU_MAX_SCB_TID
,
597 AMPDU_MAX_SCB_TID
* PKTQ_LEN_DEFAULT
);
599 sta
->ht_cap
.ht_supported
= true;
600 sta
->ht_cap
.ampdu_factor
= IEEE80211_HT_MAX_AMPDU_64K
;
601 sta
->ht_cap
.ampdu_density
= AMPDU_DEF_MPDU_DENSITY
;
602 sta
->ht_cap
.cap
= IEEE80211_HT_CAP_GRN_FLD
|
603 IEEE80211_HT_CAP_SGI_20
|
604 IEEE80211_HT_CAP_SGI_40
| IEEE80211_HT_CAP_40MHZ_INTOLERANT
;
606 /* minstrel_ht initiates addBA on our behalf by calling ieee80211_start_tx_ba_session() */
611 wl_ops_sta_remove(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
612 struct ieee80211_sta
*sta
)
618 wl_ops_ampdu_action(struct ieee80211_hw
*hw
,
619 struct ieee80211_vif
*vif
,
620 enum ieee80211_ampdu_mlme_action action
,
621 struct ieee80211_sta
*sta
, u16 tid
, u16
*ssn
,
624 struct scb
*scb
= (struct scb
*)sta
->drv_priv
;
625 struct wl_info
*wl
= hw
->priv
;
628 if (WARN_ON(scb
->magic
!= SCB_MAGIC
))
631 case IEEE80211_AMPDU_RX_START
:
633 case IEEE80211_AMPDU_RX_STOP
:
635 case IEEE80211_AMPDU_TX_START
:
637 status
= wlc_aggregatable(wl
->wlc
, tid
);
640 wiphy_err(wl
->wiphy
, "START: tid %d is not agg\'able\n",
644 /* XXX: Use the starting sequence number provided ... */
646 ieee80211_start_tx_ba_cb_irqsafe(vif
, sta
->addr
, tid
);
649 case IEEE80211_AMPDU_TX_STOP
:
651 wlc_ampdu_flush(wl
->wlc
, sta
, tid
);
653 ieee80211_stop_tx_ba_cb_irqsafe(vif
, sta
->addr
, tid
);
655 case IEEE80211_AMPDU_TX_OPERATIONAL
:
656 /* Not sure what to do here */
657 /* Power save wakeup */
660 wiphy_err(wl
->wiphy
, "%s: Invalid command, ignoring\n",
667 static void wl_ops_rfkill_poll(struct ieee80211_hw
*hw
)
669 struct wl_info
*wl
= HW_TO_WL(hw
);
673 blocked
= wlc_check_radio_disabled(wl
->wlc
);
676 wiphy_rfkill_set_hw_state(wl
->pub
->ieee_hw
->wiphy
, blocked
);
679 static void wl_ops_flush(struct ieee80211_hw
*hw
, bool drop
)
681 struct wl_info
*wl
= HW_TO_WL(hw
);
683 no_printk("%s: drop = %s\n", __func__
, drop
? "true" : "false");
685 /* wait for packet queue and dma fifos to run empty */
687 wlc_wait_for_tx_completion(wl
->wlc
, drop
);
691 static const struct ieee80211_ops wl_ops
= {
693 .start
= wl_ops_start
,
695 .add_interface
= wl_ops_add_interface
,
696 .remove_interface
= wl_ops_remove_interface
,
697 .config
= wl_ops_config
,
698 .bss_info_changed
= wl_ops_bss_info_changed
,
699 .configure_filter
= wl_ops_configure_filter
,
700 .set_tim
= wl_ops_set_tim
,
701 .sw_scan_start
= wl_ops_sw_scan_start
,
702 .sw_scan_complete
= wl_ops_sw_scan_complete
,
703 .set_tsf
= wl_ops_set_tsf
,
704 .get_stats
= wl_ops_get_stats
,
705 .sta_notify
= wl_ops_sta_notify
,
706 .conf_tx
= wl_ops_conf_tx
,
707 .get_tsf
= wl_ops_get_tsf
,
708 .sta_add
= wl_ops_sta_add
,
709 .sta_remove
= wl_ops_sta_remove
,
710 .ampdu_action
= wl_ops_ampdu_action
,
711 .rfkill_poll
= wl_ops_rfkill_poll
,
712 .flush
= wl_ops_flush
,
716 * is called in wl_pci_probe() context, therefore no locking required.
718 static int wl_set_hint(struct wl_info
*wl
, char *abbrev
)
720 return regulatory_hint(wl
->pub
->ieee_hw
->wiphy
, abbrev
);
724 * attach to the WL device.
726 * Attach to the WL device identified by vendor and device parameters.
727 * regs is a host accessible memory address pointing to WL device registers.
729 * wl_attach is not defined as static because in the case where no bus
730 * is defined, wl_attach will never be called, and thus, gcc will issue
731 * a warning that this function is defined but not used if we declare
735 * is called in wl_pci_probe() context, therefore no locking required.
737 static struct wl_info
*wl_attach(u16 vendor
, u16 device
, unsigned long regs
,
738 uint bustype
, void *btparam
, uint irq
)
740 struct wl_info
*wl
= NULL
;
743 unsigned long base_addr
;
744 struct ieee80211_hw
*hw
;
754 /* allocate private info */
755 hw
= pci_get_drvdata(btparam
); /* btparam == pdev */
758 if (WARN_ON(hw
== NULL
) || WARN_ON(wl
== NULL
))
760 wl
->wiphy
= hw
->wiphy
;
762 atomic_set(&wl
->callbacks
, 0);
764 /* setup the bottom half handler */
765 tasklet_init(&wl
->tasklet
, wl_dpc
, (unsigned long) wl
);
771 if (bustype
== PCI_BUS
) {
773 } else if (bustype
== RPC_BUS
) {
777 BCMMSG(wl
->wiphy
, "force to PCI\n");
779 wl
->bcm_bustype
= bustype
;
781 wl
->regsva
= ioremap_nocache(base_addr
, PCI_BAR0_WINSZ
);
782 if (wl
->regsva
== NULL
) {
783 wiphy_err(wl
->wiphy
, "wl%d: ioremap() failed\n", unit
);
786 spin_lock_init(&wl
->lock
);
787 spin_lock_init(&wl
->isr_lock
);
790 if (wl_request_fw(wl
, (struct pci_dev
*)btparam
) < 0) {
791 wiphy_err(wl
->wiphy
, "%s: Failed to find firmware usually in "
792 "%s\n", KBUILD_MODNAME
, "/lib/firmware/brcm");
794 wl_remove((struct pci_dev
*)btparam
);
798 /* common load-time initialization */
799 wl
->wlc
= wlc_attach((void *)wl
, vendor
, device
, unit
, wl
->piomode
,
800 wl
->regsva
, wl
->bcm_bustype
, btparam
, &err
);
803 wiphy_err(wl
->wiphy
, "%s: wlc_attach() failed with code %d\n",
804 KBUILD_MODNAME
, err
);
807 wl
->pub
= wlc_pub(wl
->wlc
);
809 wl
->pub
->ieee_hw
= hw
;
811 if (wlc_iovar_setint(wl
->wlc
, "mpc", 0)) {
812 wiphy_err(wl
->wiphy
, "wl%d: Error setting MPC variable to 0\n",
816 /* register our interrupt handler */
817 if (request_irq(irq
, wl_isr
, IRQF_SHARED
, KBUILD_MODNAME
, wl
)) {
818 wiphy_err(wl
->wiphy
, "wl%d: request_irq() failed\n", unit
);
823 /* register module */
824 wlc_module_register(wl
->pub
, NULL
, "linux", wl
, NULL
, wl_linux_watchdog
,
827 if (ieee_hw_init(hw
)) {
828 wiphy_err(wl
->wiphy
, "wl%d: %s: ieee_hw_init failed!\n", unit
,
833 memcpy(perm
, &wl
->pub
->cur_etheraddr
, ETH_ALEN
);
834 if (WARN_ON(!is_valid_ether_addr(perm
)))
836 SET_IEEE80211_PERM_ADDR(hw
, perm
);
838 err
= ieee80211_register_hw(hw
);
840 wiphy_err(wl
->wiphy
, "%s: ieee80211_register_hw failed, status"
841 "%d\n", __func__
, err
);
844 if (wl
->pub
->srom_ccode
[0])
845 err
= wl_set_hint(wl
, wl
->pub
->srom_ccode
);
847 err
= wl_set_hint(wl
, "US");
849 wiphy_err(wl
->wiphy
, "%s: regulatory_hint failed, status %d\n",
863 #define CHAN2GHZ(channel, freqency, chflags) { \
864 .band = IEEE80211_BAND_2GHZ, \
865 .center_freq = (freqency), \
866 .hw_value = (channel), \
868 .max_antenna_gain = 0, \
872 static struct ieee80211_channel wl_2ghz_chantable
[] = {
873 CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS
),
874 CHAN2GHZ(2, 2417, IEEE80211_CHAN_NO_HT40MINUS
),
875 CHAN2GHZ(3, 2422, IEEE80211_CHAN_NO_HT40MINUS
),
876 CHAN2GHZ(4, 2427, IEEE80211_CHAN_NO_HT40MINUS
),
877 CHAN2GHZ(5, 2432, 0),
878 CHAN2GHZ(6, 2437, 0),
879 CHAN2GHZ(7, 2442, 0),
880 CHAN2GHZ(8, 2447, IEEE80211_CHAN_NO_HT40PLUS
),
881 CHAN2GHZ(9, 2452, IEEE80211_CHAN_NO_HT40PLUS
),
882 CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS
),
883 CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS
),
885 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_IBSS
|
886 IEEE80211_CHAN_NO_HT40PLUS
),
888 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_IBSS
|
889 IEEE80211_CHAN_NO_HT40PLUS
),
891 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_IBSS
|
892 IEEE80211_CHAN_NO_HT40PLUS
| IEEE80211_CHAN_NO_HT40MINUS
)
895 #define CHAN5GHZ(channel, chflags) { \
896 .band = IEEE80211_BAND_5GHZ, \
897 .center_freq = 5000 + 5*(channel), \
898 .hw_value = (channel), \
900 .max_antenna_gain = 0, \
904 static struct ieee80211_channel wl_5ghz_nphy_chantable
[] = {
906 CHAN5GHZ(36, IEEE80211_CHAN_NO_HT40MINUS
),
907 CHAN5GHZ(40, IEEE80211_CHAN_NO_HT40PLUS
),
908 CHAN5GHZ(44, IEEE80211_CHAN_NO_HT40MINUS
),
909 CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS
),
912 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
913 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40MINUS
),
915 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
916 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40PLUS
),
918 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
919 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40MINUS
),
921 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
922 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40PLUS
),
925 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
926 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40MINUS
),
928 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
929 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40PLUS
),
931 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
932 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40MINUS
),
934 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
935 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40PLUS
),
937 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
938 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40MINUS
),
940 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
941 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40PLUS
),
943 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
944 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40MINUS
),
946 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
947 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40PLUS
),
949 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
950 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40MINUS
),
952 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
953 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40PLUS
),
955 IEEE80211_CHAN_RADAR
| IEEE80211_CHAN_NO_IBSS
|
956 IEEE80211_CHAN_PASSIVE_SCAN
| IEEE80211_CHAN_NO_HT40PLUS
|
957 IEEE80211_CHAN_NO_HT40MINUS
),
959 CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS
),
960 CHAN5GHZ(153, IEEE80211_CHAN_NO_HT40PLUS
),
961 CHAN5GHZ(157, IEEE80211_CHAN_NO_HT40MINUS
),
962 CHAN5GHZ(161, IEEE80211_CHAN_NO_HT40PLUS
),
963 CHAN5GHZ(165, IEEE80211_CHAN_NO_HT40PLUS
| IEEE80211_CHAN_NO_HT40MINUS
)
966 #define RATE(rate100m, _flags) { \
967 .bitrate = (rate100m), \
969 .hw_value = (rate100m / 5), \
972 static struct ieee80211_rate wl_legacy_ratetable
[] = {
974 RATE(20, IEEE80211_RATE_SHORT_PREAMBLE
),
975 RATE(55, IEEE80211_RATE_SHORT_PREAMBLE
),
976 RATE(110, IEEE80211_RATE_SHORT_PREAMBLE
),
987 static struct ieee80211_supported_band wl_band_2GHz_nphy
= {
988 .band
= IEEE80211_BAND_2GHZ
,
989 .channels
= wl_2ghz_chantable
,
990 .n_channels
= ARRAY_SIZE(wl_2ghz_chantable
),
991 .bitrates
= wl_legacy_ratetable
,
992 .n_bitrates
= ARRAY_SIZE(wl_legacy_ratetable
),
994 /* from include/linux/ieee80211.h */
995 .cap
= IEEE80211_HT_CAP_GRN_FLD
|
996 IEEE80211_HT_CAP_SGI_20
|
997 IEEE80211_HT_CAP_SGI_40
| IEEE80211_HT_CAP_40MHZ_INTOLERANT
,
998 .ht_supported
= true,
999 .ampdu_factor
= IEEE80211_HT_MAX_AMPDU_64K
,
1000 .ampdu_density
= AMPDU_DEF_MPDU_DENSITY
,
1002 /* placeholders for now */
1003 .rx_mask
= {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
1005 .tx_params
= IEEE80211_HT_MCS_TX_DEFINED
}
1009 static struct ieee80211_supported_band wl_band_5GHz_nphy
= {
1010 .band
= IEEE80211_BAND_5GHZ
,
1011 .channels
= wl_5ghz_nphy_chantable
,
1012 .n_channels
= ARRAY_SIZE(wl_5ghz_nphy_chantable
),
1013 .bitrates
= wl_legacy_ratetable
+ 4,
1014 .n_bitrates
= ARRAY_SIZE(wl_legacy_ratetable
) - 4,
1016 /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */
1017 .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 */
1018 .ht_supported
= true,
1019 .ampdu_factor
= IEEE80211_HT_MAX_AMPDU_64K
,
1020 .ampdu_density
= AMPDU_DEF_MPDU_DENSITY
,
1022 /* placeholders for now */
1023 .rx_mask
= {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
1025 .tx_params
= IEEE80211_HT_MCS_TX_DEFINED
}
1030 * is called in wl_pci_probe() context, therefore no locking required.
1032 static int ieee_hw_rate_init(struct ieee80211_hw
*hw
)
1034 struct wl_info
*wl
= HW_TO_WL(hw
);
1040 hw
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = NULL
;
1041 hw
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = NULL
;
1043 if (wlc_get(wl
->wlc
, WLC_GET_PHYLIST
, (int *)&phy_list
) < 0) {
1044 wiphy_err(hw
->wiphy
, "Phy list failed\n");
1047 if (phy_list
[0] == 'n' || phy_list
[0] == 'c') {
1048 if (phy_list
[0] == 'c') {
1050 wl_band_2GHz_nphy
.ht_cap
.mcs
.rx_mask
[1] = 0;
1051 wl_band_2GHz_nphy
.ht_cap
.mcs
.rx_highest
= 72;
1053 hw
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &wl_band_2GHz_nphy
;
1058 /* Assume all bands use the same phy. True for 11n devices. */
1059 if (NBANDS_PUB(wl
->pub
) > 1) {
1061 if (phy_list
[0] == 'n' || phy_list
[0] == 'c') {
1062 hw
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] =
1072 * is called in wl_pci_probe() context, therefore no locking required.
1074 static int ieee_hw_init(struct ieee80211_hw
*hw
)
1076 hw
->flags
= IEEE80211_HW_SIGNAL_DBM
1077 /* | IEEE80211_HW_CONNECTION_MONITOR What is this? */
1078 | IEEE80211_HW_REPORTS_TX_ACK_STATUS
1079 | IEEE80211_HW_AMPDU_AGGREGATION
;
1081 hw
->extra_tx_headroom
= wlc_get_header_len();
1082 hw
->queues
= N_TX_QUEUES
;
1083 /* FIXME: this doesn't seem to be used properly in minstrel_ht.
1084 * mac80211/status.c:ieee80211_tx_status() checks this value,
1085 * but mac80211/rc80211_minstrel_ht.c:minstrel_ht_get_rate()
1086 * appears to always set 3 rates
1088 hw
->max_rates
= 2; /* Primary rate and 1 fallback rate */
1090 hw
->channel_change_time
= 7 * 1000; /* channel change time is dependent on chip and band */
1091 hw
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
);
1093 hw
->rate_control_algorithm
= "minstrel_ht";
1095 hw
->sta_data_size
= sizeof(struct scb
);
1096 return ieee_hw_rate_init(hw
);
1100 * determines if a device is a WL device, and if so, attaches it.
1102 * This function determines if a device pointed to by pdev is a WL device,
1103 * and if so, performs a wl_attach() on it.
1105 * Perimeter lock is initialized in the course of this function.
1107 static int __devinit
1108 wl_pci_probe(struct pci_dev
*pdev
, const struct pci_device_id
*ent
)
1112 struct ieee80211_hw
*hw
;
1115 dev_info(&pdev
->dev
, "bus %d slot %d func %d irq %d\n",
1116 pdev
->bus
->number
, PCI_SLOT(pdev
->devfn
),
1117 PCI_FUNC(pdev
->devfn
), pdev
->irq
);
1119 if ((pdev
->vendor
!= PCI_VENDOR_ID_BROADCOM
) ||
1120 (((pdev
->device
& 0xff00) != 0x4300) &&
1121 ((pdev
->device
& 0xff00) != 0x4700) &&
1122 ((pdev
->device
< 43000) || (pdev
->device
> 43999))))
1125 rc
= pci_enable_device(pdev
);
1127 pr_err("%s: Cannot enable device %d-%d_%d\n",
1128 __func__
, pdev
->bus
->number
, PCI_SLOT(pdev
->devfn
),
1129 PCI_FUNC(pdev
->devfn
));
1132 pci_set_master(pdev
);
1134 pci_read_config_dword(pdev
, 0x40, &val
);
1135 if ((val
& 0x0000ff00) != 0)
1136 pci_write_config_dword(pdev
, 0x40, val
& 0xffff00ff);
1138 hw
= ieee80211_alloc_hw(sizeof(struct wl_info
), &wl_ops
);
1140 pr_err("%s: ieee80211_alloc_hw failed\n", __func__
);
1144 SET_IEEE80211_DEV(hw
, &pdev
->dev
);
1146 pci_set_drvdata(pdev
, hw
);
1148 memset(hw
->priv
, 0, sizeof(*wl
));
1150 wl
= wl_attach(pdev
->vendor
, pdev
->device
, pci_resource_start(pdev
, 0),
1151 PCI_BUS
, pdev
, pdev
->irq
);
1154 pr_err("%s: %s: wl_attach failed!\n", KBUILD_MODNAME
,
1161 static int wl_suspend(struct pci_dev
*pdev
, pm_message_t state
)
1164 struct ieee80211_hw
*hw
;
1166 hw
= pci_get_drvdata(pdev
);
1169 wiphy_err(wl
->wiphy
,
1170 "wl_suspend: pci_get_drvdata failed\n");
1174 /* only need to flag hw is down for proper resume */
1176 wl
->pub
->hw_up
= false;
1179 pci_save_state(pdev
);
1180 pci_disable_device(pdev
);
1181 return pci_set_power_state(pdev
, PCI_D3hot
);
1184 static int wl_resume(struct pci_dev
*pdev
)
1187 struct ieee80211_hw
*hw
;
1191 hw
= pci_get_drvdata(pdev
);
1194 wiphy_err(wl
->wiphy
,
1195 "wl: wl_resume: pci_get_drvdata failed\n");
1199 err
= pci_set_power_state(pdev
, PCI_D0
);
1203 pci_restore_state(pdev
);
1205 err
= pci_enable_device(pdev
);
1209 pci_set_master(pdev
);
1211 pci_read_config_dword(pdev
, 0x40, &val
);
1212 if ((val
& 0x0000ff00) != 0)
1213 pci_write_config_dword(pdev
, 0x40, val
& 0xffff00ff);
1216 * done. driver will be put in up state
1217 * in wl_ops_add_interface() call.
1223 * called from both kernel as from wl_*()
1224 * precondition: perimeter lock is not acquired.
1226 static void wl_remove(struct pci_dev
*pdev
)
1229 struct ieee80211_hw
*hw
;
1232 hw
= pci_get_drvdata(pdev
);
1235 pr_err("wl: wl_remove: pci_get_drvdata failed\n");
1240 status
= wlc_chipmatch(pdev
->vendor
, pdev
->device
);
1243 wiphy_err(wl
->wiphy
, "wl: wl_remove: wlc_chipmatch failed\n");
1247 wiphy_rfkill_set_hw_state(wl
->pub
->ieee_hw
->wiphy
, false);
1248 wiphy_rfkill_stop_polling(wl
->pub
->ieee_hw
->wiphy
);
1249 ieee80211_unregister_hw(hw
);
1254 pci_disable_device(pdev
);
1258 pci_set_drvdata(pdev
, NULL
);
1259 ieee80211_free_hw(hw
);
1262 static struct pci_driver wl_pci_driver
= {
1263 .name
= KBUILD_MODNAME
,
1264 .probe
= wl_pci_probe
,
1265 .suspend
= wl_suspend
,
1266 .resume
= wl_resume
,
1267 .remove
= __devexit_p(wl_remove
),
1268 .id_table
= wl_id_table
,
1272 * This is the main entry point for the WL driver.
1274 * This function determines if a device pointed to by pdev is a WL device,
1275 * and if so, performs a wl_attach() on it.
1278 static int __init
wl_module_init(void)
1280 int error
= -ENODEV
;
1283 if (msglevel
!= 0xdeadbeef)
1284 wl_msg_level
= msglevel
;
1286 char *var
= getvar(NULL
, "wl_msglevel");
1288 unsigned long value
;
1290 (void)strict_strtoul(var
, 0, &value
);
1291 wl_msg_level
= value
;
1294 if (phymsglevel
!= 0xdeadbeef)
1295 phyhal_msg_level
= phymsglevel
;
1297 char *var
= getvar(NULL
, "phy_msglevel");
1299 unsigned long value
;
1301 (void)strict_strtoul(var
, 0, &value
);
1302 phyhal_msg_level
= value
;
1307 error
= pci_register_driver(&wl_pci_driver
);
1317 * This function unloads the WL driver from the system.
1319 * This function unconditionally unloads the WL driver module from the
1323 static void __exit
wl_module_exit(void)
1325 pci_unregister_driver(&wl_pci_driver
);
1329 module_init(wl_module_init
);
1330 module_exit(wl_module_exit
);
1333 * This function frees the WL per-device resources.
1335 * This function frees resources owned by the WL device pointed to
1336 * by the wl parameter.
1338 * precondition: can both be called locked and unlocked
1341 static void wl_free(struct wl_info
*wl
)
1343 struct wl_timer
*t
, *next
;
1345 /* free ucode data */
1347 wl_ucode_data_free();
1349 free_irq(wl
->irq
, wl
);
1352 tasklet_kill(&wl
->tasklet
);
1355 wlc_module_unregister(wl
->pub
, "linux", wl
);
1358 /* free common resources */
1360 wlc_detach(wl
->wlc
);
1365 /* virtual interface deletion is deferred so we cannot spinwait */
1367 /* wait for all pending callbacks to complete */
1368 while (atomic_read(&wl
->callbacks
) > 0)
1372 for (t
= wl
->timers
; t
; t
= next
) {
1381 * unregister_netdev() calls get_stats() which may read chip registers
1382 * so we cannot unmap the chip registers until after calling unregister_netdev() .
1384 if (wl
->regsva
&& wl
->bcm_bustype
!= SDIO_BUS
&&
1385 wl
->bcm_bustype
!= JTAG_BUS
) {
1386 iounmap((void *)wl
->regsva
);
1391 /* flags the given rate in rateset as requested */
1392 static void wl_set_basic_rate(struct wl_rateset
*rs
, u16 rate
, bool is_br
)
1396 for (i
= 0; i
< rs
->count
; i
++) {
1397 if (rate
!= (rs
->rates
[i
] & 0x7f))
1401 rs
->rates
[i
] |= WLC_RATE_FLAG
;
1403 rs
->rates
[i
] &= WLC_RATE_MASK
;
1409 * precondition: perimeter lock has been acquired
1411 void wl_txflowcontrol(struct wl_info
*wl
, struct wl_if
*wlif
, bool state
,
1414 wiphy_err(wl
->wiphy
, "Shouldn't be here %s\n", __func__
);
1418 * precondition: perimeter lock has been acquired
1420 void wl_init(struct wl_info
*wl
)
1422 BCMMSG(WL_TO_HW(wl
)->wiphy
, "wl%d\n", wl
->pub
->unit
);
1429 * precondition: perimeter lock has been acquired
1431 uint
wl_reset(struct wl_info
*wl
)
1433 BCMMSG(WL_TO_HW(wl
)->wiphy
, "wl%d\n", wl
->pub
->unit
);
1436 /* dpc will not be rescheduled */
1443 * These are interrupt on/off entry points. Disable interrupts
1444 * during interrupt state transition.
1446 void wl_intrson(struct wl_info
*wl
)
1448 unsigned long flags
;
1450 INT_LOCK(wl
, flags
);
1451 wlc_intrson(wl
->wlc
);
1452 INT_UNLOCK(wl
, flags
);
1456 * precondition: perimeter lock has been acquired
1458 bool wl_alloc_dma_resources(struct wl_info
*wl
, uint addrwidth
)
1463 u32
wl_intrsoff(struct wl_info
*wl
)
1465 unsigned long flags
;
1468 INT_LOCK(wl
, flags
);
1469 status
= wlc_intrsoff(wl
->wlc
);
1470 INT_UNLOCK(wl
, flags
);
1474 void wl_intrsrestore(struct wl_info
*wl
, u32 macintmask
)
1476 unsigned long flags
;
1478 INT_LOCK(wl
, flags
);
1479 wlc_intrsrestore(wl
->wlc
, macintmask
);
1480 INT_UNLOCK(wl
, flags
);
1484 * precondition: perimeter lock has been acquired
1486 int wl_up(struct wl_info
*wl
)
1493 error
= wlc_up(wl
->wlc
);
1499 * precondition: perimeter lock has been acquired
1501 void wl_down(struct wl_info
*wl
)
1503 uint callbacks
, ret_val
= 0;
1505 /* call common down function */
1506 ret_val
= wlc_down(wl
->wlc
);
1507 callbacks
= atomic_read(&wl
->callbacks
) - ret_val
;
1509 /* wait for down callbacks to complete */
1512 /* For HIGH_only driver, it's important to actually schedule other work,
1513 * not just spin wait since everything runs at schedule level
1515 SPINWAIT((atomic_read(&wl
->callbacks
) > callbacks
), 100 * 1000);
1520 static irqreturn_t
wl_isr(int irq
, void *dev_id
)
1524 unsigned long flags
;
1526 wl
= (struct wl_info
*) dev_id
;
1528 WL_ISRLOCK(wl
, flags
);
1530 /* call common first level interrupt handler */
1531 ours
= wlc_isr(wl
->wlc
, &wantdpc
);
1533 /* if more to do... */
1536 /* ...and call the second level interrupt handler */
1538 tasklet_schedule(&wl
->tasklet
);
1542 WL_ISRUNLOCK(wl
, flags
);
1544 return IRQ_RETVAL(ours
);
1547 static void wl_dpc(unsigned long data
)
1551 wl
= (struct wl_info
*) data
;
1555 /* call the common second level interrupt handler */
1558 unsigned long flags
;
1560 INT_LOCK(wl
, flags
);
1561 wlc_intrsupd(wl
->wlc
);
1562 INT_UNLOCK(wl
, flags
);
1565 wl
->resched
= wlc_dpc(wl
->wlc
, true);
1568 /* wlc_dpc() may bring the driver down */
1572 /* re-schedule dpc */
1574 tasklet_schedule(&wl
->tasklet
);
1576 /* re-enable interrupts */
1585 * is called by the kernel from software irq context
1587 static void wl_timer(unsigned long data
)
1589 _wl_timer((struct wl_timer
*) data
);
1593 * precondition: perimeter lock is not acquired
1595 static void _wl_timer(struct wl_timer
*t
)
1601 t
->timer
.expires
= jiffies
+ t
->ms
* HZ
/ 1000;
1602 atomic_inc(&t
->wl
->callbacks
);
1603 add_timer(&t
->timer
);
1611 atomic_dec(&t
->wl
->callbacks
);
1617 * Adds a timer to the list. Caller supplies a timer function.
1618 * Is called from wlc.
1620 * precondition: perimeter lock has been acquired
1622 struct wl_timer
*wl_init_timer(struct wl_info
*wl
, void (*fn
) (void *arg
),
1623 void *arg
, const char *name
)
1627 t
= kzalloc(sizeof(struct wl_timer
), GFP_ATOMIC
);
1629 wiphy_err(wl
->wiphy
, "wl%d: wl_init_timer: out of memory\n",
1634 init_timer(&t
->timer
);
1635 t
->timer
.data
= (unsigned long) t
;
1636 t
->timer
.function
= wl_timer
;
1640 t
->next
= wl
->timers
;
1644 t
->name
= kmalloc(strlen(name
) + 1, GFP_ATOMIC
);
1646 strcpy(t
->name
, name
);
1652 /* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate
1653 * as well as it's easier to make it periodic
1655 * precondition: perimeter lock has been acquired
1657 void wl_add_timer(struct wl_info
*wl
, struct wl_timer
*t
, uint ms
, int periodic
)
1661 wiphy_err(wl
->wiphy
, "%s: Already set. Name: %s, per %d\n",
1662 __func__
, t
->name
, periodic
);
1666 t
->periodic
= (bool) periodic
;
1668 t
->timer
.expires
= jiffies
+ ms
* HZ
/ 1000;
1670 atomic_inc(&wl
->callbacks
);
1671 add_timer(&t
->timer
);
1675 * return true if timer successfully deleted, false if still pending
1677 * precondition: perimeter lock has been acquired
1679 bool wl_del_timer(struct wl_info
*wl
, struct wl_timer
*t
)
1683 if (!del_timer(&t
->timer
)) {
1686 atomic_dec(&wl
->callbacks
);
1693 * precondition: perimeter lock has been acquired
1695 void wl_free_timer(struct wl_info
*wl
, struct wl_timer
*t
)
1697 struct wl_timer
*tmp
;
1699 /* delete the timer in case it is active */
1700 wl_del_timer(wl
, t
);
1702 if (wl
->timers
== t
) {
1703 wl
->timers
= wl
->timers
->next
;
1714 if (tmp
->next
== t
) {
1715 tmp
->next
= t
->next
;
1728 * runs in software irq context
1730 * precondition: perimeter lock is not acquired
1732 static int wl_linux_watchdog(void *ctx
)
1743 char *wl_firmwares
[WL_MAX_FW
] = {
1749 * precondition: perimeter lock has been acquired
1751 int wl_ucode_init_buf(struct wl_info
*wl
, void **pbuf
, u32 idx
)
1755 struct wl_fw_hdr
*hdr
;
1756 for (i
= 0; i
< wl
->fw
.fw_cnt
; i
++) {
1757 hdr
= (struct wl_fw_hdr
*)wl
->fw
.fw_hdr
[i
]->data
;
1758 for (entry
= 0; entry
< wl
->fw
.hdr_num_entries
[i
];
1760 if (hdr
->idx
== idx
) {
1761 pdata
= wl
->fw
.fw_bin
[i
]->data
+ hdr
->offset
;
1762 *pbuf
= kmalloc(hdr
->len
, GFP_ATOMIC
);
1763 if (*pbuf
== NULL
) {
1764 wiphy_err(wl
->wiphy
, "fail to alloc %d"
1765 " bytes\n", hdr
->len
);
1768 memcpy(*pbuf
, pdata
, hdr
->len
);
1773 wiphy_err(wl
->wiphy
, "ERROR: ucode buf tag:%d can not be found!\n",
1781 * Precondition: Since this function is called in wl_pci_probe() context,
1782 * no locking is required.
1784 int wl_ucode_init_uint(struct wl_info
*wl
, u32
*data
, u32 idx
)
1788 struct wl_fw_hdr
*hdr
;
1789 for (i
= 0; i
< wl
->fw
.fw_cnt
; i
++) {
1790 hdr
= (struct wl_fw_hdr
*)wl
->fw
.fw_hdr
[i
]->data
;
1791 for (entry
= 0; entry
< wl
->fw
.hdr_num_entries
[i
];
1793 if (hdr
->idx
== idx
) {
1794 pdata
= wl
->fw
.fw_bin
[i
]->data
+ hdr
->offset
;
1795 if (hdr
->len
!= 4) {
1796 wiphy_err(wl
->wiphy
,
1797 "ERROR: fw hdr len\n");
1800 *data
= *((u32
*) pdata
);
1805 wiphy_err(wl
->wiphy
, "ERROR: ucode tag:%d can not be found!\n", idx
);
1810 * Precondition: Since this function is called in wl_pci_probe() context,
1811 * no locking is required.
1813 static int wl_request_fw(struct wl_info
*wl
, struct pci_dev
*pdev
)
1816 struct device
*device
= &pdev
->dev
;
1820 memset((void *)&wl
->fw
, 0, sizeof(struct wl_firmware
));
1821 for (i
= 0; i
< WL_MAX_FW
; i
++) {
1822 if (wl_firmwares
[i
] == NULL
)
1824 sprintf(fw_name
, "%s-%d.fw", wl_firmwares
[i
],
1825 UCODE_LOADER_API_VER
);
1826 status
= request_firmware(&wl
->fw
.fw_bin
[i
], fw_name
, device
);
1828 wiphy_err(wl
->wiphy
, "%s: fail to load firmware %s\n",
1829 KBUILD_MODNAME
, fw_name
);
1832 sprintf(fw_name
, "%s_hdr-%d.fw", wl_firmwares
[i
],
1833 UCODE_LOADER_API_VER
);
1834 status
= request_firmware(&wl
->fw
.fw_hdr
[i
], fw_name
, device
);
1836 wiphy_err(wl
->wiphy
, "%s: fail to load firmware %s\n",
1837 KBUILD_MODNAME
, fw_name
);
1840 wl
->fw
.hdr_num_entries
[i
] =
1841 wl
->fw
.fw_hdr
[i
]->size
/ (sizeof(struct wl_fw_hdr
));
1844 return wl_ucode_data_init(wl
);
1848 * precondition: can both be called locked and unlocked
1850 void wl_ucode_free_buf(void *p
)
1856 * Precondition: Since this function is called in wl_pci_probe() context,
1857 * no locking is required.
1859 static void wl_release_fw(struct wl_info
*wl
)
1862 for (i
= 0; i
< WL_MAX_FW
; i
++) {
1863 release_firmware(wl
->fw
.fw_bin
[i
]);
1864 release_firmware(wl
->fw
.fw_hdr
[i
]);
1870 * checks validity of all firmware images loaded from user space
1872 * Precondition: Since this function is called in wl_pci_probe() context,
1873 * no locking is required.
1875 int wl_check_firmwares(struct wl_info
*wl
)
1880 const struct firmware
*fw
;
1881 const struct firmware
*fw_hdr
;
1882 struct wl_fw_hdr
*ucode_hdr
;
1883 for (i
= 0; i
< WL_MAX_FW
&& rc
== 0; i
++) {
1884 fw
= wl
->fw
.fw_bin
[i
];
1885 fw_hdr
= wl
->fw
.fw_hdr
[i
];
1886 if (fw
== NULL
&& fw_hdr
== NULL
) {
1888 } else if (fw
== NULL
|| fw_hdr
== NULL
) {
1889 wiphy_err(wl
->wiphy
, "%s: invalid bin/hdr fw\n",
1892 } else if (fw_hdr
->size
% sizeof(struct wl_fw_hdr
)) {
1893 wiphy_err(wl
->wiphy
, "%s: non integral fw hdr file "
1894 "size %zu/%zu\n", __func__
, fw_hdr
->size
,
1895 sizeof(struct wl_fw_hdr
));
1897 } else if (fw
->size
< MIN_FW_SIZE
|| fw
->size
> MAX_FW_SIZE
) {
1898 wiphy_err(wl
->wiphy
, "%s: out of bounds fw file size "
1899 "%zu\n", __func__
, fw
->size
);
1902 /* check if ucode section overruns firmware image */
1903 ucode_hdr
= (struct wl_fw_hdr
*)fw_hdr
->data
;
1904 for (entry
= 0; entry
< wl
->fw
.hdr_num_entries
[i
] &&
1905 !rc
; entry
++, ucode_hdr
++) {
1906 if (ucode_hdr
->offset
+ ucode_hdr
->len
>
1908 wiphy_err(wl
->wiphy
,
1909 "%s: conflicting bin/hdr\n",
1916 if (rc
== 0 && wl
->fw
.fw_cnt
!= i
) {
1917 wiphy_err(wl
->wiphy
, "%s: invalid fw_cnt=%d\n", __func__
,
1925 * precondition: perimeter lock has been acquired
1927 bool wl_rfkill_set_hw_state(struct wl_info
*wl
)
1929 bool blocked
= wlc_check_radio_disabled(wl
->wlc
);
1932 wiphy_rfkill_set_hw_state(wl
->pub
->ieee_hw
->wiphy
, blocked
);
1934 wiphy_rfkill_start_polling(wl
->pub
->ieee_hw
->wiphy
);
1940 * precondition: perimeter lock has been acquired
1942 void wl_msleep(struct wl_info
*wl
, uint ms
)