Commit b83db862 authored by Arend van Spriel's avatar Arend van Spriel Committed by John W. Linville

brcm80211: fmac: use sk_buff list for handling frames in receive path

The functions in the receive patch of the fullmac now use sk_buff
list and skb_queue_xx() functions instead of dealing with list pointers
in the sk_buff directly.
Reported-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Reviewed-by: default avatarFranky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: default avatarRoland Vossen <rvossen@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 6cddafab
...@@ -574,7 +574,7 @@ struct brcmf_bus { ...@@ -574,7 +574,7 @@ struct brcmf_bus {
uint txminmax; uint txminmax;
struct sk_buff *glomd; /* Packet containing glomming descriptor */ struct sk_buff *glomd; /* Packet containing glomming descriptor */
struct sk_buff *glom; /* Packet chain for glommed superframe */ struct sk_buff_head glom; /* Packet list for glommed superframe */
uint glomerr; /* Glom packet read errors */ uint glomerr; /* Glom packet read errors */
u8 *rxbuf; /* Buffer for receiving control packets */ u8 *rxbuf; /* Buffer for receiving control packets */
...@@ -1229,16 +1229,17 @@ static uint brcmf_sdbrcm_glom_from_buf(struct brcmf_bus *bus, uint len) ...@@ -1229,16 +1229,17 @@ static uint brcmf_sdbrcm_glom_from_buf(struct brcmf_bus *bus, uint len)
struct sk_buff *p; struct sk_buff *p;
u8 *buf; u8 *buf;
p = bus->glom;
buf = bus->dataptr; buf = bus->dataptr;
/* copy the data */ /* copy the data */
for (; p && len; p = p->next) { skb_queue_walk(&bus->glom, p) {
n = min_t(uint, p->len, len); n = min_t(uint, p->len, len);
memcpy(p->data, buf, n); memcpy(p->data, buf, n);
buf += n; buf += n;
len -= n; len -= n;
ret += n; ret += n;
if (!len)
break;
} }
return ret; return ret;
...@@ -1262,7 +1263,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) ...@@ -1262,7 +1263,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq)
/* If packets, issue read(s) and send up packet chain */ /* If packets, issue read(s) and send up packet chain */
/* Return sequence numbers consumed? */ /* Return sequence numbers consumed? */
brcmf_dbg(TRACE, "start: glomd %p glom %p\n", bus->glomd, bus->glom); brcmf_dbg(TRACE, "start: glomd %p glom %p\n",
bus->glomd, skb_peek(&bus->glom));
/* If there's a descriptor, generate the packet chain */ /* If there's a descriptor, generate the packet chain */
if (bus->glomd) { if (bus->glomd) {
...@@ -1309,12 +1311,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) ...@@ -1309,12 +1311,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq)
num, sublen); num, sublen);
break; break;
} }
if (!pfirst) { skb_queue_tail(&bus->glom, pnext);
pfirst = plast = pnext;
} else {
plast->next = pnext;
plast = pnext;
}
/* Adhere to start alignment requirements */ /* Adhere to start alignment requirements */
pkt_align(pnext, sublen, BRCMF_SDALIGN); pkt_align(pnext, sublen, BRCMF_SDALIGN);
...@@ -1330,12 +1327,13 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) ...@@ -1330,12 +1327,13 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq)
brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n", brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n",
bus->nextlen, totlen, rxseq); bus->nextlen, totlen, rxseq);
} }
bus->glom = pfirst;
pfirst = pnext = NULL; pfirst = pnext = NULL;
} else { } else {
if (pfirst) if (!skb_queue_empty(&bus->glom))
brcmu_pkt_buf_free_skb(pfirst); skb_queue_walk_safe(&bus->glom, pfirst, pnext) {
bus->glom = NULL; skb_unlink(pfirst, &bus->glom);
brcmu_pkt_buf_free_skb(pfirst);
}
num = 0; num = 0;
} }
...@@ -1347,17 +1345,17 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) ...@@ -1347,17 +1345,17 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq)
/* Ok -- either we just generated a packet chain, /* Ok -- either we just generated a packet chain,
or had one from before */ or had one from before */
if (bus->glom) { if (!skb_queue_empty(&bus->glom)) {
if (BRCMF_GLOM_ON()) { if (BRCMF_GLOM_ON()) {
brcmf_dbg(GLOM, "try superframe read, packet chain:\n"); brcmf_dbg(GLOM, "try superframe read, packet chain:\n");
for (pnext = bus->glom; pnext; pnext = pnext->next) { skb_queue_walk(&bus->glom, pnext) {
brcmf_dbg(GLOM, " %p: %p len 0x%04x (%d)\n", brcmf_dbg(GLOM, " %p: %p len 0x%04x (%d)\n",
pnext, (u8 *) (pnext->data), pnext, (u8 *) (pnext->data),
pnext->len, pnext->len); pnext->len, pnext->len);
} }
} }
pfirst = bus->glom; pfirst = skb_peek(&bus->glom);
dlen = (u16) brcmu_pkttotlen(pfirst); dlen = (u16) brcmu_pkttotlen(pfirst);
/* Do an SDIO read for the superframe. Configurable iovar to /* Do an SDIO read for the superframe. Configurable iovar to
...@@ -1401,9 +1399,11 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) ...@@ -1401,9 +1399,11 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq)
} else { } else {
bus->glomerr = 0; bus->glomerr = 0;
brcmf_sdbrcm_rxfail(bus, true, false); brcmf_sdbrcm_rxfail(bus, true, false);
brcmu_pkt_buf_free_skb(bus->glom);
bus->rxglomfail++; bus->rxglomfail++;
bus->glom = NULL; skb_queue_walk_safe(&bus->glom, pfirst, pnext) {
skb_unlink(pfirst, &bus->glom);
brcmu_pkt_buf_free_skb(pfirst);
}
} }
return 0; return 0;
} }
...@@ -1524,9 +1524,11 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) ...@@ -1524,9 +1524,11 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq)
} else { } else {
bus->glomerr = 0; bus->glomerr = 0;
brcmf_sdbrcm_rxfail(bus, true, false); brcmf_sdbrcm_rxfail(bus, true, false);
brcmu_pkt_buf_free_skb(bus->glom);
bus->rxglomfail++; bus->rxglomfail++;
bus->glom = NULL; skb_queue_walk_safe(&bus->glom, pfirst, pnext) {
skb_unlink(pfirst, &bus->glom);
brcmu_pkt_buf_free_skb(pfirst);
}
} }
bus->nextlen = 0; bus->nextlen = 0;
return 0; return 0;
...@@ -1534,7 +1536,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) ...@@ -1534,7 +1536,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq)
/* Basic SD framing looks ok - process each packet (header) */ /* Basic SD framing looks ok - process each packet (header) */
save_pfirst = pfirst; save_pfirst = pfirst;
bus->glom = NULL;
plast = NULL; plast = NULL;
for (num = 0; pfirst; rxseq++, pfirst = pnext) { for (num = 0; pfirst; rxseq++, pfirst = pnext) {
...@@ -1871,10 +1872,10 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) ...@@ -1871,10 +1872,10 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished)
rxseq++, rxleft--) { rxseq++, rxleft--) {
/* Handle glomming separately */ /* Handle glomming separately */
if (bus->glom || bus->glomd) { if (bus->glomd || !skb_queue_empty(&bus->glom)) {
u8 cnt; u8 cnt;
brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n", brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n",
bus->glomd, bus->glom); bus->glomd, skb_peek(&bus->glom));
cnt = brcmf_sdbrcm_rxglom(bus, rxseq); cnt = brcmf_sdbrcm_rxglom(bus, rxseq);
brcmf_dbg(GLOM, "rxglom returned %d\n", cnt); brcmf_dbg(GLOM, "rxglom returned %d\n", cnt);
rxseq += cnt - 1; rxseq += cnt - 1;
...@@ -3623,6 +3624,8 @@ void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus) ...@@ -3623,6 +3624,8 @@ void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus)
u8 saveclk; u8 saveclk;
uint retries; uint retries;
int err; int err;
struct sk_buff *cur;
struct sk_buff *next;
brcmf_dbg(TRACE, "Enter\n"); brcmf_dbg(TRACE, "Enter\n");
...@@ -3682,11 +3685,11 @@ void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus) ...@@ -3682,11 +3685,11 @@ void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus)
/* Clear any held glomming stuff */ /* Clear any held glomming stuff */
if (bus->glomd) if (bus->glomd)
brcmu_pkt_buf_free_skb(bus->glomd); brcmu_pkt_buf_free_skb(bus->glomd);
if (!skb_queue_empty(&bus->glom))
if (bus->glom) skb_queue_walk_safe(&bus->glom, cur, next) {
brcmu_pkt_buf_free_skb(bus->glom); skb_unlink(cur, &bus->glom);
brcmu_pkt_buf_free_skb(cur);
bus->glom = bus->glomd = NULL; }
/* Clear rx control and wake any waiters */ /* Clear rx control and wake any waiters */
bus->rxlen = 0; bus->rxlen = 0;
...@@ -4461,6 +4464,7 @@ void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype, ...@@ -4461,6 +4464,7 @@ void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype,
bus->sdiodev = sdiodev; bus->sdiodev = sdiodev;
sdiodev->bus = bus; sdiodev->bus = bus;
skb_queue_head_init(&bus->glom);
bus->txbound = BRCMF_TXBOUND; bus->txbound = BRCMF_TXBOUND;
bus->rxbound = BRCMF_RXBOUND; bus->rxbound = BRCMF_RXBOUND;
bus->txminmax = BRCMF_TXMINMAX; bus->txminmax = BRCMF_TXMINMAX;
......
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