aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/brcm80211/sys/wl_mac80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/brcm80211/sys/wl_mac80211.c')
-rw-r--r--drivers/staging/brcm80211/sys/wl_mac80211.c1026
1 files changed, 245 insertions, 781 deletions
diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c
index d060377..bdd629d 100644
--- a/drivers/staging/brcm80211/sys/wl_mac80211.c
+++ b/drivers/staging/brcm80211/sys/wl_mac80211.c
@@ -21,72 +21,36 @@
#include <linux/string.h>
#include <linux/pci_ids.h>
#include <bcmdefs.h>
-#include <linuxver.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
#include <osl.h>
#define WLC_MAXBSSCFG 1 /* single BSS configs */
#include <wlc_cfg.h>
#include <net/mac80211.h>
-#include <epivers.h>
-#ifndef WLC_HIGH_ONLY
#include <phy_version.h>
-#endif
#include <bcmutils.h>
#include <pcicfg.h>
#include <wlioctl.h>
#include <wlc_key.h>
+#include <sbhndpio.h>
+#include <sbhnddma.h>
#include <wlc_channel.h>
#include <wlc_pub.h>
#include <wlc_scb.h>
#include <wl_dbg.h>
-#ifdef BCMSDIO
-#include <bcmsdh.h>
-#endif
#include <wl_export.h>
-#ifdef WLC_HIGH_ONLY
-#include "dbus.h"
-#include "bcm_rpc_tp.h"
-#include "bcm_rpc.h"
-#include "bcm_xdr.h"
-#include "wlc_rpc.h"
-#endif
#include <wl_mac80211.h>
#include <linux/firmware.h>
-#ifndef WLC_HIGH_ONLY
#include <wl_ucode.h>
#include <d11ucode_ext.h>
-#endif
-#ifdef BCMSDIO
-extern struct device *sdiommc_dev;
-#endif
-
-extern void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg,
- bool suspend);
-bool wlc_sendpkt_mac80211(wlc_info_t *wlc, void *sdu, struct ieee80211_hw *hw);
-void wlc_mac_bcn_promisc_change(wlc_info_t *wlc, bool promisc);
-void wlc_set_addrmatch(wlc_info_t *wlc, int match_reg_offset,
- const struct ether_addr *addr);
static void wl_timer(unsigned long data);
static void _wl_timer(wl_timer_t *t);
-#ifdef WLC_HIGH_ONLY
-#define RPCQ_LOCK(_wl, _flags) spin_lock_irqsave(&(_wl)->rpcq_lock, (_flags))
-#define RPCQ_UNLOCK(_wl, _flags) spin_unlock_irqrestore(&(_wl)->rpcq_lock, (_flags))
-#define TXQ_LOCK(_wl, _flags) spin_lock_irqsave(&(_wl)->txq_lock, (_flags))
-#define TXQ_UNLOCK(_wl, _flags) spin_unlock_irqrestore(&(_wl)->txq_lock, (_flags))
-static void wl_rpc_down(void *wlh);
-static void wl_rpcq_free(wl_info_t *wl);
-static void wl_rpcq_dispatch(struct wl_task *task);
-static void wl_rpc_dispatch_schedule(void *ctx, struct rpc_buf *buf);
-static void wl_start_txqwork(struct wl_task *task);
-static void wl_txq_free(wl_info_t *wl);
-static void wl_timer_task(wl_task_t *task);
-static int wl_schedule_task(wl_info_t *wl, void (*fn) (struct wl_task *),
- void *context);
-#endif /* WLC_HIGH_ONLY */
static int ieee_hw_init(struct ieee80211_hw *hw);
static int ieee_hw_rate_init(struct ieee80211_hw *hw);
@@ -134,16 +98,14 @@ struct ieee80211_tkip_data {
u8 rx_hdr[16], tx_hdr[16];
};
-#ifndef WLC_HIGH_ONLY
-#define WL_DEV_IF(dev) ((wl_if_t *)netdev_priv(dev))
-#define WL_INFO(dev) ((wl_info_t *)(WL_DEV_IF(dev)->wl)) /* points to wl */
-static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev);
-static void wl_release_fw(wl_info_t *wl);
-#endif
+#define WL_DEV_IF(dev) ((struct wl_if *)netdev_priv(dev))
+#define WL_INFO(dev) ((struct wl_info *)(WL_DEV_IF(dev)->wl))
+static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev);
+static void wl_release_fw(struct wl_info *wl);
/* local prototypes */
-static int wl_start(struct sk_buff *skb, wl_info_t *wl);
-static int wl_start_int(wl_info_t *wl, struct ieee80211_hw *hw,
+static int wl_start(struct sk_buff *skb, struct wl_info *wl);
+static int wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw,
struct sk_buff *skb);
static void wl_dpc(unsigned long data);
@@ -152,7 +114,6 @@ MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver.");
MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards");
MODULE_LICENSE("Dual BSD/GPL");
-#ifndef BCMSDIO
/* recognized PCI IDs */
static struct pci_device_id wl_id_table[] = {
{PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43225 2G */
@@ -163,55 +124,18 @@ static struct pci_device_id wl_id_table[] = {
MODULE_DEVICE_TABLE(pci, wl_id_table);
static void wl_remove(struct pci_dev *pdev);
-#endif /* !BCMSDIO */
-#ifdef BCMSDIO
-static uint sd_drivestrength = 6;
-module_param(sd_drivestrength, uint, 0);
-#endif
#ifdef BCMDBG
static int msglevel = 0xdeadbeef;
module_param(msglevel, int, 0);
-#ifndef WLC_HIGH_ONLY
static int phymsglevel = 0xdeadbeef;
module_param(phymsglevel, int, 0);
-#endif /* WLC_HIGH_ONLY */
#endif /* BCMDBG */
-static int oneonly;
-module_param(oneonly, int, 0);
-
-static int piomode;
-module_param(piomode, int, 0);
-
-static int instance_base; /* Starting instance number */
-module_param(instance_base, int, 0);
-
-#if defined(BCMDBG)
-static char *macaddr;
-module_param(macaddr, charp, S_IRUGO);
-#endif
-
-static int nompc = 1;
-module_param(nompc, int, 0);
-
-static char name[IFNAMSIZ] = "eth%d";
-module_param_string(name, name, IFNAMSIZ, 0);
-
-#ifndef SRCBASE
-#define SRCBASE "."
-#endif
-
-#define WL_MAGIC 0xdeadbeef
-
#define HW_TO_WL(hw) (hw->priv)
#define WL_TO_HW(wl) (wl->pub->ieee_hw)
-#ifdef WLC_HIGH_ONLY
-static int wl_ops_tx_nl(struct ieee80211_hw *hw, struct sk_buff *skb);
-#else
static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
-#endif
static int wl_ops_start(struct ieee80211_hw *hw);
static void wl_ops_stop(struct ieee80211_hw *hw);
static int wl_ops_add_interface(struct ieee80211_hw *hw,
@@ -249,28 +173,13 @@ static int wl_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum ieee80211_ampdu_mlme_action action,
struct ieee80211_sta *sta, u16 tid, u16 *ssn);
-#ifdef WLC_HIGH_ONLY
-static int wl_ops_tx_nl(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- int status;
- wl_info_t *wl = hw->priv;
- if (!wl->pub->up) {
- WL_ERROR(("ops->tx called while down\n"));
- status = -ENETDOWN;
- goto done;
- }
- status = wl_start(skb, wl);
- done:
- return status;
-}
-#else
static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
int status;
- wl_info_t *wl = hw->priv;
+ struct wl_info *wl = hw->priv;
WL_LOCK(wl);
if (!wl->pub->up) {
- WL_ERROR(("ops->tx called while down\n"));
+ WL_ERROR("ops->tx called while down\n");
status = -ENETDOWN;
goto done;
}
@@ -279,13 +188,14 @@ static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
WL_UNLOCK(wl);
return status;
}
-#endif /* WLC_HIGH_ONLY */
static int wl_ops_start(struct ieee80211_hw *hw)
{
- wl_info_t *wl = hw->priv;
- /* struct ieee80211_channel *curchan = hw->conf.channel; */
- WL_NONE(("%s : Initial channel: %d\n", __func__, curchan->hw_value));
+ struct wl_info *wl = hw->priv;
+ /*
+ struct ieee80211_channel *curchan = hw->conf.channel;
+ WL_NONE("%s : Initial channel: %d\n", __func__, curchan->hw_value);
+ */
WL_LOCK(wl);
ieee80211_wake_queues(hw);
@@ -296,7 +206,7 @@ static int wl_ops_start(struct ieee80211_hw *hw)
static void wl_ops_stop(struct ieee80211_hw *hw)
{
- wl_info_t *wl = hw->priv;
+ struct wl_info *wl = hw->priv;
ASSERT(wl);
WL_LOCK(wl);
wl_down(wl);
@@ -309,7 +219,7 @@ static void wl_ops_stop(struct ieee80211_hw *hw)
static int
wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
- wl_info_t *wl;
+ struct wl_info *wl;
int err;
/* Just STA for now */
@@ -318,8 +228,8 @@ wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
vif->type != NL80211_IFTYPE_STATION &&
vif->type != NL80211_IFTYPE_WDS &&
vif->type != NL80211_IFTYPE_ADHOC) {
- WL_ERROR(("%s: Attempt to add type %d, only STA for now\n",
- __func__, vif->type));
+ WL_ERROR("%s: Attempt to add type %d, only STA for now\n",
+ __func__, vif->type);
return -EOPNOTSUPP;
}
@@ -329,7 +239,7 @@ wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
WL_UNLOCK(wl);
if (err != 0)
- WL_ERROR(("%s: wl_up() returned %d\n", __func__, err));
+ WL_ERROR("%s: wl_up() returned %d\n", __func__, err);
return err;
}
@@ -343,7 +253,7 @@ static int
ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan,
enum nl80211_channel_type type)
{
- wl_info_t *wl = HW_TO_WL(hw);
+ struct wl_info *wl = HW_TO_WL(hw);
int err = 0;
switch (type) {
@@ -355,8 +265,7 @@ ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan,
break;
case NL80211_CHAN_HT40MINUS:
case NL80211_CHAN_HT40PLUS:
- WL_ERROR(("%s: Need to implement 40 Mhz Channels!\n",
- __func__));
+ WL_ERROR("%s: Need to implement 40 Mhz Channels!\n", __func__);
break;
}
@@ -368,17 +277,17 @@ ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan,
static int wl_ops_config(struct ieee80211_hw *hw, u32 changed)
{
struct ieee80211_conf *conf = &hw->conf;
- wl_info_t *wl = HW_TO_WL(hw);
+ struct wl_info *wl = HW_TO_WL(hw);
int err = 0;
int new_int;
if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) {
- WL_NONE(("%s: Setting listen interval to %d\n",
- __func__, conf->listen_interval));
+ WL_NONE("%s: Setting listen interval to %d\n",
+ __func__, conf->listen_interval);
if (wlc_iovar_setint
(wl->wlc, "bcn_li_bcn", conf->listen_interval)) {
- WL_ERROR(("%s: Error setting listen_interval\n",
- __func__));
+ WL_ERROR("%s: Error setting listen_interval\n",
+ __func__);
err = -EIO;
goto config_out;
}
@@ -386,41 +295,42 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed)
ASSERT(new_int == conf->listen_interval);
}
if (changed & IEEE80211_CONF_CHANGE_MONITOR)
- WL_NONE(("Need to set monitor mode\n"));
+ WL_NONE("Need to set monitor mode\n");
if (changed & IEEE80211_CONF_CHANGE_PS)
- WL_NONE(("Need to set Power-save mode\n"));
+ WL_NONE("Need to set Power-save mode\n");
if (changed & IEEE80211_CONF_CHANGE_POWER) {
- WL_NONE(("%s: Setting tx power to %d dbm\n", __func__,
- conf->power_level));
+ WL_NONE("%s: Setting tx power to %d dbm\n",
+ __func__, conf->power_level);
if (wlc_iovar_setint
(wl->wlc, "qtxpower", conf->power_level * 4)) {
- WL_ERROR(("%s: Error setting power_level\n", __func__));
+ WL_ERROR("%s: Error setting power_level\n", __func__);
err = -EIO;
goto config_out;
}
wlc_iovar_getint(wl->wlc, "qtxpower", &new_int);
if (new_int != (conf->power_level * 4))
- WL_ERROR(("%s: Power level req != actual, %d %d\n",
- __func__, conf->power_level * 4, new_int));
+ WL_ERROR("%s: Power level req != actual, %d %d\n",
+ __func__, conf->power_level * 4, new_int);
}
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
err = ieee_set_channel(hw, conf->channel, conf->channel_type);
}
if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) {
- WL_NONE(("%s: srl %d, lrl %d\n", __func__,
- conf->short_frame_max_tx_count,
- conf->long_frame_max_tx_count));
+ WL_NONE("%s: srl %d, lrl %d\n",
+ __func__,
+ conf->short_frame_max_tx_count,
+ conf->long_frame_max_tx_count);
if (wlc_set
(wl->wlc, WLC_SET_SRL,
conf->short_frame_max_tx_count) < 0) {
- WL_ERROR(("%s: Error setting srl\n", __func__));
+ WL_ERROR("%s: Error setting srl\n", __func__);
err = -EIO;
goto config_out;
}
if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count)
< 0) {
- WL_ERROR(("%s: Error setting lrl\n", __func__));
+ WL_ERROR("%s: Error setting lrl\n", __func__);
err = -EIO;
goto config_out;
}
@@ -435,32 +345,29 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info, u32 changed)
{
- wl_info_t *wl = HW_TO_WL(hw);
+ struct wl_info *wl = HW_TO_WL(hw);
int val;
-#ifdef WLC_HIGH_ONLY
- WL_LOCK(wl);
-#endif
if (changed & BSS_CHANGED_ASSOC) {
- WL_ERROR(("Associated:\t%s\n", info->assoc ? "True" : "False"));
+ WL_ERROR("Associated:\t%s\n", info->assoc ? "True" : "False");
/* association status changed (associated/disassociated)
* also implies a change in the AID.
*/
}
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
- WL_NONE(("Use_cts_prot:\t%s Implement me\n",
- info->use_cts_prot ? "True" : "False"));
+ WL_NONE("Use_cts_prot:\t%s Implement me\n",
+ info->use_cts_prot ? "True" : "False");
/* CTS protection changed */
}
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
- WL_NONE(("Short preamble:\t%s Implement me\n",
- info->use_short_preamble ? "True" : "False"));
+ WL_NONE("Short preamble:\t%s Implement me\n",
+ info->use_short_preamble ? "True" : "False");
/* preamble changed */
}
if (changed & BSS_CHANGED_ERP_SLOT) {
- WL_NONE(("Changing short slot:\t%s\n",
- info->use_short_slot ? "True" : "False"));
+ WL_NONE("Changing short slot:\t%s\n",
+ info->use_short_slot ? "True" : "False");
if (info->use_short_slot)
val = 1;
else
@@ -470,39 +377,36 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw,
}
if (changed & BSS_CHANGED_HT) {
- WL_NONE(("%s: HT mode - Implement me\n", __func__));
+ WL_NONE("%s: HT mode - Implement me\n", __func__);
/* 802.11n parameters changed */
}
if (changed & BSS_CHANGED_BASIC_RATES) {
- WL_NONE(("Need to change Basic Rates:\t0x%x! Implement me\n",
- (u32) info->basic_rates));
+ WL_NONE("Need to change Basic Rates:\t0x%x! Implement me\n",
+ (u32) info->basic_rates);
/* Basic rateset changed */
}
if (changed & BSS_CHANGED_BEACON_INT) {
- WL_NONE(("Beacon Interval:\t%d Implement me\n",
- info->beacon_int));
+ WL_NONE("Beacon Interval:\t%d Implement me\n",
+ info->beacon_int);
/* Beacon interval changed */
}
if (changed & BSS_CHANGED_BSSID) {
- WL_NONE(("new BSSID:\taid %d bss:%pM\n", info->aid,
- info->bssid));
+ WL_NONE("new BSSID:\taid %d bss:%pM\n",
+ info->aid, info->bssid);
/* BSSID changed, for whatever reason (IBSS and managed mode) */
/* FIXME: need to store bssid in bsscfg */
wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET,
(struct ether_addr *)info->bssid);
}
if (changed & BSS_CHANGED_BEACON) {
- WL_ERROR(("BSS_CHANGED_BEACON\n"));
+ WL_ERROR("BSS_CHANGED_BEACON\n");
/* Beacon data changed, retrieve new beacon (beaconing modes) */
}
if (changed & BSS_CHANGED_BEACON_ENABLED) {
- WL_ERROR(("Beacon enabled:\t%s\n",
- info->enable_beacon ? "True" : "False"));
+ WL_ERROR("Beacon enabled:\t%s\n",
+ info->enable_beacon ? "True" : "False");
/* Beaconing should be enabled/disabled (beaconing modes) */
}
-#ifdef WLC_HIGH_ONLY
- WL_UNLOCK(wl);
-#endif
return;
}
@@ -511,27 +415,24 @@ wl_ops_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags, u64 multicast)
{
-#ifndef WLC_HIGH_ONLY
- wl_info_t *wl = hw->priv;
-#endif
+ struct wl_info *wl = hw->priv;
changed_flags &= MAC_FILTERS;
*total_flags &= MAC_FILTERS;
if (changed_flags & FIF_PROMISC_IN_BSS)
- WL_ERROR(("FIF_PROMISC_IN_BSS\n"));
+ WL_ERROR("FIF_PROMISC_IN_BSS\n");
if (changed_flags & FIF_ALLMULTI)
- WL_ERROR(("FIF_ALLMULTI\n"));
+ WL_ERROR("FIF_ALLMULTI\n");
if (changed_flags & FIF_FCSFAIL)
- WL_ERROR(("FIF_FCSFAIL\n"));
+ WL_ERROR("FIF_FCSFAIL\n");
if (changed_flags & FIF_PLCPFAIL)
- WL_ERROR(("FIF_PLCPFAIL\n"));
+ WL_ERROR("FIF_PLCPFAIL\n");
if (changed_flags & FIF_CONTROL)
- WL_ERROR(("FIF_CONTROL\n"));
+ WL_ERROR("FIF_CONTROL\n");
if (changed_flags & FIF_OTHER_BSS)
- WL_ERROR(("FIF_OTHER_BSS\n"));
+ WL_ERROR("FIF_OTHER_BSS\n");
if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
- WL_NONE(("FIF_BCN_PRBRESP_PROMISC\n"));
-#ifndef WLC_HIGH_ONLY
+ WL_NONE("FIF_BCN_PRBRESP_PROMISC\n");
WL_LOCK(wl);
if (*total_flags & FIF_BCN_PRBRESP_PROMISC) {
wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS;
@@ -541,7 +442,6 @@ wl_ops_configure_filter(struct ieee80211_hw *hw,
wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS;
}
WL_UNLOCK(wl);
-#endif
}
return;
}
@@ -549,25 +449,25 @@ wl_ops_configure_filter(struct ieee80211_hw *hw,
static int
wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set)
{
- WL_ERROR(("%s: Enter\n", __func__));
+ WL_ERROR("%s: Enter\n", __func__);
return 0;
}
static void wl_ops_sw_scan_start(struct ieee80211_hw *hw)
{
- WL_NONE(("Scan Start\n"));
+ WL_NONE("Scan Start\n");
return;
}
static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw)
{
- WL_NONE(("Scan Complete\n"));
+ WL_NONE("Scan Complete\n");
return;
}
static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf)
{
- WL_ERROR(("%s: Enter\n", __func__));
+ WL_ERROR("%s: Enter\n", __func__);
return;
}
@@ -575,13 +475,13 @@ static int
wl_ops_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats)
{
- WL_ERROR(("%s: Enter\n", __func__));
+ WL_ERROR("%s: Enter\n", __func__);
return 0;
}
static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
{
- WL_ERROR(("%s: Enter\n", __func__));
+ WL_ERROR("%s: Enter\n", __func__);
return 0;
}
@@ -589,10 +489,10 @@ static void
wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
{
- WL_NONE(("%s: Enter\n", __func__));
+ WL_NONE("%s: Enter\n", __func__);
switch (cmd) {
default:
- WL_ERROR(("%s: Uknown cmd = %d\n", __func__, cmd));
+ WL_ERROR("%s: Unknown cmd = %d\n", __func__, cmd);
break;
}
return;
@@ -602,11 +502,11 @@ static int
wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
const struct ieee80211_tx_queue_params *params)
{
- wl_info_t *wl = hw->priv;
+ struct wl_info *wl = hw->priv;
- WL_NONE(("%s: Enter (WME config)\n", __func__));
- WL_NONE(("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue,
- params->txop, params->cw_min, params->cw_max, params->aifs));
+ WL_NONE("%s: Enter (WME config)\n", __func__);
+ WL_NONE("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue,
+ params->txop, params->cw_min, params->cw_max, params->aifs);
WL_LOCK(wl);
wlc_wme_setparams(wl->wlc, queue, (void *)params, true);
@@ -617,7 +517,7 @@ wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue,
static u64 wl_ops_get_tsf(struct ieee80211_hw *hw)
{
- WL_ERROR(("%s: Enter\n", __func__));
+ WL_ERROR("%s: Enter\n", __func__);
return 0;
}
@@ -628,11 +528,11 @@ wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct scb *scb;
int i;
- wl_info_t *wl = hw->priv;
+ struct wl_info *wl = hw->priv;
/* Init the scb */
scb = (struct scb *)sta->drv_priv;
- bzero(scb, sizeof(struct scb));
+ memset(scb, 0, sizeof(struct scb));
for (i = 0; i < NUMPRIO; i++)
scb->seqctl[i] = 0xFFFF;
scb->seqctl_nonqos = 0xFFFF;
@@ -641,20 +541,12 @@ wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
wl->pub->global_scb = scb;
wl->pub->global_ampdu = &(scb->scb_ampdu);
wl->pub->global_ampdu->scb = scb;
-#ifdef WLC_HIGH_ONLY
- wl->pub->global_ampdu->max_pdu = AMPDU_NUM_MPDU;
-#else
wl->pub->global_ampdu->max_pdu = 16;
-#endif
pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID,
AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT);
sta->ht_cap.ht_supported = true;
-#ifdef WLC_HIGH_ONLY
- sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_16K;
-#else
sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_64K;
-#endif
sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY;
sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD |
IEEE80211_HT_CAP_SGI_20 |
@@ -668,7 +560,7 @@ static int
wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta)
{
- WL_NONE(("%s: Enter\n", __func__));
+ WL_NONE("%s: Enter\n", __func__);
return 0;
}
@@ -681,19 +573,19 @@ wl_ampdu_action(struct ieee80211_hw *hw,
#if defined(BCMDBG)
struct scb *scb = (struct scb *)sta->drv_priv;
#endif
- wl_info_t *wl = hw->priv;
+ struct wl_info *wl = hw->priv;
ASSERT(scb->magic == SCB_MAGIC);
switch (action) {
case IEEE80211_AMPDU_RX_START:
- WL_NONE(("%s: action = IEEE80211_AMPDU_RX_START\n", __func__));
+ WL_NONE("%s: action = IEEE80211_AMPDU_RX_START\n", __func__);
break;
case IEEE80211_AMPDU_RX_STOP:
- WL_NONE(("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__));
+ WL_NONE("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__);
break;
case IEEE80211_AMPDU_TX_START:
if (!wlc_aggregatable(wl->wlc, tid)) {
- /* WL_ERROR(("START: tid %d is not agg' able, return FAILURE to stack\n", tid)); */
+ /* WL_ERROR("START: tid %d is not agg' able, return FAILURE to stack\n", tid); */
return -1;
}
/* XXX: Use the starting sequence number provided ... */
@@ -707,22 +599,18 @@ wl_ampdu_action(struct ieee80211_hw *hw,
case IEEE80211_AMPDU_TX_OPERATIONAL:
/* Not sure what to do here */
/* Power save wakeup */
- WL_NONE(("%s: action = IEEE80211_AMPDU_TX_OPERATIONAL\n",
- __func__));
+ WL_NONE("%s: action = IEEE80211_AMPDU_TX_OPERATIONAL\n",
+ __func__);
break;
default:
- WL_ERROR(("%s: Invalid command, ignoring\n", __func__));
+ WL_ERROR("%s: Invalid command, ignoring\n", __func__);
}
return 0;
}
static const struct ieee80211_ops wl_ops = {
-#ifdef WLC_HIGH_ONLY
- .tx = wl_ops_tx_nl,
-#else
.tx = wl_ops_tx,
-#endif
.start = wl_ops_start,
.stop = wl_ops_stop,
.add_interface = wl_ops_add_interface,
@@ -744,10 +632,10 @@ static const struct ieee80211_ops wl_ops = {
.ampdu_action = wl_ampdu_action,
};
-static int wl_set_hint(wl_info_t *wl, char *abbrev)
+static int wl_set_hint(struct wl_info *wl, char *abbrev)
{
- WL_ERROR(("%s: Sending country code %c%c to MAC80211\n", __func__,
- abbrev[0], abbrev[1]));
+ WL_ERROR("%s: Sending country code %c%c to MAC80211\n",
+ __func__, abbrev[0], abbrev[1]);
return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev);
}
@@ -762,117 +650,61 @@ static int wl_set_hint(wl_info_t *wl, char *abbrev)
* a warning that this function is defined but not used if we declare
* it as static.
*/
-static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs,
+static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs,
uint bustype, void *btparam, uint irq)
{
- wl_info_t *wl;
- osl_t *osh;
+ struct wl_info *wl;
+ struct osl_info *osh;
int unit, err;
unsigned long base_addr;
struct ieee80211_hw *hw;
u8 perm[ETH_ALEN];
- unit = wl_found + instance_base;
+ unit = wl_found;
err = 0;
if (unit < 0) {
- WL_ERROR(("wl%d: unit number overflow, exiting\n", unit));
+ WL_ERROR("wl%d: unit number overflow, exiting\n", unit);
return NULL;
}
- if (oneonly && (unit != instance_base)) {
- WL_ERROR(("wl%d: wl_attach: oneonly is set, exiting\n", unit));
- return NULL;
- }
-
- /* Requires pkttag feature */
- osh = osl_attach(btparam, bustype, true);
+ osh = osl_attach(btparam, bustype);
ASSERT(osh);
-#ifdef WLC_HIGH_ONLY
- hw = ieee80211_alloc_hw(sizeof(wl_info_t), &wl_ops);
- if (!hw) {
- WL_ERROR(("%s: ieee80211_alloc_hw failed\n", __func__));
- ASSERT(0);
- }
-
- bzero(hw->priv, sizeof(*wl));
- wl = hw->priv;
-#else
/* allocate private info */
hw = pci_get_drvdata(btparam); /* btparam == pdev */
wl = hw->priv;
-#endif
ASSERT(wl);
- wl->magic = WL_MAGIC;
wl->osh = osh;
atomic_set(&wl->callbacks, 0);
/* setup the bottom half handler */
tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl);
-#ifdef WLC_HIGH_ONLY
- wl->rpc_th = bcm_rpc_tp_attach(osh, NULL);
- if (wl->rpc_th == NULL) {
- WL_ERROR(("wl%d: %s: bcm_rpc_tp_attach failed!\n", unit,
- __func__));
- goto fail;
- }
-
- wl->rpc = bcm_rpc_attach(NULL, osh, wl->rpc_th);
- if (wl->rpc == NULL) {
- WL_ERROR(("wl%d: %s: bcm_rpc_attach failed!\n", unit,
- __func__));
- goto fail;
- }
-
- /* init tx work queue for wl_start/send pkt; no need to destroy workitem */
- INIT_WORK(&wl->txq_task.work, (work_func_t) wl_start_txqwork);
- wl->txq_task.context = wl;
-#endif /* WLC_HIGH_ONLY */
-#ifdef BCMSDIO
- SET_IEEE80211_DEV(hw, sdiommc_dev);
-#endif
base_addr = regs;
if (bustype == PCI_BUS) {
- /* piomode can be overwritten by command argument */
- wl->piomode = piomode;
- WL_TRACE(("PCI/%s\n", wl->piomode ? "PIO" : "DMA"));
+ wl->piomode = false;
} else if (bustype == RPC_BUS) {
/* Do nothing */
} else {
bustype = PCI_BUS;
- WL_TRACE(("force to PCI\n"));
+ WL_TRACE("force to PCI\n");
}
wl->bcm_bustype = bustype;
-#ifdef WLC_HIGH_ONLY
- if (wl->bcm_bustype == RPC_BUS) {
- wl->regsva = (void *)0;
- btparam = wl->rpc;
- } else
-#endif
wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ);
if (wl->regsva == NULL) {
- WL_ERROR(("wl%d: ioremap() failed\n", unit));
+ WL_ERROR("wl%d: ioremap() failed\n", unit);
goto fail;
}
-#ifdef WLC_HIGH_ONLY
- spin_lock_init(&wl->rpcq_lock);
- spin_lock_init(&wl->txq_lock);
-
- sema_init(&wl->sem, 1);
-#else
spin_lock_init(&wl->lock);
spin_lock_init(&wl->isr_lock);
-#endif
-#ifndef WLC_HIGH_ONLY
/* prepare ucode */
if (wl_request_fw(wl, (struct pci_dev *)btparam)) {
printf("%s: Failed to find firmware usually in %s\n",
@@ -881,17 +713,14 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs,
wl_remove((struct pci_dev *)btparam);
goto fail1;
}
-#endif
/* common load-time initialization */
wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, osh,
wl->regsva, wl->bcm_bustype, btparam, &err);
-#ifndef WLC_HIGH_ONLY
wl_release_fw(wl);
-#endif
if (!wl->wlc) {
- printf("%s: %s wlc_attach() failed with code %d\n",
- KBUILD_MODNAME, EPI_VERSION_STR, err);
+ printf("%s: wlc_attach() failed with code %d\n",
+ KBUILD_MODNAME, err);
goto fail;
}
wl->pub = wlc_pub(wl->wlc);
@@ -900,52 +729,35 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs,
ASSERT(wl->pub->ieee_hw);
ASSERT(wl->pub->ieee_hw->priv == wl);
-#ifdef WLC_HIGH_ONLY
- REGOPSSET(osh, (osl_rreg_fn_t) wlc_reg_read,
- (osl_wreg_fn_t) wlc_reg_write, wl->wlc);
- wl->rpc_dispatch_ctx.rpc = wl->rpc;
- wl->rpc_dispatch_ctx.wlc = wl->wlc;
- bcm_rpc_rxcb_init(wl->rpc, wl, wl_rpc_dispatch_schedule, wl,
- wl_rpc_down, NULL, NULL);
-#endif /* WLC_HIGH_ONLY */
-
- if (nompc) {
- if (wlc_iovar_setint(wl->wlc, "mpc", 0)) {
- WL_ERROR(("wl%d: Error setting MPC variable to 0\n",
- unit));
- }
+
+ if (wlc_iovar_setint(wl->wlc, "mpc", 0)) {
+ WL_ERROR("wl%d: Error setting MPC variable to 0\n", unit);
}
-#ifdef BCMSDIO
- /* Set SDIO drive strength */
- wlc_iovar_setint(wl->wlc, "sd_drivestrength", sd_drivestrength);
-#endif
-#ifdef WLC_LOW
/* register our interrupt handler */
if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
- WL_ERROR(("wl%d: request_irq() failed\n", unit));
+ WL_ERROR("wl%d: request_irq() failed\n", unit);
goto fail;
}
wl->irq = irq;
-#endif /* WLC_LOW */
/* register module */
wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog,
NULL);
if (ieee_hw_init(hw)) {
- WL_ERROR(("wl%d: %s: ieee_hw_init failed!\n", unit, __func__));
+ WL_ERROR("wl%d: %s: ieee_hw_init failed!\n", unit, __func__);
goto fail;
}
- bcopy(&wl->pub->cur_etheraddr, perm, ETHER_ADDR_LEN);
+ bcopy(&wl->pub->cur_etheraddr, perm, ETH_ALEN);
ASSERT(is_valid_ether_addr(perm));
SET_IEEE80211_PERM_ADDR(hw, perm);
err = ieee80211_register_hw(hw);
if (err) {
- WL_ERROR(("%s: ieee80211_register_hw failed, status %d\n",
- __func__, err));
+ WL_ERROR("%s: ieee80211_register_hw failed, status %d\n",
+ __func__, err);
}
if (wl->pub->srom_ccode[0])
@@ -953,19 +765,14 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs,
else
err = wl_set_hint(wl, "US");
if (err) {
- WL_ERROR(("%s: regulatory_hint failed, status %d\n", __func__,
- err));
- }
-#ifndef WLC_HIGH_ONLY
- WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver "
- EPI_VERSION_STR " (" PHY_VERSION_STR ")", unit));
-#else
- WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver "
- EPI_VERSION_STR, unit));
-#endif
+ WL_ERROR("%s: regulatory_hint failed, status %d\n",
+ __func__, err);
+ }
+ WL_ERROR("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver (" PHY_VERSION_STR ")",
+ unit);
#ifdef BCMDBG
- printf(" (Compiled in " SRCBASE " at " __TIME__ " on " __DATE__ ")");
+ printf(" (Compiled at " __TIME__ " on " __DATE__ ")");
#endif /* BCMDBG */
printf("\n");
@@ -978,54 +785,6 @@ fail1:
return NULL;
}
-#ifdef WLC_HIGH_ONLY
-static void *wl_dbus_probe_cb(void *arg, const char *desc, u32 bustype,
- u32 hdrlen)
-{
- wl_info_t *wl;
- WL_ERROR(("%s:\n", __func__));
-
- wl = wl_attach(BCM_DNGL_VID, BCM_DNGL_BDC_PID, (unsigned long) NULL, RPC_BUS,
- NULL, 0);
- if (!wl) {
- WL_ERROR(("%s: wl_attach failed\n", __func__));
- }
-
- /* This is later passed to wl_dbus_disconnect_cb */
- return wl;
-}
-
-static void wl_dbus_disconnect_cb(void *arg)
-{
- wl_info_t *wl = arg;
-
- WL_ERROR(("%s:\n", __func__));
-
- if (wl) {
-#ifdef WLC_HIGH_ONLY
- if (wl->pub->ieee_hw) {
- ieee80211_unregister_hw(wl->pub->ieee_hw);
- WL_ERROR(("%s: Back from down\n", __func__));
- }
- wlc_device_removed(wl->wlc);
- wlc_bmac_dngl_reboot(wl->rpc);
- bcm_rpc_down(wl->rpc);
-#endif
- WL_LOCK(wl);
- wl_down(wl);
- WL_UNLOCK(wl);
-#ifdef WLC_HIGH_ONLY
- if (wl->pub->ieee_hw) {
- ieee80211_free_hw(wl->pub->ieee_hw);
- WL_ERROR(("%s: Back from ieee80211_free_hw\n",
- __func__));
- wl->pub->ieee_hw = NULL;
- }
-#endif
- wl_free(wl);
- }
-}
-#endif /* WLC_HIGH_ONLY */
#define CHAN2GHZ(channel, freqency, chflags) { \
@@ -1163,29 +922,13 @@ static struct ieee80211_supported_band wl_band_2GHz_nphy = {
.cap = IEEE80211_HT_CAP_GRN_FLD |
IEEE80211_HT_CAP_SGI_20 |
IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT,
-#ifdef WLC_HIGH_ONLY
- .ht_supported = true,
- .ampdu_factor = AMPDU_RX_FACTOR_16K,
-#else
.ht_supported = true,
.ampdu_factor = AMPDU_RX_FACTOR_64K,
-#endif
.ampdu_density = AMPDU_DEF_MPDU_DENSITY,
.mcs = {
/* placeholders for now */
-#ifdef WLC_HIGH_ONLY
- /*
- * rx_mask[0] = 0xff by default
- * rx_mask[1] = 0xff if number of rx chain >=2
- * rx_mask[2] = 0xff if number of rx chain >=3
- * rx_mask[4] = 1 if 40Mhz is supported
- */
- .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- .rx_highest = 72, /* max rate of single stream */
-#else
.rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0},
.rx_highest = 500,
-#endif
.tx_params = IEEE80211_HT_MCS_TX_DEFINED}
}
};
@@ -1212,7 +955,7 @@ static struct ieee80211_supported_band wl_band_5GHz_nphy = {
static int ieee_hw_rate_init(struct ieee80211_hw *hw)
{
- wl_info_t *wl = HW_TO_WL(hw);
+ struct wl_info *wl = HW_TO_WL(hw);
int has_5g;
char phy_list[4];
@@ -1222,20 +965,16 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw)
hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL;
if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) {
- WL_ERROR(("Phy list failed\n"));
+ WL_ERROR("Phy list failed\n");
}
- WL_NONE(("%s: phylist = %c\n", __func__, phy_list[0]));
+ WL_NONE("%s: phylist = %c\n", __func__, phy_list[0]);
-#ifndef WLC_HIGH_ONLY
if (phy_list[0] == 'n' || phy_list[0] == 'c') {
if (phy_list[0] == 'c') {
/* Single stream */
wl_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0;
wl_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72;
}
-#else
- if (phy_list[0] == 's') {
-#endif
hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy;
} else {
BUG();
@@ -1245,11 +984,7 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw)
/* Assume all bands use the same phy. True for 11n devices. */
if (NBANDS_PUB(wl->pub) > 1) {
has_5g++;
-#ifndef WLC_HIGH_ONLY
if (phy_list[0] == 'n' || phy_list[0] == 'c') {
-#else
- if (phy_list[0] == 's') {
-#endif
hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
&wl_band_5GHz_nphy;
} else {
@@ -1257,7 +992,7 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw)
}
}
- WL_NONE(("%s: 2ghz = %d, 5ghz = %d\n", __func__, 1, has_5g));
+ WL_NONE("%s: 2ghz = %d, 5ghz = %d\n", __func__, 1, has_5g);
return 0;
}
@@ -1288,7 +1023,6 @@ static int ieee_hw_init(struct ieee80211_hw *hw)
return ieee_hw_rate_init(hw);
}
-#ifndef BCMSDIO
/**
* determines if a device is a WL device, and if so, attaches it.
*
@@ -1300,15 +1034,15 @@ int __devinit
wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int rc;
- wl_info_t *wl;
+ struct wl_info *wl;
struct ieee80211_hw *hw;
u32 val;
ASSERT(pdev);
- WL_TRACE(("%s: bus %d slot %d func %d irq %d\n", __func__,
- pdev->bus->number, PCI_SLOT(pdev->devfn),
- PCI_FUNC(pdev->devfn), pdev->irq));
+ WL_TRACE("%s: bus %d slot %d func %d irq %d\n",
+ __func__, pdev->bus->number, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn), pdev->irq);
if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) ||
(((pdev->device & 0xff00) != 0x4300) &&
@@ -1318,9 +1052,9 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = pci_enable_device(pdev);
if (rc) {
- WL_ERROR(("%s: Cannot enable device %d-%d_%d\n", __func__,
- pdev->bus->number, PCI_SLOT(pdev->devfn),
- PCI_FUNC(pdev->devfn)));
+ WL_ERROR("%s: Cannot enable device %d-%d_%d\n",
+ __func__, pdev->bus->number, PCI_SLOT(pdev->devfn),
+ PCI_FUNC(pdev->devfn));
return -ENODEV;
}
pci_set_master(pdev);
@@ -1329,9 +1063,9 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if ((val & 0x0000ff00) != 0)
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
- hw = ieee80211_alloc_hw(sizeof(wl_info_t), &wl_ops);
+ hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops);
if (!hw) {
- WL_ERROR(("%s: ieee80211_alloc_hw failed\n", __func__));
+ WL_ERROR("%s: ieee80211_alloc_hw failed\n", __func__);
rc = -ENOMEM;
goto err_1;
}
@@ -1340,34 +1074,34 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, hw);
- bzero(hw->priv, sizeof(*wl));
+ memset(hw->priv, 0, sizeof(*wl));
wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0),
PCI_BUS, pdev, pdev->irq);
if (!wl) {
- WL_ERROR(("%s: %s: wl_attach failed!\n",
- KBUILD_MODNAME, __func__));
+ WL_ERROR("%s: %s: wl_attach failed!\n",
+ KBUILD_MODNAME, __func__);
return -ENODEV;
}
return 0;
err_1:
- WL_ERROR(("%s: err_1: Major hoarkage\n", __func__));
+ WL_ERROR("%s: err_1: Major hoarkage\n", __func__);
return 0;
}
#ifdef LINUXSTA_PS
static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
{
- wl_info_t *wl;
+ struct wl_info *wl;
struct ieee80211_hw *hw;
- WL_TRACE(("wl: wl_suspend\n"));
+ WL_TRACE("wl: wl_suspend\n");
hw = pci_get_drvdata(pdev);
wl = HW_TO_WL(hw);
if (!wl) {
- WL_ERROR(("wl: wl_suspend: pci_get_drvdata failed\n"));
+ WL_ERROR("wl: wl_suspend: pci_get_drvdata failed\n");
return -ENODEV;
}
@@ -1382,16 +1116,16 @@ static int wl_suspend(struct pci_dev *pdev, pm_message_t state)
static int wl_resume(struct pci_dev *pdev)
{
- wl_info_t *wl;
+ struct wl_info *wl;
struct ieee80211_hw *hw;
int err = 0;
u32 val;
- WL_TRACE(("wl: wl_resume\n"));
+ WL_TRACE("wl: wl_resume\n");
hw = pci_get_drvdata(pdev);
wl = HW_TO_WL(hw);
if (!wl) {
- WL_ERROR(("wl: wl_resume: pci_get_drvdata failed\n"));
+ WL_ERROR("wl: wl_resume: pci_get_drvdata failed\n");
return -ENODEV;
}
@@ -1421,17 +1155,17 @@ static int wl_resume(struct pci_dev *pdev)
static void wl_remove(struct pci_dev *pdev)
{
- wl_info_t *wl;
+ struct wl_info *wl;
struct ieee80211_hw *hw;
hw = pci_get_drvdata(pdev);
wl = HW_TO_WL(hw);
if (!wl) {
- WL_ERROR(("wl: wl_remove: pci_get_drvdata failed\n"));
+ WL_ERROR("wl: wl_remove: pci_get_drvdata failed\n");
return;
}
if (!wlc_chipmatch(pdev->vendor, pdev->device)) {
- WL_ERROR(("wl: wl_remove: wlc_chipmatch failed\n"));
+ WL_ERROR("wl: wl_remove: wlc_chipmatch failed\n");
return;
}
if (wl->wlc) {
@@ -1439,7 +1173,7 @@ static void wl_remove(struct pci_dev *pdev)
WL_LOCK(wl);
wl_down(wl);
WL_UNLOCK(wl);
- WL_NONE(("%s: Down\n", __func__));
+ WL_NONE("%s: Down\n", __func__);
}
pci_disable_device(pdev);
@@ -1459,7 +1193,6 @@ static struct pci_driver wl_pci_driver = {
.remove = __devexit_p(wl_remove),
.id_table = wl_id_table,
};
-#endif /* !BCMSDIO */
/**
* This is the main entry point for the WL driver.
@@ -1480,7 +1213,6 @@ static int __init wl_module_init(void)
if (var)
wl_msg_level = simple_strtoul(var, NULL, 0);
}
-#ifndef WLC_HIGH_ONLY
{
extern u32 phyhal_msg_level;
@@ -1492,25 +1224,13 @@ static int __init wl_module_init(void)
phyhal_msg_level = simple_strtoul(var, NULL, 0);
}
}
-#endif /* WLC_HIGH_ONLY */
#endif /* BCMDBG */
-#ifndef BCMSDIO
error = pci_register_driver(&wl_pci_driver);
if (!error)
return 0;
-#endif /* !BCMSDIO */
-#ifdef WLC_HIGH_ONLY
- /* BMAC_NOTE: define hardcode number, why NODEVICE is ok ? */
- error =
- dbus_register(BCM_DNGL_VID, 0, wl_dbus_probe_cb,
- wl_dbus_disconnect_cb, NULL, NULL, NULL);
- if (error == DBUS_ERR_NODEVICE) {
- error = DBUS_OK;
- }
-#endif /* WLC_HIGH_ONLY */
return error;
}
@@ -1524,13 +1244,8 @@ static int __init wl_module_init(void)
*/
static void __exit wl_module_exit(void)
{
-#ifndef BCMSDIO
pci_unregister_driver(&wl_pci_driver);
-#endif /* !BCMSDIO */
-#ifdef WLC_HIGH_ONLY
- dbus_deregister();
-#endif /* WLC_HIGH_ONLY */
}
module_init(wl_module_init);
@@ -1543,19 +1258,17 @@ module_exit(wl_module_exit);
* by the wl parameter.
*
*/
-void wl_free(wl_info_t *wl)
+void wl_free(struct wl_info *wl)
{
wl_timer_t *t, *next;
- osl_t *osh;
+ struct osl_info *osh;
ASSERT(wl);
-#ifndef WLC_HIGH_ONLY
/* free ucode data */
if (wl->fw.fw_cnt)
wl_ucode_data_free();
if (wl->irq)
free_irq(wl->irq, wl);
-#endif
/* kill dpc */
tasklet_kill(&wl->tasklet);
@@ -1593,103 +1306,50 @@ void wl_free(wl_info_t *wl)
* unregister_netdev() calls get_stats() which may read chip registers
* so we cannot unmap the chip registers until after calling unregister_netdev() .
*/
- if (wl->regsva && BUSTYPE(wl->bcm_bustype) != SDIO_BUS &&
- BUSTYPE(wl->bcm_bustype) != JTAG_BUS) {
+ if (wl->regsva && wl->bcm_bustype != SDIO_BUS &&
+ wl->bcm_bustype != JTAG_BUS) {
iounmap((void *)wl->regsva);
}
wl->regsva = NULL;
-#ifdef WLC_HIGH_ONLY
- wl_rpcq_free(wl);
-
- wl_txq_free(wl);
-
- if (wl->rpc) {
- bcm_rpc_detach(wl->rpc);
- wl->rpc = NULL;
- }
-
- if (wl->rpc_th) {
- bcm_rpc_tp_detach(wl->rpc_th);
- wl->rpc_th = NULL;
- }
-#endif /* WLC_HIGH_ONLY */
osl_detach(osh);
}
-#ifdef WLC_LOW
/* transmit a packet */
-static int BCMFASTPATH wl_start(struct sk_buff *skb, wl_info_t *wl)
+static int BCMFASTPATH wl_start(struct sk_buff *skb, struct wl_info *wl)
{
if (!wl)
return -ENETDOWN;
return wl_start_int(wl, WL_TO_HW(wl), skb);
}
-#endif /* WLC_LOW */
static int BCMFASTPATH
-wl_start_int(wl_info_t *wl, struct ieee80211_hw *hw, struct sk_buff *skb)
+wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, struct sk_buff *skb)
{
-#ifdef WLC_HIGH_ONLY
- WL_LOCK(wl);
-#endif
wlc_sendpkt_mac80211(wl->wlc, skb, hw);
-#ifdef WLC_HIGH_ONLY
- WL_UNLOCK(wl);
-#endif
return NETDEV_TX_OK;
}
-void wl_txflowcontrol(wl_info_t *wl, struct wl_if *wlif, bool state, int prio)
+void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state,
+ int prio)
{
- WL_ERROR(("Shouldn't be here %s\n", __func__));
+ WL_ERROR("Shouldn't be here %s\n", __func__);
}
-#if defined(WLC_HIGH_ONLY)
-/* Schedule a completion handler to run at safe time */
-static int
-wl_schedule_task(wl_info_t *wl, void (*fn) (struct wl_task *task),
- void *context)
+void wl_init(struct wl_info *wl)
{
- wl_task_t *task;
-
- WL_TRACE(("wl%d: wl_schedule_task\n", wl->pub->unit));
-
- task = kmalloc(sizeof(wl_task_t), GFP_ATOMIC);
- if (!task) {
- WL_ERROR(("wl%d: wl_schedule_task: out of memory\n", wl->pub->unit));
- return -ENOMEM;
- }
-
- INIT_WORK(&task->work, (work_func_t) fn);
- task->context = context;
-
- if (!schedule_work(&task->work)) {
- WL_ERROR(("wl%d: schedule_work() failed\n", wl->pub->unit));
- kfree(task);
- return -ENOMEM;
- }
-
- atomic_inc(&wl->callbacks);
-
- return 0;
-}
-#endif /* defined(WLC_HIGH_ONLY) */
-
-void wl_init(wl_info_t *wl)
-{
- WL_TRACE(("wl%d: wl_init\n", wl->pub->unit));
+ WL_TRACE("wl%d: wl_init\n", wl->pub->unit);
wl_reset(wl);
wlc_init(wl->wlc);
}
-uint wl_reset(wl_info_t *wl)
+uint wl_reset(struct wl_info *wl)
{
- WL_TRACE(("wl%d: wl_reset\n", wl->pub->unit));
+ WL_TRACE("wl%d: wl_reset\n", wl->pub->unit);
wlc_reset(wl->wlc);
@@ -1703,25 +1363,22 @@ uint wl_reset(wl_info_t *wl)
* These are interrupt on/off entry points. Disable interrupts
* during interrupt state transition.
*/
-void BCMFASTPATH wl_intrson(wl_info_t *wl)
+void BCMFASTPATH wl_intrson(struct wl_info *wl)
{
-#if defined(WLC_LOW)
unsigned long flags;
INT_LOCK(wl, flags);
wlc_intrson(wl->wlc);
INT_UNLOCK(wl, flags);
-#endif /* WLC_LOW */
}
-bool wl_alloc_dma_resources(wl_info_t *wl, uint addrwidth)
+bool wl_alloc_dma_resources(struct wl_info *wl, uint addrwidth)
{
return true;
}
-u32 BCMFASTPATH wl_intrsoff(wl_info_t *wl)
+u32 BCMFASTPATH wl_intrsoff(struct wl_info *wl)
{
-#if defined(WLC_LOW)
unsigned long flags;
u32 status;
@@ -1729,23 +1386,18 @@ u32 BCMFASTPATH wl_intrsoff(wl_info_t *wl)
status = wlc_intrsoff(wl->wlc);
INT_UNLOCK(wl, flags);
return status;
-#else
- return 0;
-#endif /* WLC_LOW */
}
-void wl_intrsrestore(wl_info_t *wl, u32 macintmask)
+void wl_intrsrestore(struct wl_info *wl, u32 macintmask)
{
-#if defined(WLC_LOW)
unsigned long flags;
INT_LOCK(wl, flags);
wlc_intrsrestore(wl->wlc, macintmask);
INT_UNLOCK(wl, flags);
-#endif /* WLC_LOW */
}
-int wl_up(wl_info_t *wl)
+int wl_up(struct wl_info *wl)
{
int error = 0;
@@ -1757,7 +1409,7 @@ int wl_up(wl_info_t *wl)
return error;
}
-void wl_down(wl_info_t *wl)
+void wl_down(struct wl_info *wl)
{
uint callbacks, ret_val = 0;
@@ -1768,24 +1420,21 @@ void wl_down(wl_info_t *wl)
/* wait for down callbacks to complete */
WL_UNLOCK(wl);
-#ifndef WLC_HIGH_ONLY
/* For HIGH_only driver, it's important to actually schedule other work,
* not just spin wait since everything runs at schedule level
*/
SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000);
-#endif /* WLC_HIGH_ONLY */
WL_LOCK(wl);
}
irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id)
{
-#if defined(WLC_LOW)
- wl_info_t *wl;
+ struct wl_info *wl;
bool ours, wantdpc;
unsigned long flags;
- wl = (wl_info_t *) dev_id;
+ wl = (struct wl_info *) dev_id;
WL_ISRLOCK(wl, flags);
@@ -1805,17 +1454,13 @@ irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id)
WL_ISRUNLOCK(wl, flags);
return IRQ_RETVAL(ours);
-#else
- return IRQ_RETVAL(0);
-#endif /* WLC_LOW */
}
static void BCMFASTPATH wl_dpc(unsigned long data)
{
-#ifdef WLC_LOW
- wl_info_t *wl;
+ struct wl_info *wl;
- wl = (wl_info_t *) data;
+ wl = (struct wl_info *) data;
WL_LOCK(wl);
@@ -1846,20 +1491,19 @@ static void BCMFASTPATH wl_dpc(unsigned long data)
done:
WL_UNLOCK(wl);
-#endif /* WLC_LOW */
}
-static void wl_link_up(wl_info_t *wl, char *ifname)
+static void wl_link_up(struct wl_info *wl, char *ifname)
{
- WL_ERROR(("wl%d: link up (%s)\n", wl->pub->unit, ifname));
+ WL_ERROR("wl%d: link up (%s)\n", wl->pub->unit, ifname);
}
-static void wl_link_down(wl_info_t *wl, char *ifname)
+static void wl_link_down(struct wl_info *wl, char *ifname)
{
- WL_ERROR(("wl%d: link down (%s)\n", wl->pub->unit, ifname));
+ WL_ERROR("wl%d: link down (%s)\n", wl->pub->unit, ifname);
}
-void wl_event(wl_info_t *wl, char *ifname, wlc_event_t *e)
+void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e)
{
switch (e->event.event_type) {
@@ -1877,12 +1521,7 @@ void wl_event(wl_info_t *wl, char *ifname, wlc_event_t *e)
static void wl_timer(unsigned long data)
{
-#ifndef WLC_HIGH_ONLY
_wl_timer((wl_timer_t *) data);
-#else
- wl_timer_t *t = (wl_timer_t *) data;
- wl_schedule_task(t->wl, wl_timer_task, t);
-#endif /* WLC_HIGH_ONLY */
}
static void _wl_timer(wl_timer_t *t)
@@ -1906,18 +1545,18 @@ static void _wl_timer(wl_timer_t *t)
WL_UNLOCK(t->wl);
}
-wl_timer_t *wl_init_timer(wl_info_t *wl, void (*fn) (void *arg), void *arg,
+wl_timer_t *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), void *arg,
const char *name)
{
wl_timer_t *t;
t = kmalloc(sizeof(wl_timer_t), GFP_ATOMIC);
if (!t) {
- WL_ERROR(("wl%d: wl_init_timer: out of memory\n", wl->pub->unit));
+ WL_ERROR("wl%d: wl_init_timer: out of memory\n", wl->pub->unit);
return 0;
}
- bzero(t, sizeof(wl_timer_t));
+ memset(t, 0, sizeof(wl_timer_t));
init_timer(&t->timer);
t->timer.data = (unsigned long) t;
@@ -1940,12 +1579,12 @@ wl_timer_t *wl_init_timer(wl_info_t *wl, void (*fn) (void *arg), void *arg,
/* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate
* as well as it's easier to make it periodic
*/
-void wl_add_timer(wl_info_t *wl, wl_timer_t *t, uint ms, int periodic)
+void wl_add_timer(struct wl_info *wl, wl_timer_t *t, uint ms, int periodic)
{
#ifdef BCMDBG
if (t->set) {
- WL_ERROR(("%s: Already set. Name: %s, per %d\n",
- __func__, t->name, periodic));
+ WL_ERROR("%s: Already set. Name: %s, per %d\n",
+ __func__, t->name, periodic);
}
#endif
ASSERT(!t->set);
@@ -1960,7 +1599,7 @@ void wl_add_timer(wl_info_t *wl, wl_timer_t *t, uint ms, int periodic)
}
/* return true if timer successfully deleted, false if still pending */
-bool wl_del_timer(wl_info_t *wl, wl_timer_t *t)
+bool wl_del_timer(struct wl_info *wl, wl_timer_t *t)
{
if (t->set) {
t->set = false;
@@ -1973,7 +1612,7 @@ bool wl_del_timer(wl_info_t *wl, wl_timer_t *t)
return true;
}
-void wl_free_timer(wl_info_t *wl, wl_timer_t *t)
+void wl_free_timer(struct wl_info *wl, wl_timer_t *t)
{
wl_timer_t *tmp;
@@ -2009,7 +1648,7 @@ void wl_free_timer(wl_info_t *wl, wl_timer_t *t)
static int wl_linux_watchdog(void *ctx)
{
- wl_info_t *wl = (wl_info_t *) ctx;
+ struct wl_info *wl = (struct wl_info *) ctx;
struct net_device_stats *stats = NULL;
uint id;
/* refresh stats */
@@ -2049,233 +1688,12 @@ struct wl_fw_hdr {
u32 idx;
};
-#ifdef WLC_HIGH_ONLY
-static void wl_rpc_down(void *wlh)
-{
- wl_info_t *wl = (wl_info_t *) (wlh);
-
- wlc_device_removed(wl->wlc);
-
- wl_rpcq_free(wl);
-}
-
-static int BCMFASTPATH wl_start(struct sk_buff *skb, wl_info_t *wl)
-{
-
- unsigned long flags;
-
- skb->prev = NULL;
-
- /* Lock the queue as tasklet could be running at this time */
- TXQ_LOCK(wl, flags);
- if (wl->txq_head == NULL)
- wl->txq_head = skb;
- else {
- wl->txq_tail->prev = skb;
- }
- wl->txq_tail = skb;
-
- if (wl->txq_dispatched == false) {
- wl->txq_dispatched = true;
-
- if (schedule_work(&wl->txq_task.work)) {
- atomic_inc(&wl->callbacks);
- } else {
- WL_ERROR(("wl%d: wl_start/schedule_work failed\n",
- wl->pub->unit));
- }
- }
-
- TXQ_UNLOCK(wl, flags);
-
- return 0;
-
-}
-
-static void wl_start_txqwork(struct wl_task *task)
-{
- wl_info_t *wl = (wl_info_t *) task->context;
- struct sk_buff *skb;
- unsigned long flags;
- uint count = 0;
-
- WL_TRACE(("wl%d: wl_start_txqwork\n", wl->pub->unit));
-
- /* First remove an entry then go for execution */
- TXQ_LOCK(wl, flags);
- while (wl->txq_head) {
- skb = wl->txq_head;
- wl->txq_head = skb->prev;
- skb->prev = NULL;
- if (wl->txq_head == NULL)
- wl->txq_tail = NULL;
- TXQ_UNLOCK(wl, flags);
-
- /* it has WL_LOCK/WL_UNLOCK inside */
- wl_start_int(wl, WL_TO_HW(wl), skb);
-
- /* bounded our execution, reshedule ourself next */
- if (++count >= 10)
- break;
-
- TXQ_LOCK(wl, flags);
- }
-
- if (count >= 10) {
- if (!schedule_work(&wl->txq_task.work)) {
- WL_ERROR(("wl%d: wl_start/schedule_work failed\n",
- wl->pub->unit));
- atomic_dec(&wl->callbacks);
- }
- } else {
- wl->txq_dispatched = false;
- TXQ_UNLOCK(wl, flags);
- atomic_dec(&wl->callbacks);
- }
-
- return;
-}
-
-static void wl_txq_free(wl_info_t *wl)
-{
- struct sk_buff *skb;
-
- if (wl->txq_head == NULL) {
- ASSERT(wl->txq_tail == NULL);
- return;
- }
-
- while (wl->txq_head) {
- skb = wl->txq_head;
- wl->txq_head = skb->prev;
- PKTFREE(wl->osh, skb, true);
- }
-
- wl->txq_tail = NULL;
-}
-
-static void wl_rpcq_free(wl_info_t *wl)
-{
- rpc_buf_t *buf;
-
- if (wl->rpcq_head == NULL) {
- ASSERT(wl->rpcq_tail == NULL);
- return;
- }
-
- while (wl->rpcq_head) {
- buf = wl->rpcq_head;
- wl->rpcq_head = bcm_rpc_buf_next_get(wl->rpc_th, buf);
- bcm_rpc_buf_free(wl->rpc_dispatch_ctx.rpc, buf);
- }
-
- wl->rpcq_tail = NULL;
-}
-
-static void wl_rpcq_dispatch(struct wl_task *task)
-{
- wl_info_t *wl = (wl_info_t *) task->context;
- rpc_buf_t *buf;
- unsigned long flags;
-
- /* First remove an entry then go for execution */
- RPCQ_LOCK(wl, flags);
- while (wl->rpcq_head) {
- buf = wl->rpcq_head;
- wl->rpcq_head = bcm_rpc_buf_next_get(wl->rpc_th, buf);
-
- if (wl->rpcq_head == NULL)
- wl->rpcq_tail = NULL;
- RPCQ_UNLOCK(wl, flags);
-
- WL_LOCK(wl);
- wlc_rpc_high_dispatch(&wl->rpc_dispatch_ctx, buf);
- WL_UNLOCK(wl);
-
- RPCQ_LOCK(wl, flags);
- }
-
- wl->rpcq_dispatched = false;
-
- RPCQ_UNLOCK(wl, flags);
-
- kfree(task);
- atomic_dec(&wl->callbacks);
-}
-
-static void wl_rpcq_add(wl_info_t *wl, rpc_buf_t *buf)
-{
- unsigned long flags;
-
- bcm_rpc_buf_next_set(wl->rpc_th, buf, NULL);
-
- /* Lock the queue as tasklet could be running at this time */
- RPCQ_LOCK(wl, flags);
- if (wl->rpcq_head == NULL)
- wl->rpcq_head = buf;
- else
- bcm_rpc_buf_next_set(wl->rpc_th, wl->rpcq_tail, buf);
-
- wl->rpcq_tail = buf;
-
- if (wl->rpcq_dispatched == false) {
- wl->rpcq_dispatched = true;
- wl_schedule_task(wl, wl_rpcq_dispatch, wl);
- }
-
- RPCQ_UNLOCK(wl, flags);
-}
-
-#if defined(BCMDBG)
-static const struct name_entry rpc_name_tbl[] = RPC_ID_TABLE;
-#endif /* BCMDBG */
-
-/* dongle-side rpc dispatch routine */
-static void wl_rpc_dispatch_schedule(void *ctx, struct rpc_buf *buf)
-{
- bcm_xdr_buf_t b;
- wl_info_t *wl = (wl_info_t *) ctx;
- wlc_rpc_id_t rpc_id;
- int err;
-
- bcm_xdr_buf_init(&b, bcm_rpc_buf_data(wl->rpc_th, buf),
- bcm_rpc_buf_len_get(wl->rpc_th, buf));
-
- err = bcm_xdr_unpack_u32(&b, &rpc_id);
- ASSERT(!err);
- WL_TRACE(("%s: Dispatch id %s\n", __func__,
- WLC_RPC_ID_LOOKUP(rpc_name_tbl, rpc_id)));
-
- /* Handle few emergency ones */
- switch (rpc_id) {
- default:
- wl_rpcq_add(wl, buf);
- break;
- }
-}
-
-static void wl_timer_task(wl_task_t *task)
-{
- wl_timer_t *t = (wl_timer_t *) task->context;
-
- _wl_timer(t);
- kfree(task);
-
- /* This dec is for the task_schedule. The timer related
- * callback is decremented in _wl_timer
- */
- atomic_dec(&t->wl->callbacks);
-}
-#endif /* WLC_HIGH_ONLY */
-
-#ifndef WLC_HIGH_ONLY
char *wl_firmwares[WL_MAX_FW] = {
"brcm/bcm43xx",
NULL
};
-#ifdef WLC_LOW
-int wl_ucode_init_buf(wl_info_t *wl, void **pbuf, u32 idx)
+int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx)
{
int i, entry;
const u8 *pdata;
@@ -2301,7 +1719,7 @@ int wl_ucode_init_buf(wl_info_t *wl, void **pbuf, u32 idx)
return -1;
}
-int wl_ucode_init_uint(wl_info_t *wl, u32 *data, u32 idx)
+int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx)
{
int i, entry;
const u8 *pdata;
@@ -2321,22 +1739,21 @@ int wl_ucode_init_uint(wl_info_t *wl, u32 *data, u32 idx)
printf("ERROR: ucode tag:%d can not be found!\n", idx);
return -1;
}
-#endif /* WLC_LOW */
-static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev)
+static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev)
{
int status;
struct device *device = &pdev->dev;
char fw_name[100];
int i;
- bzero((void *)&wl->fw, sizeof(struct wl_firmware));
+ memset((void *)&wl->fw, 0, sizeof(struct wl_firmware));
for (i = 0; i < WL_MAX_FW; i++) {
if (wl_firmwares[i] == NULL)
break;
sprintf(fw_name, "%s-%d.fw", wl_firmwares[i],
UCODE_LOADER_API_VER);
- WL_NONE(("request fw %s\n", fw_name));
+ WL_NONE("request fw %s\n", fw_name);
status = request_firmware(&wl->fw.fw_bin[i], fw_name, device);
if (status) {
printf("%s: fail to load firmware %s\n",
@@ -2344,7 +1761,7 @@ static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev)
wl_release_fw(wl);
return status;
}
- WL_NONE(("request fw %s\n", fw_name));
+ WL_NONE("request fw %s\n", fw_name);
sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i],
UCODE_LOADER_API_VER);
status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device);
@@ -2356,22 +1773,19 @@ static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev)
}
wl->fw.hdr_num_entries[i] =
wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr));
- WL_NONE(("request fw %s find: %d entries\n", fw_name,
- wl->fw.hdr_num_entries[i]));
+ WL_NONE("request fw %s find: %d entries\n",
+ fw_name, wl->fw.hdr_num_entries[i]);
}
wl->fw.fw_cnt = i;
- wl_ucode_data_init(wl);
- return 0;
+ return wl_ucode_data_init(wl);
}
-#ifdef WLC_LOW
void wl_ucode_free_buf(void *p)
{
kfree(p);
}
-#endif /* WLC_LOW */
-static void wl_release_fw(wl_info_t *wl)
+static void wl_release_fw(struct wl_info *wl)
{
int i;
for (i = 0; i < WL_MAX_FW; i++) {
@@ -2379,4 +1793,54 @@ static void wl_release_fw(wl_info_t *wl)
release_firmware(wl->fw.fw_hdr[i]);
}
}
-#endif /* WLC_HIGH_ONLY */
+
+
+/*
+ * checks validity of all firmware images loaded from user space
+ */
+int wl_check_firmwares(struct wl_info *wl)
+{
+ int i;
+ int entry;
+ int rc = 0;
+ const struct firmware *fw;
+ const struct firmware *fw_hdr;
+ struct wl_fw_hdr *ucode_hdr;
+ for (i = 0; i < WL_MAX_FW && rc == 0; i++) {
+ fw = wl->fw.fw_bin[i];
+ fw_hdr = wl->fw.fw_hdr[i];
+ if (fw == NULL && fw_hdr == NULL) {
+ break;
+ } else if (fw == NULL || fw_hdr == NULL) {
+ WL_ERROR("%s: invalid bin/hdr fw\n", __func__);
+ rc = -EBADF;
+ } else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) {
+ WL_ERROR("%s: non integral fw hdr file size %d/%zu\n",
+ __func__, fw_hdr->size,
+ sizeof(struct wl_fw_hdr));
+ rc = -EBADF;
+ } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) {
+ WL_ERROR("%s: out of bounds fw file size %d\n",
+ __func__, fw->size);
+ rc = -EBADF;
+ } else {
+ /* check if ucode section overruns firmware image */
+ ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data;
+ for (entry = 0; entry < wl->fw.hdr_num_entries[i] && rc;
+ entry++, ucode_hdr++) {
+ if (ucode_hdr->offset + ucode_hdr->len >
+ fw->size) {
+ WL_ERROR("%s: conflicting bin/hdr\n",
+ __func__);
+ rc = -EBADF;
+ }
+ }
+ }
+ }
+ if (rc == 0 && wl->fw.fw_cnt != i) {
+ WL_ERROR("%s: invalid fw_cnt=%d\n", __func__, wl->fw.fw_cnt);
+ rc = -EBADF;
+ }
+ return rc;
+}
+