* [PATCH 1/9] brcmfmac: simplify transmit path
From: Arend van Spriel @ 2013-06-26 12:20 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1372249222-4858-1-git-send-email-arend@broadcom.com>
When getting a transmit packet from the networking layer simply
enqueue the packet unconditional and have it handled by the dequeue
worker. The transfer of the packet to the bus-specific driver part
is now done from one context.
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 54 ++------------------
1 file changed, 5 insertions(+), 49 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 13e75c4..41f902d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1707,37 +1707,6 @@ static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws)
return -ENAVAIL;
}
-static int brcmf_fws_consume_credit(struct brcmf_fws_info *fws, int fifo,
- struct sk_buff *skb)
-{
- struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
- int *credit = &fws->fifo_credit[fifo];
-
- if (fifo != BRCMF_FWS_FIFO_AC_BE)
- fws->borrow_defer_timestamp = jiffies +
- BRCMF_FWS_BORROW_DEFER_PERIOD;
-
- if (!(*credit)) {
- /* Try to borrow a credit from other queue */
- if (fifo != BRCMF_FWS_FIFO_AC_BE ||
- (brcmf_fws_borrow_credit(fws) != 0)) {
- brcmf_dbg(DATA, "ac=%d, credits depleted\n", fifo);
- return -ENAVAIL;
- }
- } else {
- (*credit)--;
- if (!(*credit))
- fws->fifo_credit_map &= ~(1 << fifo);
- }
-
- brcmf_fws_macdesc_use_req_credit(entry, skb);
-
- brcmf_dbg(DATA, "ac=%d, credits=%02d:%02d:%02d:%02d\n", fifo,
- fws->fifo_credit[0], fws->fifo_credit[1],
- fws->fifo_credit[2], fws->fifo_credit[3]);
- return 0;
-}
-
static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
struct sk_buff *skb)
{
@@ -1819,25 +1788,12 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
eh->h_dest, multicast, fifo);
brcmf_fws_lock(drvr, flags);
- /* multicast credit support is conditional, setting
- * flag to false to assure credit is consumed below.
- */
- if (fws->bcmc_credit_check)
- multicast = false;
-
- if (skcb->mac->suppressed ||
- fws->bus_flow_blocked ||
- brcmf_fws_macdesc_closed(fws, skcb->mac, fifo) ||
- brcmu_pktq_mlen(&skcb->mac->psq, 3 << (fifo * 2)) ||
- (!multicast &&
- brcmf_fws_consume_credit(fws, fifo, skb) < 0)) {
- /* enqueue the packet in delayQ */
- drvr->fws->fifo_delay_map |= 1 << fifo;
- brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb);
- } else {
- brcmf_fws_commit_skb(fws, fifo, skb);
- }
+ brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb);
+ if (fifo != BRCMF_FWS_FIFO_AC_BE && fifo < BRCMF_FWS_FIFO_BCMC)
+ fws->borrow_defer_timestamp = jiffies +
+ BRCMF_FWS_BORROW_DEFER_PERIOD;
brcmf_fws_unlock(drvr, flags);
+ brcmf_fws_schedule_deq(fws);
return 0;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH 4/9] brcmfmac: use unified dongle address preparation function
From: Arend van Spriel @ 2013-06-26 12:20 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Franky Lin, Arend van Spriel
In-Reply-To: <1372249222-4858-1-git-send-email-arend@broadcom.com>
From: Franky Lin <frankyl@broadcom.com>
Introduce a unified dongle backplane address preparation function
brcmf_sdio_addrprep to replace duplicate address prep code.
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 79 +++++++-------------
.../net/wireless/brcm80211/brcmfmac/sdio_host.h | 3 -
2 files changed, 27 insertions(+), 55 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index c9c5ad2..70cd0e9 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -162,7 +162,7 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
return 0;
}
-int
+static int
brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
{
int err = 0, i;
@@ -193,12 +193,33 @@ brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
return err;
}
+static int
+brcmf_sdio_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr)
+{
+ uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
+ int err = 0;
+
+ if (bar0 != sdiodev->sbwad) {
+ err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
+ if (err)
+ return err;
+
+ sdiodev->sbwad = bar0;
+ }
+
+ *addr &= SBSDIO_SB_OFT_ADDR_MASK;
+
+ if (width == 4)
+ *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+
+ return 0;
+}
+
int
brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
void *data, bool write)
{
u8 func_num, reg_size;
- u32 bar;
s32 retry = 0;
int ret;
@@ -218,18 +239,7 @@ brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
func_num = SDIO_FUNC_1;
reg_size = 4;
- /* Set the window for SB core register */
- bar = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
- if (bar != sdiodev->sbwad) {
- ret = brcmf_sdcard_set_sbaddr_window(sdiodev, bar);
- if (ret != 0) {
- memset(data, 0xFF, reg_size);
- return ret;
- }
- sdiodev->sbwad = bar;
- }
- addr &= SBSDIO_SB_OFT_ADDR_MASK;
- addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+ brcmf_sdio_addrprep(sdiodev, reg_size, &addr);
}
do {
@@ -452,28 +462,6 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
return ret;
}
-static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn,
- uint width, u32 *addr)
-{
- uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
- int err = 0;
-
- if (bar0 != sdiodev->sbwad) {
- err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
- if (err)
- return err;
-
- sdiodev->sbwad = bar0;
- }
-
- *addr &= SBSDIO_SB_OFT_ADDR_MASK;
-
- if (width == 4)
- *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
-
- return 0;
-}
-
int
brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
uint flags, u8 *buf, uint nbytes)
@@ -508,7 +496,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
fn, addr, pkt->len);
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
- err = brcmf_sdcard_recv_prepare(sdiodev, fn, width, &addr);
+ err = brcmf_sdio_addrprep(sdiodev, width, &addr);
if (err)
goto done;
@@ -532,7 +520,7 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
fn, addr, pktq->qlen);
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
- err = brcmf_sdcard_recv_prepare(sdiodev, fn, width, &addr);
+ err = brcmf_sdio_addrprep(sdiodev, width, &addr);
if (err)
goto done;
@@ -570,33 +558,20 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
uint flags, struct sk_buff *pkt)
{
uint width;
- uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
int err = 0;
struct sk_buff_head pkt_list;
brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
fn, addr, pkt->len);
- if (bar0 != sdiodev->sbwad) {
- err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
- if (err)
- goto done;
-
- sdiodev->sbwad = bar0;
- }
-
- addr &= SBSDIO_SB_OFT_ADDR_MASK;
-
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
- if (width == 4)
- addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
+ brcmf_sdio_addrprep(sdiodev, width, &addr);
skb_queue_head_init(&pkt_list);
skb_queue_tail(&pkt_list, pkt);
err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, &pkt_list);
skb_dequeue_tail(&pkt_list);
-done:
return err;
}
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 69c03fe..09786a5 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -249,9 +249,6 @@ extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev);
-extern int brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
- u32 address);
-
/* attach, return handler on success, NULL if failed.
* The handler shall be provided by all subsequent calls. No local cache
* cfghdl points to the starting address of pci device mapped memory
--
1.7.10.4
^ permalink raw reply related
* [PATCH 3/9] brcmfmac: remove SDIO_REQ_ASYNC flag
From: Arend van Spriel @ 2013-06-26 12:20 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Franky Lin, Arend van Spriel
In-Reply-To: <1372249222-4858-1-git-send-email-arend@broadcom.com>
From: Franky Lin <frankyl@broadcom.com>
Remove SDIO_REQ_ASYNC from brcmfmac since it is not being used.
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 14 +++-----------
drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h | 2 --
2 files changed, 3 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 3f8e69c..c9c5ad2 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -453,15 +453,11 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
}
static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn,
- uint flags, uint width, u32 *addr)
+ uint width, u32 *addr)
{
uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
int err = 0;
- /* Async not implemented yet */
- if (flags & SDIO_REQ_ASYNC)
- return -ENOTSUPP;
-
if (bar0 != sdiodev->sbwad) {
err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
if (err)
@@ -512,7 +508,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
fn, addr, pkt->len);
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
- err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
+ err = brcmf_sdcard_recv_prepare(sdiodev, fn, width, &addr);
if (err)
goto done;
@@ -536,7 +532,7 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
fn, addr, pktq->qlen);
width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
- err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr);
+ err = brcmf_sdcard_recv_prepare(sdiodev, fn, width, &addr);
if (err)
goto done;
@@ -581,10 +577,6 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
fn, addr, pkt->len);
- /* Async not implemented yet */
- if (flags & SDIO_REQ_ASYNC)
- return -ENOTSUPP;
-
if (bar0 != sdiodev->sbwad) {
err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
if (err)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 793df66..69c03fe 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -229,8 +229,6 @@ brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
#define SDIO_REQ_4BYTE 0x1
/* Fixed address (FIFO) (vs. incrementing address) */
#define SDIO_REQ_FIXED 0x2
-/* Async request (vs. sync request) */
-#define SDIO_REQ_ASYNC 0x4
/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
* rw: read or write (0/1)
--
1.7.10.4
^ permalink raw reply related
* [PATCH 0/9] brcmfmac: platform data change and cleanup
From: Arend van Spriel @ 2013-06-26 12:20 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
Testing the recently added scatter-gather support in SDIO on an
OMAP4 Panda showed DMA failures. This is due to alignment requirements
for that particular piece of hardware. Added flag to the platform data
to use a backup mechanism.
Other cleanup was done in firmware-signalling and some comment referring
to v2.4 kernel support triggered cleanup in rx path.
Arend van Spriel (6):
brcmfmac: simplify transmit path
brcmfmac: remove (ab)use of NL80211_NUM_ACS
brcmfmac: tag packet in the netdev transmit callback
brcmfmac: cleanup debug messages in brcmf_fws_hdrpush()
brcmfmac: reduce firmware-signalling locking scope in rx path
brcmfmac: remove code and comment for older kernel support
Franky Lin (3):
brcmfmac: remove SDIO_REQ_ASYNC flag
brcmfmac: use unified dongle address preparation function
brcmfmac: add broken scatter-gather DMA support
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 165 +++++++------
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 29 +--
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 260 ++++++++------------
.../net/wireless/brcm80211/brcmfmac/sdio_host.h | 5 -
include/linux/platform_data/brcmfmac-sdio.h | 5 +
5 files changed, 204 insertions(+), 260 deletions(-)
--
1.7.10.4
^ permalink raw reply
* [PATCH 5/9] brcmfmac: add broken scatter-gather DMA support
From: Arend van Spriel @ 2013-06-26 12:20 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Franky Lin, Arend van Spriel
In-Reply-To: <1372249222-4858-1-git-send-email-arend@broadcom.com>
From: Franky Lin <frankyl@broadcom.com>
DMA engine of some old SDIO host controllers require block size alignment for
data length of each scatterlist item. This patch introduces an intermediate
buffer list to support this kind of platform. It decreases the throughput
because of an extra memcpy in critical data path. So don't turn this on unless
it's necessary.
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 78 +++++++++++++++++++---
include/linux/platform_data/brcmfmac-sdio.h | 5 ++
2 files changed, 72 insertions(+), 11 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 70cd0e9..e3f3c48 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -331,10 +331,11 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
bool write, u32 addr, struct sk_buff_head *pktlist)
{
unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset;
- unsigned int max_blks, max_req_sz;
+ unsigned int max_blks, max_req_sz, orig_offset, dst_offset;
unsigned short max_seg_sz, seg_sz;
- unsigned char *pkt_data;
- struct sk_buff *pkt_next = NULL;
+ unsigned char *pkt_data, *orig_data, *dst_data;
+ struct sk_buff *pkt_next = NULL, *local_pkt_next;
+ struct sk_buff_head local_list, *target_list;
struct mmc_request mmc_req;
struct mmc_command mmc_cmd;
struct mmc_data mmc_dat;
@@ -371,6 +372,32 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
req_sz);
}
+ target_list = pktlist;
+ /* for host with broken sg support, prepare a page aligned list */
+ __skb_queue_head_init(&local_list);
+ if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
+ req_sz = 0;
+ skb_queue_walk(pktlist, pkt_next)
+ req_sz += pkt_next->len;
+ req_sz = ALIGN(req_sz, sdiodev->func[fn]->cur_blksize);
+ while (req_sz > PAGE_SIZE) {
+ pkt_next = brcmu_pkt_buf_get_skb(PAGE_SIZE);
+ if (pkt_next == NULL) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+ __skb_queue_tail(&local_list, pkt_next);
+ req_sz -= PAGE_SIZE;
+ }
+ pkt_next = brcmu_pkt_buf_get_skb(req_sz);
+ if (pkt_next == NULL) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+ __skb_queue_tail(&local_list, pkt_next);
+ target_list = &local_list;
+ }
+
host = sdiodev->func[fn]->card->host;
func_blk_sz = sdiodev->func[fn]->cur_blksize;
/* Blocks per command is limited by host count, host transfer
@@ -380,13 +407,15 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
max_req_sz = min_t(unsigned int, host->max_req_size,
max_blks * func_blk_sz);
max_seg_sz = min_t(unsigned short, host->max_segs, SG_MAX_SINGLE_ALLOC);
- max_seg_sz = min_t(unsigned short, max_seg_sz, pktlist->qlen);
- seg_sz = pktlist->qlen;
+ max_seg_sz = min_t(unsigned short, max_seg_sz, target_list->qlen);
+ seg_sz = target_list->qlen;
pkt_offset = 0;
- pkt_next = pktlist->next;
+ pkt_next = target_list->next;
- if (sg_alloc_table(&st, max_seg_sz, GFP_KERNEL))
- return -ENOMEM;
+ if (sg_alloc_table(&st, max_seg_sz, GFP_KERNEL)) {
+ ret = -ENOMEM;
+ goto exit;
+ }
while (seg_sz) {
req_sz = 0;
@@ -396,7 +425,7 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
memset(&mmc_dat, 0, sizeof(struct mmc_data));
sgl = st.sgl;
/* prep sg table */
- while (pkt_next != (struct sk_buff *)pktlist) {
+ while (pkt_next != (struct sk_buff *)target_list) {
pkt_data = pkt_next->data + pkt_offset;
sg_data_sz = pkt_next->len - pkt_offset;
if (sg_data_sz > host->max_seg_size)
@@ -423,8 +452,8 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
if (req_sz % func_blk_sz != 0) {
brcmf_err("sg request length %u is not %u aligned\n",
req_sz, func_blk_sz);
- sg_free_table(&st);
- return -ENOTBLK;
+ ret = -ENOTBLK;
+ goto exit;
}
mmc_dat.sg = st.sgl;
mmc_dat.sg_len = sg_cnt;
@@ -457,7 +486,34 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
}
}
+ if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
+ local_pkt_next = local_list.next;
+ orig_offset = 0;
+ skb_queue_walk(pktlist, pkt_next) {
+ dst_offset = 0;
+ do {
+ req_sz = local_pkt_next->len - orig_offset;
+ req_sz = min_t(uint, pkt_next->len - dst_offset,
+ req_sz);
+ orig_data = local_pkt_next->data + orig_offset;
+ dst_data = pkt_next->data + dst_offset;
+ memcpy(dst_data, orig_data, req_sz);
+ orig_offset += req_sz;
+ dst_offset += req_sz;
+ if (orig_offset == local_pkt_next->len) {
+ orig_offset = 0;
+ local_pkt_next = local_pkt_next->next;
+ }
+ if (dst_offset == pkt_next->len)
+ break;
+ } while (!skb_queue_empty(&local_list));
+ }
+ }
+
+exit:
sg_free_table(&st);
+ while ((pkt_next = __skb_dequeue(&local_list)) != NULL)
+ brcmu_pkt_buf_free_skb(pkt_next);
return ret;
}
diff --git a/include/linux/platform_data/brcmfmac-sdio.h b/include/linux/platform_data/brcmfmac-sdio.h
index 1ade657..b717499 100644
--- a/include/linux/platform_data/brcmfmac-sdio.h
+++ b/include/linux/platform_data/brcmfmac-sdio.h
@@ -90,6 +90,10 @@ void __init brcmfmac_init_pdata(void)
* oob_irq_nr, oob_irq_flags: the OOB interrupt information. The values are
* used for registering the irq using request_irq function.
*
+ * broken_sg_support: flag for broken sg list support of SDIO host controller.
+ * Set this to true if the SDIO host controller has higher align requirement
+ * than 32 bytes for each scatterlist item.
+ *
* power_on: This function is called by the brcmfmac when the module gets
* loaded. This can be particularly useful for low power devices. The platform
* spcific routine may for example decide to power up the complete device.
@@ -116,6 +120,7 @@ struct brcmfmac_sdio_platform_data {
bool oob_irq_supported;
unsigned int oob_irq_nr;
unsigned long oob_irq_flags;
+ bool broken_sg_support;
void (*power_on)(void);
void (*power_off)(void);
void (*reset)(void);
--
1.7.10.4
^ permalink raw reply related
* [PATCH 9/9] brcmfmac: remove code and comment for older kernel support
From: Arend van Spriel @ 2013-06-26 12:20 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1372249222-4858-1-git-send-email-arend@broadcom.com>
In the code of the receive path some code was dealing with how
things were done in older kernels. Not really needed for an
upstream driver.
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
.../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 29 ++------------------
1 file changed, 2 insertions(+), 27 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 8c402e7..8e89755 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -281,8 +281,6 @@ void brcmf_txflowblock(struct device *dev, bool state)
void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
{
- unsigned char *eth;
- uint len;
struct sk_buff *skb, *pnext;
struct brcmf_if *ifp;
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -306,33 +304,12 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
continue;
}
- /* Get the protocol, maintain skb around eth_type_trans()
- * The main reason for this hack is for the limitation of
- * Linux 2.4 where 'eth_type_trans' uses the
- * 'net->hard_header_len'
- * to perform skb_pull inside vs ETH_HLEN. Since to avoid
- * coping of the packet coming from the network stack to add
- * BDC, Hardware header etc, during network interface
- * registration
- * we set the 'net->hard_header_len' to ETH_HLEN + extra space
- * required
- * for BDC, Hardware header etc. and not just the ETH_HLEN
- */
- eth = skb->data;
- len = skb->len;
-
skb->dev = ifp->ndev;
skb->protocol = eth_type_trans(skb, skb->dev);
if (skb->pkt_type == PACKET_MULTICAST)
ifp->stats.multicast++;
- skb->data = eth;
- skb->len = len;
-
- /* Strip header, count, deliver upward */
- skb_pull(skb, ETH_HLEN);
-
/* Process special event packets */
brcmf_fweh_process_skb(drvr, skb);
@@ -348,10 +325,8 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
netif_rx(skb);
else
/* If the receive is not processed inside an ISR,
- * the softirqd must be woken explicitly to service
- * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled
- * by netif_rx_ni(), but in earlier kernels, we need
- * to do it manually.
+ * the softirqd must be woken explicitly to service the
+ * NET_RX_SOFTIRQ. This is handled by netif_rx_ni().
*/
netif_rx_ni(skb);
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH 7/9] brcmfmac: cleanup debug messages in brcmf_fws_hdrpush()
From: Arend van Spriel @ 2013-06-26 12:20 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1372249222-4858-1-git-send-email-arend@broadcom.com>
Trivial cleanup of debug messages.
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 2b078a1..9c6d182 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -796,9 +796,8 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
u8 fillers;
__le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod);
- brcmf_dbg(TRACE, "enter: ea=%pM, ifidx=%u (%u), pkttag=0x%08X, hslot=%d\n",
- entry->ea, entry->interface_id,
- brcmf_skb_if_flags_get_field(skb, INDEX),
+ brcmf_dbg(TRACE, "enter: %s, idx=%d pkttag=0x%08X, hslot=%d\n",
+ entry->name, brcmf_skb_if_flags_get_field(skb, INDEX),
le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff);
if (entry->send_tim_signal)
data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
@@ -822,8 +821,8 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
wlh[2] = entry->mac_handle;
wlh[3] = entry->traffic_pending_bmp;
- brcmf_dbg(TRACE, "adding TIM info: %02X:%02X:%02X:%02X\n",
- wlh[0], wlh[1], wlh[2], wlh[3]);
+ brcmf_dbg(TRACE, "adding TIM info: handle %d bmp 0x%X\n",
+ entry->mac_handle, entry->traffic_pending_bmp);
wlh += BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2;
entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH 6/9] brcmfmac: tag packet in the netdev transmit callback
From: Arend van Spriel @ 2013-06-26 12:20 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1372249222-4858-1-git-send-email-arend@broadcom.com>
Transmit packets needs to be tagged in order to receive a tx status
feedback from the firmware. Determine the tag in the netdev transmit
callback instead of determining the tag just before transfer to the
device. This reduces the number of exception flows and hence makes
the driver code simpler.
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 130 ++++++++------------
1 file changed, 48 insertions(+), 82 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index e4fd13a..2b078a1 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1575,21 +1575,14 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
return 0;
}
-static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
+static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
struct sk_buff *p)
{
struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
struct brcmf_fws_mac_descriptor *entry = skcb->mac;
- int rc = 0;
- bool first_time;
- int hslot = BRCMF_FWS_HANGER_MAXITEMS;
- u8 free_ctr;
u8 flags;
- first_time = skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED;
-
brcmf_skb_if_flags_set_field(p, TRANSMIT, 1);
- brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST;
if (brcmf_skb_if_flags_get_field(p, REQUESTED)) {
@@ -1600,80 +1593,36 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
flags |= BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED;
}
brcmf_skb_htod_tag_set_field(p, FLAGS, flags);
- if (first_time) {
- /* obtaining free slot may fail, but that will be caught
- * by the hanger push. This assures the packet has a BDC
- * header upon return.
- */
- hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
- free_ctr = entry->seq[fifo];
- brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
- brcmf_skb_htod_tag_set_field(p, FREERUN, free_ctr);
- rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
- if (rc)
- brcmf_err("hanger push failed: rc=%d\n", rc);
- }
-
- if (rc == 0)
- brcmf_fws_hdrpush(fws, p);
-
- return rc;
+ brcmf_fws_hdrpush(fws, p);
}
-static void
-brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
- struct sk_buff *skb, int fifo)
+static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
+ struct sk_buff *skb, int fifo)
{
- /*
- put the packet back to the head of queue
-
- - suppressed packet goes back to suppress sub-queue
- - pull out the header, if new or delayed packet
-
- Note: hslot is used only when header removal is done.
- */
struct brcmf_fws_mac_descriptor *entry;
- enum brcmf_fws_skb_state state;
struct sk_buff *pktout;
+ int qidx, hslot;
int rc = 0;
- int hslot;
- state = brcmf_skbcb(skb)->state;
entry = brcmf_skbcb(skb)->mac;
- hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
-
- if (entry != NULL) {
- if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) {
- /* wl-header is saved for suppressed packets */
- pktout = brcmu_pktq_penq_head(&entry->psq, 2 * fifo + 1,
- skb);
- if (pktout == NULL) {
- brcmf_err("suppress queue full\n");
- rc = -ENOSPC;
- }
- } else {
- /* delay-q packets are going to delay-q */
- pktout = brcmu_pktq_penq_head(&entry->psq,
- 2 * fifo, skb);
- if (pktout == NULL) {
- brcmf_err("delay queue full\n");
- rc = -ENOSPC;
- }
-
- /* free the hanger slot */
- brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &pktout,
- true);
-
- /* decrement sequence count */
- entry->seq[fifo]--;
+ if (entry->occupied) {
+ qidx = 2 *fifo;
+ if (brcmf_skbcb(skb)->state == BRCMF_FWS_SKBSTATE_SUPPRESSED)
+ qidx++;
+
+ pktout = brcmu_pktq_penq_head(&entry->psq, qidx, skb);
+ if (pktout == NULL) {
+ brcmf_err("%s queue %d full\n", entry->name, qidx);
+ rc = -ENOSPC;
}
} else {
- brcmf_err("no mac entry linked\n");
+ brcmf_err("%s entry removed\n", entry->name);
rc = -ENOENT;
}
if (rc) {
fws->stats.rollback_failed++;
+ hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
hslot, 0);
} else {
@@ -1720,15 +1669,10 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
if (IS_ERR(entry))
return PTR_ERR(entry);
- rc = brcmf_fws_precommit_skb(fws, fifo, skb);
- if (rc < 0) {
- fws->stats.generic_error++;
- goto rollback;
- }
-
- brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags,
- skcb->htod);
+ brcmf_fws_precommit_skb(fws, fifo, skb);
rc = brcmf_bus_txdata(bus, skb);
+ brcmf_dbg(DATA, "%s flags %X htod %X bus_tx %d\n", entry->name,
+ skcb->if_flags, skcb->htod, rc);
if (rc < 0) {
brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
goto rollback;
@@ -1737,7 +1681,6 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
entry->transit_count++;
if (entry->suppressed)
entry->suppr_transit_count++;
- entry->seq[fifo]++;
fws->stats.pkt2bus++;
fws->stats.send_pkts[fifo]++;
if (brcmf_skb_if_flags_get_field(skb, REQUESTED))
@@ -1750,6 +1693,24 @@ rollback:
return rc;
}
+static int brcmf_fws_assign_htod(struct brcmf_fws_info *fws, struct sk_buff *p,
+ int fifo)
+{
+ struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
+ int rc, hslot;
+
+ hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
+ brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
+ brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]);
+ brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
+ rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
+ if (!rc)
+ skcb->mac->seq[fifo]++;
+ else
+ fws->stats.generic_error++;
+ return rc;
+}
+
int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
{
struct brcmf_pub *drvr = ifp->drvr;
@@ -1778,22 +1739,27 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
/* set control buffer information */
skcb->if_flags = 0;
- skcb->mac = brcmf_fws_macdesc_find(fws, ifp, eh->h_dest);
skcb->state = BRCMF_FWS_SKBSTATE_NEW;
brcmf_skb_if_flags_set_field(skb, INDEX, ifp->ifidx);
if (!multicast)
fifo = brcmf_fws_prio2fifo[skb->priority];
- brcmf_dbg(DATA, "%s mac %pM multi %d fifo %d\n", skcb->mac->name,
- eh->h_dest, multicast, fifo);
-
brcmf_fws_lock(drvr, flags);
- brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb);
if (fifo != BRCMF_FWS_FIFO_AC_BE && fifo < BRCMF_FWS_FIFO_BCMC)
fws->borrow_defer_timestamp = jiffies +
BRCMF_FWS_BORROW_DEFER_PERIOD;
+
+ skcb->mac = brcmf_fws_macdesc_find(fws, ifp, eh->h_dest);
+ brcmf_dbg(DATA, "%s mac %pM multi %d fifo %d\n", skcb->mac->name,
+ eh->h_dest, multicast, fifo);
+ if (!brcmf_fws_assign_htod(fws, skb, fifo)) {
+ brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb);
+ brcmf_fws_schedule_deq(fws);
+ } else {
+ brcmf_err("drop skb: no hanger slot\n");
+ brcmu_pkt_buf_free_skb(skb);
+ }
brcmf_fws_unlock(drvr, flags);
- brcmf_fws_schedule_deq(fws);
return 0;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH 8/9] brcmfmac: reduce firmware-signalling locking scope in rx path
From: Arend van Spriel @ 2013-06-26 12:20 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1372249222-4858-1-git-send-email-arend@broadcom.com>
In the receive path a spinlock is taken upon parsing the TLV signal
header. This moves to locking to the TLV handling functions where
it protects the data structures.
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 77 +++++++++++++-------
1 file changed, 51 insertions(+), 26 deletions(-)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 9c6d182..386fbfc 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -905,10 +905,26 @@ static int brcmf_fws_rssi_indicate(struct brcmf_fws_info *fws, s8 rssi)
return 0;
}
+/* using macro so sparse checking does not complain
+ * about locking imbalance.
+ */
+#define brcmf_fws_lock(drvr, flags) \
+do { \
+ flags = 0; \
+ spin_lock_irqsave(&((drvr)->fws_spinlock), (flags)); \
+} while (0)
+
+/* using macro so sparse checking does not complain
+ * about locking imbalance.
+ */
+#define brcmf_fws_unlock(drvr, flags) \
+ spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags))
+
static
int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
{
struct brcmf_fws_mac_descriptor *entry, *existing;
+ ulong flags;
u8 mac_handle;
u8 ifidx;
u8 *addr;
@@ -922,8 +938,10 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
if (entry->occupied) {
brcmf_dbg(TRACE, "deleting %s mac %pM\n",
entry->name, addr);
+ brcmf_fws_lock(fws->drvr, flags);
brcmf_fws_macdesc_cleanup(fws, entry, -1);
brcmf_fws_macdesc_deinit(entry);
+ brcmf_fws_unlock(fws->drvr, flags);
} else
fws->stats.mac_update_failed++;
return 0;
@@ -932,11 +950,13 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
existing = brcmf_fws_macdesc_lookup(fws, addr);
if (IS_ERR(existing)) {
if (!entry->occupied) {
+ brcmf_fws_lock(fws->drvr, flags);
entry->mac_handle = mac_handle;
brcmf_fws_macdesc_init(entry, addr, ifidx);
brcmf_fws_macdesc_set_name(fws, entry);
brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT,
BRCMF_FWS_PSQ_LEN);
+ brcmf_fws_unlock(fws->drvr, flags);
brcmf_dbg(TRACE, "add %s mac %pM\n", entry->name, addr);
} else {
fws->stats.mac_update_failed++;
@@ -944,11 +964,13 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
} else {
if (entry != existing) {
brcmf_dbg(TRACE, "copy mac %s\n", existing->name);
+ brcmf_fws_lock(fws->drvr, flags);
memcpy(entry, existing,
offsetof(struct brcmf_fws_mac_descriptor, psq));
entry->mac_handle = mac_handle;
brcmf_fws_macdesc_deinit(existing);
brcmf_fws_macdesc_set_name(fws, entry);
+ brcmf_fws_unlock(fws->drvr, flags);
brcmf_dbg(TRACE, "relocate %s mac %pM\n", entry->name,
addr);
} else {
@@ -964,7 +986,9 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws,
u8 type, u8 *data)
{
struct brcmf_fws_mac_descriptor *entry;
+ ulong flags;
u8 mac_handle;
+ int ret;
mac_handle = data[0];
entry = &fws->desc.nodes[mac_handle & 0x1F];
@@ -972,26 +996,30 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws,
fws->stats.mac_ps_update_failed++;
return -ESRCH;
}
+ brcmf_fws_lock(fws->drvr, flags);
/* a state update should wipe old credits */
entry->requested_credit = 0;
entry->requested_packet = 0;
if (type == BRCMF_FWS_TYPE_MAC_OPEN) {
entry->state = BRCMF_FWS_STATE_OPEN;
- return BRCMF_FWS_RET_OK_SCHEDULE;
+ ret = BRCMF_FWS_RET_OK_SCHEDULE;
} else {
entry->state = BRCMF_FWS_STATE_CLOSE;
brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BK, false);
brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BE, false);
brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VI, false);
brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VO, true);
+ ret = BRCMF_FWS_RET_OK_NOSCHEDULE;
}
- return BRCMF_FWS_RET_OK_NOSCHEDULE;
+ brcmf_fws_unlock(fws->drvr, flags);
+ return ret;
}
static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws,
u8 type, u8 *data)
{
struct brcmf_fws_mac_descriptor *entry;
+ ulong flags;
u8 ifidx;
int ret;
@@ -1010,17 +1038,24 @@ static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws,
brcmf_dbg(TRACE, "%s (%d): %s\n", brcmf_fws_get_tlv_name(type), type,
entry->name);
+ brcmf_fws_lock(fws->drvr, flags);
switch (type) {
case BRCMF_FWS_TYPE_INTERFACE_OPEN:
entry->state = BRCMF_FWS_STATE_OPEN;
- return BRCMF_FWS_RET_OK_SCHEDULE;
+ ret = BRCMF_FWS_RET_OK_SCHEDULE;
+ break;
case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
entry->state = BRCMF_FWS_STATE_CLOSE;
- return BRCMF_FWS_RET_OK_NOSCHEDULE;
+ ret = BRCMF_FWS_RET_OK_NOSCHEDULE;
+ break;
default:
ret = -EINVAL;
- break;
+ brcmf_fws_unlock(fws->drvr, flags);
+ goto fail;
}
+ brcmf_fws_unlock(fws->drvr, flags);
+ return ret;
+
fail:
fws->stats.if_update_failed++;
return ret;
@@ -1030,6 +1065,7 @@ static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type,
u8 *data)
{
struct brcmf_fws_mac_descriptor *entry;
+ ulong flags;
entry = &fws->desc.nodes[data[1] & 0x1F];
if (!entry->occupied) {
@@ -1043,12 +1079,14 @@ static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type,
brcmf_dbg(TRACE, "%s (%d): %s cnt %d bmp %d\n",
brcmf_fws_get_tlv_name(type), type, entry->name,
data[0], data[2]);
+ brcmf_fws_lock(fws->drvr, flags);
if (type == BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT)
entry->requested_credit = data[0];
else
entry->requested_packet = data[0];
entry->ac_bitmap = data[2];
+ brcmf_fws_unlock(fws->drvr, flags);
return BRCMF_FWS_RET_OK_SCHEDULE;
}
@@ -1345,6 +1383,7 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
u8 *data)
{
+ ulong flags;
int i;
if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) {
@@ -1353,16 +1392,19 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
}
brcmf_dbg(DATA, "enter: data %pM\n", data);
+ brcmf_fws_lock(fws->drvr, flags);
for (i = 0; i < BRCMF_FWS_FIFO_COUNT; i++)
brcmf_fws_return_credits(fws, i, data[i]);
brcmf_dbg(DATA, "map: credit %x delay %x\n", fws->fifo_credit_map,
fws->fifo_delay_map);
+ brcmf_fws_unlock(fws->drvr, flags);
return BRCMF_FWS_RET_OK_SCHEDULE;
}
static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
{
+ ulong lflags;
__le32 status_le;
u32 status;
u32 hslot;
@@ -1376,7 +1418,10 @@ static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
hslot = brcmf_txstatus_get_field(status, HSLOT);
genbit = brcmf_txstatus_get_field(status, GENERATION);
- return brcmf_fws_txs_process(fws, flags, hslot, genbit);
+ brcmf_fws_lock(fws->drvr, lflags);
+ brcmf_fws_txs_process(fws, flags, hslot, genbit);
+ brcmf_fws_unlock(fws->drvr, lflags);
+ return BRCMF_FWS_RET_OK_NOSCHEDULE;
}
static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data)
@@ -1389,21 +1434,6 @@ static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data)
return 0;
}
-/* using macro so sparse checking does not complain
- * about locking imbalance.
- */
-#define brcmf_fws_lock(drvr, flags) \
-do { \
- flags = 0; \
- spin_lock_irqsave(&((drvr)->fws_spinlock), (flags)); \
-} while (0)
-
-/* using macro so sparse checking does not complain
- * about locking imbalance.
- */
-#define brcmf_fws_unlock(drvr, flags) \
- spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags))
-
static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp,
const struct brcmf_event_msg *e,
void *data)
@@ -1454,7 +1484,6 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
struct sk_buff *skb)
{
struct brcmf_fws_info *fws = drvr->fws;
- ulong flags;
u8 *signal_data;
s16 data_len;
u8 type;
@@ -1474,9 +1503,6 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
return 0;
}
- /* lock during tlv parsing */
- brcmf_fws_lock(drvr, flags);
-
fws->stats.header_pulls++;
data_len = signal_len;
signal_data = skb->data;
@@ -1570,7 +1596,6 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
if (skb->len == 0)
fws->stats.header_only_pkt++;
- brcmf_fws_unlock(drvr, flags);
return 0;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH 2/9] brcmfmac: remove (ab)use of NL80211_NUM_ACS
From: Arend van Spriel @ 2013-06-26 12:20 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, Arend van Spriel
In-Reply-To: <1372249222-4858-1-git-send-email-arend@broadcom.com>
Used NL80211_NUM_ACS to indicate the BCMC fifo used in the driver
which has the same value now, but it is a bad idea relying on that.
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 41f902d..e4fd13a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1851,7 +1851,7 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
fws = container_of(worker, struct brcmf_fws_info, fws_dequeue_work);
brcmf_fws_lock(fws->drvr, flags);
- for (fifo = NL80211_NUM_ACS; fifo >= 0 && !fws->bus_flow_blocked;
+ for (fifo = BRCMF_FWS_FIFO_BCMC; fifo >= 0 && !fws->bus_flow_blocked;
fifo--) {
while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) &&
(fifo == BRCMF_FWS_FIFO_BCMC))) {
--
1.7.10.4
^ permalink raw reply related
* Re: pull request: bluetooth 2013-06-23
From: Pavel Machek @ 2013-06-26 11:52 UTC (permalink / raw)
To: Gustavo Padovan, Marcel Holtmann, linville, linux-wireless,
linux-bluetooth, linux-kernel, Rafael J. Wysocki
In-Reply-To: <20130625210039.GA28448@joana>
On Tue 2013-06-25 22:00:39, Gustavo Padovan wrote:
> Hi Marcel,
>
> * Marcel Holtmann <marcel@holtmann.org> [2013-06-25 13:49:19 -0700]:
>
> > Hi Pavel,
> >
> > >> Jaganath Kanakkassery (1):
> > >> Bluetooth: Fix invalid length check in l2cap_information_rsp()
> > >
> > > Could we add the "3.10 vs. thinkpad x60" patch that fixes regression?
> > > It is from Johan Hedberg…
> >
> > that one went into net-next tree. It is scheduled for 3.11 right now.
> >
> > After 3.10 is out, maybe it can go into -stable, but otherwise I think it is bit late now. Unless someone wants to cherry-pick it.
>
> That patch is actually in 3.10 already, it was included in the last pull
> request and John took it to wireless.git.
Is it? I tried pulling yesterday (some updates) and today (no
changes), am on:
Linux amd 3.10.0-rc7+ #267 SMP Tue Jun 25 23:32:24 CEST 2013 i686
GNU/Linux
and bluetooth is still broken :-(.
Pavel
--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
^ permalink raw reply
* Stable releases 3.6 - 2.6.26 are not available [hosting is down]
From: Viktor @ 2013-06-26 11:30 UTC (permalink / raw)
To: linux-wireless
Hi there,
All the links on the http://wireless.kernel.org/en/users/Download/stable [1]
page under the 'compat-wireless stable releases' header appear to be broken.
For example, when trying to download the stable build for 3.2 kernel [2] I am
getting:
The requested URL /kernel/compat-wireless-3-stable/v3.2/compat-wireless-3.2.5-
1.tar.bz2 was not found on this server.
Looks like the hosting on www.orbit-lab.org has been down at least for one
week since 20.06.2013. Is there any other hosting where the stable compat-
wireless builds can be downloaded? Who will take an action to restore the
links?
Links:
[1] http://wireless.kernel.org/en/users/Download/stable#compat-
wireless_stable_releases
[2] http://www.orbit-lab.org/kernel/compat-wireless-3-stable/v3.2/compat-
wireless-3.2.5-1.tar.bz2
// Viktor
^ permalink raw reply
* Fwd: Re: TP-Link 8200ND - rtl8192cu module not loading / working
From: shiki.biomernok @ 2013-06-26 11:30 UTC (permalink / raw)
To: linux-wireless, Larry.Finger
In-Reply-To: <51A77433.2060702@lwfinger.net>
Hello everyone!
CC'ing my original message that I sent to Larry.
It's been a while, but I've been busy and I couldn't fiddle with the
wireless device.
Basically it's a 8192cu device. Larry suspected it's not, but I think he
saw the advertisement displayed on top of the TP-Link page.
I even mailed TP-Link, and here is the reply:
The chipset is Realtek RTL8192CU and you can download the driver
from
http://www.realtek.com/downloads/downloadsView.aspx?Langid=1&PNid=21&PFid=48&Level=5&Conn=4&DownTypeID=3&GetDown=false&Downloads=true.
Thank you.
Tested with many kernels, but none of them worked.
Ubuntu 13.04 (both stock + updated), Fedora (Schrodinger-1), Fedora Beta
(Schrodinger), openSUSE (normal+tumbleweed).
I even tried the latest kernels since 3.10-rc4. (latest I tried is -rc7)
Basically this device *should* work with the 8192cu driver, but it just
won't.
If you just plug it in, nothing happens.
You have to first:
$ modprobe 8192cu
$ echo 2357 0100 > /sys/bus/usb/drivers/rtl8192cu/new_id
Then it lights up, it shows up in NM-Applet. But it won't work.
I tried enabling the realtek debug option at the kernel driver, but it
didn't help.
Even with that, I only see the authentication failed messages.
Dmesg shows the errors: http://pastebin.com/QCfXYCZ1
Hope you guys can come up with some tips/ideas.
Ps.: I hope you don't mind the CC Larry.
Best regards,
-------- Original Message --------
Subject: Re: TP-Link 8200ND - rtl8192cu module not loading / working
Date: Thu, 30 May 2013 10:45:55 -0500
From: Larry Finger <Larry.Finger@lwfinger.net>
To: Me <shiki.biomernok@gmail.com>
CC: wlanfae@realtek.com
On 05/29/2013 02:21 PM, I wrote:
> Dear Realtek!
>
> I just bought a TP-Link 8200ND wireless USB device, that uses the Realtek
> rtl8192cu driver. The driver is included in every recent kernel, but I can't use it.
>
> Things I tried:
> - Plug it in: It only shows a blank string at "lsusb".
> - Loading the module by hand: "lsusb" is still empty, but "dmesg" shows the
> module is loaded, and I can mess around under /sys/bus/usb/drivers/8192cu/
> - Adding a new ID from the Debian wiki for known devices.
> This works as far as "dmesg" is concerned. It will say I connected a new device,
> like a Realtek wifi USB device. BUT I still don't have anything in my network
> manager/ifconfig/rfkill. Nothing.
>
> This is what I see in lsusb:
> Bus 002 Device 002: ID 2357:0100
>
>
> I would be more than willing to help you guys out with this.
> Can even set up my laptop with SSH so you could debug/develop/reboot whatever
> you need.
In the future, I will refuse to answer your e-mails regarding wireless devices
*UNLESS* you also Cc a wireless mailing list. The "best" option would be
linux-wireless@vger.kernel.org. If you have any questions about why I insist on
this, please read the following two links as to why emailing a single person
directly is usually not a good thing, and causes extra work on a single person:
http://www.arm.linux.org.uk/news/?newsitem=11
http://www.eyrie.org/~eagle/faqs/questions.html
I cannot add you to the list as that would expose your email address on a public
forum, and I will not create a second breach of etiquette just because you
already did one.
Your device is *NOT* an RTL8192CU device. I wondered when I saw the 300 Mbps,
but I was certain when I saw it was a dual-band device.
I have a driver for your device, but I will not tell you how to get it until you
place a proper request on some mailing list!
Larry
^ permalink raw reply
* RE: [PATCH] wireless: vlan priority handling in WMM
From: voncken @ 2013-06-26 9:36 UTC (permalink / raw)
To: 'Johannes Berg'; +Cc: linux-wireless
In-Reply-To: <1372232028.8157.1.camel@jlt4.sipsolutions.net>
>>On Tue, 2013-06-25 at 17:31 +0200, cedric.voncken@acksys.fr wrote:
>> From: Cedric Voncken <cedric.voncken@acksys.fr>
>>
>> If the VLAN priority is set in skb->vlan_tci use it to determine the WMM priority.
>What's the VLAN priority? How are you even running 802.1q on top of wifi? heh.
I used the wireless as bridge (The wireless vif client is bridged with my eth0). The VLAN tag is already present in frame when I received it from eth0. The eth0 driver set the skb->vlan_tci.
>> @@ -694,6 +695,10 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb)
>> if (skb->priority >= 256 && skb->priority <= 263)
>> return skb->priority - 256;
>>
>> + vlan_priority = (skb->vlan_tci >> 13) & 0x07;
>Are there no symbolic constants for this?
Fix in V2
>> + if (vlan_priority > 0)
>> + return vlan_priority;
>I think you got indentation a bit confused :-)
Sorry, it will fix in V2.
Cedric
^ permalink raw reply
* Re: [PATCH] Documentation: dt: bindings: TI WiLink modules
From: Tony Lindgren @ 2013-06-26 8:22 UTC (permalink / raw)
To: Luciano Coelho
Cc: grant.likely, linux-doc, linux-kernel, linux-wireless,
rob.herring, devicetree-discuss, linux-omap, linux-arm-kernel,
balbi
In-Reply-To: <1372234384.18889.37.camel@cumari.coelho.fi>
* Luciano Coelho <coelho@ti.com> [130626 01:19]:
> Hi Tony,
>
> On Tue, 2013-06-25 at 23:24 -0700, Tony Lindgren wrote:
> > * Luciano Coelho <coelho@ti.com> [130625 12:43]:
> > > On Tue, 2013-06-25 at 11:35 +0300, Luciano Coelho wrote:
> > > > Add device tree bindings documentation for the TI WiLink modules.
> > > > Currently only the WLAN part of the WiLink6, WiLink7 and WiLink8
> > > > modules is supported.
> > > >
> > > > Signed-off-by: Luciano Coelho <coelho@ti.com>
> > > > ---
>
> [...]
>
> > > > +Optional properties:
> > > > +--------------------
> > > > +
> > > > +- refclock: the internal WLAN reference clock frequency (required for
> > > > + WiLink6 and WiLink7; not used for WiLink8). Must be one of the
> > > > + following:
> > > > + 0 = 19.2 MHz
> > > > + 1 = 26.0 MHz
> > > > + 2 = 38.4 MHz
> > > > + 3 = 52.0 MHz
> > > > + 4 = 38.4 MHz, XTAL
> > > > + 5 = 26.0 MHz, XTAL
> >
> > This is just the omap refclock, right? If so, you can just pass the
> > standard clock phandle. I know we don't yet have the DT clocks merged,
> > but Tero just posted another revision of those.
>
> This is an internal clock. This clock is part of the module that
> contains the WiLink chip. It is not associated with the clocks in the
> main board (OMAP).
>
>
> > > > +- tcxoclock: the internal WLAN TCXO clock frequency (required for
> > > > + WiLink7 not used for WiLink6 and WiLink8). Must be one of the
> > > > + following:
> > > > + 0 = 19.200 MHz
> > > > + 1 = 26.000 MHz
> > > > + 2 = 38.400 MHz
> > > > + 3 = 52.000 MHz
> > > > + 4 = 16.368 MHz
> > > > + 5 = 32.736 MHz
> > > > + 6 = 16.800 MHz
> > > > + 7 = 33.600 MHz
> >
> > Where does this clock come from? Maybe this can be set based on the
> > compatible value if it's completely internal?
>
> This is also a completely internal clock. My "compatible" values are
> based on the WiLink chip itself, not in the module that contains the
> chip. There are several modules and they are the ones that specify the
> clock frequencies. This data I'm passing here is just to tell the
> WiLink chip which frequencies the module uses.
>
> My driver is for the WiLink chip itself, not to the module (in theory).
> So I think having the WiLink values as bindings would be more generic
> than having to specify values for each available module (eg.
> "lsr-research,tiwi-ble") and mapping those values to specific
> frequencies in the driver.
>
>
> > > If this is okay for everyone, can I push this via my tree (which goes to
> > > linux-wireless->net->linus)? I think it makes more sense to send the
> > > documentation together with the patch that actually implements the DT
> > > node parsing in the driver.
> >
> > If we can use the standard bindings, it might be worth waiting until
> > we have the DT clocks available as we have the pdata workaround merged
> > anyways. That's because then we don't need to support the custom
> > binding later on ;)
>
> I looked into Tero's patches and I considered using the generic clock
> bindings, but I think it doesn't make sense in this case. The thing is
> that the module is not providing the clocks to the main board. Neither
> is the WiLink chip consuming clocks from the main board.
>
> I thought about specifying clock providers and consumers to be used only
> by the module and WiLink chip, but I think it's overkill. And we would
> also have to find a way to prevent the main clock framework from trying
> to handle them.
>
> So, my conclusion was that, even though these *are* clocks, from the
> main board's perspective they're just specifications of what the module
> looks like.
>
> Does this make sense?
OK yes, in that case looks fine to me:
Acked-by: Tony Lindgren <tony@atomide.com>
^ permalink raw reply
* Re: [PATCH] Documentation: dt: bindings: TI WiLink modules
From: Luciano Coelho @ 2013-06-26 8:13 UTC (permalink / raw)
To: Tony Lindgren
Cc: grant.likely, linux-doc, linux-kernel, linux-wireless,
rob.herring, devicetree-discuss, linux-omap, linux-arm-kernel,
balbi
In-Reply-To: <20130626062409.GK5523@atomide.com>
Hi Tony,
On Tue, 2013-06-25 at 23:24 -0700, Tony Lindgren wrote:
> * Luciano Coelho <coelho@ti.com> [130625 12:43]:
> > On Tue, 2013-06-25 at 11:35 +0300, Luciano Coelho wrote:
> > > Add device tree bindings documentation for the TI WiLink modules.
> > > Currently only the WLAN part of the WiLink6, WiLink7 and WiLink8
> > > modules is supported.
> > >
> > > Signed-off-by: Luciano Coelho <coelho@ti.com>
> > > ---
[...]
> > > +Optional properties:
> > > +--------------------
> > > +
> > > +- refclock: the internal WLAN reference clock frequency (required for
> > > + WiLink6 and WiLink7; not used for WiLink8). Must be one of the
> > > + following:
> > > + 0 = 19.2 MHz
> > > + 1 = 26.0 MHz
> > > + 2 = 38.4 MHz
> > > + 3 = 52.0 MHz
> > > + 4 = 38.4 MHz, XTAL
> > > + 5 = 26.0 MHz, XTAL
>
> This is just the omap refclock, right? If so, you can just pass the
> standard clock phandle. I know we don't yet have the DT clocks merged,
> but Tero just posted another revision of those.
This is an internal clock. This clock is part of the module that
contains the WiLink chip. It is not associated with the clocks in the
main board (OMAP).
> > > +- tcxoclock: the internal WLAN TCXO clock frequency (required for
> > > + WiLink7 not used for WiLink6 and WiLink8). Must be one of the
> > > + following:
> > > + 0 = 19.200 MHz
> > > + 1 = 26.000 MHz
> > > + 2 = 38.400 MHz
> > > + 3 = 52.000 MHz
> > > + 4 = 16.368 MHz
> > > + 5 = 32.736 MHz
> > > + 6 = 16.800 MHz
> > > + 7 = 33.600 MHz
>
> Where does this clock come from? Maybe this can be set based on the
> compatible value if it's completely internal?
This is also a completely internal clock. My "compatible" values are
based on the WiLink chip itself, not in the module that contains the
chip. There are several modules and they are the ones that specify the
clock frequencies. This data I'm passing here is just to tell the
WiLink chip which frequencies the module uses.
My driver is for the WiLink chip itself, not to the module (in theory).
So I think having the WiLink values as bindings would be more generic
than having to specify values for each available module (eg.
"lsr-research,tiwi-ble") and mapping those values to specific
frequencies in the driver.
> > If this is okay for everyone, can I push this via my tree (which goes to
> > linux-wireless->net->linus)? I think it makes more sense to send the
> > documentation together with the patch that actually implements the DT
> > node parsing in the driver.
>
> If we can use the standard bindings, it might be worth waiting until
> we have the DT clocks available as we have the pdata workaround merged
> anyways. That's because then we don't need to support the custom
> binding later on ;)
I looked into Tero's patches and I considered using the generic clock
bindings, but I think it doesn't make sense in this case. The thing is
that the module is not providing the clocks to the main board. Neither
is the WiLink chip consuming clocks from the main board.
I thought about specifying clock providers and consumers to be used only
by the module and WiLink chip, but I think it's overkill. And we would
also have to find a way to prevent the main clock framework from trying
to handle them.
So, my conclusion was that, even though these *are* clocks, from the
main board's perspective they're just specifications of what the module
looks like.
Does this make sense?
--
Cheers,
Luca.
^ permalink raw reply
* [PATCH] bcma: add support for BCM43142
From: Rafał Miłecki @ 2013-06-26 8:02 UTC (permalink / raw)
To: linux-wireless, John W. Linville; +Cc: Rafał Miłecki
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
drivers/bcma/bcma_private.h | 2 +
drivers/bcma/driver_chipcommon.c | 11 ++-
drivers/bcma/driver_chipcommon_pmu.c | 123 +++++++++++++++++++++++++++
drivers/bcma/host_pci.c | 1 +
drivers/bcma/main.c | 19 +++++
drivers/bcma/sprom.c | 1 +
include/linux/bcma/bcma.h | 1 +
include/linux/bcma/bcma_driver_chipcommon.h | 55 ++++++++++++
8 files changed, 211 insertions(+), 2 deletions(-)
diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
index 79595a0..0215f9a 100644
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -22,6 +22,8 @@
struct bcma_bus;
/* main.c */
+bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
+ int timeout);
int bcma_bus_register(struct bcma_bus *bus);
void bcma_bus_unregister(struct bcma_bus *bus);
int __init bcma_bus_early_register(struct bcma_bus *bus,
diff --git a/drivers/bcma/driver_chipcommon.c b/drivers/bcma/driver_chipcommon.c
index 036c674..b068f98 100644
--- a/drivers/bcma/driver_chipcommon.c
+++ b/drivers/bcma/driver_chipcommon.c
@@ -140,8 +140,15 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
bcma_core_chipcommon_early_init(cc);
if (cc->core->id.rev >= 20) {
- bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0);
- bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0);
+ u32 pullup = 0, pulldown = 0;
+
+ if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) {
+ pullup = 0x402e0;
+ pulldown = 0x20500;
+ }
+
+ bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup);
+ bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown);
}
if (cc->capabilities & BCMA_CC_CAP_PMU)
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index edca73a..5081a8c 100644
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -56,6 +56,109 @@ void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
}
EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
+static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc)
+{
+ u32 ilp_ctl, alp_hz;
+
+ if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) &
+ BCMA_CC_PMU_STAT_EXT_LPO_AVAIL))
+ return 0;
+
+ bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ,
+ BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT));
+ usleep_range(1000, 2000);
+
+ ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ);
+ ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK;
+
+ bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0);
+
+ alp_hz = ilp_ctl * 32768 / 4;
+ return (alp_hz + 50000) / 100000 * 100;
+}
+
+static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq)
+{
+ struct bcma_bus *bus = cc->core->bus;
+ u32 freq_tgt_target = 0, freq_tgt_current;
+ u32 pll0, mask;
+
+ switch (bus->chipinfo.id) {
+ case BCMA_CHIP_ID_BCM43142:
+ /* pmu2_xtaltab0_adfll_485 */
+ switch (xtalfreq) {
+ case 12000:
+ freq_tgt_target = 0x50D52;
+ break;
+ case 20000:
+ freq_tgt_target = 0x307FE;
+ break;
+ case 26000:
+ freq_tgt_target = 0x254EA;
+ break;
+ case 37400:
+ freq_tgt_target = 0x19EF8;
+ break;
+ case 52000:
+ freq_tgt_target = 0x12A75;
+ break;
+ }
+ break;
+ }
+
+ if (!freq_tgt_target) {
+ bcma_err(bus, "Unknown TGT frequency for xtalfreq %d\n",
+ xtalfreq);
+ return;
+ }
+
+ pll0 = bcma_chipco_pll_read(cc, BCMA_CC_PMU15_PLL_PLLCTL0);
+ freq_tgt_current = (pll0 & BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK) >>
+ BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
+
+ if (freq_tgt_current == freq_tgt_target) {
+ bcma_debug(bus, "Target TGT frequency already set\n");
+ return;
+ }
+
+ /* Turn off PLL */
+ switch (bus->chipinfo.id) {
+ case BCMA_CHIP_ID_BCM43142:
+ mask = (u32)~(BCMA_RES_4314_HT_AVAIL |
+ BCMA_RES_4314_MACPHY_CLK_AVAIL);
+
+ bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask);
+ bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask);
+ bcma_wait_value(cc->core, BCMA_CLKCTLST,
+ BCMA_CLKCTLST_HAVEHT, 0, 20000);
+ break;
+ }
+
+ pll0 &= ~BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK;
+ pll0 |= freq_tgt_target << BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT;
+ bcma_chipco_pll_write(cc, BCMA_CC_PMU15_PLL_PLLCTL0, pll0);
+
+ /* Flush */
+ if (cc->pmu.rev >= 2)
+ bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD);
+
+ /* TODO: Do we need to update OTP? */
+}
+
+static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
+{
+ struct bcma_bus *bus = cc->core->bus;
+ u32 xtalfreq = bcma_pmu_xtalfreq(cc);
+
+ switch (bus->chipinfo.id) {
+ case BCMA_CHIP_ID_BCM43142:
+ if (xtalfreq == 0)
+ xtalfreq = 20000;
+ bcma_pmu2_pll_init0(cc, xtalfreq);
+ break;
+ }
+}
+
static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
{
struct bcma_bus *bus = cc->core->bus;
@@ -66,6 +169,25 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc)
min_msk = 0x200D;
max_msk = 0xFFFF;
break;
+ case BCMA_CHIP_ID_BCM43142:
+ min_msk = BCMA_RES_4314_LPLDO_PU |
+ BCMA_RES_4314_PMU_SLEEP_DIS |
+ BCMA_RES_4314_PMU_BG_PU |
+ BCMA_RES_4314_CBUCK_LPOM_PU |
+ BCMA_RES_4314_CBUCK_PFM_PU |
+ BCMA_RES_4314_CLDO_PU |
+ BCMA_RES_4314_LPLDO2_LVM |
+ BCMA_RES_4314_WL_PMU_PU |
+ BCMA_RES_4314_LDO3P3_PU |
+ BCMA_RES_4314_OTP_PU |
+ BCMA_RES_4314_WL_PWRSW_PU |
+ BCMA_RES_4314_LQ_AVAIL |
+ BCMA_RES_4314_LOGIC_RET |
+ BCMA_RES_4314_MEM_SLEEP |
+ BCMA_RES_4314_MACPHY_RET |
+ BCMA_RES_4314_WL_CORE_READY;
+ max_msk = 0x3FFFFFFF;
+ break;
default:
bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n",
bus->chipinfo.id);
@@ -165,6 +287,7 @@ void bcma_pmu_init(struct bcma_drv_cc *cc)
bcma_cc_set32(cc, BCMA_CC_PMU_CTL,
BCMA_CC_PMU_CTL_NOILPONW);
+ bcma_pmu_pll_init(cc);
bcma_pmu_resources_init(cc);
bcma_pmu_workarounds(cc);
}
diff --git a/drivers/bcma/host_pci.c b/drivers/bcma/host_pci.c
index fbf2759..a355e63 100644
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -275,6 +275,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = {
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
{ 0, },
};
diff --git a/drivers/bcma/main.c b/drivers/bcma/main.c
index f72f52b..0067422 100644
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -93,6 +93,25 @@ struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
return NULL;
}
+bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
+ int timeout)
+{
+ unsigned long deadline = jiffies + timeout;
+ u32 val;
+
+ do {
+ val = bcma_read32(core, reg);
+ if ((val & mask) == value)
+ return true;
+ cpu_relax();
+ udelay(10);
+ } while (!time_after_eq(jiffies, deadline));
+
+ bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg);
+
+ return false;
+}
+
static void bcma_release_core_dev(struct device *dev)
{
struct bcma_device *core = container_of(dev, struct bcma_device, dev);
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index de15b4f..72bf454 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -503,6 +503,7 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
case BCMA_CHIP_ID_BCM4331:
present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
break;
+ case BCMA_CHIP_ID_BCM43142:
case BCMA_CHIP_ID_BCM43224:
case BCMA_CHIP_ID_BCM43225:
/* for these chips OTP is always available */
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
index 2e34db8..622fc50 100644
--- a/include/linux/bcma/bcma.h
+++ b/include/linux/bcma/bcma.h
@@ -144,6 +144,7 @@ struct bcma_host_ops {
/* Chip IDs of PCIe devices */
#define BCMA_CHIP_ID_BCM4313 0x4313
+#define BCMA_CHIP_ID_BCM43142 43142
#define BCMA_CHIP_ID_BCM43224 43224
#define BCMA_PKG_ID_BCM43224_FAB_CSM 0x8
#define BCMA_PKG_ID_BCM43224_FAB_SMIC 0xa
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index b8b09ea..c49e1a1 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -330,6 +330,8 @@
#define BCMA_CC_PMU_CAP 0x0604 /* PMU capabilities */
#define BCMA_CC_PMU_CAP_REVISION 0x000000FF /* Revision mask */
#define BCMA_CC_PMU_STAT 0x0608 /* PMU status */
+#define BCMA_CC_PMU_STAT_EXT_LPO_AVAIL 0x00000100
+#define BCMA_CC_PMU_STAT_WDRESET 0x00000080
#define BCMA_CC_PMU_STAT_INTPEND 0x00000040 /* Interrupt pending */
#define BCMA_CC_PMU_STAT_SBCLKST 0x00000030 /* Backplane clock status? */
#define BCMA_CC_PMU_STAT_HAVEALP 0x00000008 /* ALP available */
@@ -355,6 +357,11 @@
#define BCMA_CC_REGCTL_DATA 0x065C
#define BCMA_CC_PLLCTL_ADDR 0x0660
#define BCMA_CC_PLLCTL_DATA 0x0664
+#define BCMA_CC_PMU_STRAPOPT 0x0668 /* (corerev >= 28) */
+#define BCMA_CC_PMU_XTAL_FREQ 0x066C /* (pmurev >= 10) */
+#define BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK 0x00001FFF
+#define BCMA_CC_PMU_XTAL_FREQ_MEASURE_MASK 0x80000000
+#define BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT 31
#define BCMA_CC_SPROM 0x0800 /* SPROM beginning */
/* NAND flash MLC controller registers (corerev >= 38) */
#define BCMA_CC_NAND_REVISION 0x0C00
@@ -435,6 +442,23 @@
#define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_MASK 0x00000007
#define BCMA_CC_PMU6_4706_PROC_NDIV_MODE_SHIFT 0
+/* PMU rev 15 */
+#define BCMA_CC_PMU15_PLL_PLLCTL0 0
+#define BCMA_CC_PMU15_PLL_PC0_CLKSEL_MASK 0x00000003
+#define BCMA_CC_PMU15_PLL_PC0_CLKSEL_SHIFT 0
+#define BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK 0x003FFFFC
+#define BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT 2
+#define BCMA_CC_PMU15_PLL_PC0_PRESCALE_MASK 0x00C00000
+#define BCMA_CC_PMU15_PLL_PC0_PRESCALE_SHIFT 22
+#define BCMA_CC_PMU15_PLL_PC0_KPCTRL_MASK 0x07000000
+#define BCMA_CC_PMU15_PLL_PC0_KPCTRL_SHIFT 24
+#define BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_MASK 0x38000000
+#define BCMA_CC_PMU15_PLL_PC0_FCNTCTRL_SHIFT 27
+#define BCMA_CC_PMU15_PLL_PC0_FDCMODE_MASK 0x40000000
+#define BCMA_CC_PMU15_PLL_PC0_FDCMODE_SHIFT 30
+#define BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_MASK 0x80000000
+#define BCMA_CC_PMU15_PLL_PC0_CTRLBIAS_SHIFT 31
+
/* ALP clock on pre-PMU chips */
#define BCMA_CC_PMU_ALP_CLOCK 20000000
/* HT clock for systems with PMU-enabled chipcommon */
@@ -507,6 +531,37 @@
#define BCMA_CHIPCTL_5357_I2S_PINS_ENABLE BIT(18)
#define BCMA_CHIPCTL_5357_I2CSPI_PINS_ENABLE BIT(19)
+#define BCMA_RES_4314_LPLDO_PU BIT(0)
+#define BCMA_RES_4314_PMU_SLEEP_DIS BIT(1)
+#define BCMA_RES_4314_PMU_BG_PU BIT(2)
+#define BCMA_RES_4314_CBUCK_LPOM_PU BIT(3)
+#define BCMA_RES_4314_CBUCK_PFM_PU BIT(4)
+#define BCMA_RES_4314_CLDO_PU BIT(5)
+#define BCMA_RES_4314_LPLDO2_LVM BIT(6)
+#define BCMA_RES_4314_WL_PMU_PU BIT(7)
+#define BCMA_RES_4314_LNLDO_PU BIT(8)
+#define BCMA_RES_4314_LDO3P3_PU BIT(9)
+#define BCMA_RES_4314_OTP_PU BIT(10)
+#define BCMA_RES_4314_XTAL_PU BIT(11)
+#define BCMA_RES_4314_WL_PWRSW_PU BIT(12)
+#define BCMA_RES_4314_LQ_AVAIL BIT(13)
+#define BCMA_RES_4314_LOGIC_RET BIT(14)
+#define BCMA_RES_4314_MEM_SLEEP BIT(15)
+#define BCMA_RES_4314_MACPHY_RET BIT(16)
+#define BCMA_RES_4314_WL_CORE_READY BIT(17)
+#define BCMA_RES_4314_ILP_REQ BIT(18)
+#define BCMA_RES_4314_ALP_AVAIL BIT(19)
+#define BCMA_RES_4314_MISC_PWRSW_PU BIT(20)
+#define BCMA_RES_4314_SYNTH_PWRSW_PU BIT(21)
+#define BCMA_RES_4314_RX_PWRSW_PU BIT(22)
+#define BCMA_RES_4314_RADIO_PU BIT(23)
+#define BCMA_RES_4314_VCO_LDO_PU BIT(24)
+#define BCMA_RES_4314_AFE_LDO_PU BIT(25)
+#define BCMA_RES_4314_RX_LDO_PU BIT(26)
+#define BCMA_RES_4314_TX_LDO_PU BIT(27)
+#define BCMA_RES_4314_HT_AVAIL BIT(28)
+#define BCMA_RES_4314_MACPHY_CLK_AVAIL BIT(29)
+
/* Data for the PMU, if available.
* Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU)
*/
--
1.7.10.4
^ permalink raw reply related
* [PATCH] b43: replace B43_BCMA_EXTRA with modparam allhwsupport
From: Rafał Miłecki @ 2013-06-26 7:55 UTC (permalink / raw)
To: linux-wireless, John W. Linville; +Cc: b43-dev, Rafał Miłecki
This allows enabling support for extra hardware with just a module
param, without kernel/module recompilation.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
drivers/net/wireless/b43/Kconfig | 6 ------
drivers/net/wireless/b43/main.c | 12 ++++++++++--
2 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 3f21e0b..51ff0b1 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -31,12 +31,6 @@ config B43_BCMA
depends on B43 && (BCMA = y || BCMA = B43)
default y
-config B43_BCMA_EXTRA
- bool "Hardware support that overlaps with the brcmsmac driver"
- depends on B43_BCMA
- default n if BRCMSMAC
- default y
-
config B43_SSB
bool
depends on B43 && (SSB = y || SSB = B43)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index a95b77a..0e933bb 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -113,13 +113,15 @@ static int b43_modparam_pio = 0;
module_param_named(pio, b43_modparam_pio, int, 0644);
MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
+static int modparam_allhwsupport = !IS_ENABLED(CONFIG_BRCMSMAC);
+module_param_named(allhwsupport, modparam_allhwsupport, int, 0444);
+MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)");
+
#ifdef CONFIG_B43_BCMA
static const struct bcma_device_id b43_bcma_tbl[] = {
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
-#ifdef CONFIG_B43_BCMA_EXTRA
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
-#endif
BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
BCMA_CORETABLE_END
};
@@ -5396,6 +5398,12 @@ static int b43_bcma_probe(struct bcma_device *core)
struct b43_wl *wl;
int err;
+ if (!modparam_allhwsupport &&
+ (core->id.rev == 0x17 || core->id.rev == 0x18)) {
+ pr_err("Support for cores revisions 0x17 and 0x18 disabled by module param allhwsupport=0. Try b43.allhwsupport=1\n");
+ return -ENOTSUPP;
+ }
+
dev = b43_bus_dev_bcma_init(core);
if (!dev)
return -ENODEV;
--
1.7.10.4
^ permalink raw reply related
* Re: [PATCH] cfg80211/mac80211: fix doc compilation warnings
From: Johannes Berg @ 2013-06-26 7:37 UTC (permalink / raw)
To: Michael Opdenacker; +Cc: davem, linux-wireless, linux-kernel
In-Reply-To: <1372189700-6247-1-git-send-email-michael.opdenacker@free-electrons.com>
On Tue, 2013-06-25 at 21:48 +0200, Michael Opdenacker wrote:
> This patch fixes countless "No description found for parameter"
> warnings generating documentation (running "make htmldocs"),
> because the comments do not match the actual prototypes in the code.
>
> This issue didn't exist in 3.9. It may we worth fixing in 3.10
> (if it's not too late).
I think it's way late. Besides, all of this is already fixed in -next
trees.
> @@ -4153,6 +4153,7 @@ void cfg80211_report_wowlan_wakeup(struct wireless_dev *wdev,
> * cfg80211_crit_proto_stopped() - indicate critical protocol stopped by driver.
> *
> * @wdev: the wireless device for which critical protocol is stopped.
> + * @gfp: the type of memory to allocate (see kmalloc).
This is also wrong, the allocation flags don't really change the *type*
of memory, but only *how* it is allocated.
johannes
^ permalink raw reply
* Re: [PATCH] wireless: vlan priority handling in WMM
From: Johannes Berg @ 2013-06-26 7:33 UTC (permalink / raw)
To: cedric.voncken; +Cc: linux-wireless
In-Reply-To: <1372174262-13526-1-git-send-email-cedric.voncken@acksys.fr>
On Tue, 2013-06-25 at 17:31 +0200, cedric.voncken@acksys.fr wrote:
> From: Cedric Voncken <cedric.voncken@acksys.fr>
>
> If the VLAN priority is set in skb->vlan_tci use it to determine the WMM priority.
What's the VLAN priority? How are you even running 802.1q on top of
wifi? heh.
> @@ -694,6 +695,10 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb)
> if (skb->priority >= 256 && skb->priority <= 263)
> return skb->priority - 256;
>
> + vlan_priority = (skb->vlan_tci >> 13) & 0x07;
Are there no symbolic constants for this?
> + if (vlan_priority > 0)
> + return vlan_priority;
I think you got indentation a bit confused :-)
johannes
^ permalink raw reply
* Re: regression after, " ath9k_htc: Add support for mesh interfaces"
From: Johannes Berg @ 2013-06-26 7:31 UTC (permalink / raw)
To: Thomas Pedersen
Cc: Oleksij Rempel, ath9k-devel@lists.ath9k.org,
linux-wireless@vger.kernel.org, Javier Cardona
In-Reply-To: <CAG6hwVMa+i=wXRyfcwaXH8NesCXgKXW6Ad4dzgd9DZONGYA=xQ@mail.gmail.com>
On Tue, 2013-06-25 at 13:05 -0700, Thomas Pedersen wrote:
> That warning is triggered by wiphy_verify_combinations():
>
> if (WARN_ON((wiphy->interface_modes & types) != types))
> return -EINVAL;
>
> But before that, the mesh iftype bit is cleared in ieee80211_register_hw():
>
> #ifndef CONFIG_MAC80211_MESH
> /* mesh depends on Kconfig, but drivers should set it if they want */
> local->hw.wiphy->interface_modes &= ~BIT(NL80211_IFTYPE_MESH_POINT);
> #endif
>
> It seems the intention was to avoid an #ifdef CONFIG_MAC80211_MESH in
> every driver, but then mac80211 also has to clear the MESH_POINT bit
> for each ieee80211_iface_limit? I don't really see a cleaner way of
> resolving this.
The problem is that the data structures there are const, so we can't
modify them. I think the other drivers just have an #ifdef on
MAC80211_MESH or so in there.
johannes
^ permalink raw reply
* [PATCH v2] ath10k: leave MMIC generation to the HW
From: Michal Kazior @ 2013-06-26 6:57 UTC (permalink / raw)
To: ath9k-devel, linux-wireless; +Cc: Michal Kazior
In-Reply-To: <1372060350-31460-4-git-send-email-michal.kazior@tieto.com>
Apparently HW doesn't require us to generate MMIC
for TKIP suite.
Each frame was 8 bytes longer than it should be
and some APs would drop frames that exceed 1520
bytes of 802.11 payload. This could be observed
during throughput tests or fragmented IP traffic.
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
drivers/net/wireless/ath/ath10k/mac.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 4867f30..bfee06d 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -56,7 +56,6 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
break;
case WLAN_CIPHER_SUITE_TKIP:
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
arg.key_cipher = WMI_CIPHER_TKIP;
arg.key_txmic_len = 8;
arg.key_rxmic_len = 8;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2] ath10k: fix 5ghz channel definitions
From: Michal Kazior @ 2013-06-26 6:54 UTC (permalink / raw)
To: ath9k-devel, linux-wireless; +Cc: Michal Kazior
In-Reply-To: <1372060350-31460-3-git-send-email-michal.kazior@tieto.com>
Nonsense channel flags were being set.
Although it doesn't seem this was visible to the
user the patch makes sure that channel
availability won't be crippled in the future if
ath_common behaviour changes.
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
drivers/net/wireless/ath/ath10k/mac.c | 48 ++++++++++++++++-----------------
1 file changed, 24 insertions(+), 24 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 4867f30..441a3e7 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -2798,30 +2798,30 @@ static const struct ieee80211_channel ath10k_2ghz_channels[] = {
};
static const struct ieee80211_channel ath10k_5ghz_channels[] = {
- CHAN5G(36, 5180, 14),
- CHAN5G(40, 5200, 15),
- CHAN5G(44, 5220, 16),
- CHAN5G(48, 5240, 17),
- CHAN5G(52, 5260, 18),
- CHAN5G(56, 5280, 19),
- CHAN5G(60, 5300, 20),
- CHAN5G(64, 5320, 21),
- CHAN5G(100, 5500, 22),
- CHAN5G(104, 5520, 23),
- CHAN5G(108, 5540, 24),
- CHAN5G(112, 5560, 25),
- CHAN5G(116, 5580, 26),
- CHAN5G(120, 5600, 27),
- CHAN5G(124, 5620, 28),
- CHAN5G(128, 5640, 29),
- CHAN5G(132, 5660, 30),
- CHAN5G(136, 5680, 31),
- CHAN5G(140, 5700, 32),
- CHAN5G(149, 5745, 33),
- CHAN5G(153, 5765, 34),
- CHAN5G(157, 5785, 35),
- CHAN5G(161, 5805, 36),
- CHAN5G(165, 5825, 37),
+ CHAN5G(36, 5180, 0),
+ CHAN5G(40, 5200, 0),
+ CHAN5G(44, 5220, 0),
+ CHAN5G(48, 5240, 0),
+ CHAN5G(52, 5260, 0),
+ CHAN5G(56, 5280, 0),
+ CHAN5G(60, 5300, 0),
+ CHAN5G(64, 5320, 0),
+ CHAN5G(100, 5500, 0),
+ CHAN5G(104, 5520, 0),
+ CHAN5G(108, 5540, 0),
+ CHAN5G(112, 5560, 0),
+ CHAN5G(116, 5580, 0),
+ CHAN5G(120, 5600, 0),
+ CHAN5G(124, 5620, 0),
+ CHAN5G(128, 5640, 0),
+ CHAN5G(132, 5660, 0),
+ CHAN5G(136, 5680, 0),
+ CHAN5G(140, 5700, 0),
+ CHAN5G(149, 5745, 0),
+ CHAN5G(153, 5765, 0),
+ CHAN5G(157, 5785, 0),
+ CHAN5G(161, 5805, 0),
+ CHAN5G(165, 5825, 0),
};
static struct ieee80211_rate ath10k_rates[] = {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v2] ath10k: fix MSI-X setup failpath
From: Michal Kazior @ 2013-06-26 6:50 UTC (permalink / raw)
To: ath9k-devel, linux-wireless; +Cc: Michal Kazior
In-Reply-To: <1372150661-6862-1-git-send-email-michal.kazior@tieto.com>
Irqs were not freed up correctly upon msi-x setup
failure.
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
---
drivers/net/wireless/ath/ath10k/pci.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index 1a59638..63c58b5 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1882,9 +1882,10 @@ static int ath10k_pci_start_intr_msix(struct ath10k *ar, int num)
ath10k_warn("request_irq(%d) failed %d\n",
ar_pci->pdev->irq + i, ret);
- for (; i >= MSI_ASSIGN_CE_INITIAL; i--)
- free_irq(ar_pci->pdev->irq, ar);
+ for (i--; i >= MSI_ASSIGN_CE_INITIAL; i--)
+ free_irq(ar_pci->pdev->irq + i, ar);
+ free_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW, ar);
pci_disable_msi(ar_pci->pdev);
return ret;
}
--
1.7.9.5
^ permalink raw reply related
* ADHOC issue with WL12xx driver
From: Błażej Szajrych @ 2013-06-26 6:50 UTC (permalink / raw)
To: linux-wireless, backports; +Cc: daw, pg
[-- Attachment #1: Type: text/plain, Size: 1735 bytes --]
Hi,
We are encountering serious AD-HOC problems:
. Commands are run successfully
. The network is theoretically created
. It is not visible for other devices and the DMESG show that an error
occurs and the firmware reboots
More info:
. The box running Linux is the VAR SOM OM44
. The operation system we are using is Ubuntu 12.04 LTS on the
3.4.0-1490-omap4 kernel.
. The processor is in the ARM architecture.
. WiFi card: Murata LBEH59XUHC.
. WiFi driver: wl12xx, wlcore firmware wl127x-fw-5-sr.bin with Rev
6.3.10.0.135.
. Network connection through the router is working. Network manager is
used to configure the connection.
. Ad-hoc mode connection is not working - the network is not visible
to other computers.
Commands used to configure the network in adhoc mode are as follows (wlan0
is the WiFi interface name):
1. Using iw:
. ifconfig wlan0 down
. iw wlan0 set type ibss
. ifconfig wlan0 up
. iw wlan0 ibss join ADHOC_TEST 2437
2. Using iwconfig
. ifconfig wlan0 down
. iwconfig wlan0 mode ad-hoc
. iwconfig wlan0 channel 6
. iwconfig wlan0 essid ADHOC_TEST
. ifconfig wlan0 up
Attached you will find the dmesg messages (dmesg.txt).
Using the latest backport of Compat Wireless backports-3.10-rc1-2 did not
help.
Testing with different WiFI dongles gave different results.
TP Link WN725N that uses the Realtek 8192cu driver and is based on the
RTL8188CUS-GR chipset is working correctly in AD-HOC mode.
Could you guide us in anyway in resolving this issue?
Pozdrawiam, Best Regards,
Błażej Szajrych
Software Developer
+48 669 710 648
Macrix Polska Sp. Z o. o. Sp. K.
ul. Podlaska 15
PL 60-623 Poznan
tel.: +48 61 865 47 23
fax: +48 61 865 47 24
[-- Attachment #2: dmesg.txt --]
[-- Type: text/plain, Size: 7493 bytes --]
[ 5138.270751] ---[ end trace da227214a8249879 ]---
[ 5138.270782] wlcore: ERROR failed to initiate cmd role enable
[ 5138.278594] wlcore: WARNING cmd join failed -110
[ 5138.278625] wlcore: Reading FW panic log
[ 5138.278625] ------------[ cut here ]------------
[ 5138.278686] WARNING: at /home/variscite/Downloads/backports-3.10-rc1-2/drivers/net/wireless/ti/wlcore/cmd.c:63 wlcore_cmd_send_failsafe+0x40/0x3a0 [wlcore]()
[ 5138.278686] Modules linked in: rtl8192c_common(O) rtlwifi(O) 8192cu(O) omapdrm_pvr(O) wl12xx(O) wlcore(O) mac80211(O) cfg80211(O) joydev omapdce(C) rpmsg_omx bnep(O) omaprpc(C) rfcomm(O) omap_remoteproc rpmsg_resmgr_common ppdev remoteproc bluetooth(O) omap_rpmsg_resmgr rpmsg_resmgr virtio_rpmsg_bus lp virtio virtio_ring parport dm_multipath at24 wlcore_sdio(O) compat(O) hid_apple usbhid hid dm_mirror dm_region_hash dm_log btrfs zlib_deflate libcrc32c
[ 5138.278778] [<c001bc38>] (unwind_backtrace+0x0/0xec) from [<c05accd0>] (dump_stack+0x20/0x24)
[ 5138.278808] [<c05accd0>] (dump_stack+0x20/0x24) from [<c00458d4>] (warn_slowpath_common+0x5c/0x74)
[ 5138.278808] [<c00458d4>] (warn_slowpath_common+0x5c/0x74) from [<c0045918>] (warn_slowpath_null+0x2c/0x34)
[ 5138.278839] [<c0045918>] (warn_slowpath_null+0x2c/0x34) from [<bf40c304>] (wlcore_cmd_send_failsafe+0x40/0x3a0 [wlcore])
[ 5138.278900] [<bf40c304>] (wlcore_cmd_send_failsafe+0x40/0x3a0 [wlcore]) from [<bf40c690>] (wl1271_cmd_send+0x2c/0x38 [wlcore])
[ 5138.278930] [<bf40c690>] (wl1271_cmd_send+0x2c/0x38 [wlcore]) from [<bf40edf4>] (wl12xx_cmd_stop_fwlog+0x7c/0xb8 [wlcore])
[ 5138.278991] [<bf40edf4>] (wl12xx_cmd_stop_fwlog+0x7c/0xb8 [wlcore]) from [<bf409908>] (wl1271_recovery_work+0xcc/0x3ac [wlcore])
[ 5138.279022] [<bf409908>] (wl1271_recovery_work+0xcc/0x3ac [wlcore]) from [<c0061d0c>] (process_one_work+0x294/0x48c)
[ 5138.279022] [<c0061d0c>] (process_one_work+0x294/0x48c) from [<c0062214>] (worker_thread+0x144/0x240)
[ 5138.279052] [<c0062214>] (worker_thread+0x144/0x240) from [<c0067090>] (kthread+0x9c/0xa8)
[ 5138.279052] [<c0067090>] (kthread+0x9c/0xa8) from [<c00144a4>] (kernel_thread_exit+0x0/0x8)
[ 5138.279052] ---[ end trace da227214a824987a ]---
[ 5138.279083] ------------[ cut here ]------------
[ 5138.279083] WARNING: at /home/variscite/Downloads/backports-3.10-rc1-2/drivers/net/wireless/ti/wlcore/main.c:790 wl12xx_queue_recovery_work+0x30/0x6c [wlcore]()
[ 5138.279113] Modules linked in: rtl8192c_common(O) rtlwifi(O) 8192cu(O) omapdrm_pvr(O) wl12xx(O) wlcore(O) mac80211(O) cfg80211(O) joydev omapdce(C) rpmsg_omx bnep(O) omaprpc(C) rfcomm(O) omap_remoteproc rpmsg_resmgr_common ppdev remoteproc bluetooth(O) omap_rpmsg_resmgr rpmsg_resmgr virtio_rpmsg_bus lp virtio virtio_ring parport dm_multipath at24 wlcore_sdio(O) compat(O) hid_apple usbhid hid dm_mirror dm_region_hash dm_log btrfs zlib_deflate libcrc32c
[ 5138.279205] [<c001bc38>] (unwind_backtrace+0x0/0xec) from [<c05accd0>] (dump_stack+0x20/0x24)
[ 5138.279205] [<c05accd0>] (dump_stack+0x20/0x24) from [<c00458d4>] (warn_slowpath_common+0x5c/0x74)
[ 5138.279235] [<c00458d4>] (warn_slowpath_common+0x5c/0x74) from [<c0045918>] (warn_slowpath_null+0x2c/0x34)
[ 5138.279266] [<c0045918>] (warn_slowpath_null+0x2c/0x34) from [<bf4093f8>] (wl12xx_queue_recovery_work+0x30/0x6c [wlcore])
[ 5138.279296] [<bf4093f8>] (wl12xx_queue_recovery_work+0x30/0x6c [wlcore]) from [<bf40c644>] (wlcore_cmd_send_failsafe+0x380/0x3a0 [wlcore])
[ 5138.279357] [<bf40c644>] (wlcore_cmd_send_failsafe+0x380/0x3a0 [wlcore]) from [<bf40c690>] (wl1271_cmd_send+0x2c/0x38 [wlcore])
[ 5138.279388] [<bf40c690>] (wl1271_cmd_send+0x2c/0x38 [wlcore]) from [<bf40edf4>] (wl12xx_cmd_stop_fwlog+0x7c/0xb8 [wlcore])
[ 5138.279418] [<bf40edf4>] (wl12xx_cmd_stop_fwlog+0x7c/0xb8 [wlcore]) from [<bf409908>] (wl1271_recovery_work+0xcc/0x3ac [wlcore])
[ 5138.279449] [<bf409908>] (wl1271_recovery_work+0xcc/0x3ac [wlcore]) from [<c0061d0c>] (process_one_work+0x294/0x48c)
[ 5138.279479] [<c0061d0c>] (process_one_work+0x294/0x48c) from [<c0062214>] (worker_thread+0x144/0x240)
[ 5138.279479] [<c0062214>] (worker_thread+0x144/0x240) from [<c0067090>] (kthread+0x9c/0xa8)
[ 5138.279510] [<c0067090>] (kthread+0x9c/0xa8) from [<c00144a4>] (kernel_thread_exit+0x0/0x8)
[ 5138.279510] ---[ end trace da227214a824987b ]---
[ 5138.279510] wlcore: ERROR failed to send stop firmware logger command
[ 5138.289611] wlcore: Hardware recovery in progress. FW ver: Rev 6.3.10.0.133
[ 5138.289916] wlcore: pc: 0x1b6d6, hint_sts: 0x00000000 count: 574
[ 5138.290161] wlcore: down
[ 5138.292236] ieee80211 phy0: Hardware restart was requested
[ 5138.876770] wlcore: firmware booted (Rev 6.3.10.0.133)
[ 5140.889648] wlcore: ERROR command complete timeout
[ 5140.894653] ------------[ cut here ]------------
[ 5140.894714] WARNING: at /home/variscite/Downloads/backports-3.10-rc1-2/drivers/net/wireless/ti/wlcore/main.c:790 wl12xx_queue_recovery_work+0x30/0x6c [wlcore]()
[ 5140.894714] Modules linked in: rtl8192c_common(O) rtlwifi(O) 8192cu(O) omapdrm_pvr(O) wl12xx(O) wlcore(O) mac80211(O) cfg80211(O) joydev omapdce(C) rpmsg_omx bnep(O) omaprpc(C) rfcomm(O) omap_remoteproc rpmsg_resmgr_common ppdev remoteproc bluetooth(O) omap_rpmsg_resmgr rpmsg_resmgr virtio_rpmsg_bus lp virtio virtio_ring parport dm_multipath at24 wlcore_sdio(O) compat(O) hid_apple usbhid hid dm_mirror dm_region_hash dm_log btrfs zlib_deflate libcrc32c
[ 5140.894836] [<c001bc38>] (unwind_backtrace+0x0/0xec) from [<c05accd0>] (dump_stack+0x20/0x24)
[ 5140.894866] [<c05accd0>] (dump_stack+0x20/0x24) from [<c00458d4>] (warn_slowpath_common+0x5c/0x74)
[ 5140.894866] [<c00458d4>] (warn_slowpath_common+0x5c/0x74) from [<c0045918>] (warn_slowpath_null+0x2c/0x34)
[ 5140.894897] [<c0045918>] (warn_slowpath_null+0x2c/0x34) from [<bf4093f8>] (wl12xx_queue_recovery_work+0x30/0x6c [wlcore])
[ 5140.894958] [<bf4093f8>] (wl12xx_queue_recovery_work+0x30/0x6c [wlcore]) from [<bf40c644>] (wlcore_cmd_send_failsafe+0x380/0x3a0 [wlcore])
[ 5140.894989] [<bf40c644>] (wlcore_cmd_send_failsafe+0x380/0x3a0 [wlcore]) from [<bf40c690>] (wl1271_cmd_send+0x2c/0x38 [wlcore])
[ 5140.895050] [<bf40c690>] (wl1271_cmd_send+0x2c/0x38 [wlcore]) from [<bf40d6a0>] (wl12xx_cmd_role_start_ibss+0x174/0x1c8 [wlcore])
[ 5140.895080] [<bf40d6a0>] (wl12xx_cmd_role_start_ibss+0x174/0x1c8 [wlcore]) from [<bf407e88>] (wl1271_op_bss_info_changed+0x834/0xcb4 [wlcore])
[ 5140.895202] [<bf407e88>] (wl1271_op_bss_info_changed+0x834/0xcb4 [wlcore]) from [<bf345be0>] (ieee80211_bss_info_change_notify+0x198/0x240 [mac80211])
[ 5140.895416] [<bf345be0>] (ieee80211_bss_info_change_notify+0x198/0x240 [mac80211]) from [<bf36db98>] (ieee80211_reconfig+0x1630/0x1e18 [mac80211])
[ 5140.895568] [<bf36db98>] (ieee80211_reconfig+0x1630/0x1e18 [mac80211]) from [<bf34518c>] (ieee80211_restart_work+0x80/0x94 [mac80211])
[ 5140.895660] [<bf34518c>] (ieee80211_restart_work+0x80/0x94 [mac80211]) from [<c0061d0c>] (process_one_work+0x294/0x48c)
[ 5140.895690] [<c0061d0c>] (process_one_work+0x294/0x48c) from [<c0062214>] (worker_thread+0x144/0x240)
[ 5140.895690] [<c0062214>] (worker_thread+0x144/0x240) from [<c0067090>] (kthread+0x9c/0xa8)
[ 5140.895721] [<c0067090>] (kthread+0x9c/0xa8) from [<c00144a4>] (kernel_thread_exit+0x0/0x8)
[ 5140.895721] ---[ end trace da227214a824987c ]---
[ 5140.895751] wlcore: ERROR failed to initiate cmd role enable
[ 5140.903717] wlcore: WARNING cmd join failed -110
[ 5140.903778] wlcore: Reading FW panic log
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox