Commit 4dd8b26a authored by Hante Meuleman's avatar Hante Meuleman Committed by Kalle Valo

brcmfmac: use SDIO DPC for control frames.

Control frames are normally handled outside DPC, but sometimes
within DPC. To simplify code always handle control within DPC.
Reviewed-by: default avatarArend Van Spriel <arend@broadcom.com>
Reviewed-by: default avatarFranky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: default avatarPieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: default avatarDaniel (Deognyoun) Kim <dekim@broadcom.com>
Signed-off-by: default avatarHante Meuleman <meuleman@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 69d03ee0
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#include "firmware.h" #include "firmware.h"
#define DCMD_RESP_TIMEOUT 2000 /* In milli second */ #define DCMD_RESP_TIMEOUT 2000 /* In milli second */
#define CTL_DONE_TIMEOUT 2000 /* In milli second */
#ifdef DEBUG #ifdef DEBUG
...@@ -495,9 +496,9 @@ struct brcmf_sdio { ...@@ -495,9 +496,9 @@ struct brcmf_sdio {
u8 *ctrl_frame_buf; u8 *ctrl_frame_buf;
u16 ctrl_frame_len; u16 ctrl_frame_len;
bool ctrl_frame_stat; bool ctrl_frame_stat;
int ctrl_frame_err;
spinlock_t txq_lock; /* protect bus->txq */ spinlock_t txq_lock; /* protect bus->txq */
struct semaphore tx_seq_lock; /* protect bus->tx_seq */
wait_queue_head_t ctrl_wait; wait_queue_head_t ctrl_wait;
wait_queue_head_t dcmd_resp_wait; wait_queue_head_t dcmd_resp_wait;
...@@ -2376,8 +2377,6 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes) ...@@ -2376,8 +2377,6 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
/* Send frames until the limit or some other event */ /* Send frames until the limit or some other event */
for (cnt = 0; (cnt < maxframes) && data_ok(bus);) { for (cnt = 0; (cnt < maxframes) && data_ok(bus);) {
pkt_num = 1; pkt_num = 1;
if (down_interruptible(&bus->tx_seq_lock))
return cnt;
if (bus->txglom) if (bus->txglom)
pkt_num = min_t(u8, bus->tx_max - bus->tx_seq, pkt_num = min_t(u8, bus->tx_max - bus->tx_seq,
bus->sdiodev->txglomsz); bus->sdiodev->txglomsz);
...@@ -2393,13 +2392,10 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes) ...@@ -2393,13 +2392,10 @@ static uint brcmf_sdio_sendfromq(struct brcmf_sdio *bus, uint maxframes)
__skb_queue_tail(&pktq, pkt); __skb_queue_tail(&pktq, pkt);
} }
spin_unlock_bh(&bus->txq_lock); spin_unlock_bh(&bus->txq_lock);
if (i == 0) { if (i == 0)
up(&bus->tx_seq_lock);
break; break;
}
ret = brcmf_sdio_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL); ret = brcmf_sdio_txpkt(bus, &pktq, SDPCM_DATA_CHANNEL);
up(&bus->tx_seq_lock);
cnt += i; cnt += i;
...@@ -2743,18 +2739,15 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus) ...@@ -2743,18 +2739,15 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
brcmf_sdio_clrintr(bus); brcmf_sdio_clrintr(bus);
if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) && if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) &&
(down_interruptible(&bus->tx_seq_lock) == 0)) { data_ok(bus)) {
if (data_ok(bus)) {
sdio_claim_host(bus->sdiodev->func[1]); sdio_claim_host(bus->sdiodev->func[1]);
err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf, err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf,
bus->ctrl_frame_len); bus->ctrl_frame_len);
sdio_release_host(bus->sdiodev->func[1]); sdio_release_host(bus->sdiodev->func[1]);
bus->ctrl_frame_err = err;
bus->ctrl_frame_stat = false; bus->ctrl_frame_stat = false;
brcmf_sdio_wait_event_wakeup(bus); brcmf_sdio_wait_event_wakeup(bus);
} }
up(&bus->tx_seq_lock);
}
/* Send queued frames (limit 1 if rx may still be pending) */ /* Send queued frames (limit 1 if rx may still be pending) */
if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) && if ((bus->clkstate == CLK_AVAIL) && !atomic_read(&bus->fcstate) &&
brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit && brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && txlimit &&
...@@ -2965,43 +2958,30 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) ...@@ -2965,43 +2958,30 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
struct brcmf_bus *bus_if = dev_get_drvdata(dev); struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio *bus = sdiodev->bus; struct brcmf_sdio *bus = sdiodev->bus;
int ret = -1; int ret;
brcmf_dbg(TRACE, "Enter\n"); brcmf_dbg(TRACE, "Enter\n");
if (down_interruptible(&bus->tx_seq_lock))
return -EINTR;
if (!data_ok(bus)) {
brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n",
bus->tx_max, bus->tx_seq);
up(&bus->tx_seq_lock);
/* Send from dpc */ /* Send from dpc */
bus->ctrl_frame_buf = msg; bus->ctrl_frame_buf = msg;
bus->ctrl_frame_len = msglen; bus->ctrl_frame_len = msglen;
bus->ctrl_frame_stat = true; bus->ctrl_frame_stat = true;
if (atomic_read(&bus->dpc_tskcnt) == 0) {
atomic_inc(&bus->dpc_tskcnt);
queue_work(bus->brcmf_wq, &bus->datawork);
}
wait_event_interruptible_timeout(bus->ctrl_wait, wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat,
!bus->ctrl_frame_stat, msecs_to_jiffies(CTL_DONE_TIMEOUT));
msecs_to_jiffies(2000));
if (!bus->ctrl_frame_stat) { if (!bus->ctrl_frame_stat) {
brcmf_dbg(SDIO, "ctrl_frame_stat == false\n"); brcmf_dbg(SDIO, "ctrl_frame complete, err=%d\n",
ret = 0; bus->ctrl_frame_err);
ret = bus->ctrl_frame_err;
} else { } else {
brcmf_dbg(SDIO, "ctrl_frame_stat == true\n"); brcmf_dbg(SDIO, "ctrl_frame timeout\n");
bus->ctrl_frame_stat = false; bus->ctrl_frame_stat = false;
if (down_interruptible(&bus->tx_seq_lock)) ret = -ETIMEDOUT;
return -EINTR;
ret = -1;
}
}
if (ret == -1) {
sdio_claim_host(bus->sdiodev->func[1]);
brcmf_sdio_bus_sleep(bus, false, false);
ret = brcmf_sdio_tx_ctrlframe(bus, msg, msglen);
sdio_release_host(bus->sdiodev->func[1]);
up(&bus->tx_seq_lock);
} }
if (ret) if (ret)
...@@ -3009,7 +2989,7 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) ...@@ -3009,7 +2989,7 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
else else
bus->sdcnt.tx_ctlpkts++; bus->sdcnt.tx_ctlpkts++;
return ret ? -EIO : 0; return ret;
} }
#ifdef DEBUG #ifdef DEBUG
...@@ -4165,7 +4145,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) ...@@ -4165,7 +4145,6 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
spin_lock_init(&bus->rxctl_lock); spin_lock_init(&bus->rxctl_lock);
spin_lock_init(&bus->txq_lock); spin_lock_init(&bus->txq_lock);
sema_init(&bus->tx_seq_lock, 1);
init_waitqueue_head(&bus->ctrl_wait); init_waitqueue_head(&bus->ctrl_wait);
init_waitqueue_head(&bus->dcmd_resp_wait); init_waitqueue_head(&bus->dcmd_resp_wait);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment