Commit 7d7f5d04 authored by David S. Miller's avatar David S. Miller
Browse files

Merge tag 'wireless-drivers-next-for-davem-2016-01-09' of...

Merge tag 'wireless-drivers-next-for-davem-2016-01-09' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next



Kalle Valo says:

====================
brcmfmac

* query features through firmware command
* ARP offload through inet notifier
* force probe to succeed for debugging purposes
* random mac support for scheduled scan
* support wowl upon net detect

iwlwifi

* bug fixes and improvements for firmware debug system
* advertise support for Rx A-MSDU in A-MPDU
* support -20.ucode
* fix WoWLAN for iwldvm
* preparations towards multiple Rx queues
* platform power improvements for GO mode when no clients are associated
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents a78cb84c 42e0ed0d
......@@ -3860,7 +3860,8 @@ static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
ht_cap.cap |= WLAN_HT_CAP_SM_PS_STATIC << IEEE80211_HT_CAP_SM_PS_SHIFT;
ht_cap.cap |=
WLAN_HT_CAP_SM_PS_DISABLED << IEEE80211_HT_CAP_SM_PS_SHIFT;
if (ar->ht_cap_info & WMI_HT_CAP_HT20_SGI)
ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
......
......@@ -487,6 +487,9 @@ static int ath10k_pci_force_wake(struct ath10k *ar)
unsigned long flags;
int ret = 0;
if (ar_pci->pci_ps)
return ret;
spin_lock_irqsave(&ar_pci->ps_lock, flags);
if (!ar_pci->ps_awake) {
......@@ -2480,12 +2483,10 @@ static int ath10k_pci_hif_resume(struct ath10k *ar)
u32 val;
int ret = 0;
if (ar_pci->pci_ps == 0) {
ret = ath10k_pci_force_wake(ar);
if (ret) {
ath10k_err(ar, "failed to wake up target: %d\n", ret);
return ret;
}
ret = ath10k_pci_force_wake(ar);
if (ret) {
ath10k_err(ar, "failed to wake up target: %d\n", ret);
return ret;
}
/* Suspend/Resume resets the PCI configuration space, so we have to
......@@ -2592,13 +2593,10 @@ static irqreturn_t ath10k_pci_interrupt_handler(int irq, void *arg)
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
int ret;
if (ar_pci->pci_ps == 0) {
ret = ath10k_pci_force_wake(ar);
if (ret) {
ath10k_warn(ar, "failed to wake device up on irq: %d\n",
ret);
return IRQ_NONE;
}
ret = ath10k_pci_force_wake(ar);
if (ret) {
ath10k_warn(ar, "failed to wake device up on irq: %d\n", ret);
return IRQ_NONE;
}
if (ar_pci->num_msi_intrs == 0) {
......@@ -3071,17 +3069,15 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
goto err_sleep;
}
ret = ath10k_pci_force_wake(ar);
if (ret) {
ath10k_warn(ar, "failed to wake up device : %d\n", ret);
goto err_free_pipes;
}
ath10k_pci_ce_deinit(ar);
ath10k_pci_irq_disable(ar);
if (ar_pci->pci_ps == 0) {
ret = ath10k_pci_force_wake(ar);
if (ret) {
ath10k_warn(ar, "failed to wake up device : %d\n", ret);
goto err_free_pipes;
}
}
ret = ath10k_pci_init_irq(ar);
if (ret) {
ath10k_err(ar, "failed to init irqs: %d\n", ret);
......
......@@ -206,7 +206,7 @@ bool ath9k_hw_nvram_check_version(struct ath_hw *ah, int version, int minrev)
ath_err(common, "Bad EEPROM VER 0x%04x or REV 0x%04x\n",
ah->eep_ops->get_eeprom_ver(ah),
ah->eep_ops->get_eeprom_rev(ah));
return -EINVAL;
return false;
}
return true;
......
......@@ -834,7 +834,7 @@ void ath9k_htc_ani_work(struct work_struct *work)
if (longcal || shortcal)
common->ani.caldone =
ath9k_hw_calibrate(ah, ah->curchan,
ah->rxchainmask, longcal);
ah->rxchainmask, longcal) > 0;
ath9k_htc_ps_restore(priv);
}
......
......@@ -828,6 +828,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
ieee80211_hw_set(hw, RX_INCLUDES_FCS);
ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
if (ath9k_ps_enable)
ieee80211_hw_set(hw, SUPPORTS_PS);
......
......@@ -474,36 +474,37 @@ static int wcn36xx_rx_handle_packets(struct wcn36xx *wcn,
struct wcn36xx_dxe_desc *dxe = ctl->desc;
dma_addr_t dma_addr;
struct sk_buff *skb;
int ret = 0, int_mask;
u32 value;
if (ch->ch_type == WCN36XX_DXE_CH_RX_L) {
value = WCN36XX_DXE_CTRL_RX_L;
int_mask = WCN36XX_DXE_INT_CH1_MASK;
} else {
value = WCN36XX_DXE_CTRL_RX_H;
int_mask = WCN36XX_DXE_INT_CH3_MASK;
}
while (!(dxe->ctrl & WCN36XX_DXE_CTRL_VALID_MASK)) {
skb = ctl->skb;
dma_addr = dxe->dst_addr_l;
wcn36xx_dxe_fill_skb(wcn->dev, ctl);
switch (ch->ch_type) {
case WCN36XX_DXE_CH_RX_L:
dxe->ctrl = WCN36XX_DXE_CTRL_RX_L;
wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_ENCH_ADDR,
WCN36XX_DXE_INT_CH1_MASK);
break;
case WCN36XX_DXE_CH_RX_H:
dxe->ctrl = WCN36XX_DXE_CTRL_RX_H;
wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_ENCH_ADDR,
WCN36XX_DXE_INT_CH3_MASK);
break;
default:
wcn36xx_warn("Unknown channel\n");
}
dma_unmap_single(wcn->dev, dma_addr, WCN36XX_PKT_SIZE,
DMA_FROM_DEVICE);
wcn36xx_rx_skb(wcn, skb);
ret = wcn36xx_dxe_fill_skb(wcn->dev, ctl);
if (0 == ret) {
/* new skb allocation ok. Use the new one and queue
* the old one to network system.
*/
dma_unmap_single(wcn->dev, dma_addr, WCN36XX_PKT_SIZE,
DMA_FROM_DEVICE);
wcn36xx_rx_skb(wcn, skb);
} /* else keep old skb not submitted and use it for rx DMA */
dxe->ctrl = value;
ctl = ctl->next;
dxe = ctl->desc;
}
wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_ENCH_ADDR, int_mask);
ch->head_blk_ctl = ctl;
return 0;
}
......
......@@ -394,9 +394,13 @@ static irqreturn_t wil6210_irq_misc_thread(int irq, void *cookie)
wil_fw_core_dump(wil);
wil_notify_fw_error(wil);
isr &= ~ISR_MISC_FW_ERROR;
wil_fw_error_recovery(wil);
if (wil->platform_ops.notify_crash) {
wil_err(wil, "notify platform driver about FW crash");
wil->platform_ops.notify_crash(wil->platform_handle);
} else {
wil_fw_error_recovery(wil);
}
}
if (isr & ISR_MISC_MBOX_EVT) {
wil_dbg_irq(wil, "MBOX event\n");
wmi_recv_cmd(wil);
......
......@@ -987,7 +987,7 @@ int __wil_down(struct wil6210_priv *wil)
}
mutex_lock(&wil->mutex);
if (!iter)
if (iter < 0)
wil_err(wil, "timeout waiting for idle FW/HW\n");
wil_reset(wil, false);
......
/*
* Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
* Copyright (c) 2012-2015 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
......@@ -125,11 +125,37 @@ static int wil_if_pcie_disable(struct wil6210_priv *wil)
return 0;
}
static int wil_platform_rop_ramdump(void *wil_handle, void *buf, uint32_t size)
{
struct wil6210_priv *wil = wil_handle;
if (!wil)
return -EINVAL;
return wil_fw_copy_crash_dump(wil, buf, size);
}
static int wil_platform_rop_fw_recovery(void *wil_handle)
{
struct wil6210_priv *wil = wil_handle;
if (!wil)
return -EINVAL;
wil_fw_error_recovery(wil);
return 0;
}
static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct wil6210_priv *wil;
struct device *dev = &pdev->dev;
int rc;
const struct wil_platform_rops rops = {
.ramdump = wil_platform_rop_ramdump,
.fw_recovery = wil_platform_rop_fw_recovery,
};
/* check HW */
dev_info(&pdev->dev, WIL_NAME
......@@ -154,7 +180,7 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* rollback to if_free */
wil->platform_handle =
wil_platform_init(&pdev->dev, &wil->platform_ops);
wil_platform_init(&pdev->dev, &wil->platform_ops, &rops, wil);
if (!wil->platform_handle) {
rc = -ENODEV;
wil_err(wil, "wil_platform_init failed\n");
......
......@@ -261,9 +261,19 @@ struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
void wil_tid_ampdu_rx_free(struct wil6210_priv *wil,
struct wil_tid_ampdu_rx *r)
{
int i;
if (!r)
return;
wil_release_reorder_frames(wil, r, r->head_seq_num + r->buf_size);
/* Do not pass remaining frames to the network stack - it may be
* not expecting to get any more Rx. Rx from here may lead to
* kernel OOPS since some per-socket accounting info was already
* released.
*/
for (i = 0; i < r->buf_size; i++)
kfree_skb(r->reorder_buf[i]);
kfree(r->reorder_buf);
kfree(r->reorder_time);
kfree(r);
......
......@@ -828,6 +828,7 @@ int wil_can_suspend(struct wil6210_priv *wil, bool is_runtime);
int wil_suspend(struct wil6210_priv *wil, bool is_runtime);
int wil_resume(struct wil6210_priv *wil, bool is_runtime);
int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size);
void wil_fw_core_dump(struct wil6210_priv *wil);
#endif /* __WIL6210_H__ */
......@@ -51,8 +51,7 @@ static int wil_fw_get_crash_dump_bounds(struct wil6210_priv *wil,
return 0;
}
static int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest,
u32 size)
int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size)
{
int i;
const struct fw_map *map;
......
......@@ -33,7 +33,8 @@ void wil_platform_modexit(void)
* It returns a handle which is used with the rest of the API
*
*/
void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops)
void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops,
const struct wil_platform_rops *rops, void *wil_handle)
{
void *handle = ops; /* to return some non-NULL for 'void' impl. */
......
/*
* Copyright (c) 2014 Qualcomm Atheros, Inc.
* Copyright (c) 2014-2015 Qualcomm Atheros, Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
......@@ -20,16 +20,48 @@
struct device;
/**
* struct wil_platform_ops - wil platform module callbacks
* struct wil_platform_ops - wil platform module calls from this
* driver to platform driver
*/
struct wil_platform_ops {
int (*bus_request)(void *handle, uint32_t kbps /* KBytes/Sec */);
int (*suspend)(void *handle);
int (*resume)(void *handle);
void (*uninit)(void *handle);
int (*notify_crash)(void *handle);
};
void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops);
/**
* struct wil_platform_rops - wil platform module callbacks from
* platform driver to this driver
* @ramdump: store a ramdump from the wil firmware. The platform
* driver may add additional data to the ramdump to
* generate the final crash dump.
* @fw_recovery: start a firmware recovery process. Called as
* part of a crash recovery process which may include other
* related platform subsystems.
*/
struct wil_platform_rops {
int (*ramdump)(void *wil_handle, void *buf, uint32_t size);
int (*fw_recovery)(void *wil_handle);
};
/**
* wil_platform_init - initialize the platform driver
*
* @dev - pointer to the wil6210 device
* @ops - structure with platform driver operations. Platform
* driver will fill this structure with function pointers.
* @rops - structure with callbacks from platform driver to
* this driver. The platform driver copies the structure to
* its own storage. Can be NULL if this driver does not
* support crash recovery.
* @wil_handle - context for this driver that will be passed
* when platform driver invokes one of the callbacks in
* rops. May be NULL if rops is NULL.
*/
void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops,
const struct wil_platform_rops *rops, void *wil_handle);
int __init wil_platform_modinit(void);
void wil_platform_modexit(void);
......
......@@ -47,6 +47,8 @@
#include "debug.h"
#include "sdio.h"
#include "of.h"
#include "core.h"
#include "common.h"
#define SDIOH_API_ACCESS_RETRY_LIMIT 2
......@@ -57,7 +59,6 @@
/* Maximum milliseconds to wait for F2 to come up */
#define SDIO_WAIT_F2RDY 3000
#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
#define BRCMF_DEFAULT_RXGLOM_SIZE 32 /* max rx frames in glom chain */
struct brcmf_sdiod_freezer {
......@@ -68,10 +69,6 @@ struct brcmf_sdiod_freezer {
struct completion resumed;
};
static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
MODULE_PARM_DESC(txglomsz, "maximum tx packet chain size [SDIO]");
static irqreturn_t brcmf_sdiod_oob_irqhandler(int irq, void *dev_id)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev_id);
......@@ -890,7 +887,8 @@ static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
if (!sdiodev->sg_support)
return;
nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, brcmf_sdiod_txglomsz);
nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE,
sdiodev->bus_if->drvr->settings->sdiod_txglomsz);
nents += (nents >> 4) + 1;
WARN_ON(nents > sdiodev->max_segment_count);
......@@ -902,7 +900,7 @@ static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev)
sdiodev->sg_support = false;
}
sdiodev->txglomsz = brcmf_sdiod_txglomsz;
sdiodev->txglomsz = sdiodev->bus_if->drvr->settings->sdiod_txglomsz;
}
#ifdef CONFIG_PM_SLEEP
......
......@@ -29,7 +29,7 @@
#include "cfg80211.h"
/* T1 start SCO/eSCO priority suppression */
#define BRCMF_BTCOEX_OPPR_WIN_TIME 2000
#define BRCMF_BTCOEX_OPPR_WIN_TIME msecs_to_jiffies(2000)
/* BT registers values during DHCP */
#define BRCMF_BT_DHCP_REG50 0x8022
......@@ -314,8 +314,7 @@ static void brcmf_btcoex_handler(struct work_struct *work)
} else {
btci->timeout -= BRCMF_BTCOEX_OPPR_WIN_TIME;
mod_timer(&btci->timer,
jiffies +
msecs_to_jiffies(BRCMF_BTCOEX_OPPR_WIN_TIME));
jiffies + BRCMF_BTCOEX_OPPR_WIN_TIME);
}
btci->timer_on = true;
break;
......@@ -328,12 +327,11 @@ static void brcmf_btcoex_handler(struct work_struct *work)
/* DHCP is not over yet, start lowering BT priority */
brcmf_dbg(INFO, "DHCP T1:%d expired\n",
BRCMF_BTCOEX_OPPR_WIN_TIME);
jiffies_to_msecs(BRCMF_BTCOEX_OPPR_WIN_TIME));
brcmf_btcoex_boost_wifi(btci, true);
btci->bt_state = BRCMF_BT_DHCP_FLAG_FORCE_TIMEOUT;
mod_timer(&btci->timer,
jiffies + msecs_to_jiffies(btci->timeout));
mod_timer(&btci->timer, jiffies + btci->timeout);
btci->timer_on = true;
break;
......@@ -477,7 +475,7 @@ int brcmf_btcoex_set_mode(struct brcmf_cfg80211_vif *vif,
return -EBUSY;
/* Start BT timer only for SCO connection */
if (brcmf_btcoex_is_sco_active(ifp)) {
btci->timeout = duration;
btci->timeout = msecs_to_jiffies(duration);
btci->vif = vif;
brcmf_btcoex_dhcp_start(btci);
}
......
......@@ -75,6 +75,8 @@
#define BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON 2
#define BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF 4
#define BRCMF_VIF_EVENT_TIMEOUT msecs_to_jiffies(1500)
/**
* enum brcmf_scan_status - scan engine status
*
......@@ -226,6 +228,27 @@ struct brcmf_cfg80211_vif_event {
struct brcmf_cfg80211_vif *vif;
};
/**
* struct brcmf_cfg80211_wowl - wowl related information.
*
* @active: set on suspend, cleared on resume.
* @pre_pmmode: firmware PM mode at entering suspend.
* @nd: net dectect data.
* @nd_info: helper struct to pass to cfg80211.
* @nd_data_wait: wait queue to sync net detect data.
* @nd_data_completed: completion for net detect data.
* @nd_enabled: net detect enabled.
*/
struct brcmf_cfg80211_wowl {
bool active;
u32 pre_pmmode;
struct cfg80211_wowlan_nd_match *nd;
struct cfg80211_wowlan_nd_info *nd_info;
wait_queue_head_t nd_data_wait;
bool nd_data_completed;
bool nd_enabled;
};
/**
* struct brcmf_cfg80211_info - dongle private data of cfg80211 interface
*
......@@ -259,8 +282,7 @@ struct brcmf_cfg80211_vif_event {
* @vif_list: linked list of vif instances.
* @vif_cnt: number of vif instances.
* @vif_event: vif event signalling.
* @wowl_enabled; set during suspend, is wowl used.
* @pre_wowl_pmmode: intermediate storage of pm mode during wowl.
* @wowl: wowl related information.
*/
struct brcmf_cfg80211_info {
struct wiphy *wiphy;
......@@ -292,9 +314,8 @@ struct brcmf_cfg80211_info {
struct brcmf_cfg80211_vif_event vif_event;
struct completion vif_disabled;
struct brcmu_d11inf d11inf;
bool wowl_enabled;
u32 pre_wowl_pmmode;
struct brcmf_assoclist_le assoclist;
struct brcmf_cfg80211_wowl wowl;
};
/**
......
......@@ -35,6 +35,47 @@ const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
/* boost value for RSSI_DELTA in preferred join selection */
#define BRCMF_JOIN_PREF_RSSI_BOOST 8
#define BRCMF_DEFAULT_TXGLOM_SIZE 32 /* max tx frames in glom chain */
static int brcmf_sdiod_txglomsz = BRCMF_DEFAULT_TXGLOM_SIZE;
module_param_named(txglomsz, brcmf_sdiod_txglomsz, int, 0);
MODULE_PARM_DESC(txglomsz, "Maximum tx packet chain size [SDIO]");
/* Debug level configuration. See debug.h for bits, sysfs modifiable */
int brcmf_msg_level;
module_param_named(debug, brcmf_msg_level, int, S_IRUSR | S_IWUSR);
MODULE_PARM_DESC(debug, "Level of debug output");
static int brcmf_p2p_enable;
module_param_named(p2pon, brcmf_p2p_enable, int, 0);
MODULE_PARM_DESC(p2pon, "Enable legacy p2p management functionality");
static int brcmf_feature_disable;
module_param_named(feature_disable, brcmf_feature_disable, int, 0);
MODULE_PARM_DESC(feature_disable, "Disable features");
static char brcmf_firmware_path[BRCMF_FW_ALTPATH_LEN];
module_param_string(alternative_fw_path, brcmf_firmware_path,
BRCMF_FW_ALTPATH_LEN, S_IRUSR);
MODULE_PARM_DESC(alternative_fw_path, "Alternative firmware path");
static int brcmf_fcmode;
module_param_named(fcmode, brcmf_fcmode, int, 0);
MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control");
static int brcmf_roamoff;
module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");
#ifdef DEBUG
/* always succeed brcmf_bus_start() */
static int brcmf_ignore_probe_fail;
module_param_named(ignore_probe_fail, brcmf_ignore_probe_fail, int, 0);
MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging");
#endif
struct brcmf_mp_global_t brcmf_mp_global;
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
{
s8 eventmask[BRCMF_EVENTING_MASK_LEN];
......@@ -178,3 +219,34 @@ void __brcmf_dbg(u32 level, const char *func, const char *fmt, ...)
va_end(args);
}
#endif
void brcmf_mp_attach(void)
{
strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path,
BRCMF_FW_ALTPATH_LEN);
}
int brcmf_mp_device_attach(struct brcmf_pub *drvr)
{
drvr->settings = kzalloc(sizeof(*drvr->settings), GFP_ATOMIC);
if (!drvr->settings) {
brcmf_err("Failed to alloca storage space for settings\n");
return -ENOMEM;
}
drvr->settings->sdiod_txglomsz = brcmf_sdiod_txglomsz;
drvr->settings->p2p_enable = !!brcmf_p2p_enable;
drvr->settings->feature_disable = brcmf_feature_disable;
drvr->settings->fcmode = brcmf_fcmode;
drvr->settings->roamoff = !!brcmf_roamoff;
#ifdef DEBUG
drvr->settings->ignore_probe_fail = !!brcmf_ignore_probe_fail;
#endif
return 0;
}
void brcmf_mp_device_detach(struct brcmf_pub *drvr)
{
kfree(drvr->settings);
}
......@@ -17,6 +17,62 @@
extern const u8 ALLFFMAC[ETH_ALEN];
#define BRCMF_FW_ALTPATH_LEN 256
/* Definitions for the module global and device specific settings are defined
* here. Two structs are used for them. brcmf_mp_global_t and brcmf_mp_device.
* The mp_global is instantiated once in a global struct and gets initialized
* by the common_attach function which should be called before any other
* (module) initiliazation takes place. The device specific settings is part
* of the drvr struct and should be initialized on every brcmf_attach.
*/
/**