2012-11-06 00:22:45

by Franky Lin

[permalink] [raw]
Subject: [PATCH 00/24] brcmfmac: miscellaneous bug fix and code clean up patches


In this series, Arend provides some patches related to cfg80211 interface code. I have 5 patches focus on sdio bus data path. Hante removed iscan code and did some work on init/deinit code path.

Arend van Spriel (9):
brcmfmac: remove obsolete structure ap_info
brcmfmac: simplify if-else condition in brcmf_cfg80211_escan()
brcmfmac: restrict error condition in brcmf_inform_bss()
brcmfmac: make pointer type constant in brcmf_set_management_ie()
brcmfmac: change parameter of brcmf_set_management_ie()
brcmfmac: remove obsolete variable from brcmf_cfg80211_start_ap()
brcmfmac: fix NULL pointer access in brcmf_create_iovar()
brcmfmac: fix build regression
brcmfmac: use struct brcmf_if parameter in firmware event callbacks

Franky Lin (5):
brcmfmac: use dynamically allocated control frame buffer
brcmfmac: decrease the range of SDIO access lock
brcmfmac: protect consecutive SDIO access with sdio_claim_host
brcmfmac: remove brcmf_sdbrcm_wait_for_event
brcmfmac: change return type of brcmf_sdio_hdparser

Hante Meuleman (10):
brcmfmac: remove obsolete i-scan and clean up related code.
brcmfmac: use fwil for netdev callbacks.
brcmfmac: handle exceptions in brcmf_bus_start correct.
brcmfmac: use wait_event_timeout for 8021x pending count
brcmfmac: fix pkt_filter sizeof calculation.
brcmfmac: remove obsolete function brcmf_c_mkiovar
brcmfmac: return immediately error for out of range key_idx.
brcmfmac: check bus state to be data before sending data.
brcmfmac: on halting driver check before release or free.
brcmfmac: add dedicated USB log level.

drivers/net/wireless/brcm80211/Kconfig | 8 -
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 28 +-
.../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 7 +-
drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 48 +-
drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | 70 --
.../net/wireless/brcm80211/brcmfmac/dhd_common.c | 29 +-
drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 10 +-
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 314 +++------
.../net/wireless/brcm80211/brcmfmac/dhd_proto.h | 3 -
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 227 +++---
drivers/net/wireless/brcm80211/brcmfmac/fwil.c | 4 +-
drivers/net/wireless/brcm80211/brcmfmac/usb.c | 81 ++-
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 725 ++------------------
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 119 +---
14 files changed, 414 insertions(+), 1259 deletions(-)

--
1.7.9.5




2012-11-06 00:22:49

by Franky Lin

[permalink] [raw]
Subject: [PATCH 08/24] brcmfmac: use wait_event_timeout for 8021x pending count

From: Hante Meuleman <[email protected]>

brcmf_netdev_wait_pend8021x was polling to see if 8021x data was
already sent. Code was replaced using wait_event_timeout.

Reviewed-by: Arend Van Spriel <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 1 +
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 34 +++++++++-----------
2 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 34bad32..8d4789b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -621,6 +621,7 @@ struct brcmf_pub {
struct work_struct multicast_work;
u8 macvalue[ETH_ALEN];
atomic_t pend_8021x_cnt;
+ wait_queue_head_t pend_8021x_wait;
#ifdef DEBUG
struct dentry *dbgfs_dir;
#endif
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 9e2451f..0f81f31 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -52,6 +52,7 @@ MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver.");
MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards");
MODULE_LICENSE("Dual BSD/GPL");

+#define MAX_WAIT_FOR_8021X_TX 50 /* msecs */

/* Error bits */
int brcmf_msg_level = BRCMF_ERROR_VAL;
@@ -404,9 +405,11 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
eh = (struct ethhdr *)(txp->data);
type = ntohs(eh->h_proto);

- if (type == ETH_P_PAE)
+ if (type == ETH_P_PAE) {
atomic_dec(&drvr->pend_8021x_cnt);
-
+ if (waitqueue_active(&drvr->pend_8021x_wait))
+ wake_up(&drvr->pend_8021x_wait);
+ }
}

static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
@@ -822,6 +825,8 @@ int brcmf_attach(uint bus_hdrlen, struct device *dev)

INIT_LIST_HEAD(&drvr->bus_if->dcmd_list);

+ init_waitqueue_head(&drvr->pend_8021x_wait);
+
return ret;

fail:
@@ -924,26 +929,19 @@ static int brcmf_get_pend_8021x_cnt(struct brcmf_pub *drvr)
return atomic_read(&drvr->pend_8021x_cnt);
}

-#define MAX_WAIT_FOR_8021X_TX 10
-
int brcmf_netdev_wait_pend8021x(struct net_device *ndev)
{
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_pub *drvr = ifp->drvr;
- int timeout = 10 * HZ / 1000;
- int ntimes = MAX_WAIT_FOR_8021X_TX;
- int pend = brcmf_get_pend_8021x_cnt(drvr);
-
- while (ntimes && pend) {
- if (pend) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(timeout);
- set_current_state(TASK_RUNNING);
- ntimes--;
- }
- pend = brcmf_get_pend_8021x_cnt(drvr);
- }
- return pend;
+ int err;
+
+ err = wait_event_timeout(drvr->pend_8021x_wait,
+ !brcmf_get_pend_8021x_cnt(drvr),
+ msecs_to_jiffies(MAX_WAIT_FOR_8021X_TX));
+
+ WARN_ON(!err);
+
+ return !err;
}

static void brcmf_driver_init(struct work_struct *work)
--
1.7.9.5



2012-11-06 00:22:49

by Franky Lin

[permalink] [raw]
Subject: [PATCH 11/24] brcmfmac: remove obsolete variable from brcmf_cfg80211_start_ap()

From: Arend van Spriel <[email protected]>

The function brcmf_cfg80211_start_ap() had some variables declared
that were not used or not needed any longer. This patch removes
those variables.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Hante Meuleman <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 83a2421..4b5b475 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3087,7 +3087,7 @@ static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)

static s32
brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
- bool is_rsn_ie, s32 bssidx)
+ bool is_rsn_ie)
{
struct brcmf_if *ifp = netdev_priv(ndev);
u32 auth = 0; /* d11 open authentication */
@@ -3510,7 +3510,6 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_tlv *rsn_ie;
struct brcmf_vs_tlv *wpa_ie;
struct brcmf_join_params join_params;
- struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
s32 bssidx = 0;

WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
@@ -3572,14 +3571,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
WL_TRACE("WPA(2) IE is found\n");
if (wpa_ie != NULL) {
/* WPA IE */
- err = brcmf_configure_wpaie(ndev, wpa_ie, false,
- bssidx);
+ err = brcmf_configure_wpaie(ndev, wpa_ie, false);
if (err < 0)
goto exit;
} else {
/* RSN IE */
err = brcmf_configure_wpaie(ndev,
- (struct brcmf_vs_tlv *)rsn_ie, true, bssidx);
+ (struct brcmf_vs_tlv *)rsn_ie, true);
if (err < 0)
goto exit;
}
--
1.7.9.5



2012-11-06 00:22:49

by Franky Lin

[permalink] [raw]
Subject: [PATCH 14/24] brcmfmac: use dynamically allocated control frame buffer

Rxbuf in SDIO interface is used in normal frame and control frame
read. Use dynamically allocated buffer in control frame read path
for post processing to avoid conflicts.

Signed-off-by: Franky Lin <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 53 ++++++++++++++------
1 file changed, 38 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 415f2be..1d7a340 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -533,9 +533,11 @@ struct brcmf_sdio {
u8 *rxbuf; /* Buffer for receiving control packets */
uint rxblen; /* Allocated length of rxbuf */
u8 *rxctl; /* Aligned pointer into rxbuf */
+ u8 *rxctl_orig; /* pointer for freeing rxctl */
u8 *databuf; /* Buffer for receiving big glom packet */
u8 *dataptr; /* Aligned pointer into databuf */
uint rxlen; /* Length of valid data in buffer */
+ spinlock_t rxctl_lock; /* protection lock for ctrl frame resources */

u8 sdpcm_ver; /* Bus protocol reported by dongle */

@@ -1442,21 +1444,24 @@ static void
brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
{
uint rdlen, pad;
-
+ u8 *buf = NULL, *rbuf;
int sdret;

brcmf_dbg(TRACE, "Enter\n");

- /* Set rxctl for frame (w/optional alignment) */
- bus->rxctl = bus->rxbuf;
- bus->rxctl += BRCMF_FIRSTREAD;
- pad = ((unsigned long)bus->rxctl % BRCMF_SDALIGN);
+ if (bus->rxblen)
+ buf = vzalloc(bus->rxblen);
+ if (!buf) {
+ brcmf_dbg(ERROR, "no memory for control frame\n");
+ goto done;
+ }
+ rbuf = bus->rxbuf;
+ pad = ((unsigned long)rbuf % BRCMF_SDALIGN);
if (pad)
- bus->rxctl += (BRCMF_SDALIGN - pad);
- bus->rxctl -= BRCMF_FIRSTREAD;
+ rbuf += (BRCMF_SDALIGN - pad);

/* Copy the already-read portion over */
- memcpy(bus->rxctl, hdr, BRCMF_FIRSTREAD);
+ memcpy(buf, hdr, BRCMF_FIRSTREAD);
if (len <= BRCMF_FIRSTREAD)
goto gotpkt;

@@ -1493,11 +1498,11 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
goto done;
}

- /* Read remainder of frame body into the rxctl buffer */
+ /* Read remain of frame body */
sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
bus->sdiodev->sbwad,
SDIO_FUNC_2,
- F2SYNC, (bus->rxctl + BRCMF_FIRSTREAD), rdlen);
+ F2SYNC, rbuf, rdlen);
bus->sdcnt.f2rxdata++;

/* Control frame failures need retransmission */
@@ -1507,16 +1512,26 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff)
bus->sdcnt.rxc_errors++;
brcmf_sdbrcm_rxfail(bus, true, true);
goto done;
- }
+ } else
+ memcpy(buf + BRCMF_FIRSTREAD, rbuf, rdlen);

gotpkt:

brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(),
- bus->rxctl, len, "RxCtrl:\n");
+ buf, len, "RxCtrl:\n");

/* Point to valid data and indicate its length */
- bus->rxctl += doff;
+ spin_lock_bh(&bus->rxctl_lock);
+ if (bus->rxctl) {
+ brcmf_dbg(ERROR, "last control frame is being processed.\n");
+ spin_unlock_bh(&bus->rxctl_lock);
+ vfree(buf);
+ goto done;
+ }
+ bus->rxctl = buf + doff;
+ bus->rxctl_orig = buf;
bus->rxlen = len - doff;
+ spin_unlock_bh(&bus->rxctl_lock);

done:
/* Awake any waiters */
@@ -2023,7 +2038,9 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
brcmf_sdbrcm_free_glom(bus);

/* Clear rx control and wake any waiters */
+ spin_lock_bh(&bus->rxctl_lock);
bus->rxlen = 0;
+ spin_unlock_bh(&bus->rxctl_lock);
brcmf_sdbrcm_dcmd_resp_wake(bus);

/* Reset some F2 state stuff */
@@ -2989,6 +3006,7 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
int timeleft;
uint rxlen = 0;
bool pending;
+ u8 *buf;
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio *bus = sdiodev->bus;
@@ -2998,11 +3016,15 @@ brcmf_sdbrcm_bus_rxctl(struct device *dev, unsigned char *msg, uint msglen)
/* Wait until control frame is available */
timeleft = brcmf_sdbrcm_dcmd_resp_wait(bus, &bus->rxlen, &pending);

- down(&bus->sdsem);
+ spin_lock_bh(&bus->rxctl_lock);
rxlen = bus->rxlen;
memcpy(msg, bus->rxctl, min(msglen, rxlen));
+ bus->rxctl = NULL;
+ buf = bus->rxctl_orig;
+ bus->rxctl_orig = NULL;
bus->rxlen = 0;
- up(&bus->sdsem);
+ spin_unlock_bh(&bus->rxctl_lock);
+ vfree(buf);

if (rxlen) {
brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n",
@@ -3860,6 +3882,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
goto fail;
}

+ spin_lock_init(&bus->rxctl_lock);
spin_lock_init(&bus->txqlock);
init_waitqueue_head(&bus->ctrl_wait);
init_waitqueue_head(&bus->dcmd_resp_wait);
--
1.7.9.5



2012-11-06 00:22:51

by Franky Lin

[permalink] [raw]
Subject: [PATCH 19/24] brcmfmac: fix build regression

From: Arend van Spriel <[email protected]>

This fixes a build regression for x86_64 target that showed up
in 3.7-rc1 due to:

commit 1a87334239757b69eb9885979c32bbf871b3ec88
Author: Hante Meuleman <[email protected]>
Date: Thu Sep 27 14:17:54 2012 +0200

brcmfmac: add hostap supoort.

Reported-by: Yuanhan Liu <[email protected]>
Reported-by: Geert Uytterhoeven <[email protected]>
Reported-by: Randy Dunlap <[email protected]>
Reviewed-by: Hante Meuleman <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 4b5b475..228fcae 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3515,7 +3515,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
settings->channel_type, settings->beacon_interval,
settings->dtim_period);
- WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n",
+ WL_TRACE("ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
settings->ssid, settings->ssid_len, settings->auth_type,
settings->inactivity_timeout);

--
1.7.9.5



2012-11-06 00:22:45

by Franky Lin

[permalink] [raw]
Subject: [PATCH 09/24] brcmfmac: fix pkt_filter sizeof calculation.

From: Hante Meuleman <[email protected]>

sizeof calculation in setting pkt_filter was incorrect. This
patch fixes that and removes related defines which have become
obsolete.

Reviewed-by: Arend Van Spriel <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/dhd_common.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 866b669..a70393a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -42,10 +42,6 @@

#define MSGTRACE_VERSION 1

-#define BRCMF_PKT_FILTER_FIXED_LEN offsetof(struct brcmf_pkt_filter_le, u)
-#define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \
- offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern)
-
#ifdef DEBUG
static const char brcmf_version[] =
"Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on "
@@ -686,8 +682,8 @@ static void brcmf_c_pktfilter_offload_set(struct brcmf_if *ifp, char *arg)
}

pkt_filter->u.pattern.size_bytes = cpu_to_le32(mask_size);
- buf_len = sizeof(*pkt_filter);
- buf_len -= sizeof(pkt_filter->u.pattern.mask_and_pattern);
+ buf_len = offsetof(struct brcmf_pkt_filter_le,
+ u.pattern.mask_and_pattern);
buf_len += mask_size + pattern_size;

err = brcmf_fil_iovar_data_set(ifp, "pkt_filter_add", pkt_filter,
--
1.7.9.5



2012-11-06 00:22:49

by Franky Lin

[permalink] [raw]
Subject: [PATCH 15/24] brcmfmac: decrease the range of SDIO access lock

Semaphore sdsem which protects consecutive SDIO bus access is used
to lock down unnecessary wide range. Decrease the locking range
provides the capability of parallel processing.

Signed-off-by: Franky Lin <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 62 +++++++++++---------
1 file changed, 34 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 1d7a340..e328852 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -1274,6 +1274,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
* read directly into the chained packet, or allocate a large
* packet and and copy into the chain.
*/
+ down(&bus->sdsem);
if (usechain) {
errcode = brcmf_sdcard_recv_chain(bus->sdiodev,
bus->sdiodev->sbwad,
@@ -1295,6 +1296,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
dlen);
errcode = -1;
}
+ up(&bus->sdsem);
bus->sdcnt.f2rxdata++;

/* On failure, kill the superframe, allow a couple retries */
@@ -1399,11 +1401,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
pfirst->prev);
}
/* sent any remaining packets up */
- if (bus->glom.qlen) {
- up(&bus->sdsem);
+ if (bus->glom.qlen)
brcmf_rx_frame(bus->sdiodev->dev, ifidx, &bus->glom);
- down(&bus->sdsem);
- }

bus->sdcnt.rxglomframes++;
bus->sdcnt.rxglompkts += bus->glom.qlen;
@@ -1586,6 +1585,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)

rd->len_left = rd->len;
/* read header first for unknow frame length */
+ down(&bus->sdsem);
if (!rd->len) {
sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
bus->sdiodev->sbwad,
@@ -1598,6 +1598,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
sdret);
bus->sdcnt.rx_hdrfail++;
brcmf_sdbrcm_rxfail(bus, true, true);
+ up(&bus->sdsem);
continue;
}

@@ -1607,6 +1608,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)

if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd,
BRCMF_SDIO_FT_NORMAL)) {
+ up(&bus->sdsem);
if (!bus->rxpending)
break;
else
@@ -1622,6 +1624,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
rd->len_nxtfrm = 0;
/* treat all packet as event if we don't know */
rd->channel = SDPCM_EVENT_CHANNEL;
+ up(&bus->sdsem);
continue;
}
rd->len_left = rd->len > BRCMF_FIRSTREAD ?
@@ -1639,6 +1642,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
bus->sdiodev->bus_if->dstats.rx_dropped++;
brcmf_sdbrcm_rxfail(bus, false,
RETRYCHAN(rd->channel));
+ up(&bus->sdsem);
continue;
}
skb_pull(pkt, head_read);
@@ -1647,6 +1651,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
SDIO_FUNC_2, F2SYNC, pkt);
bus->sdcnt.f2rxdata++;
+ up(&bus->sdsem);

if (sdret < 0) {
brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n",
@@ -1749,10 +1754,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
continue;
}

- /* Unlock during rx call */
- up(&bus->sdsem);
brcmf_rx_packet(bus->sdiodev->dev, ifidx, pkt);
- down(&bus->sdsem);
}

rxcount = maxframes - rxleft;
@@ -1772,9 +1774,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
static void
brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar)
{
- up(&bus->sdsem);
wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2);
- down(&bus->sdsem);
return;
}

@@ -1879,6 +1879,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
if (len & (ALIGNMENT - 1))
len = roundup(len, ALIGNMENT);

+ down(&bus->sdsem);
ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad,
SDIO_FUNC_2, F2SYNC, pkt);
bus->sdcnt.f2txdata++;
@@ -1906,15 +1907,14 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
}

}
+ up(&bus->sdsem);
if (ret == 0)
bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;

done:
/* restore pkt buffer pointer before calling tx complete routine */
skb_pull(pkt, SDPCM_HDRLEN + pad);
- up(&bus->sdsem);
brcmf_txcomplete(bus->sdiodev->dev, pkt, ret != 0);
- down(&bus->sdsem);

if (free_pkt)
brcmu_pkt_buf_free_skb(pkt);
@@ -1955,9 +1955,11 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
/* In poll mode, need to check for other events */
if (!bus->intr && cnt) {
/* Check device status, signal pending interrupt */
+ down(&bus->sdsem);
ret = r_sdreg32(bus, &intstatus,
offsetof(struct sdpcmd_regs,
intstatus));
+ up(&bus->sdsem);
bus->sdcnt.f2txdata++;
if (ret != 0)
break;
@@ -2028,6 +2030,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)

/* Turn off the backplane clock (only) */
brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
+ up(&bus->sdsem);

/* Clear the data packet queues */
brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
@@ -2046,8 +2049,6 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
/* Reset some F2 state stuff */
bus->rxskip = false;
bus->tx_seq = bus->rx_seq = 0;
-
- up(&bus->sdsem);
}

#ifdef CONFIG_BRCMFMAC_SDIO_OOB
@@ -2216,6 +2217,8 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
intstatus |= brcmf_sdbrcm_hostmail(bus);
}

+ up(&bus->sdsem);
+
/* Generally don't ask for these, can get CRC errors... */
if (intstatus & I_WR_OOSYNC) {
brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n");
@@ -2262,6 +2265,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
(bus->clkstate == CLK_AVAIL)) {
int i;

+ down(&bus->sdsem);
err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad,
SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf,
(u32) bus->ctrl_frame_len);
@@ -2295,6 +2299,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
} else {
bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
}
+ up(&bus->sdsem);
bus->ctrl_frame_stat = false;
brcmf_sdbrcm_wait_event_wakeup(bus);
}
@@ -2326,8 +2331,6 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
bus->activity = false;
brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
}
-
- up(&bus->sdsem);
}

static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt)
@@ -2618,11 +2621,10 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)

/* precondition: IS_ALIGNED((unsigned long)frame, 2) */

- /* Need to lock here to protect txseq and SDIO tx calls */
- down(&bus->sdsem);
-
/* Make sure backplane clock is on */
+ down(&bus->sdsem);
brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
+ up(&bus->sdsem);

/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
*(__le16 *) frame = cpu_to_le16((u16) msglen);
@@ -2664,7 +2666,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
frame, min_t(u16, len, 16), "TxHdr:\n");

do {
+ down(&bus->sdsem);
ret = brcmf_tx_frame(bus, frame, len);
+ up(&bus->sdsem);
} while (ret < 0 && retries++ < TXRETRIES);
}

@@ -2674,13 +2678,13 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);

bus->activity = false;
+ down(&bus->sdsem);
brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
+ up(&bus->sdsem);
} else {
spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
}

- up(&bus->sdsem);
-
if (ret)
bus->sdcnt.tx_ctlerrs++;
else
@@ -2710,8 +2714,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
* Read last word in socram to determine
* address of sdpcm_shared structure
*/
+ down(&bus->sdsem);
rv = brcmf_sdbrcm_membytes(bus, false, shaddr,
(u8 *)&addr_le, 4);
+ up(&bus->sdsem);
if (rv < 0)
return rv;

@@ -2834,12 +2840,14 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
if ((sh->flags & SDPCM_SHARED_TRAP) == 0)
return 0;

+ down(&bus->sdsem);
error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr,
sizeof(struct brcmf_trap_info));
if (error < 0)
return error;

nbytes = brcmf_sdio_dump_console(bus, sh, data, count);
+ up(&bus->sdsem);
if (nbytes < 0)
return nbytes;

@@ -2885,6 +2893,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
return 0;
}

+ down(&bus->sdsem);
if (sh->assert_file_addr != 0) {
error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr,
(u8 *)file, 80);
@@ -2897,6 +2906,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
if (error < 0)
return error;
}
+ up(&bus->sdsem);

res = scnprintf(buf, sizeof(buf),
"dongle assert: %s:%d: assert(%s)\n",
@@ -2909,9 +2919,7 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_sdio *bus)
int error;
struct sdpcm_shared sh;

- down(&bus->sdsem);
error = brcmf_sdio_readshared(bus, &sh);
- up(&bus->sdsem);

if (error < 0)
return error;
@@ -2938,7 +2946,6 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data,
if (pos != 0)
return 0;

- down(&bus->sdsem);
error = brcmf_sdio_readshared(bus, &sh);
if (error < 0)
goto done;
@@ -2955,7 +2962,6 @@ static int brcmf_sdbrcm_died_dump(struct brcmf_sdio *bus, char __user *data,
error += nbytes;
*ppos += error;
done:
- up(&bus->sdsem);
return error;
}

@@ -3511,8 +3517,6 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)

brcmf_dbg(TIMER, "Enter\n");

- down(&bus->sdsem);
-
/* Poll period: check device if appropriate. */
if (bus->poll && (++bus->polltick >= bus->pollrate)) {
u32 intstatus = 0;
@@ -3561,11 +3565,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
bus->console.count += BRCMF_WD_POLL_MS;
if (bus->console.count >= bus->console_interval) {
bus->console.count -= bus->console_interval;
+ down(&bus->sdsem);
/* Make sure backplane clock is on */
brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
if (brcmf_sdbrcm_readconsole(bus) < 0)
/* stop on error */
bus->console_interval = 0;
+ up(&bus->sdsem);
}
}
#endif /* DEBUG */
@@ -3578,13 +3584,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
bus->activity = false;
brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
} else {
+ down(&bus->sdsem);
brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
+ up(&bus->sdsem);
}
}
}

- up(&bus->sdsem);
-
return (atomic_read(&bus->ipend) > 0);
}

--
1.7.9.5



2012-11-06 00:22:50

by Franky Lin

[permalink] [raw]
Subject: [PATCH 13/24] brcmfmac: fix NULL pointer access in brcmf_create_iovar()

From: Arend van Spriel <[email protected]>

The function brcmf_fil_bsscfg_data_get() calls brcmf_create_iovar()
with data pointer set to NULL, which caused a NULL pointer access.
As it should be possible to provide data in message towards the
firmware, it should just pass the data buffer instead.

Reviewed-by: Hante Meuleman <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/fwil.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
index 4b272c3..f121d41 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -294,7 +294,7 @@ brcmf_fil_bsscfg_data_get(struct brcmf_if *ifp, char *name,

mutex_lock(&drvr->proto_block);

- buflen = brcmf_create_bsscfg(ifp->bssidx, name, NULL, len,
+ buflen = brcmf_create_bsscfg(ifp->bssidx, name, data, len,
drvr->proto_buf, sizeof(drvr->proto_buf));
if (buflen) {
err = brcmf_fil_cmd_data(ifp, BRCMF_C_GET_VAR, drvr->proto_buf,
--
1.7.9.5



2012-11-06 00:22:45

by Franky Lin

[permalink] [raw]
Subject: [PATCH 18/24] brcmfmac: change return type of brcmf_sdio_hdparser

Use int instead of bool as the return type of function
brcmf_sdio_hdparser to explicitly describe error returns.

Signed-off-by: Franky Lin <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 47 ++++++++++----------
1 file changed, 23 insertions(+), 24 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index eec1cbf..ba339f7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -1037,9 +1037,9 @@ static void brcmf_sdbrcm_free_glom(struct brcmf_sdio *bus)
}
}

-static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
- struct brcmf_sdio_read *rd,
- enum brcmf_sdio_frmtype type)
+static int brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
+ struct brcmf_sdio_read *rd,
+ enum brcmf_sdio_frmtype type)
{
u16 len, checksum;
u8 rx_seq, fc, tx_seq_max;
@@ -1054,26 +1054,26 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
/* All zero means no more to read */
if (!(len | checksum)) {
bus->rxpending = false;
- return false;
+ return -ENODATA;
}
if ((u16)(~(len ^ checksum))) {
brcmf_dbg(ERROR, "HW header checksum error\n");
bus->sdcnt.rx_badhdr++;
brcmf_sdbrcm_rxfail(bus, false, false);
- return false;
+ return -EIO;
}
if (len < SDPCM_HDRLEN) {
brcmf_dbg(ERROR, "HW header length error\n");
- return false;
+ return -EPROTO;
}
if (type == BRCMF_SDIO_FT_SUPER &&
(roundup(len, bus->blocksize) != rd->len)) {
brcmf_dbg(ERROR, "HW superframe header length error\n");
- return false;
+ return -EPROTO;
}
if (type == BRCMF_SDIO_FT_SUB && len > rd->len) {
brcmf_dbg(ERROR, "HW subframe header length error\n");
- return false;
+ return -EPROTO;
}
rd->len = len;

@@ -1091,7 +1091,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
SDPCM_GLOMDESC(&header[SDPCM_FRAMETAG_LEN])) {
brcmf_dbg(ERROR, "Glom descriptor found in superframe head\n");
rd->len = 0;
- return false;
+ return -EINVAL;
}
rx_seq = SDPCM_PACKET_SEQUENCE(&header[SDPCM_FRAMETAG_LEN]);
rd->channel = SDPCM_PACKET_CHANNEL(&header[SDPCM_FRAMETAG_LEN]);
@@ -1102,18 +1102,18 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
bus->sdcnt.rx_toolong++;
brcmf_sdbrcm_rxfail(bus, false, false);
rd->len = 0;
- return false;
+ return -EPROTO;
}
if (type == BRCMF_SDIO_FT_SUPER && rd->channel != SDPCM_GLOM_CHANNEL) {
brcmf_dbg(ERROR, "Wrong channel for superframe\n");
rd->len = 0;
- return false;
+ return -EINVAL;
}
if (type == BRCMF_SDIO_FT_SUB && rd->channel != SDPCM_DATA_CHANNEL &&
rd->channel != SDPCM_EVENT_CHANNEL) {
brcmf_dbg(ERROR, "Wrong channel for subframe\n");
rd->len = 0;
- return false;
+ return -EINVAL;
}
rd->dat_offset = SDPCM_DOFFSET_VALUE(&header[SDPCM_FRAMETAG_LEN]);
if (rd->dat_offset < SDPCM_HDRLEN || rd->dat_offset > rd->len) {
@@ -1121,7 +1121,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
bus->sdcnt.rx_badhdr++;
brcmf_sdbrcm_rxfail(bus, false, false);
rd->len = 0;
- return false;
+ return -ENXIO;
}
if (rd->seq_num != rx_seq) {
brcmf_dbg(ERROR, "seq %d: sequence number error, expect %d\n",
@@ -1131,7 +1131,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
}
/* no need to check the reset for subframe */
if (type == BRCMF_SDIO_FT_SUB)
- return true;
+ return 0;
rd->len_nxtfrm = header[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET];
if (rd->len_nxtfrm << 4 > MAX_RX_DATASZ) {
/* only warm for NON glom packet */
@@ -1155,7 +1155,7 @@ static bool brcmf_sdio_hdparser(struct brcmf_sdio *bus, u8 *header,
}
bus->tx_max = tx_seq_max;

- return true;
+ return 0;
}

static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
@@ -1323,8 +1323,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
rd_new.seq_num = rxseq;
rd_new.len = dlen;
sdio_claim_host(bus->sdiodev->func[1]);
- errcode = -!brcmf_sdio_hdparser(bus, pfirst->data, &rd_new,
- BRCMF_SDIO_FT_SUPER);
+ errcode = brcmf_sdio_hdparser(bus, pfirst->data, &rd_new,
+ BRCMF_SDIO_FT_SUPER);
sdio_release_host(bus->sdiodev->func[1]);
bus->cur_read.len = rd_new.len_nxtfrm << 4;

@@ -1342,9 +1342,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
rd_new.len = pnext->len;
rd_new.seq_num = rxseq++;
sdio_claim_host(bus->sdiodev->func[1]);
- errcode = -!brcmf_sdio_hdparser(bus, pnext->data,
- &rd_new,
- BRCMF_SDIO_FT_SUB);
+ errcode = brcmf_sdio_hdparser(bus, pnext->data, &rd_new,
+ BRCMF_SDIO_FT_SUB);
sdio_release_host(bus->sdiodev->func[1]);
brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
pnext->data, 32, "subframe:\n");
@@ -1612,8 +1611,8 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
bus->rxhdr, SDPCM_HDRLEN,
"RxHdr:\n");

- if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd,
- BRCMF_SDIO_FT_NORMAL)) {
+ if (brcmf_sdio_hdparser(bus, bus->rxhdr, rd,
+ BRCMF_SDIO_FT_NORMAL)) {
sdio_release_host(bus->sdiodev->func[1]);
if (!bus->rxpending)
break;
@@ -1679,8 +1678,8 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN);
rd_new.seq_num = rd->seq_num;
sdio_claim_host(bus->sdiodev->func[1]);
- if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new,
- BRCMF_SDIO_FT_NORMAL)) {
+ if (brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new,
+ BRCMF_SDIO_FT_NORMAL)) {
rd->len = 0;
brcmu_pkt_buf_free_skb(pkt);
}
--
1.7.9.5



2012-11-06 00:22:45

by Franky Lin

[permalink] [raw]
Subject: [PATCH 10/24] brcmfmac: change parameter of brcmf_set_management_ie()

From: Arend van Spriel <[email protected]>

The function brcmf_set_management_ie() operates on virtual
interface data and brcmf_cfg80211_vif structure provides
all information needed for interfacing with firmware. As
this function will also be needed for interface without
an associated net device it makes sense to provide the vif
instead of deriving it from the net device.

Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Reviewed-by: Hante Meuleman <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 33 +++++++++++---------
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 6 ++++
2 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 0970c1a..83a2421 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3344,12 +3344,11 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
}

static
-s32 brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
- struct net_device *ndev, s32 pktflag,
- const u8 *vndr_ie_buf, u32 vndr_ie_len)
+s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
+ const u8 *vndr_ie_buf, u32 vndr_ie_len)
{
- struct brcmf_if *ifp = netdev_priv(ndev);
- struct vif_saved_ie *saved_ie = &ifp->vif->saved_ie;
+ struct brcmf_if *ifp;
+ struct vif_saved_ie *saved_ie;
s32 err = 0;
u8 *iovar_ie_buf;
u8 *curr_ie_buf;
@@ -3366,8 +3365,12 @@ s32 brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
u8 *ptr;
int remained_buf_len;

- WL_TRACE("bssidx %d, pktflag : 0x%02X\n",
- brcmf_ndev_bssidx(ndev), pktflag);
+ if (!vif)
+ return -ENODEV;
+ ifp = vif->ifp;
+ saved_ie = &vif->saved_ie;
+
+ WL_TRACE("bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
if (!iovar_ie_buf)
return -ENOMEM;
@@ -3585,20 +3588,20 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
brcmf_configure_opensecurity(ndev, bssidx);
}
/* Set Beacon IEs to FW */
- err = brcmf_set_management_ie(cfg, ndev,
- VNDR_IE_BEACON_FLAG,
- settings->beacon.tail,
- settings->beacon.tail_len);
+ err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
+ VNDR_IE_BEACON_FLAG,
+ settings->beacon.tail,
+ settings->beacon.tail_len);
if (err)
WL_ERR("Set Beacon IE Failed\n");
else
WL_TRACE("Applied Vndr IEs for Beacon\n");

/* Set Probe Response IEs to FW */
- err = brcmf_set_management_ie(cfg, ndev,
- VNDR_IE_PRBRSP_FLAG,
- settings->beacon.proberesp_ies,
- settings->beacon.proberesp_ies_len);
+ err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
+ VNDR_IE_PRBRSP_FLAG,
+ settings->beacon.proberesp_ies,
+ settings->beacon.proberesp_ies_len);
if (err)
WL_ERR("Set Probe Resp IE Failed\n");
else
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index 3c59931..e4de9fc 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -468,6 +468,12 @@ static inline struct brcmf_cfg80211_profile *ndev_to_prof(struct net_device *nd)
return &ifp->vif->profile;
}

+static inline struct brcmf_cfg80211_vif *ndev_to_vif(struct net_device *ndev)
+{
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ return ifp->vif;
+}
+
static inline struct
brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg)
{
--
1.7.9.5



2012-11-06 00:22:49

by Franky Lin

[permalink] [raw]
Subject: [PATCH 07/24] brcmfmac: handle exceptions in brcmf_bus_start correct.

From: Hante Meuleman <[email protected]>

On exception during brcmf_bus_start the netdev should be freed,
if already allocated.

Reviewed-by: Arend Van Spriel <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index b130f20..9e2451f 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -708,7 +708,6 @@ int brcmf_net_attach(struct brcmf_if *ifp)

fail:
ndev->netdev_ops = NULL;
- free_netdev(ndev);
return -EBADE;
}

@@ -858,15 +857,21 @@ int brcmf_bus_start(struct device *dev)
/* Bus is ready, do any initialization */
ret = brcmf_c_preinit_dcmds(ifp);
if (ret < 0)
- return ret;
+ goto fail;

drvr->config = brcmf_cfg80211_attach(drvr);
- if (drvr->config == NULL)
- return -ENOMEM;
+ if (drvr->config == NULL) {
+ ret = -ENOMEM;
+ goto fail;
+ }

ret = brcmf_net_attach(ifp);
+fail:
if (ret < 0) {
brcmf_dbg(ERROR, "brcmf_net_attach failed");
+ if (drvr->config)
+ brcmf_cfg80211_detach(drvr->config);
+ free_netdev(drvr->iflist[0]->ndev);
drvr->iflist[0] = NULL;
return ret;
}
--
1.7.9.5



2012-11-06 00:22:44

by Franky Lin

[permalink] [raw]
Subject: [PATCH 02/24] brcmfmac: simplify if-else condition in brcmf_cfg80211_escan()

From: Arend van Spriel <[email protected]>

Code flow was:
err = foo();
if (!err)
return err;
else
goto exit;
return 0;

Changed it to just to exit label if err is non-zero.

Reviewed-by: Hante Meuleman <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 9da9d05..f05ab77 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -966,9 +966,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
if (escan_req) {
err = brcmf_do_escan(cfg, wiphy, ndev, request);
- if (!err)
- return err;
- else
+ if (err)
goto scan_out;
} else {
WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
--
1.7.9.5



2012-11-06 00:22:44

by Franky Lin

[permalink] [raw]
Subject: [PATCH 12/24] brcmfmac: remove obsolete function brcmf_c_mkiovar

From: Hante Meuleman <[email protected]>

the refactored firmware interface layer made this function obsolete.

Reviewed-by: Arend Van Spriel <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 3 ---
.../net/wireless/brcm80211/brcmfmac/dhd_common.c | 21 --------------------
2 files changed, 24 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 8d4789b..9807092 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -671,9 +671,6 @@ static inline s32 brcmf_ndev_bssidx(struct net_device *ndev)

extern const struct bcmevent_name bcmevent_names[];

-extern uint brcmf_c_mkiovar(char *name, char *data, uint datalen,
- char *buf, uint len);
-
extern int brcmf_netdev_wait_pend8021x(struct net_device *ndev);

/* Return pointer to interface name */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index a70393a..3b31139 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -68,27 +68,6 @@ struct msgtrace_hdr {
} __packed;


-uint
-brcmf_c_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen)
-{
- uint len;
-
- len = strlen(name) + 1;
-
- if ((len + datalen) > buflen)
- return 0;
-
- strncpy(buf, name, buflen);
-
- /* append data onto the end of the name string */
- if (data && datalen) {
- memcpy(&buf[len], data, datalen);
- len += datalen;
- }
-
- return len;
-}
-
bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
struct sk_buff *pkt, int prec)
{
--
1.7.9.5



2012-11-06 00:22:51

by Franky Lin

[permalink] [raw]
Subject: [PATCH 23/24] brcmfmac: add dedicated USB log level.

From: Hante Meuleman <[email protected]>

Add USB log level and update and add log messages in usb module.

Reviewed-by: Arend Van Spriel <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 1 +
drivers/net/wireless/brcm80211/brcmfmac/usb.c | 81 +++++++++++++--------
2 files changed, 53 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index 55a4738..a0e18a1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -31,6 +31,7 @@
#define BRCMF_EVENT_VAL 0x0400
#define BRCMF_BTA_VAL 0x0800
#define BRCMF_FIL_VAL 0x1000
+#define BRCMF_USB_VAL 0x2000

#if defined(DEBUG)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 484a6e4..15070b6 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -170,6 +170,7 @@ static void brcmf_usb_ioctl_resp_wake(struct brcmf_usbdev_info *devinfo)
static void
brcmf_usb_ctl_complete(struct brcmf_usbdev_info *devinfo, int type, int status)
{
+ brcmf_dbg(USB, "Enter, status=%d\n", status);

if (unlikely(devinfo == NULL))
return;
@@ -197,6 +198,7 @@ brcmf_usb_ctlread_complete(struct urb *urb)
struct brcmf_usbdev_info *devinfo =
(struct brcmf_usbdev_info *)urb->context;

+ brcmf_dbg(USB, "Enter\n");
devinfo->ctl_urb_actual_length = urb->actual_length;
brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_READ,
urb->status);
@@ -208,6 +210,7 @@ brcmf_usb_ctlwrite_complete(struct urb *urb)
struct brcmf_usbdev_info *devinfo =
(struct brcmf_usbdev_info *)urb->context;

+ brcmf_dbg(USB, "Enter\n");
brcmf_usb_ctl_complete(devinfo, BRCMF_USB_CBCTL_WRITE,
urb->status);
}
@@ -223,6 +226,7 @@ brcmf_usb_send_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len)
int ret;
u16 size;

+ brcmf_dbg(USB, "Enter\n");
if (devinfo == NULL || buf == NULL ||
len == 0 || devinfo->ctl_urb == NULL)
return -EINVAL;
@@ -262,6 +266,7 @@ brcmf_usb_recv_ctl(struct brcmf_usbdev_info *devinfo, u8 *buf, int len)
int ret;
u16 size;

+ brcmf_dbg(USB, "Enter\n");
if ((devinfo == NULL) || (buf == NULL) || (len == 0)
|| (devinfo->ctl_urb == NULL))
return -EINVAL;
@@ -295,6 +300,7 @@ static int brcmf_usb_tx_ctlpkt(struct device *dev, u8 *buf, u32 len)
int timeout = 0;
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);

+ brcmf_dbg(USB, "Enter\n");
if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
/* TODO: handle suspend/resume */
return -EIO;
@@ -325,6 +331,7 @@ static int brcmf_usb_rx_ctlpkt(struct device *dev, u8 *buf, u32 len)
int timeout = 0;
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);

+ brcmf_dbg(USB, "Enter\n");
if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
/* TODO: handle suspend/resume */
return -EIO;
@@ -453,6 +460,8 @@ static void brcmf_usb_tx_complete(struct urb *urb)
struct brcmf_usbreq *req = (struct brcmf_usbreq *)urb->context;
struct brcmf_usbdev_info *devinfo = req->devinfo;

+ brcmf_dbg(USB, "Enter, urb->status=%d, skb=%p\n", urb->status,
+ req->skb);
brcmf_usb_del_fromq(devinfo, req);
if (urb->status == 0)
devinfo->bus_pub.bus->dstats.tx_packets++;
@@ -478,6 +487,7 @@ static void brcmf_usb_rx_complete(struct urb *urb)
struct sk_buff *skb;
int ifidx = 0;

+ brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status);
brcmf_usb_del_fromq(devinfo, req);
skb = req->skb;
req->skb = NULL;
@@ -558,13 +568,13 @@ brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state)
struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus;
int old_state;

+ brcmf_dbg(USB, "Enter, current state=%d, new state=%d\n",
+ devinfo->bus_pub.state, state);

if (devinfo->bus_pub.state == state)
return;

old_state = devinfo->bus_pub.state;
- brcmf_dbg(TRACE, "dbus state change from %d to to %d\n",
- old_state, state);

/* Don't update state if it's PnP firmware re-download */
if (state != BCMFMAC_USB_STATE_PNP_FWDL) /* TODO */
@@ -577,10 +587,10 @@ brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state)

/* update state of upper layer */
if (state == BCMFMAC_USB_STATE_DOWN) {
- brcmf_dbg(INFO, "DBUS is down\n");
+ brcmf_dbg(USB, "DBUS is down\n");
bcmf_bus->state = BRCMF_BUS_DOWN;
} else {
- brcmf_dbg(INFO, "DBUS current state=%d\n", state);
+ brcmf_dbg(USB, "DBUS current state=%d\n", state);
}
}

@@ -591,6 +601,8 @@ brcmf_usb_intr_complete(struct urb *urb)
(struct brcmf_usbdev_info *)urb->context;
bool killed;

+ brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status);
+
if (devinfo == NULL)
return;

@@ -621,6 +633,7 @@ static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)
struct brcmf_usbreq *req;
int ret;

+ brcmf_dbg(USB, "Enter, skb=%p\n", skb);
if (devinfo->bus_pub.state != BCMFMAC_USB_STATE_UP) {
/* TODO: handle suspend/resume */
return -EIO;
@@ -665,6 +678,7 @@ static int brcmf_usb_up(struct device *dev)
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);
u16 ifnum;

+ brcmf_dbg(USB, "Enter\n");
if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_UP)
return 0;

@@ -727,10 +741,10 @@ static void brcmf_usb_down(struct device *dev)
{
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);

+ brcmf_dbg(USB, "Enter\n");
if (devinfo == NULL)
return;

- brcmf_dbg(TRACE, "enter\n");
if (devinfo->bus_pub.state == BCMFMAC_USB_STATE_DOWN)
return;

@@ -808,7 +822,7 @@ brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo)
struct bootrom_id_le id;
u32 chipid, chiprev;

- brcmf_dbg(TRACE, "enter\n");
+ brcmf_dbg(USB, "Enter\n");

if (devinfo == NULL)
return false;
@@ -822,11 +836,11 @@ brcmf_usb_dlneeded(struct brcmf_usbdev_info *devinfo)
chiprev = le32_to_cpu(id.chiprev);

if ((chipid & 0x4300) == 0x4300)
- brcmf_dbg(INFO, "chip %x rev 0x%x\n", chipid, chiprev);
+ brcmf_dbg(USB, "chip %x rev 0x%x\n", chipid, chiprev);
else
- brcmf_dbg(INFO, "chip %d rev 0x%x\n", chipid, chiprev);
+ brcmf_dbg(USB, "chip %d rev 0x%x\n", chipid, chiprev);
if (chipid == BRCMF_POSTBOOT_ID) {
- brcmf_dbg(INFO, "firmware already downloaded\n");
+ brcmf_dbg(USB, "firmware already downloaded\n");
brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id,
sizeof(struct bootrom_id_le));
return false;
@@ -843,7 +857,7 @@ brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo)
struct bootrom_id_le id;
u16 wait = 0, wait_time;

- brcmf_dbg(TRACE, "enter\n");
+ brcmf_dbg(USB, "Enter\n");

if (devinfo == NULL)
return -EINVAL;
@@ -861,7 +875,7 @@ brcmf_usb_resetcfg(struct brcmf_usbdev_info *devinfo)
}

if (id.chip == cpu_to_le32(BRCMF_POSTBOOT_ID)) {
- brcmf_dbg(INFO, "download done %d ms postboot chip 0x%x/rev 0x%x\n",
+ brcmf_dbg(USB, "download done %d ms postboot chip 0x%x/rev 0x%x\n",
wait, le32_to_cpu(id.chip), le32_to_cpu(id.chiprev));

brcmf_usb_dl_cmd(devinfo, DL_RESETCFG, &id,
@@ -911,7 +925,8 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)
struct rdl_state_le state;
u32 rdlstate, rdlbytes;
int err = 0;
- brcmf_dbg(TRACE, "fw %p, len %d\n", fw, fwlen);
+
+ brcmf_dbg(USB, "Enter, fw %p, len %d\n", fw, fwlen);

bulkchunk = kmalloc(RDL_CHUNK, GFP_ATOMIC);
if (bulkchunk == NULL) {
@@ -986,7 +1001,7 @@ brcmf_usb_dl_writeimage(struct brcmf_usbdev_info *devinfo, u8 *fw, int fwlen)

fail:
kfree(bulkchunk);
- brcmf_dbg(TRACE, "err=%d\n", err);
+ brcmf_dbg(USB, "Exit, err=%d\n", err);
return err;
}

@@ -994,7 +1009,7 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len)
{
int err;

- brcmf_dbg(TRACE, "enter\n");
+ brcmf_dbg(USB, "Enter\n");

if (devinfo == NULL)
return -EINVAL;
@@ -1007,7 +1022,7 @@ static int brcmf_usb_dlstart(struct brcmf_usbdev_info *devinfo, u8 *fw, int len)
devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_DONE;
else
devinfo->bus_pub.state = BCMFMAC_USB_STATE_DL_PENDING;
- brcmf_dbg(TRACE, "exit: err=%d\n", err);
+ brcmf_dbg(USB, "Exit, err=%d\n", err);

return err;
}
@@ -1016,7 +1031,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
{
struct rdl_state_le state;

- brcmf_dbg(TRACE, "enter\n");
+ brcmf_dbg(USB, "Enter\n");
if (!devinfo)
return -EINVAL;

@@ -1039,7 +1054,7 @@ static int brcmf_usb_dlrun(struct brcmf_usbdev_info *devinfo)
brcmf_dbg(ERROR, "Dongle not runnable\n");
return -EINVAL;
}
- brcmf_dbg(TRACE, "exit\n");
+ brcmf_dbg(USB, "Exit\n");
return 0;
}

@@ -1066,7 +1081,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)
int devid, chiprev;
int err;

- brcmf_dbg(TRACE, "enter\n");
+ brcmf_dbg(USB, "Enter\n");
if (devinfo == NULL)
return -ENODEV;

@@ -1094,7 +1109,7 @@ brcmf_usb_fw_download(struct brcmf_usbdev_info *devinfo)

static void brcmf_usb_detach(struct brcmf_usbdev_info *devinfo)
{
- brcmf_dbg(TRACE, "devinfo %p\n", devinfo);
+ brcmf_dbg(USB, "Enter, devinfo %p\n", devinfo);

/* free the URBS */
brcmf_usb_free_q(&devinfo->rx_freeq, false);
@@ -1129,6 +1144,7 @@ static int check_file(const u8 *headers)
struct trx_header_le *trx;
int actual_len = -1;

+ brcmf_dbg(USB, "Enter\n");
/* Extract trx header */
trx = (struct trx_header_le *) headers;
if (trx->magic != cpu_to_le32(TRX_MAGIC))
@@ -1150,6 +1166,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
struct brcmf_usb_image *fw_image;
int err;

+ brcmf_dbg(USB, "Enter\n");
switch (devinfo->bus_pub.devid) {
case 43143:
fwname = BRCMF_USB_43143_FW_NAME;
@@ -1166,7 +1183,7 @@ static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)
return -EINVAL;
break;
}
-
+ brcmf_dbg(USB, "Loading FW %s\n", fwname);
list_for_each_entry(fw_image, &fw_image_list, list) {
if (fw_image->fwname == fwname) {
devinfo->image = fw_image->image;
@@ -1211,6 +1228,8 @@ static
struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
int nrxq, int ntxq)
{
+ brcmf_dbg(USB, "Enter\n");
+
devinfo->bus_pub.nrxq = nrxq;
devinfo->rx_low_watermark = nrxq / 2;
devinfo->bus_pub.devinfo = devinfo;
@@ -1263,7 +1282,7 @@ struct brcmf_usbdev *brcmf_usb_attach(struct brcmf_usbdev_info *devinfo,
if (!brcmf_usb_dlneeded(devinfo))
return &devinfo->bus_pub;

- brcmf_dbg(TRACE, "start fw downloading\n");
+ brcmf_dbg(USB, "Start fw downloading\n");
if (brcmf_usb_get_fw(devinfo))
goto error;

@@ -1286,6 +1305,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo,
int ret;
struct device *dev = devinfo->dev;

+ brcmf_dbg(USB, "Enter\n");
bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ);
if (!bus_pub)
return -ENODEV;
@@ -1309,7 +1329,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo,
/* Attach to the common driver interface */
ret = brcmf_attach(hdrlen, dev);
if (ret) {
- brcmf_dbg(ERROR, "dhd_attach failed\n");
+ brcmf_dbg(ERROR, "brcmf_attach failed\n");
goto fail;
}

@@ -1333,7 +1353,7 @@ brcmf_usb_disconnect_cb(struct brcmf_usbdev_info *devinfo)
{
if (!devinfo)
return;
- brcmf_dbg(TRACE, "enter: bus_pub %p\n", devinfo);
+ brcmf_dbg(USB, "Enter, bus_pub %p\n", devinfo);

brcmf_detach(devinfo->dev);
kfree(devinfo->bus_pub.bus);
@@ -1351,7 +1371,7 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
u8 endpoint_num;
struct brcmf_usbdev_info *devinfo;

- brcmf_dbg(TRACE, "enter\n");
+ brcmf_dbg(USB, "Enter\n");

devinfo = kzalloc(sizeof(*devinfo), GFP_ATOMIC);
if (devinfo == NULL)
@@ -1452,9 +1472,9 @@ brcmf_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;

if (usb->speed == USB_SPEED_HIGH)
- brcmf_dbg(INFO, "Broadcom high speed USB wireless device detected\n");
+ brcmf_dbg(USB, "Broadcom high speed USB wireless device detected\n");
else
- brcmf_dbg(INFO, "Broadcom full speed USB wireless device detected\n");
+ brcmf_dbg(USB, "Broadcom full speed USB wireless device detected\n");

ret = brcmf_usb_probe_cb(devinfo, "", USB_BUS, 0);
if (ret)
@@ -1476,10 +1496,11 @@ brcmf_usb_disconnect(struct usb_interface *intf)
{
struct brcmf_usbdev_info *devinfo;

- brcmf_dbg(TRACE, "enter\n");
+ brcmf_dbg(USB, "Enter\n");
devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf);
brcmf_usb_disconnect_cb(devinfo);
kfree(devinfo);
+ brcmf_dbg(USB, "Exit\n");
}

/*
@@ -1490,7 +1511,7 @@ static int brcmf_usb_suspend(struct usb_interface *intf, pm_message_t state)
struct usb_device *usb = interface_to_usbdev(intf);
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);

- brcmf_dbg(TRACE, "enter\n");
+ brcmf_dbg(USB, "Enter\n");
devinfo->bus_pub.state = BCMFMAC_USB_STATE_DOWN;
devinfo->suspend_state = USBOS_SUSPEND_STATE_SUSPENDED;
return 0;
@@ -1504,7 +1525,7 @@ static int brcmf_usb_resume(struct usb_interface *intf)
struct usb_device *usb = interface_to_usbdev(intf);
struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);

- brcmf_dbg(TRACE, "enter\n");
+ brcmf_dbg(USB, "Enter\n");
devinfo->suspend_state = USBOS_SUSPEND_STATE_DEVICE_ACTIVE;
brcmf_bus_start(&usb->dev);
return 0;
@@ -1554,12 +1575,14 @@ static void brcmf_release_fw(struct list_head *q)

void brcmf_usb_exit(void)
{
+ brcmf_dbg(USB, "Enter\n");
usb_deregister(&brcmf_usbdrvr);
brcmf_release_fw(&fw_image_list);
}

void brcmf_usb_init(void)
{
+ brcmf_dbg(USB, "Enter\n");
INIT_LIST_HEAD(&fw_image_list);
usb_register(&brcmf_usbdrvr);
}
--
1.7.9.5



2012-11-06 00:22:44

by Franky Lin

[permalink] [raw]
Subject: [PATCH 03/24] brcmfmac: restrict error condition in brcmf_inform_bss()

From: Arend van Spriel <[email protected]>

The function brcmf_inform_bss() validates the version received
from the device, before processing the individual bss entries.
This error condition is only applicable when the list contains
entries. A specific scan, ie. for a specific ssid, can result
in a scan completion without finding any bss entries. No need
to flag it as an error in the log when this happens.

Reviewed-by: Hante Meuleman <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index f05ab77..c979ce1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -2345,7 +2345,8 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
int i;

bss_list = cfg->bss_list;
- if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
+ if (bss_list->count != 0 &&
+ bss_list->version != BRCMF_BSS_INFO_VERSION) {
WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
bss_list->version);
return -EOPNOTSUPP;
--
1.7.9.5



2012-11-06 00:22:51

by Franky Lin

[permalink] [raw]
Subject: [PATCH 24/24] brcmfmac: use struct brcmf_if parameter in firmware event callbacks

From: Arend van Spriel <[email protected]>

Firmware events are passed to wl_cfg80211 module associated with
the primary net device. With virtual interface support events can
be received for different interfaces, ie. struct brcmf_if instances.
Pass it in the event to determine appropriate net device associated
with the event.

Reviewed-by: Hante Meuleman <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 3 +-
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 47 ++++++++++----------
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 42 ++++++++---------
3 files changed, 46 insertions(+), 46 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 2bb1207..c2cd28e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -304,8 +304,9 @@ static int brcmf_host_event(struct brcmf_pub *drvr, int *ifidx,
if (bcmerror != 0)
return bcmerror;

+ /* only forward if interface has netdev */
if (drvr->iflist[*ifidx]->ndev)
- brcmf_cfg80211_event(drvr->iflist[*ifidx]->ndev,
+ brcmf_cfg80211_event(drvr->iflist[*ifidx],
event, *data);

return bcmerror;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 4fbf5b3..4387ca5 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -2453,10 +2453,11 @@ brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
}

static s32
-brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg,
- struct net_device *ndev,
+brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
const struct brcmf_event_msg *e, void *data)
{
+ struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
+ struct net_device *ndev = ifp->ndev;
s32 status;
s32 err = 0;
struct brcmf_escan_result_le *escan_result_le;
@@ -2772,10 +2773,11 @@ brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
* cfg80211_scan_request one out of the received PNO event.
*/
static s32
-brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg,
- struct net_device *ndev,
+brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
const struct brcmf_event_msg *e, void *data)
{
+ struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
+ struct net_device *ndev = ifp->ndev;
struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
struct cfg80211_scan_request *request = NULL;
struct cfg80211_ssid *ssid = NULL;
@@ -4111,11 +4113,11 @@ brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
}

static s32
-brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg,
- struct net_device *ndev,
+brcmf_notify_connect_status(struct brcmf_if *ifp,
const struct brcmf_event_msg *e, void *data)
{
- struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
+ struct net_device *ndev = ifp->ndev;
struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
s32 err = 0;

@@ -4163,28 +4165,26 @@ brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg,
}

static s32
-brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg,
- struct net_device *ndev,
+brcmf_notify_roaming_status(struct brcmf_if *ifp,
const struct brcmf_event_msg *e, void *data)
{
- struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
s32 err = 0;
u32 event = be32_to_cpu(e->event_type);
u32 status = be32_to_cpu(e->status);

if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
- brcmf_bss_roaming_done(cfg, ndev, e);
+ brcmf_bss_roaming_done(cfg, ifp->ndev, e);
else
- brcmf_bss_connect_done(cfg, ndev, e, true);
+ brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
}

return err;
}

static s32
-brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg,
- struct net_device *ndev,
+brcmf_notify_mic_status(struct brcmf_if *ifp,
const struct brcmf_event_msg *e, void *data)
{
u16 flags = be16_to_cpu(e->flags);
@@ -4195,7 +4195,7 @@ brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg,
else
key_type = NL80211_KEYTYPE_PAIRWISE;

- cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
+ cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
NULL, GFP_KERNEL);

return 0;
@@ -4288,9 +4288,10 @@ static struct brcmf_cfg80211_event_q *brcmf_deq_event(
*/

static s32
-brcmf_enq_event(struct brcmf_cfg80211_info *cfg, u32 event,
+brcmf_enq_event(struct brcmf_if *ifp, u32 event,
const struct brcmf_event_msg *msg, void *data)
{
+ struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
struct brcmf_cfg80211_event_q *e;
s32 err = 0;
ulong flags;
@@ -4308,6 +4309,7 @@ brcmf_enq_event(struct brcmf_cfg80211_info *cfg, u32 event,
return -ENOMEM;

e->etype = event;
+ e->ifp = ifp;
memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
if (data)
memcpy(&e->edata, data, data_len);
@@ -4340,9 +4342,7 @@ static void brcmf_cfg80211_event_handler(struct work_struct *work)
do {
WL_INFO("event type (%d)\n", e->etype);
if (cfg->el.handler[e->etype])
- cfg->el.handler[e->etype](cfg,
- cfg_to_ndev(cfg),
- &e->emsg, e->edata);
+ cfg->el.handler[e->etype](e->ifp, &e->emsg, e->edata);
else
WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
brcmf_put_event(e);
@@ -4461,14 +4461,13 @@ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
}
}

-void
-brcmf_cfg80211_event(struct net_device *ndev,
- const struct brcmf_event_msg *e, void *data)
+void brcmf_cfg80211_event(struct brcmf_if *ifp,
+ const struct brcmf_event_msg *e, void *data)
{
+ struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
u32 event_type = be32_to_cpu(e->event_type);
- struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);

- if (!brcmf_enq_event(cfg, event_type, e, data))
+ if (!brcmf_enq_event(ifp, event_type, e, data))
schedule_work(&cfg->event_work);
}

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index e4de9fc..399925d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -137,17 +137,6 @@ struct brcmf_cfg80211_conf {
struct ieee80211_channel channel;
};

-/* forward declaration */
-struct brcmf_cfg80211_info;
-
-/* cfg80211 main event loop */
-struct brcmf_cfg80211_event_loop {
- s32(*handler[BRCMF_E_LAST]) (struct brcmf_cfg80211_info *cfg,
- struct net_device *ndev,
- const struct brcmf_event_msg *e,
- void *data);
-};
-
/* basic structure of scan request */
struct brcmf_cfg80211_scan_req {
struct brcmf_ssid_le ssid_le;
@@ -159,14 +148,6 @@ struct brcmf_cfg80211_ie {
u8 buf[WL_TLV_INFO_MAX];
};

-/* event queue for cfg80211 main event */
-struct brcmf_cfg80211_event_q {
- struct list_head evt_q_list;
- u32 etype;
- struct brcmf_event_msg emsg;
- s8 edata[1];
-};
-
/* security information with currently associated ap */
struct brcmf_cfg80211_security {
u32 wpa_versions;
@@ -245,6 +226,25 @@ struct brcmf_cfg80211_vif {
struct list_head list;
};

+/* forward declaration */
+struct brcmf_cfg80211_info;
+
+/* cfg80211 main event loop */
+struct brcmf_cfg80211_event_loop {
+ s32(*handler[BRCMF_E_LAST]) (struct brcmf_if *ifp,
+ const struct brcmf_event_msg *e,
+ void *data);
+};
+
+/* event queue for cfg80211 main event */
+struct brcmf_cfg80211_event_q {
+ struct list_head evt_q_list;
+ u32 etype;
+ struct brcmf_if *ifp;
+ struct brcmf_event_msg emsg;
+ s8 edata[1];
+};
+
/* association inform */
struct brcmf_cfg80211_connect_info {
u8 *req_ie;
@@ -484,8 +484,8 @@ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr);
void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);

/* event handler from dongle */
-void brcmf_cfg80211_event(struct net_device *ndev,
- const struct brcmf_event_msg *e, void *data);
+void brcmf_cfg80211_event(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
+ void *data);
s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg);
s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg);

--
1.7.9.5



2012-11-06 00:22:50

by Franky Lin

[permalink] [raw]
Subject: [PATCH 22/24] brcmfmac: on halting driver check before release or free.

From: Hante Meuleman <[email protected]>

brcmf_netdev_stop shall first check bus_if status before bringing
down cfg80211. brcmf_detach shall first check if driver is
allocated.

Reviewed-by: Arend Van Spriel <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index a0d8950..2bb1207 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -600,10 +600,12 @@ static int brcmf_netdev_stop(struct net_device *ndev)
struct brcmf_pub *drvr = ifp->drvr;

brcmf_dbg(TRACE, "Enter\n");
- brcmf_cfg80211_down(drvr->config);
+
if (drvr->bus_if->drvr_up == 0)
return 0;

+ brcmf_cfg80211_down(drvr->config);
+
/* Set state and stop OS transmissions */
drvr->bus_if->drvr_up = false;
netif_stop_queue(ndev);
@@ -905,6 +907,8 @@ void brcmf_detach(struct device *dev)

brcmf_dbg(TRACE, "Enter\n");

+ if (drvr == NULL)
+ return;

/* make sure primary interface removed last */
for (i = BRCMF_MAX_IFS-1; i > -1; i--)
--
1.7.9.5



2012-11-06 00:22:49

by Franky Lin

[permalink] [raw]
Subject: [PATCH 04/24] brcmfmac: make pointer type constant in brcmf_set_management_ie()

From: Arend van Spriel <[email protected]>

The vendor ie buffer passed to brcmf_set_management_ie() is not modified
and the caller always provided a constant buffer, which needed a cast.
Better making the buffer parameter of the function constant so the
casts can be removed.

Reviewed-by: Hante Meuleman <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Arend van Spriel <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index c979ce1..94da6c9 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3681,7 +3681,7 @@ exit:
}

static s32
-brcmf_parse_vndr_ies(u8 *vndr_ie_buf, u32 vndr_ie_len,
+brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
struct parsed_vndr_ies *vndr_ies)
{
s32 err = 0;
@@ -3760,10 +3760,10 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
return ie_len + VNDR_IE_HDR_SIZE;
}

-static s32
-brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
- struct net_device *ndev, s32 pktflag,
- u8 *vndr_ie_buf, u32 vndr_ie_len)
+static
+s32 brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
+ struct net_device *ndev, s32 pktflag,
+ const u8 *vndr_ie_buf, u32 vndr_ie_len)
{
struct brcmf_if *ifp = netdev_priv(ndev);
struct vif_saved_ie *saved_ie = &ifp->vif->saved_ie;
@@ -4004,7 +4004,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
/* Set Beacon IEs to FW */
err = brcmf_set_management_ie(cfg, ndev,
VNDR_IE_BEACON_FLAG,
- (u8 *)settings->beacon.tail,
+ settings->beacon.tail,
settings->beacon.tail_len);
if (err)
WL_ERR("Set Beacon IE Failed\n");
@@ -4014,7 +4014,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
/* Set Probe Response IEs to FW */
err = brcmf_set_management_ie(cfg, ndev,
VNDR_IE_PRBRSP_FLAG,
- (u8 *)settings->beacon.proberesp_ies,
+ settings->beacon.proberesp_ies,
settings->beacon.proberesp_ies_len);
if (err)
WL_ERR("Set Probe Resp IE Failed\n");
--
1.7.9.5



2012-11-06 00:22:45

by Franky Lin

[permalink] [raw]
Subject: [PATCH 16/24] brcmfmac: protect consecutive SDIO access with sdio_claim_host

Semaphore sdsem is used to protect consecutive memory access
through SDIO bus. Same functionality is provided by sdio_claim_host/
sdio_release_host interface as well. Replace sdsem with
sdio_claim_host.

Signed-off-by: Franky Lin <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 28 +----
.../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 7 +-
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 118 ++++++++++++--------
3 files changed, 82 insertions(+), 71 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 3b2c4c2..1aec434 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -84,6 +84,8 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
return ret;
sdiodev->irq_wake = true;

+ sdio_claim_host(sdiodev->func[1]);
+
/* must configure SDIO_CCCR_IENx to enable irq */
data = brcmf_sdio_regrb(sdiodev, SDIO_CCCR_IENx, &ret);
data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
@@ -95,6 +97,8 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
data |= SDIO_SEPINT_ACT_HI;
brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);

+ sdio_release_host(sdiodev->func[1]);
+
return 0;
}

@@ -102,8 +106,10 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
{
brcmf_dbg(TRACE, "Entering\n");

+ sdio_claim_host(sdiodev->func[1]);
brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL);
brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL);
+ sdio_release_host(sdiodev->func[1]);

if (sdiodev->irq_wake) {
disable_irq_wake(sdiodev->irq);
@@ -249,9 +255,7 @@ u8 brcmf_sdio_regrb(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
int retval;

brcmf_dbg(INFO, "addr:0x%08x\n", addr);
- sdio_claim_host(sdiodev->func[1]);
retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
- sdio_release_host(sdiodev->func[1]);
brcmf_dbg(INFO, "data:0x%02x\n", data);

if (ret)
@@ -266,9 +270,7 @@ u32 brcmf_sdio_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
int retval;

brcmf_dbg(INFO, "addr:0x%08x\n", addr);
- sdio_claim_host(sdiodev->func[1]);
retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, false);
- sdio_release_host(sdiodev->func[1]);
brcmf_dbg(INFO, "data:0x%08x\n", data);

if (ret)
@@ -283,9 +285,7 @@ void brcmf_sdio_regwb(struct brcmf_sdio_dev *sdiodev, u32 addr,
int retval;

brcmf_dbg(INFO, "addr:0x%08x, data:0x%02x\n", addr, data);
- sdio_claim_host(sdiodev->func[1]);
retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
- sdio_release_host(sdiodev->func[1]);

if (ret)
*ret = retval;
@@ -297,9 +297,7 @@ void brcmf_sdio_regwl(struct brcmf_sdio_dev *sdiodev, u32 addr,
int retval;

brcmf_dbg(INFO, "addr:0x%08x, data:0x%08x\n", addr, data);
- sdio_claim_host(sdiodev->func[1]);
retval = brcmf_sdio_regrw_helper(sdiodev, addr, &data, true);
- sdio_release_host(sdiodev->func[1]);

if (ret)
*ret = retval;
@@ -364,8 +362,6 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
fn, addr, pkt->len);

- sdio_claim_host(sdiodev->func[1]);
-
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
if (err)
@@ -376,8 +372,6 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
fn, addr, pkt);

done:
- sdio_release_host(sdiodev->func[1]);
-
return err;
}

@@ -391,8 +385,6 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n",
fn, addr, pktq->qlen);

- sdio_claim_host(sdiodev->func[1]);
-
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
if (err)
@@ -403,8 +395,6 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
pktq);

done:
- sdio_release_host(sdiodev->func[1]);
-
return err;
}

@@ -446,8 +436,6 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
if (flags & SDIO_REQ_ASYNC)
return -ENOTSUPP;

- sdio_claim_host(sdiodev->func[1]);
-
if (bar0 != sdiodev->sbwad) {
err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
if (err)
@@ -467,8 +455,6 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
addr, pkt);

done:
- sdio_release_host(sdiodev->func[1]);
-
return err;
}

@@ -510,10 +496,8 @@ int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn)
brcmf_dbg(TRACE, "Enter\n");

/* issue abort cmd52 command through F0 */
- sdio_claim_host(sdiodev->func[1]);
brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0,
SDIO_CCCR_ABORT, &t_func);
- sdio_release_host(sdiodev->func[1]);

brcmf_dbg(TRACE, "Exit\n");
return 0;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
index c3247d5..c62ec2a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c
@@ -372,9 +372,7 @@ static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev)
}

/* Enable Function 1 */
- sdio_claim_host(sdiodev->func[1]);
err_ret = sdio_enable_func(sdiodev->func[1]);
- sdio_release_host(sdiodev->func[1]);
if (err_ret)
brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret);

@@ -393,16 +391,14 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
sdiodev->num_funcs = 2;

sdio_claim_host(sdiodev->func[1]);
+
err_ret = sdio_set_block_size(sdiodev->func[1], SDIO_FUNC1_BLOCKSIZE);
- sdio_release_host(sdiodev->func[1]);
if (err_ret) {
brcmf_dbg(ERROR, "Failed to set F1 blocksize\n");
goto out;
}

- sdio_claim_host(sdiodev->func[2]);
err_ret = sdio_set_block_size(sdiodev->func[2], SDIO_FUNC2_BLOCKSIZE);
- sdio_release_host(sdiodev->func[2]);
if (err_ret) {
brcmf_dbg(ERROR, "Failed to set F2 blocksize\n");
goto out;
@@ -411,6 +407,7 @@ int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev)
brcmf_sdioh_enablefuncs(sdiodev);

out:
+ sdio_release_host(sdiodev->func[1]);
brcmf_dbg(TRACE, "Done\n");
return err_ret;
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index e328852..7b8c653 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -584,8 +584,6 @@ struct brcmf_sdio {
struct list_head dpc_tsklst;
spinlock_t dpc_tl_lock;

- struct semaphore sdsem;
-
const struct firmware *firmware;
u32 fw_ptr;

@@ -1274,7 +1272,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
* read directly into the chained packet, or allocate a large
* packet and and copy into the chain.
*/
- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
if (usechain) {
errcode = brcmf_sdcard_recv_chain(bus->sdiodev,
bus->sdiodev->sbwad,
@@ -1296,7 +1294,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
dlen);
errcode = -1;
}
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);
bus->sdcnt.f2rxdata++;

/* On failure, kill the superframe, allow a couple retries */
@@ -1305,6 +1303,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
dlen, errcode);
bus->sdiodev->bus_if->dstats.rx_errors++;

+ sdio_claim_host(bus->sdiodev->func[1]);
if (bus->glomerr++ < 3) {
brcmf_sdbrcm_rxfail(bus, true, true);
} else {
@@ -1313,6 +1312,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
bus->sdcnt.rxglomfail++;
brcmf_sdbrcm_free_glom(bus);
}
+ sdio_release_host(bus->sdiodev->func[1]);
return 0;
}

@@ -1322,8 +1322,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)

rd_new.seq_num = rxseq;
rd_new.len = dlen;
+ sdio_claim_host(bus->sdiodev->func[1]);
errcode = -!brcmf_sdio_hdparser(bus, pfirst->data, &rd_new,
BRCMF_SDIO_FT_SUPER);
+ sdio_release_host(bus->sdiodev->func[1]);
bus->cur_read.len = rd_new.len_nxtfrm << 4;

/* Remove superframe header, remember offset */
@@ -1339,9 +1341,11 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)

rd_new.len = pnext->len;
rd_new.seq_num = rxseq++;
+ sdio_claim_host(bus->sdiodev->func[1]);
errcode = -!brcmf_sdio_hdparser(bus, pnext->data,
&rd_new,
BRCMF_SDIO_FT_SUB);
+ sdio_release_host(bus->sdiodev->func[1]);
brcmf_dbg_hex_dump(BRCMF_GLOM_ON(),
pnext->data, 32, "subframe:\n");

@@ -1351,6 +1355,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
if (errcode) {
/* Terminate frame on error, request
a couple retries */
+ sdio_claim_host(bus->sdiodev->func[1]);
if (bus->glomerr++ < 3) {
/* Restore superframe header space */
skb_push(pfirst, sfdoff);
@@ -1361,6 +1366,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
bus->sdcnt.rxglomfail++;
brcmf_sdbrcm_free_glom(bus);
}
+ sdio_release_host(bus->sdiodev->func[1]);
bus->cur_read.len = 0;
return 0;
}
@@ -1585,7 +1591,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)

rd->len_left = rd->len;
/* read header first for unknow frame length */
- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
if (!rd->len) {
sdret = brcmf_sdcard_recv_buf(bus->sdiodev,
bus->sdiodev->sbwad,
@@ -1598,7 +1604,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
sdret);
bus->sdcnt.rx_hdrfail++;
brcmf_sdbrcm_rxfail(bus, true, true);
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);
continue;
}

@@ -1608,7 +1614,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)

if (!brcmf_sdio_hdparser(bus, bus->rxhdr, rd,
BRCMF_SDIO_FT_NORMAL)) {
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);
if (!bus->rxpending)
break;
else
@@ -1624,7 +1630,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
rd->len_nxtfrm = 0;
/* treat all packet as event if we don't know */
rd->channel = SDPCM_EVENT_CHANNEL;
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);
continue;
}
rd->len_left = rd->len > BRCMF_FIRSTREAD ?
@@ -1642,7 +1648,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
bus->sdiodev->bus_if->dstats.rx_dropped++;
brcmf_sdbrcm_rxfail(bus, false,
RETRYCHAN(rd->channel));
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);
continue;
}
skb_pull(pkt, head_read);
@@ -1651,15 +1657,17 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
sdret = brcmf_sdcard_recv_pkt(bus->sdiodev, bus->sdiodev->sbwad,
SDIO_FUNC_2, F2SYNC, pkt);
bus->sdcnt.f2rxdata++;
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);

if (sdret < 0) {
brcmf_dbg(ERROR, "read %d bytes from channel %d failed: %d\n",
rd->len, rd->channel, sdret);
brcmu_pkt_buf_free_skb(pkt);
bus->sdiodev->bus_if->dstats.rx_errors++;
+ sdio_claim_host(bus->sdiodev->func[1]);
brcmf_sdbrcm_rxfail(bus, true,
RETRYCHAN(rd->channel));
+ sdio_release_host(bus->sdiodev->func[1]);
continue;
}

@@ -1670,6 +1678,7 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
} else {
memcpy(bus->rxhdr, pkt->data, SDPCM_HDRLEN);
rd_new.seq_num = rd->seq_num;
+ sdio_claim_host(bus->sdiodev->func[1]);
if (!brcmf_sdio_hdparser(bus, bus->rxhdr, &rd_new,
BRCMF_SDIO_FT_NORMAL)) {
rd->len = 0;
@@ -1682,9 +1691,11 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
roundup(rd_new.len, 16) >> 4);
rd->len = 0;
brcmf_sdbrcm_rxfail(bus, true, true);
+ sdio_release_host(bus->sdiodev->func[1]);
brcmu_pkt_buf_free_skb(pkt);
continue;
}
+ sdio_release_host(bus->sdiodev->func[1]);
rd->len_nxtfrm = rd_new.len_nxtfrm;
rd->channel = rd_new.channel;
rd->dat_offset = rd_new.dat_offset;
@@ -1700,7 +1711,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
rd_new.seq_num);
/* Force retry w/normal header read */
rd->len = 0;
+ sdio_claim_host(bus->sdiodev->func[1]);
brcmf_sdbrcm_rxfail(bus, false, true);
+ sdio_release_host(bus->sdiodev->func[1]);
brcmu_pkt_buf_free_skb(pkt);
continue;
}
@@ -1723,7 +1736,9 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
} else {
brcmf_dbg(ERROR, "%s: glom superframe w/o "
"descriptor!\n", __func__);
+ sdio_claim_host(bus->sdiodev->func[1]);
brcmf_sdbrcm_rxfail(bus, false, false);
+ sdio_release_host(bus->sdiodev->func[1]);
}
/* prepare the descriptor for the next read */
rd->len = rd->len_nxtfrm << 4;
@@ -1879,7 +1894,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
if (len & (ALIGNMENT - 1))
len = roundup(len, ALIGNMENT);

- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
ret = brcmf_sdcard_send_pkt(bus->sdiodev, bus->sdiodev->sbwad,
SDIO_FUNC_2, F2SYNC, pkt);
bus->sdcnt.f2txdata++;
@@ -1907,7 +1922,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt,
}

}
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);
if (ret == 0)
bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;

@@ -1955,11 +1970,11 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_sdio *bus, uint maxframes)
/* In poll mode, need to check for other events */
if (!bus->intr && cnt) {
/* Check device status, signal pending interrupt */
- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
ret = r_sdreg32(bus, &intstatus,
offsetof(struct sdpcmd_regs,
intstatus));
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);
bus->sdcnt.f2txdata++;
if (ret != 0)
break;
@@ -1996,7 +2011,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)
bus->watchdog_tsk = NULL;
}

- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);

/* Enable clock for device interrupts */
brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
@@ -2030,7 +2045,7 @@ static void brcmf_sdbrcm_bus_stop(struct device *dev)

/* Turn off the backplane clock (only) */
brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);

/* Clear the data packet queues */
brcmu_pktq_flush(&bus->txq, true, NULL, NULL);
@@ -2132,7 +2147,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)

brcmf_dbg(TRACE, "Enter\n");

- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);

/* If waiting for HTAVAIL, check status */
if (bus->clkstate == CLK_PENDING) {
@@ -2186,9 +2201,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
/* Pending interrupt indicates new device status */
if (atomic_read(&bus->ipend) > 0) {
atomic_set(&bus->ipend, 0);
- sdio_claim_host(bus->sdiodev->func[1]);
err = brcmf_sdio_intr_rstatus(bus);
- sdio_release_host(bus->sdiodev->func[1]);
}

/* Start with leftover status bits */
@@ -2217,7 +2230,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
intstatus |= brcmf_sdbrcm_hostmail(bus);
}

- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);

/* Generally don't ask for these, can get CRC errors... */
if (intstatus & I_WR_OOSYNC) {
@@ -2265,7 +2278,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
(bus->clkstate == CLK_AVAIL)) {
int i;

- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
err = brcmf_sdcard_send_buf(bus->sdiodev, bus->sdiodev->sbwad,
SDIO_FUNC_2, F2SYNC, bus->ctrl_frame_buf,
(u32) bus->ctrl_frame_len);
@@ -2299,7 +2312,7 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
} else {
bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP;
}
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);
bus->ctrl_frame_stat = false;
brcmf_sdbrcm_wait_event_wakeup(bus);
}
@@ -2329,7 +2342,9 @@ static void brcmf_sdbrcm_dpc(struct brcmf_sdio *bus)
if ((bus->clkstate != CLK_PENDING)
&& bus->idletime == BRCMF_IDLE_IMMEDIATE) {
bus->activity = false;
+ sdio_claim_host(bus->sdiodev->func[1]);
brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
+ sdio_release_host(bus->sdiodev->func[1]);
}
}

@@ -2622,9 +2637,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
/* precondition: IS_ALIGNED((unsigned long)frame, 2) */

/* Make sure backplane clock is on */
- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);

/* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */
*(__le16 *) frame = cpu_to_le16((u16) msglen);
@@ -2666,9 +2681,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
frame, min_t(u16, len, 16), "TxHdr:\n");

do {
- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
ret = brcmf_tx_frame(bus, frame, len);
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);
} while (ret < 0 && retries++ < TXRETRIES);
}

@@ -2678,9 +2693,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);

bus->activity = false;
- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
brcmf_sdbrcm_clkctl(bus, CLK_NONE, true);
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);
} else {
spin_unlock_irqrestore(&bus->dpc_tl_lock, flags);
}
@@ -2714,10 +2729,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
* Read last word in socram to determine
* address of sdpcm_shared structure
*/
- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
rv = brcmf_sdbrcm_membytes(bus, false, shaddr,
(u8 *)&addr_le, 4);
- up(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
if (rv < 0)
return rv;

@@ -2736,8 +2751,10 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
}

/* Read hndrte_shared structure */
+ sdio_claim_host(bus->sdiodev->func[1]);
rv = brcmf_sdbrcm_membytes(bus, false, addr, (u8 *)&sh_le,
sizeof(struct sdpcm_shared_le));
+ sdio_release_host(bus->sdiodev->func[1]);
if (rv < 0)
return rv;

@@ -2840,14 +2857,14 @@ static int brcmf_sdio_trap_info(struct brcmf_sdio *bus, struct sdpcm_shared *sh,
if ((sh->flags & SDPCM_SHARED_TRAP) == 0)
return 0;

- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
error = brcmf_sdbrcm_membytes(bus, false, sh->trap_addr, (u8 *)&tr,
sizeof(struct brcmf_trap_info));
if (error < 0)
return error;

nbytes = brcmf_sdio_dump_console(bus, sh, data, count);
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);
if (nbytes < 0)
return nbytes;

@@ -2893,7 +2910,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
return 0;
}

- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
if (sh->assert_file_addr != 0) {
error = brcmf_sdbrcm_membytes(bus, false, sh->assert_file_addr,
(u8 *)file, 80);
@@ -2906,7 +2923,7 @@ static int brcmf_sdio_assert_info(struct brcmf_sdio *bus,
if (error < 0)
return error;
}
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);

res = scnprintf(buf, sizeof(buf),
"dongle assert: %s:%d: assert(%s)\n",
@@ -3366,13 +3383,16 @@ brcmf_sdbrcm_download_firmware(struct brcmf_sdio *bus)
{
bool ret;

- /* Download the firmware */
+ sdio_claim_host(bus->sdiodev->func[1]);
+
brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);

ret = _brcmf_sdbrcm_download_firmware(bus) == 0;

brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false);

+ sdio_release_host(bus->sdiodev->func[1]);
+
return ret;
}

@@ -3401,7 +3421,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
bus->sdcnt.tickcnt = 0;
brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);

- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);

/* Make sure backplane clock is on, needed to generate F2 interrupt */
brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
@@ -3470,7 +3490,7 @@ static int brcmf_sdbrcm_bus_init(struct device *dev)
brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);

exit:
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);

return ret;
}
@@ -3533,9 +3553,11 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
u8 devpend;
spin_unlock_irqrestore(&bus->dpc_tl_lock,
flags);
+ sdio_claim_host(bus->sdiodev->func[1]);
devpend = brcmf_sdio_regrb(bus->sdiodev,
SDIO_CCCR_INTx,
NULL);
+ sdio_release_host(bus->sdiodev->func[1]);
intstatus =
devpend & (INTR_STATUS_FUNC1 |
INTR_STATUS_FUNC2);
@@ -3565,13 +3587,13 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
bus->console.count += BRCMF_WD_POLL_MS;
if (bus->console.count >= bus->console_interval) {
bus->console.count -= bus->console_interval;
- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
/* Make sure backplane clock is on */
brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
if (brcmf_sdbrcm_readconsole(bus) < 0)
/* stop on error */
bus->console_interval = 0;
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);
}
}
#endif /* DEBUG */
@@ -3584,9 +3606,9 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus)
bus->activity = false;
brcmf_sdbrcm_wd_timer(bus, BRCMF_WD_POLL_MS);
} else {
- down(&bus->sdsem);
+ sdio_claim_host(bus->sdiodev->func[1]);
brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
- up(&bus->sdsem);
+ sdio_release_host(bus->sdiodev->func[1]);
}
}
}
@@ -3685,6 +3707,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)

bus->alp_only = true;

+ sdio_claim_host(bus->sdiodev->func[1]);
+
pr_debug("F1 signature read @0x18000000=0x%4x\n",
brcmf_sdio_regrl(bus->sdiodev, SI_ENUM_BASE, NULL));

@@ -3732,6 +3756,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
reg_val = brcmf_sdio_regrl(bus->sdiodev, reg_addr, NULL);
brcmf_sdio_regwl(bus->sdiodev, reg_addr, reg_val | CC_BPRESEN, NULL);

+ sdio_release_host(bus->sdiodev->func[1]);
+
brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN);

/* Locate an appropriately-aligned portion of hdrbuf */
@@ -3747,6 +3773,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva)
return true;

fail:
+ sdio_release_host(bus->sdiodev->func[1]);
return false;
}

@@ -3754,6 +3781,8 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
{
brcmf_dbg(TRACE, "Enter\n");

+ sdio_claim_host(bus->sdiodev->func[1]);
+
/* Disable F2 to clear any intermediate frame state on the dongle */
brcmf_sdio_regwb(bus->sdiodev, SDIO_CCCR_IOEx,
SDIO_FUNC_ENABLE_1, NULL);
@@ -3764,6 +3793,8 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_sdio *bus)
/* Done with backplane-dependent accesses, can drop clock... */
brcmf_sdio_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL);

+ sdio_release_host(bus->sdiodev->func[1]);
+
/* ...and initialize clock/power states */
bus->clkstate = CLK_SDONLY;
bus->idletime = BRCMF_IDLE_INTERVAL;
@@ -3819,8 +3850,10 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_sdio *bus)
brcmf_dbg(TRACE, "Enter\n");

if (bus->ci) {
+ sdio_claim_host(bus->sdiodev->func[1]);
brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false);
brcmf_sdbrcm_clkctl(bus, CLK_NONE, false);
+ sdio_release_host(bus->sdiodev->func[1]);
brcmf_sdio_chip_detach(&bus->ci);
if (bus->vars && bus->varsz)
kfree(bus->vars);
@@ -3905,9 +3938,6 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
bus->timer.data = (unsigned long)bus;
bus->timer.function = brcmf_sdbrcm_watchdog;

- /* Initialize thread based operation and lock */
- sema_init(&bus->sdsem, 1);
-
/* Initialize watchdog thread */
init_completion(&bus->watchdog_wait);
bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread,
--
1.7.9.5



2012-11-06 00:22:45

by Franky Lin

[permalink] [raw]
Subject: [PATCH 21/24] brcmfmac: check bus state to be data before sending data.

From: Hante Meuleman <[email protected]>

brcmf_netdev_start_xmit and brcmf_fil_cmd_data are checking
bus state for down. These functions should check for data
state.

Reviewed-by: Arend Van Spriel <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 2 +-
drivers/net/wireless/brcm80211/brcmfmac/fwil.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 0f81f31..a0d8950 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -216,7 +216,7 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *ndev)

/* Reject if down */
if (!drvr->bus_if->drvr_up ||
- (drvr->bus_if->state == BRCMF_BUS_DOWN)) {
+ (drvr->bus_if->state != BRCMF_BUS_DATA)) {
brcmf_dbg(ERROR, "xmit rejected drvup=%d state=%d\n",
drvr->bus_if->drvr_up,
drvr->bus_if->state);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
index f121d41..62e0960 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.c
@@ -35,7 +35,7 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, u32 cmd, void *data, u32 len, bool set)
struct brcmf_pub *drvr = ifp->drvr;
s32 err;

- if (drvr->bus_if->state == BRCMF_BUS_DOWN) {
+ if (drvr->bus_if->state != BRCMF_BUS_DATA) {
brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n");
return -EIO;
}
--
1.7.9.5



2012-11-06 00:22:45

by Franky Lin

[permalink] [raw]
Subject: [PATCH 06/24] brcmfmac: use fwil for netdev callbacks.

From: Hante Meuleman <[email protected]>

Change setting up multicast, mac address and offloading to use the
refactored firmware interface layer. Remove obsolete brcmf_proto_dcmd
function.

Reviewed-by: Arend Van Spriel <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | 70 ------
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 256 ++++++--------------
.../net/wireless/brcm80211/brcmfmac/dhd_proto.h | 3 -
3 files changed, 70 insertions(+), 259 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
index b9d8a5a..601d4d7 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c
@@ -277,76 +277,6 @@ done:
return ret;
}

-int
-brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx, struct brcmf_dcmd *dcmd,
- int len)
-{
- struct brcmf_proto *prot = drvr->prot;
- int ret = -1;
-
- if (drvr->bus_if->state == BRCMF_BUS_DOWN) {
- brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n");
- return ret;
- }
- mutex_lock(&drvr->proto_block);
-
- brcmf_dbg(TRACE, "Enter\n");
-
- if (len > BRCMF_DCMD_MAXLEN)
- goto done;
-
- if (prot->pending == true) {
- brcmf_dbg(TRACE, "CDC packet is pending!!!! cmd=0x%x (%lu) lastcmd=0x%x (%lu)\n",
- dcmd->cmd, (unsigned long)dcmd->cmd, prot->lastcmd,
- (unsigned long)prot->lastcmd);
- if (dcmd->cmd == BRCMF_C_SET_VAR ||
- dcmd->cmd == BRCMF_C_GET_VAR)
- brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)dcmd->buf);
-
- goto done;
- }
-
- prot->pending = true;
- prot->lastcmd = dcmd->cmd;
- if (dcmd->set)
- ret = brcmf_proto_cdc_set_dcmd(drvr, ifidx, dcmd->cmd,
- dcmd->buf, len);
- else {
- ret = brcmf_proto_cdc_query_dcmd(drvr, ifidx, dcmd->cmd,
- dcmd->buf, len);
- if (ret > 0)
- dcmd->used = ret -
- sizeof(struct brcmf_proto_cdc_dcmd);
- }
-
- if (ret >= 0)
- ret = 0;
- else {
- struct brcmf_proto_cdc_dcmd *msg = &prot->msg;
- /* len == needed when set/query fails from dongle */
- dcmd->needed = le32_to_cpu(msg->len);
- }
-
- /* Intercept the wme_dp dongle cmd here */
- if (!ret && dcmd->cmd == BRCMF_C_SET_VAR &&
- !strcmp(dcmd->buf, "wme_dp")) {
- int slen;
- __le32 val = 0;
-
- slen = strlen("wme_dp") + 1;
- if (len >= (int)(slen + sizeof(int)))
- memcpy(&val, (char *)dcmd->buf + slen, sizeof(int));
- drvr->wme_dp = (u8) le32_to_cpu(val);
- }
-
- prot->pending = false;
-
-done:
- mutex_unlock(&drvr->proto_block);
-
- return ret;
-}
-
static bool pkt_sum_needed(struct sk_buff *skb)
{
return skb->ip_summed == CHECKSUM_PARTIAL;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 2976523..b130f20 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -45,6 +45,7 @@
#include "dhd_proto.h"
#include "dhd_dbg.h"
#include "wl_cfg80211.h"
+#include "fwil.h"

MODULE_AUTHOR("Broadcom Corporation");
MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver.");
@@ -95,38 +96,35 @@ char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)

static void _brcmf_set_multicast_list(struct work_struct *work)
{
+ struct brcmf_if *ifp;
struct net_device *ndev;
struct netdev_hw_addr *ha;
- u32 dcmd_value, cnt;
+ u32 cmd_value, cnt;
__le32 cnt_le;
- __le32 dcmd_le_value;
-
- struct brcmf_dcmd dcmd;
char *buf, *bufp;
- uint buflen;
- int ret;
-
+ u32 buflen;
+ s32 err;
struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
multicast_work);

- ndev = drvr->iflist[0]->ndev;
- cnt = netdev_mc_count(ndev);
+ brcmf_dbg(TRACE, "enter\n");
+
+ ifp = drvr->iflist[0];
+ ndev = ifp->ndev;

/* Determine initial value of allmulti flag */
- dcmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false;
+ cmd_value = (ndev->flags & IFF_ALLMULTI) ? true : false;

/* Send down the multicast list first. */
-
- buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN);
- bufp = buf = kmalloc(buflen, GFP_ATOMIC);
- if (!bufp)
+ cnt = netdev_mc_count(ndev);
+ buflen = sizeof(cnt) + (cnt * ETH_ALEN);
+ buf = kmalloc(buflen, GFP_ATOMIC);
+ if (!buf)
return;
-
- strcpy(bufp, "mcast_list");
- bufp += strlen("mcast_list") + 1;
+ bufp = buf;

cnt_le = cpu_to_le32(cnt);
- memcpy(bufp, &cnt_le, sizeof(cnt));
+ memcpy(bufp, &cnt_le, sizeof(cnt_le));
bufp += sizeof(cnt_le);

netdev_for_each_mc_addr(ha, ndev) {
@@ -137,110 +135,55 @@ static void _brcmf_set_multicast_list(struct work_struct *work)
cnt--;
}

- memset(&dcmd, 0, sizeof(dcmd));
- dcmd.cmd = BRCMF_C_SET_VAR;
- dcmd.buf = buf;
- dcmd.len = buflen;
- dcmd.set = true;
-
- ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
- if (ret < 0) {
- brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n",
- brcmf_ifname(drvr, 0), cnt);
- dcmd_value = cnt ? true : dcmd_value;
+ err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen);
+ if (err < 0) {
+ brcmf_dbg(ERROR, "Setting mcast_list failed, %d\n", err);
+ cmd_value = cnt ? true : cmd_value;
}

kfree(buf);

- /* Now send the allmulti setting. This is based on the setting in the
+ /*
+ * Now send the allmulti setting. This is based on the setting in the
* net_device flags, but might be modified above to be turned on if we
* were trying to set some addresses and dongle rejected it...
*/
-
- buflen = sizeof("allmulti") + sizeof(dcmd_value);
- buf = kmalloc(buflen, GFP_ATOMIC);
- if (!buf)
- return;
-
- dcmd_le_value = cpu_to_le32(dcmd_value);
-
- if (!brcmf_c_mkiovar
- ("allmulti", (void *)&dcmd_le_value,
- sizeof(dcmd_le_value), buf, buflen)) {
- brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n",
- brcmf_ifname(drvr, 0),
- (int)sizeof(dcmd_value), buflen);
- kfree(buf);
- return;
- }
-
- memset(&dcmd, 0, sizeof(dcmd));
- dcmd.cmd = BRCMF_C_SET_VAR;
- dcmd.buf = buf;
- dcmd.len = buflen;
- dcmd.set = true;
-
- ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
- if (ret < 0) {
- brcmf_dbg(ERROR, "%s: set allmulti %d failed\n",
- brcmf_ifname(drvr, 0),
- le32_to_cpu(dcmd_le_value));
- }
-
- kfree(buf);
-
- /* Finally, pick up the PROMISC flag as well, like the NIC
- driver does */
-
- dcmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
- dcmd_le_value = cpu_to_le32(dcmd_value);
-
- memset(&dcmd, 0, sizeof(dcmd));
- dcmd.cmd = BRCMF_C_SET_PROMISC;
- dcmd.buf = &dcmd_le_value;
- dcmd.len = sizeof(dcmd_le_value);
- dcmd.set = true;
-
- ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
- if (ret < 0) {
- brcmf_dbg(ERROR, "%s: set promisc %d failed\n",
- brcmf_ifname(drvr, 0),
- le32_to_cpu(dcmd_le_value));
- }
+ err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value);
+ if (err < 0)
+ brcmf_dbg(ERROR, "Setting allmulti failed, %d\n", err);
+
+ /*Finally, pick up the PROMISC flag */
+ cmd_value = (ndev->flags & IFF_PROMISC) ? true : false;
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value);
+ if (err < 0)
+ brcmf_dbg(ERROR, "Setting BRCMF_C_SET_PROMISC failed, %d\n",
+ err);
}

static void
_brcmf_set_mac_address(struct work_struct *work)
{
- char buf[32];
- struct brcmf_dcmd dcmd;
- int ret;
+ struct brcmf_if *ifp;
+ struct net_device *ndev;
+ s32 err;

struct brcmf_pub *drvr = container_of(work, struct brcmf_pub,
setmacaddr_work);

brcmf_dbg(TRACE, "enter\n");
- if (!brcmf_c_mkiovar("cur_etheraddr", (char *)drvr->macvalue,
- ETH_ALEN, buf, 32)) {
- brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n",
- brcmf_ifname(drvr, 0));
- return;
- }
- memset(&dcmd, 0, sizeof(dcmd));
- dcmd.cmd = BRCMF_C_SET_VAR;
- dcmd.buf = buf;
- dcmd.len = 32;
- dcmd.set = true;

- ret = brcmf_proto_dcmd(drvr, 0, &dcmd, dcmd.len);
- if (ret < 0)
- brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n",
- brcmf_ifname(drvr, 0));
- else
- memcpy(drvr->iflist[0]->ndev->dev_addr,
- drvr->macvalue, ETH_ALEN);
+ ifp = drvr->iflist[0];
+ ndev = ifp->ndev;

- return;
+ err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", drvr->macvalue,
+ ETH_ALEN);
+ if (err < 0) {
+ brcmf_dbg(ERROR, "Setting cur_etheraddr failed, %d\n", err);
+ } else {
+ brcmf_dbg(TRACE, "MAC address updated to %pM\n",
+ drvr->macvalue);
+ memcpy(ndev->dev_addr, drvr->macvalue, ETH_ALEN);
+ }
}

static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr)
@@ -487,83 +430,26 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *ndev)
return &ifp->stats;
}

-/* Retrieve current toe component enables, which are kept
- as a bitmap in toe_ol iovar */
-static int brcmf_toe_get(struct brcmf_pub *drvr, int ifidx, u32 *toe_ol)
-{
- struct brcmf_dcmd dcmd;
- __le32 toe_le;
- char buf[32];
- int ret;
-
- memset(&dcmd, 0, sizeof(dcmd));
-
- dcmd.cmd = BRCMF_C_GET_VAR;
- dcmd.buf = buf;
- dcmd.len = (uint) sizeof(buf);
- dcmd.set = false;
-
- strcpy(buf, "toe_ol");
- ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
- if (ret < 0) {
- /* Check for older dongle image that doesn't support toe_ol */
- if (ret == -EIO) {
- brcmf_dbg(ERROR, "%s: toe not supported by device\n",
- brcmf_ifname(drvr, ifidx));
- return -EOPNOTSUPP;
- }
-
- brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n",
- brcmf_ifname(drvr, ifidx), ret);
- return ret;
- }
-
- memcpy(&toe_le, buf, sizeof(u32));
- *toe_ol = le32_to_cpu(toe_le);
- return 0;
-}
-
-/* Set current toe component enables in toe_ol iovar,
- and set toe global enable iovar */
-static int brcmf_toe_set(struct brcmf_pub *drvr, int ifidx, u32 toe_ol)
+/*
+ * Set current toe component enables in toe_ol iovar,
+ * and set toe global enable iovar
+ */
+static int brcmf_toe_set(struct brcmf_if *ifp, u32 toe_ol)
{
- struct brcmf_dcmd dcmd;
- char buf[32];
- int ret;
- __le32 toe_le = cpu_to_le32(toe_ol);
-
- memset(&dcmd, 0, sizeof(dcmd));
-
- dcmd.cmd = BRCMF_C_SET_VAR;
- dcmd.buf = buf;
- dcmd.len = (uint) sizeof(buf);
- dcmd.set = true;
-
- /* Set toe_ol as requested */
- strcpy(buf, "toe_ol");
- memcpy(&buf[sizeof("toe_ol")], &toe_le, sizeof(u32));
+ s32 err;

- ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
- if (ret < 0) {
- brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n",
- brcmf_ifname(drvr, ifidx), ret);
- return ret;
+ err = brcmf_fil_iovar_int_set(ifp, "toe_ol", toe_ol);
+ if (err < 0) {
+ brcmf_dbg(ERROR, "Setting toe_ol failed, %d\n", err);
+ return err;
}

- /* Enable toe globally only if any components are enabled. */
- toe_le = cpu_to_le32(toe_ol != 0);
+ err = brcmf_fil_iovar_int_set(ifp, "toe", (toe_ol != 0));
+ if (err < 0)
+ brcmf_dbg(ERROR, "Setting toe failed, %d\n", err);

- strcpy(buf, "toe");
- memcpy(&buf[sizeof("toe")], &toe_le, sizeof(u32));
-
- ret = brcmf_proto_dcmd(drvr, ifidx, &dcmd, dcmd.len);
- if (ret < 0) {
- brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n",
- brcmf_ifname(drvr, ifidx), ret);
- return ret;
- }
+ return err;

- return 0;
}

static void brcmf_ethtool_get_drvinfo(struct net_device *ndev,
@@ -581,8 +467,9 @@ static const struct ethtool_ops brcmf_ethtool_ops = {
.get_drvinfo = brcmf_ethtool_get_drvinfo,
};

-static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
+static int brcmf_ethtool(struct brcmf_if *ifp, void __user *uaddr)
{
+ struct brcmf_pub *drvr = ifp->drvr;
struct ethtool_drvinfo info;
char drvname[sizeof(info.driver)];
u32 cmd;
@@ -633,7 +520,7 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
/* Get toe offload components from dongle */
case ETHTOOL_GRXCSUM:
case ETHTOOL_GTXCSUM:
- ret = brcmf_toe_get(drvr, 0, &toe_cmpnt);
+ ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
if (ret < 0)
return ret;

@@ -654,7 +541,7 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
return -EFAULT;

/* Read the current settings, update and write back */
- ret = brcmf_toe_get(drvr, 0, &toe_cmpnt);
+ ret = brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_cmpnt);
if (ret < 0)
return ret;

@@ -666,18 +553,16 @@ static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr)
else
toe_cmpnt &= ~csum_dir;

- ret = brcmf_toe_set(drvr, 0, toe_cmpnt);
+ ret = brcmf_toe_set(ifp, toe_cmpnt);
if (ret < 0)
return ret;

/* If setting TX checksum mode, tell Linux the new mode */
if (cmd == ETHTOOL_STXCSUM) {
if (edata.data)
- drvr->iflist[0]->ndev->features |=
- NETIF_F_IP_CSUM;
+ ifp->ndev->features |= NETIF_F_IP_CSUM;
else
- drvr->iflist[0]->ndev->features &=
- ~NETIF_F_IP_CSUM;
+ ifp->ndev->features &= ~NETIF_F_IP_CSUM;
}

break;
@@ -701,7 +586,7 @@ static int brcmf_netdev_ioctl_entry(struct net_device *ndev, struct ifreq *ifr,
return -1;

if (cmd == SIOCETHTOOL)
- return brcmf_ethtool(drvr, ifr->ifr_data);
+ return brcmf_ethtool(ifp, ifr->ifr_data);

return -EOPNOTSUPP;
}
@@ -730,7 +615,6 @@ static int brcmf_netdev_open(struct net_device *ndev)
struct brcmf_bus *bus_if = drvr->bus_if;
u32 toe_ol;
s32 ret = 0;
- uint up = 0;

brcmf_dbg(TRACE, "ifidx %d\n", ifp->idx);

@@ -746,7 +630,7 @@ static int brcmf_netdev_open(struct net_device *ndev)
memcpy(ndev->dev_addr, drvr->mac, ETH_ALEN);

/* Get current TOE mode from dongle */
- if (brcmf_toe_get(drvr, ifp->idx, &toe_ol) >= 0
+ if (brcmf_fil_iovar_int_get(ifp, "toe_ol", &toe_ol) >= 0
&& (toe_ol & TOE_TX_CSUM_OL) != 0)
drvr->iflist[ifp->idx]->ndev->features |=
NETIF_F_IP_CSUM;
@@ -756,7 +640,7 @@ static int brcmf_netdev_open(struct net_device *ndev)
}

/* make sure RF is ready for work */
- brcmf_proto_cdc_set_dcmd(drvr, 0, BRCMF_C_UP, (char *)&up, sizeof(up));
+ brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);

/* Allow transmit calls */
netif_start_queue(ndev);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
index 7fe6779..9b7969d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_proto.h
@@ -43,7 +43,4 @@ extern int brcmf_proto_dcmd(struct brcmf_pub *drvr, int ifidx,
/* Sets dongle media info (drv_version, mac address). */
extern int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);

-extern int brcmf_proto_cdc_set_dcmd(struct brcmf_pub *drvr, int ifidx,
- uint cmd, void *buf, uint len);
-
#endif /* _BRCMF_PROTO_H_ */
--
1.7.9.5



2012-11-06 00:22:45

by Franky Lin

[permalink] [raw]
Subject: [PATCH 01/24] brcmfmac: remove obsolete structure ap_info

From: Arend van Spriel <[email protected]>

The data stored in ap_info structure is no longer used so remove
it from the driver.

Signed-off-by: Arend van Spriel <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 28 --------------------
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 13 ---------
2 files changed, 41 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index cb30fea..9da9d05 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -486,13 +486,6 @@ brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,

if (ap) {
set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
- if (!cfg->ap_info)
- cfg->ap_info = kzalloc(sizeof(*cfg->ap_info),
- GFP_KERNEL);
- if (!cfg->ap_info) {
- err = -ENOMEM;
- goto done;
- }
WL_INFO("IF Type = AP\n");
} else {
err = brcmf_fil_cmd_int_set(netdev_priv(ndev),
@@ -3990,11 +3983,6 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
settings->beacon.tail_len);

- kfree(cfg->ap_info->rsn_ie);
- cfg->ap_info->rsn_ie = NULL;
- kfree(cfg->ap_info->wpa_ie);
- cfg->ap_info->wpa_ie = NULL;
-
if ((wpa_ie != NULL || rsn_ie != NULL)) {
WL_TRACE("WPA(2) IE is found\n");
if (wpa_ie != NULL) {
@@ -4003,26 +3991,16 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
bssidx);
if (err < 0)
goto exit;
- cfg->ap_info->wpa_ie = kmemdup(wpa_ie,
- wpa_ie->len +
- TLV_HDR_LEN,
- GFP_KERNEL);
} else {
/* RSN IE */
err = brcmf_configure_wpaie(ndev,
(struct brcmf_vs_tlv *)rsn_ie, true, bssidx);
if (err < 0)
goto exit;
- cfg->ap_info->rsn_ie = kmemdup(rsn_ie,
- rsn_ie->len +
- TLV_HDR_LEN,
- GFP_KERNEL);
}
- cfg->ap_info->security_mode = true;
} else {
WL_TRACE("No WPA(2) IEs found\n");
brcmf_configure_opensecurity(ndev, bssidx);
- cfg->ap_info->security_mode = false;
}
/* Set Beacon IEs to FW */
err = brcmf_set_management_ie(cfg, ndev,
@@ -4766,12 +4744,6 @@ static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
cfg->iscan = NULL;
kfree(cfg->pmk_list);
cfg->pmk_list = NULL;
- if (cfg->ap_info) {
- kfree(cfg->ap_info->wpa_ie);
- kfree(cfg->ap_info->rsn_ie);
- kfree(cfg->ap_info);
- cfg->ap_info = NULL;
- }
}

static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index 1dd96f1..d7d473c 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -323,17 +323,6 @@ struct escan_info {
struct net_device *ndev;
};

-/* Structure to hold WPS, WPA IEs for a AP */
-struct ap_info {
- u8 probe_res_ie[IE_MAX_LEN];
- u8 beacon_ie[IE_MAX_LEN];
- u32 probe_res_ie_len;
- u32 beacon_ie_len;
- u8 *wpa_ie;
- u8 *rsn_ie;
- bool security_mode;
-};
-
/**
* struct brcmf_pno_param_le - PNO scan configuration parameters
*
@@ -455,7 +444,6 @@ struct brcmf_pno_scanresults_le {
* @escan_timeout: Timer for catch scan timeout.
* @escan_timeout_work: scan timeout worker.
* @escan_ioctl_buf: dongle command buffer for escan commands.
- * @ap_info: host ap information.
* @vif_list: linked list of vif instances.
* @vif_cnt: number of vif instances.
*/
@@ -497,7 +485,6 @@ struct brcmf_cfg80211_info {
struct timer_list escan_timeout;
struct work_struct escan_timeout_work;
u8 *escan_ioctl_buf;
- struct ap_info *ap_info;
struct list_head vif_list;
u8 vif_cnt;
};
--
1.7.9.5



2012-11-06 00:22:51

by Franky Lin

[permalink] [raw]
Subject: [PATCH 20/24] brcmfmac: return immediately error for out of range key_idx.

From: Hante Meuleman <[email protected]>

when brcmf_cfg80211_del_key was called with out of range key index
then firmware would return error. Checking was added to
brcmf_cfg80211_del_key to immediately return error.

Reviewed-by: Arend Van Spriel <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 228fcae..4fbf5b3 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -1822,6 +1822,12 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
if (!check_vif_up(ifp->vif))
return -EIO;

+ if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
+ /* we ignore this key index in this case */
+ WL_ERR("invalid key index (%d)\n", key_idx);
+ return -EINVAL;
+ }
+
memset(&key, 0, sizeof(key));

key.index = (u32) key_idx;
@@ -1832,15 +1838,6 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,

/* Set the new key/index */
err = send_key_to_dongle(ndev, &key);
- if (err) {
- if (err == -EINVAL) {
- if (key.index >= DOT11_MAX_DEFAULT_KEYS)
- /* we ignore this key index in this case */
- WL_ERR("invalid key index (%d)\n", key_idx);
- }
- /* Ignore this error, may happen during DISASSOC */
- err = -EAGAIN;
- }

WL_TRACE("Exit\n");
return err;
--
1.7.9.5



2012-11-06 00:22:49

by Franky Lin

[permalink] [raw]
Subject: [PATCH 17/24] brcmfmac: remove brcmf_sdbrcm_wait_for_event

brcmf_sdbrcm_wait_for_event is now a one line function and only
used by brcmf_sdbrcm_bus_txctl. Intergrate the function call
wait_event_interruptible_timeout into brcmf_sdbrcm_bus_txctl.

Signed-off-by: Franky Lin <[email protected]>
---
drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
index 7b8c653..eec1cbf 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c
@@ -1787,13 +1787,6 @@ static uint brcmf_sdio_readframes(struct brcmf_sdio *bus, uint maxframes)
}

static void
-brcmf_sdbrcm_wait_for_event(struct brcmf_sdio *bus, bool *lockvar)
-{
- wait_event_interruptible_timeout(bus->ctrl_wait, !*lockvar, HZ * 2);
- return;
-}
-
-static void
brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
{
if (waitqueue_active(&bus->ctrl_wait))
@@ -2662,7 +2655,9 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
bus->ctrl_frame_buf = frame;
bus->ctrl_frame_len = len;

- brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat);
+ wait_event_interruptible_timeout(bus->ctrl_wait,
+ !bus->ctrl_frame_stat,
+ msecs_to_jiffies(2000));

if (!bus->ctrl_frame_stat) {
brcmf_dbg(INFO, "ctrl_frame_stat == false\n");
--
1.7.9.5



2012-11-06 00:22:45

by Franky Lin

[permalink] [raw]
Subject: [PATCH 05/24] brcmfmac: remove obsolete i-scan and clean up related code.

From: Hante Meuleman <[email protected]>

e-scan has become the default scanning method. This patch removes
the i-scan related code and cleans up e-scan related code to be
always enabled.

Reviewed-by: Arend Van Spriel <[email protected]>
Reviewed-by: Pieter-Paul Giesberts <[email protected]>
Signed-off-by: Hante Meuleman <[email protected]>
Signed-off-by: Franky Lin <[email protected]>
---
drivers/net/wireless/brcm80211/Kconfig | 8 -
drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 44 --
drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 9 +-
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 581 +-------------------
.../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 68 +--
5 files changed, 27 insertions(+), 683 deletions(-)

diff --git a/drivers/net/wireless/brcm80211/Kconfig b/drivers/net/wireless/brcm80211/Kconfig
index c9d811e..b480088 100644
--- a/drivers/net/wireless/brcm80211/Kconfig
+++ b/drivers/net/wireless/brcm80211/Kconfig
@@ -55,14 +55,6 @@ config BRCMFMAC_USB
IEEE802.11n embedded FullMAC WLAN driver. Say Y if you want to
use the driver for an USB wireless card.

-config BRCMISCAN
- bool "Broadcom I-Scan (OBSOLETE)"
- depends on BRCMFMAC
- ---help---
- This option enables the I-Scan method. By default fullmac uses the
- new E-Scan method which uses less memory in firmware and gives no
- limitation on the number of scan results.
-
config BRCMDBG
bool "Broadcom driver debug functions"
depends on BRCMSMAC || BRCMFMAC
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 8704daa..34bad32 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -100,19 +100,6 @@
#define BRCMF_SCAN_PARAMS_COUNT_MASK 0x0000ffff
#define BRCMF_SCAN_PARAMS_NSSID_SHIFT 16

-#define BRCMF_SCAN_ACTION_START 1
-#define BRCMF_SCAN_ACTION_CONTINUE 2
-#define WL_SCAN_ACTION_ABORT 3
-
-#define BRCMF_ISCAN_REQ_VERSION 1
-
-/* brcmf_iscan_results status values */
-#define BRCMF_SCAN_RESULTS_SUCCESS 0
-#define BRCMF_SCAN_RESULTS_PARTIAL 1
-#define BRCMF_SCAN_RESULTS_PENDING 2
-#define BRCMF_SCAN_RESULTS_ABORTED 3
-#define BRCMF_SCAN_RESULTS_NO_MEM 4
-
/* Indicates this key is using soft encrypt */
#define WL_SOFT_KEY (1 << 0)
/* primary (ie tx) key */
@@ -452,14 +439,6 @@ struct brcmf_scan_params_le {
__le16 channel_list[1]; /* list of chanspecs */
};

-/* incremental scan struct */
-struct brcmf_iscan_params_le {
- __le32 version;
- __le16 action;
- __le16 scan_duration;
- struct brcmf_scan_params_le params_le;
-};
-
struct brcmf_scan_results {
u32 buflen;
u32 version;
@@ -467,12 +446,6 @@ struct brcmf_scan_results {
struct brcmf_bss_info_le bss_info_le[];
};

-struct brcmf_scan_results_le {
- __le32 buflen;
- __le32 version;
- __le32 count;
-};
-
struct brcmf_escan_params_le {
__le32 version;
__le16 action;
@@ -508,23 +481,6 @@ struct brcmf_join_params {
struct brcmf_assoc_params_le params_le;
};

-/* incremental scan results struct */
-struct brcmf_iscan_results {
- union {
- u32 status;
- __le32 status_le;
- };
- union {
- struct brcmf_scan_results results;
- struct brcmf_scan_results_le results_le;
- };
-};
-
-/* size of brcmf_iscan_results not including variable length array */
-#define BRCMF_ISCAN_RESULTS_FIXED_SIZE \
- (sizeof(struct brcmf_scan_results) + \
- offsetof(struct brcmf_iscan_results, results))
-
struct brcmf_wsec_key {
u32 index; /* key index */
u32 len; /* key length */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
index eefa6c2..55a4738 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h
@@ -27,11 +27,10 @@
#define BRCMF_HDRS_VAL 0x0040
#define BRCMF_BYTES_VAL 0x0080
#define BRCMF_INTR_VAL 0x0100
-#define BRCMF_GLOM_VAL 0x0400
-#define BRCMF_EVENT_VAL 0x0800
-#define BRCMF_BTA_VAL 0x1000
-#define BRCMF_ISCAN_VAL 0x2000
-#define BRCMF_FIL_VAL 0x4000
+#define BRCMF_GLOM_VAL 0x0200
+#define BRCMF_EVENT_VAL 0x0400
+#define BRCMF_BTA_VAL 0x0800
+#define BRCMF_FIL_VAL 0x1000

#if defined(DEBUG)

diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 94da6c9..0970c1a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -522,185 +522,6 @@ static void brcmf_set_mpc(struct net_device *ndev, int mpc)
}
}

-static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le,
- struct brcmf_ssid *ssid)
-{
- memset(params_le->bssid, 0xFF, ETH_ALEN);
- params_le->bss_type = DOT11_BSSTYPE_ANY;
- params_le->scan_type = 0;
- params_le->channel_num = 0;
- params_le->nprobes = cpu_to_le32(-1);
- params_le->active_time = cpu_to_le32(-1);
- params_le->passive_time = cpu_to_le32(-1);
- params_le->home_time = cpu_to_le32(-1);
- if (ssid && ssid->SSID_len) {
- params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len);
- memcpy(&params_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len);
- }
-}
-
-static s32
-brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
- struct brcmf_ssid *ssid, u16 action)
-{
- s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
- offsetof(struct brcmf_iscan_params_le, params_le);
- struct brcmf_iscan_params_le *params;
- s32 err = 0;
-
- if (ssid && ssid->SSID_len)
- params_size += sizeof(struct brcmf_ssid);
- params = kzalloc(params_size, GFP_KERNEL);
- if (!params)
- return -ENOMEM;
- BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
-
- brcmf_iscan_prep(&params->params_le, ssid);
-
- params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
- params->action = cpu_to_le16(action);
- params->scan_duration = cpu_to_le16(0);
-
- err = brcmf_fil_iovar_data_set(netdev_priv(iscan->ndev), "iscan",
- params, params_size);
- if (err) {
- if (err == -EBUSY)
- WL_INFO("system busy : iscan canceled\n");
- else
- WL_ERR("error (%d)\n", err);
- }
-
- kfree(params);
- return err;
-}
-
-static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
- struct net_device *ndev = cfg_to_ndev(cfg);
- struct brcmf_ssid ssid;
- u32 passive_scan;
- s32 err = 0;
-
- /* Broadcast scan by default */
- memset(&ssid, 0, sizeof(ssid));
-
- iscan->state = WL_ISCAN_STATE_SCANING;
-
- passive_scan = cfg->active_scan ? 0 : 1;
- err = brcmf_fil_cmd_int_set(netdev_priv(ndev),
- BRCMF_C_SET_PASSIVE_SCAN, passive_scan);
- if (err) {
- WL_ERR("error (%d)\n", err);
- return err;
- }
- brcmf_set_mpc(ndev, 0);
- cfg->iscan_kickstart = true;
- err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
- if (err) {
- brcmf_set_mpc(ndev, 1);
- cfg->iscan_kickstart = false;
- return err;
- }
- mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
- iscan->timer_on = 1;
- return err;
-}
-
-static s32
-brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
- struct cfg80211_scan_request *request,
- struct cfg80211_ssid *this_ssid)
-{
- struct brcmf_if *ifp = netdev_priv(ndev);
- struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
- struct cfg80211_ssid *ssids;
- struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
- u32 passive_scan;
- bool iscan_req;
- bool spec_scan;
- s32 err = 0;
- u32 SSID_len;
-
- if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
- WL_ERR("Scanning already: status (%lu)\n", cfg->scan_status);
- return -EAGAIN;
- }
- if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
- WL_ERR("Scanning being aborted: status (%lu)\n",
- cfg->scan_status);
- return -EAGAIN;
- }
- if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
- WL_ERR("Connecting: status (%lu)\n", ifp->vif->sme_state);
- return -EAGAIN;
- }
-
- iscan_req = false;
- spec_scan = false;
- if (request) {
- /* scan bss */
- ssids = request->ssids;
- if (cfg->iscan_on && (!ssids || !ssids->ssid_len))
- iscan_req = true;
- } else {
- /* scan in ibss */
- /* we don't do iscan in ibss */
- ssids = this_ssid;
- }
-
- cfg->scan_request = request;
- set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
- if (iscan_req) {
- err = brcmf_do_iscan(cfg);
- if (!err)
- return err;
- else
- goto scan_out;
- } else {
- WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
- ssids->ssid, ssids->ssid_len);
- memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
- SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
- sr->ssid_le.SSID_len = cpu_to_le32(0);
- if (SSID_len) {
- memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
- sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
- spec_scan = true;
- } else {
- WL_SCAN("Broadcast scan\n");
- }
-
- passive_scan = cfg->active_scan ? 0 : 1;
- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
- passive_scan);
- if (err) {
- WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
- goto scan_out;
- }
- brcmf_set_mpc(ndev, 0);
- err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
- &sr->ssid_le, sizeof(sr->ssid_le));
- if (err) {
- if (err == -EBUSY)
- WL_INFO("system busy : scan for \"%s\" "
- "canceled\n", sr->ssid_le.SSID);
- else
- WL_ERR("WLC_SCAN error (%d)\n", err);
-
- brcmf_set_mpc(ndev, 1);
- goto scan_out;
- }
- }
-
- return 0;
-
-scan_out:
- clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
- cfg->scan_request = NULL;
- return err;
-}
-
static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
struct cfg80211_scan_request *request)
{
@@ -924,7 +745,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
struct brcmf_if *ifp = netdev_priv(ndev);
struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
struct cfg80211_ssid *ssids;
- struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
+ struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
u32 passive_scan;
bool escan_req;
bool spec_scan;
@@ -1018,7 +839,6 @@ static s32
brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
{
struct net_device *ndev = request->wdev->netdev;
- struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
s32 err = 0;

WL_TRACE("Enter\n");
@@ -1027,10 +847,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
struct brcmf_cfg80211_vif, wdev)))
return -EIO;

- if (cfg->iscan_on)
- err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL);
- else if (cfg->escan_on)
- err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
+ err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);

if (err)
WL_ERR("scan error (%d)\n", err);
@@ -2352,7 +2169,7 @@ static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
return -EOPNOTSUPP;
}
WL_SCAN("scanned AP count (%d)\n", bss_list->count);
- for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
+ for (i = 0; i < bss_list->count; i++) {
bi = next_bss_le(bss_list, bi);
err = brcmf_inform_single_bss(cfg, bi);
if (err)
@@ -2574,33 +2391,10 @@ update_bss_info_out:

static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
struct escan_info *escan = &cfg->escan_info;
- struct brcmf_ssid ssid;

set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
- if (cfg->iscan_on) {
- iscan->state = WL_ISCAN_STATE_IDLE;
-
- if (iscan->timer_on) {
- del_timer_sync(&iscan->timer);
- iscan->timer_on = 0;
- }
-
- cancel_work_sync(&iscan->work);
-
- /* Abort iscan running in FW */
- memset(&ssid, 0, sizeof(ssid));
- brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
-
- if (cfg->scan_request) {
- /* Indidate scan abort to cfg80211 layer */
- WL_INFO("Terminating scan in progress\n");
- cfg80211_scan_done(cfg->scan_request, true);
- cfg->scan_request = NULL;
- }
- }
- if (cfg->escan_on && cfg->scan_request) {
+ if (cfg->scan_request) {
escan->escan_state = WL_ESCAN_STATE_IDLE;
brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
}
@@ -2608,198 +2402,6 @@ static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
}

-static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
- bool aborted)
-{
- struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
- struct net_device *ndev = cfg_to_ndev(cfg);
-
- if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
- WL_ERR("Scan complete while device not scanning\n");
- return;
- }
- if (cfg->scan_request) {
- WL_SCAN("ISCAN Completed scan: %s\n",
- aborted ? "Aborted" : "Done");
- cfg80211_scan_done(cfg->scan_request, aborted);
- brcmf_set_mpc(ndev, 1);
- cfg->scan_request = NULL;
- }
- cfg->iscan_kickstart = false;
-}
-
-static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
-{
- if (iscan->state != WL_ISCAN_STATE_IDLE) {
- WL_SCAN("wake up iscan\n");
- schedule_work(&iscan->work);
- return 0;
- }
-
- return -EIO;
-}
-
-static s32
-brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
- struct brcmf_scan_results **bss_list)
-{
- struct brcmf_scan_results *results;
- struct brcmf_scan_results_le *results_le;
- struct brcmf_iscan_results *list_buf;
- s32 err = 0;
-
- memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
- list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
- results = &list_buf->results;
- results_le = &list_buf->results_le;
- results_le->buflen = cpu_to_le32(sizeof(iscan->scan_buf));
- results_le->version = 0;
- results_le->count = 0;
-
- err = brcmf_fil_iovar_data_get(netdev_priv(iscan->ndev), "iscanresults",
- iscan->scan_buf,
- sizeof(iscan->scan_buf));
- if (err) {
- WL_ERR("error (%d)\n", err);
- return err;
- }
- results->buflen = le32_to_cpu(results_le->buflen);
- results->version = le32_to_cpu(results_le->version);
- results->count = le32_to_cpu(results_le->count);
- WL_SCAN("results->count = %d\n", results_le->count);
- WL_SCAN("results->buflen = %d\n", results_le->buflen);
- *status = le32_to_cpu(list_buf->status_le);
- WL_SCAN("status = %d\n", *status);
- *bss_list = results;
-
- return err;
-}
-
-static s32 brcmf_iscan_done(struct brcmf_cfg80211_info *cfg)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
- s32 err = 0;
-
- iscan->state = WL_ISCAN_STATE_IDLE;
- brcmf_inform_bss(cfg);
- brcmf_notify_iscan_complete(iscan, false);
-
- return err;
-}
-
-static s32 brcmf_iscan_pending(struct brcmf_cfg80211_info *cfg)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
- s32 err = 0;
-
- /* Reschedule the timer */
- mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
- iscan->timer_on = 1;
-
- return err;
-}
-
-static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_info *cfg)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
- s32 err = 0;
-
- brcmf_inform_bss(cfg);
- brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
- /* Reschedule the timer */
- mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
- iscan->timer_on = 1;
-
- return err;
-}
-
-static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_info *cfg)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
- s32 err = 0;
-
- iscan->state = WL_ISCAN_STATE_IDLE;
- brcmf_notify_iscan_complete(iscan, true);
-
- return err;
-}
-
-static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan =
- container_of(work, struct brcmf_cfg80211_iscan_ctrl,
- work);
- struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
- struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
- u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
-
- if (iscan->timer_on) {
- del_timer_sync(&iscan->timer);
- iscan->timer_on = 0;
- }
-
- if (brcmf_get_iscan_results(iscan, &status, &cfg->bss_list)) {
- status = BRCMF_SCAN_RESULTS_ABORTED;
- WL_ERR("Abort iscan\n");
- }
-
- el->handler[status](cfg);
-}
-
-static void brcmf_iscan_timer(unsigned long data)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan =
- (struct brcmf_cfg80211_iscan_ctrl *)data;
-
- if (iscan) {
- iscan->timer_on = 0;
- WL_SCAN("timer expired\n");
- brcmf_wakeup_iscan(iscan);
- }
-}
-
-static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_info *cfg)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
-
- if (cfg->iscan_on) {
- iscan->state = WL_ISCAN_STATE_IDLE;
- INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
- }
-
- return 0;
-}
-
-static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
-{
- memset(el, 0, sizeof(*el));
- el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
- el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
- el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
- el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
- el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
-}
-
-static s32 brcmf_init_iscan(struct brcmf_cfg80211_info *cfg)
-{
- struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
- int err = 0;
-
- if (cfg->iscan_on) {
- iscan->ndev = cfg_to_ndev(cfg);
- brcmf_init_iscan_eloop(&iscan->el);
- iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
- init_timer(&iscan->timer);
- iscan->timer.data = (unsigned long) iscan;
- iscan->timer.function = brcmf_iscan_timer;
- err = brcmf_invoke_iscan(cfg);
- if (!err)
- iscan->data = cfg;
- }
-
- return err;
-}
-
static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
{
struct brcmf_cfg80211_info *cfg =
@@ -2817,8 +2419,7 @@ static void brcmf_escan_timeout(unsigned long data)

if (cfg->scan_request) {
WL_ERR("timer expired\n");
- if (cfg->escan_on)
- schedule_work(&cfg->escan_timeout_work);
+ schedule_work(&cfg->escan_timeout_work);
}
}

@@ -2871,11 +2472,9 @@ brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg,

status = be32_to_cpu(e->status);

- if (!ndev || !cfg->escan_on ||
- !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
- WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n",
- ndev, cfg->escan_on,
- !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
+ if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
+ WL_ERR("scan not ready ndev %p drv_status %x\n", ndev,
+ !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
return -EPERM;
}

@@ -2953,17 +2552,15 @@ exit:
static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
{

- if (cfg->escan_on) {
- cfg->el.handler[BRCMF_E_ESCAN_RESULT] =
- brcmf_cfg80211_escan_handler;
- cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
- /* Init scan_timeout timer */
- init_timer(&cfg->escan_timeout);
- cfg->escan_timeout.data = (unsigned long) cfg;
- cfg->escan_timeout.function = brcmf_escan_timeout;
- INIT_WORK(&cfg->escan_timeout_work,
- brcmf_cfg80211_escan_timeout_worker);
- }
+ cfg->el.handler[BRCMF_E_ESCAN_RESULT] =
+ brcmf_cfg80211_escan_handler;
+ cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
+ /* Init scan_timeout timer */
+ init_timer(&cfg->escan_timeout);
+ cfg->escan_timeout.data = (unsigned long) cfg;
+ cfg->escan_timeout.function = brcmf_escan_timeout;
+ INIT_WORK(&cfg->escan_timeout_work,
+ brcmf_cfg80211_escan_timeout_worker);
}

static __always_inline void brcmf_delay(u32 ms)
@@ -2978,20 +2575,8 @@ static __always_inline void brcmf_delay(u32 ms)

static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
{
- struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
- struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
-
- /*
- * Check for BRCMF_VIF_STATUS_READY before any function call which
- * could result is bus access. Don't block the resume for
- * any driver error conditions
- */
WL_TRACE("Enter\n");

- if (check_vif_up(ifp->vif))
- brcmf_invoke_iscan(cfg);
-
- WL_TRACE("Exit\n");
return 0;
}

@@ -3301,7 +2886,6 @@ out_err:
return err;
}

-#ifndef CONFIG_BRCMISCAN
static int brcmf_dev_pno_clean(struct net_device *ndev)
{
int ret;
@@ -3438,7 +3022,6 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
brcmf_notify_escan_complete(cfg, ndev, true, true);
return 0;
}
-#endif /* CONFIG_BRCMISCAN */

#ifdef CONFIG_NL80211_TESTMODE
static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
@@ -4146,11 +3729,8 @@ static struct cfg80211_ops wl_cfg80211_ops = {
.start_ap = brcmf_cfg80211_start_ap,
.stop_ap = brcmf_cfg80211_stop_ap,
.del_station = brcmf_cfg80211_del_station,
-#ifndef CONFIG_BRCMISCAN
- /* scheduled scan need e-scan, which is mutual exclusive with i-scan */
.sched_scan_start = brcmf_cfg80211_sched_scan_start,
.sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
-#endif
#ifdef CONFIG_NL80211_TESTMODE
.testmode_cmd = brcmf_cfg80211_testmode
#endif
@@ -4174,13 +3754,11 @@ static s32 brcmf_mode_to_nl80211_iftype(s32 mode)

static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
{
-#ifndef CONFIG_BRCMFISCAN
/* scheduled scan settings */
wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
-#endif
}

static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
@@ -4625,78 +4203,6 @@ brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg,
return 0;
}

-static s32
-brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg,
- struct net_device *ndev,
- const struct brcmf_event_msg *e, void *data)
-{
- struct brcmf_if *ifp = netdev_priv(ndev);
- struct brcmf_channel_info_le channel_inform_le;
- struct brcmf_scan_results_le *bss_list_le;
- u32 len = WL_SCAN_BUF_MAX;
- s32 err = 0;
- bool scan_abort = false;
- u32 scan_channel;
-
- WL_TRACE("Enter\n");
-
- if (cfg->iscan_on && cfg->iscan_kickstart) {
- WL_TRACE("Exit\n");
- return brcmf_wakeup_iscan(cfg_to_iscan(cfg));
- }
-
- if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
- WL_ERR("Scan complete while device not scanning\n");
- scan_abort = true;
- err = -EINVAL;
- goto scan_done_out;
- }
-
- err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CHANNEL,
- &channel_inform_le,
- sizeof(channel_inform_le));
- if (err) {
- WL_ERR("scan busy (%d)\n", err);
- scan_abort = true;
- goto scan_done_out;
- }
- scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
- if (scan_channel)
- WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
- cfg->bss_list = cfg->scan_results;
- bss_list_le = (struct brcmf_scan_results_le *) cfg->bss_list;
-
- memset(cfg->scan_results, 0, len);
- bss_list_le->buflen = cpu_to_le32(len);
- err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_SCAN_RESULTS,
- cfg->scan_results, len);
- if (err) {
- WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
- err = -EINVAL;
- scan_abort = true;
- goto scan_done_out;
- }
- cfg->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
- cfg->scan_results->version = le32_to_cpu(bss_list_le->version);
- cfg->scan_results->count = le32_to_cpu(bss_list_le->count);
-
- err = brcmf_inform_bss(cfg);
- if (err)
- scan_abort = true;
-
-scan_done_out:
- if (cfg->scan_request) {
- WL_SCAN("calling cfg80211_scan_done\n");
- cfg80211_scan_done(cfg->scan_request, scan_abort);
- brcmf_set_mpc(ndev, 1);
- cfg->scan_request = NULL;
- }
-
- WL_TRACE("Exit\n");
-
- return err;
-}
-
static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
{
conf->mode = (u32)-1;
@@ -4710,7 +4216,6 @@ static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
{
memset(el, 0, sizeof(*el));
- el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
el->handler[BRCMF_E_DEAUTH_IND] = brcmf_notify_connect_status;
el->handler[BRCMF_E_DEAUTH] = brcmf_notify_connect_status;
@@ -4725,53 +4230,27 @@ static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)

static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
{
- kfree(cfg->scan_results);
- cfg->scan_results = NULL;
- kfree(cfg->bss_info);
- cfg->bss_info = NULL;
kfree(cfg->conf);
cfg->conf = NULL;
- kfree(cfg->scan_req_int);
- cfg->scan_req_int = NULL;
kfree(cfg->escan_ioctl_buf);
cfg->escan_ioctl_buf = NULL;
- kfree(cfg->dcmd_buf);
- cfg->dcmd_buf = NULL;
kfree(cfg->extra_buf);
cfg->extra_buf = NULL;
- kfree(cfg->iscan);
- cfg->iscan = NULL;
kfree(cfg->pmk_list);
cfg->pmk_list = NULL;
}

static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
{
- cfg->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
- if (!cfg->scan_results)
- goto init_priv_mem_out;
cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
if (!cfg->conf)
goto init_priv_mem_out;
- cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
- if (!cfg->bss_info)
- goto init_priv_mem_out;
- cfg->scan_req_int = kzalloc(sizeof(*cfg->scan_req_int),
- GFP_KERNEL);
- if (!cfg->scan_req_int)
- goto init_priv_mem_out;
cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
if (!cfg->escan_ioctl_buf)
goto init_priv_mem_out;
- cfg->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
- if (!cfg->dcmd_buf)
- goto init_priv_mem_out;
cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
if (!cfg->extra_buf)
goto init_priv_mem_out;
- cfg->iscan = kzalloc(sizeof(*cfg->iscan), GFP_KERNEL);
- if (!cfg->iscan)
- goto init_priv_mem_out;
cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
if (!cfg->pmk_list)
goto init_priv_mem_out;
@@ -4899,21 +4378,8 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)

cfg->scan_request = NULL;
cfg->pwr_save = true;
-#ifdef CONFIG_BRCMISCAN
- cfg->iscan_on = true; /* iscan on & off switch.
- we enable iscan per default */
- cfg->escan_on = false; /* escan on & off switch.
- we disable escan per default */
-#else
- cfg->iscan_on = false; /* iscan on & off switch.
- we disable iscan per default */
- cfg->escan_on = true; /* escan on & off switch.
- we enable escan per default */
-#endif
cfg->roam_on = true; /* roam on & off switch.
we enable roam per default */
-
- cfg->iscan_kickstart = false;
cfg->active_scan = true; /* we do active scan for
specific scan per default */
cfg->dongle_up = false; /* dongle is not up yet */
@@ -4924,9 +4390,6 @@ static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
INIT_WORK(&cfg->event_work, brcmf_cfg80211_event_handler);
brcmf_init_eloop_handler(&cfg->el);
mutex_init(&cfg->usr_sync);
- err = brcmf_init_iscan(cfg);
- if (err)
- return err;
brcmf_init_escan(cfg);
brcmf_init_conf(cfg->conf);
brcmf_link_down(cfg);
@@ -5044,7 +4507,6 @@ static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
setbit(eventmask, BRCMF_E_PMKID_CACHE);
setbit(eventmask, BRCMF_E_TXFAIL);
setbit(eventmask, BRCMF_E_JOIN_START);
- setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
setbit(eventmask, BRCMF_E_ESCAN_RESULT);
setbit(eventmask, BRCMF_E_PFN_NET_FOUND);

@@ -5236,17 +4698,10 @@ default_conf_out:
static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
{
struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
- s32 err = 0;

set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);

- err = brcmf_config_dongle(cfg);
- if (err)
- return err;
-
- brcmf_invoke_iscan(cfg);
-
- return err;
+ return brcmf_config_dongle(cfg);
}

static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
index d7d473c..3c59931 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h
@@ -84,31 +84,12 @@ do { \
#define WL_CONN(fmt, args...)
#endif /* (defined DEBUG) */

-#define WL_NUM_SCAN_MAX 1
-#define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used
- * for 2.6.33 kernel
- * or later
- */
-#define WL_SCAN_BUF_MAX (1024 * 8)
+#define WL_NUM_SCAN_MAX 10
+#define WL_NUM_PMKIDS_MAX MAXPMKID
#define WL_TLV_INFO_MAX 1024
#define WL_BSS_INFO_MAX 2048
-#define WL_ASSOC_INFO_MAX 512 /*
- * needs to grab assoc info from dongle to
- * report it to cfg80211 through "connect"
- * event
- */
-#define WL_DCMD_LEN_MAX 1024
-#define WL_EXTRA_BUF_MAX 2048
-#define WL_ISCAN_BUF_MAX 2048 /*
- * the buf length can be BRCMF_DCMD_MAXLEN
- * to reduce iteration
- */
-#define WL_ISCAN_TIMER_INTERVAL_MS 3000
-#define WL_SCAN_ERSULTS_LAST (BRCMF_SCAN_RESULTS_NO_MEM+1)
-#define WL_AP_MAX 256 /* virtually unlimitted as long
- * as kernel memory allows
- */
-
+#define WL_ASSOC_INFO_MAX 512 /* assoc related fil max buf */
+#define WL_EXTRA_BUF_MAX 2048
#define WL_ROAM_TRIGGER_LEVEL -75
#define WL_ROAM_DELTA 20
#define WL_BEACON_TIMEOUT 3
@@ -145,12 +126,6 @@ enum wl_mode {
WL_MODE_AP
};

-/* dongle iscan state */
-enum wl_iscan_state {
- WL_ISCAN_STATE_IDLE,
- WL_ISCAN_STATE_SCANING
-};
-
/* dongle configuration */
struct brcmf_cfg80211_conf {
u32 mode; /* adhoc , infrastructure or ap */
@@ -270,26 +245,6 @@ struct brcmf_cfg80211_vif {
struct list_head list;
};

-/* dongle iscan event loop */
-struct brcmf_cfg80211_iscan_eloop {
- s32 (*handler[WL_SCAN_ERSULTS_LAST])
- (struct brcmf_cfg80211_info *cfg);
-};
-
-/* dongle iscan controller */
-struct brcmf_cfg80211_iscan_ctrl {
- struct net_device *ndev;
- struct timer_list timer;
- u32 timer_ms;
- u32 timer_on;
- s32 state;
- struct work_struct work;
- struct brcmf_cfg80211_iscan_eloop el;
- void *data;
- s8 dcmd_buf[BRCMF_DCMD_SMLEN];
- s8 scan_buf[WL_ISCAN_BUF_MAX];
-};
-
/* association inform */
struct brcmf_cfg80211_connect_info {
u8 *req_ie;
@@ -415,19 +370,15 @@ struct brcmf_pno_scanresults_le {
* @evt_q_lock: for event queue synchronization.
* @usr_sync: mainly for dongle up/down synchronization.
* @bss_list: bss_list holding scanned ap information.
- * @scan_results: results of the last scan.
* @scan_req_int: internal scan request object.
* @bss_info: bss information for cfg80211 layer.
* @ie: information element object for internal purpose.
- * @iscan: iscan controller information.
* @conn_info: association info.
* @pmk_list: wpa2 pmk list.
* @event_work: event handler work struct.
* @scan_status: scan activity on the dongle.
* @pub: common driver information.
* @channel: current channel.
- * @iscan_on: iscan on/off switch.
- * @iscan_kickstart: indicate iscan already started.
* @active_scan: current scan mode.
* @sched_escan: e-scan for scheduled scan support running.
* @ibss_starter: indicates this sta is ibss starter.
@@ -439,7 +390,6 @@ struct brcmf_pno_scanresults_le {
* @dcmd_buf: dcmd buffer.
* @extra_buf: mainly to grab assoc information.
* @debugfsdir: debugfs folder for this device.
- * @escan_on: escan on/off switch.
* @escan_info: escan information.
* @escan_timeout: Timer for catch scan timeout.
* @escan_timeout_work: scan timeout worker.
@@ -456,19 +406,15 @@ struct brcmf_cfg80211_info {
spinlock_t evt_q_lock;
struct mutex usr_sync;
struct brcmf_scan_results *bss_list;
- struct brcmf_scan_results *scan_results;
- struct brcmf_cfg80211_scan_req *scan_req_int;
+ struct brcmf_cfg80211_scan_req scan_req_int;
struct wl_cfg80211_bss_info *bss_info;
struct brcmf_cfg80211_ie ie;
- struct brcmf_cfg80211_iscan_ctrl *iscan;
struct brcmf_cfg80211_connect_info conn_info;
struct brcmf_cfg80211_pmk_list *pmk_list;
struct work_struct event_work;
unsigned long scan_status;
struct brcmf_pub *pub;
u32 channel;
- bool iscan_on;
- bool iscan_kickstart;
bool active_scan;
bool sched_escan;
bool ibss_starter;
@@ -480,7 +426,6 @@ struct brcmf_cfg80211_info {
u8 *dcmd_buf;
u8 *extra_buf;
struct dentry *debugfsdir;
- bool escan_on;
struct escan_info escan_info;
struct timer_list escan_timeout;
struct work_struct escan_timeout_work;
@@ -523,9 +468,6 @@ static inline struct brcmf_cfg80211_profile *ndev_to_prof(struct net_device *nd)
return &ifp->vif->profile;
}

-#define iscan_to_cfg(i) ((struct brcmf_cfg80211_info *)(i->data))
-#define cfg_to_iscan(w) (w->iscan)
-
static inline struct
brcmf_cfg80211_connect_info *cfg_to_conn(struct brcmf_cfg80211_info *cfg)
{
--
1.7.9.5