mirror of
https://github.com/torvalds/linux.git
synced 2024-11-15 08:31:55 +00:00
brcmfmac: determine alignment values during probe
The alignment values were being determined for each transmit and receive depending on platform data. Instead determine these once during the probe. Reviewed-by: Franky Lin <frankyl@broadcom.com> Reviewed-by: Hante Meuleman <meuleman@broadcom.com> Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
f931868d49
commit
e217d1c8bf
@ -462,6 +462,8 @@ struct brcmf_sdio {
|
|||||||
u8 tx_hdrlen; /* sdio bus header length for tx packet */
|
u8 tx_hdrlen; /* sdio bus header length for tx packet */
|
||||||
bool txglom; /* host tx glomming enable flag */
|
bool txglom; /* host tx glomming enable flag */
|
||||||
struct sk_buff *txglom_sgpad; /* scatter-gather padding buffer */
|
struct sk_buff *txglom_sgpad; /* scatter-gather padding buffer */
|
||||||
|
u16 head_align; /* buffer pointer alignment */
|
||||||
|
u16 sgentry_align; /* scatter-gather buffer alignment */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* clkstate */
|
/* clkstate */
|
||||||
@ -1313,7 +1315,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
|||||||
{
|
{
|
||||||
u16 dlen, totlen;
|
u16 dlen, totlen;
|
||||||
u8 *dptr, num = 0;
|
u8 *dptr, num = 0;
|
||||||
u32 align = 0;
|
|
||||||
u16 sublen;
|
u16 sublen;
|
||||||
struct sk_buff *pfirst, *pnext;
|
struct sk_buff *pfirst, *pnext;
|
||||||
|
|
||||||
@ -1328,11 +1329,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
|||||||
brcmf_dbg(SDIO, "start: glomd %p glom %p\n",
|
brcmf_dbg(SDIO, "start: glomd %p glom %p\n",
|
||||||
bus->glomd, skb_peek(&bus->glom));
|
bus->glomd, skb_peek(&bus->glom));
|
||||||
|
|
||||||
if (bus->sdiodev->pdata)
|
|
||||||
align = bus->sdiodev->pdata->sd_sgentry_align;
|
|
||||||
if (align < 4)
|
|
||||||
align = 4;
|
|
||||||
|
|
||||||
/* If there's a descriptor, generate the packet chain */
|
/* If there's a descriptor, generate the packet chain */
|
||||||
if (bus->glomd) {
|
if (bus->glomd) {
|
||||||
pfirst = pnext = NULL;
|
pfirst = pnext = NULL;
|
||||||
@ -1356,9 +1352,9 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
|||||||
pnext = NULL;
|
pnext = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (sublen % align) {
|
if (sublen % bus->sgentry_align) {
|
||||||
brcmf_err("sublen %d not multiple of %d\n",
|
brcmf_err("sublen %d not multiple of %d\n",
|
||||||
sublen, align);
|
sublen, bus->sgentry_align);
|
||||||
}
|
}
|
||||||
totlen += sublen;
|
totlen += sublen;
|
||||||
|
|
||||||
@ -1371,7 +1367,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate/chain packet for next subframe */
|
/* Allocate/chain packet for next subframe */
|
||||||
pnext = brcmu_pkt_buf_get_skb(sublen + align);
|
pnext = brcmu_pkt_buf_get_skb(sublen + bus->sgentry_align);
|
||||||
if (pnext == NULL) {
|
if (pnext == NULL) {
|
||||||
brcmf_err("bcm_pkt_buf_get_skb failed, num %d len %d\n",
|
brcmf_err("bcm_pkt_buf_get_skb failed, num %d len %d\n",
|
||||||
num, sublen);
|
num, sublen);
|
||||||
@ -1380,7 +1376,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq)
|
|||||||
skb_queue_tail(&bus->glom, pnext);
|
skb_queue_tail(&bus->glom, pnext);
|
||||||
|
|
||||||
/* Adhere to start alignment requirements */
|
/* Adhere to start alignment requirements */
|
||||||
pkt_align(pnext, sublen, align);
|
pkt_align(pnext, sublen, bus->sgentry_align);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If all allocations succeeded, save packet chain
|
/* If all allocations succeeded, save packet chain
|
||||||
@ -1908,18 +1904,13 @@ brcmf_sdbrcm_wait_event_wakeup(struct brcmf_sdio *bus)
|
|||||||
|
|
||||||
static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt)
|
static int brcmf_sdio_txpkt_hdalign(struct brcmf_sdio *bus, struct sk_buff *pkt)
|
||||||
{
|
{
|
||||||
u16 head_align, head_pad;
|
u16 head_pad;
|
||||||
u8 *dat_buf;
|
u8 *dat_buf;
|
||||||
|
|
||||||
/* SDIO ADMA requires at least 32 bit alignment */
|
|
||||||
head_align = 4;
|
|
||||||
if (bus->sdiodev->pdata && bus->sdiodev->pdata->sd_head_align > 4)
|
|
||||||
head_align = bus->sdiodev->pdata->sd_head_align;
|
|
||||||
|
|
||||||
dat_buf = (u8 *)(pkt->data);
|
dat_buf = (u8 *)(pkt->data);
|
||||||
|
|
||||||
/* Check head padding */
|
/* Check head padding */
|
||||||
head_pad = ((unsigned long)dat_buf % head_align);
|
head_pad = ((unsigned long)dat_buf % bus->head_align);
|
||||||
if (head_pad) {
|
if (head_pad) {
|
||||||
if (skb_headroom(pkt) < head_pad) {
|
if (skb_headroom(pkt) < head_pad) {
|
||||||
bus->sdiodev->bus_if->tx_realloc++;
|
bus->sdiodev->bus_if->tx_realloc++;
|
||||||
@ -1949,25 +1940,22 @@ static int brcmf_sdio_txpkt_prep_sg(struct brcmf_sdio *bus,
|
|||||||
{
|
{
|
||||||
struct brcmf_sdio_dev *sdiodev;
|
struct brcmf_sdio_dev *sdiodev;
|
||||||
struct sk_buff *pkt_pad;
|
struct sk_buff *pkt_pad;
|
||||||
u16 tail_pad, tail_chop, sg_align, chain_pad;
|
u16 tail_pad, tail_chop, chain_pad;
|
||||||
unsigned int blksize;
|
unsigned int blksize;
|
||||||
bool lastfrm;
|
bool lastfrm;
|
||||||
int ntail, ret;
|
int ntail, ret;
|
||||||
|
|
||||||
sdiodev = bus->sdiodev;
|
sdiodev = bus->sdiodev;
|
||||||
blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize;
|
blksize = sdiodev->func[SDIO_FUNC_2]->cur_blksize;
|
||||||
sg_align = 4;
|
|
||||||
if (sdiodev->pdata && sdiodev->pdata->sd_sgentry_align > 4)
|
|
||||||
sg_align = sdiodev->pdata->sd_sgentry_align;
|
|
||||||
/* sg entry alignment should be a divisor of block size */
|
/* sg entry alignment should be a divisor of block size */
|
||||||
WARN_ON(blksize % sg_align);
|
WARN_ON(blksize % bus->sgentry_align);
|
||||||
|
|
||||||
/* Check tail padding */
|
/* Check tail padding */
|
||||||
lastfrm = skb_queue_is_last(pktq, pkt);
|
lastfrm = skb_queue_is_last(pktq, pkt);
|
||||||
tail_pad = 0;
|
tail_pad = 0;
|
||||||
tail_chop = pkt->len % sg_align;
|
tail_chop = pkt->len % bus->sgentry_align;
|
||||||
if (tail_chop)
|
if (tail_chop)
|
||||||
tail_pad = sg_align - tail_chop;
|
tail_pad = bus->sgentry_align - tail_chop;
|
||||||
chain_pad = (total_len + tail_pad) % blksize;
|
chain_pad = (total_len + tail_pad) % blksize;
|
||||||
if (lastfrm && chain_pad)
|
if (lastfrm && chain_pad)
|
||||||
tail_pad += blksize - chain_pad;
|
tail_pad += blksize - chain_pad;
|
||||||
@ -4099,6 +4087,18 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev)
|
|||||||
bus->txminmax = BRCMF_TXMINMAX;
|
bus->txminmax = BRCMF_TXMINMAX;
|
||||||
bus->tx_seq = SDPCM_SEQ_WRAP - 1;
|
bus->tx_seq = SDPCM_SEQ_WRAP - 1;
|
||||||
|
|
||||||
|
/* platform specific configuration:
|
||||||
|
* alignments must be at least 4 bytes for ADMA
|
||||||
|
*/
|
||||||
|
bus->head_align = ALIGNMENT;
|
||||||
|
bus->sgentry_align = ALIGNMENT;
|
||||||
|
if (sdiodev->pdata) {
|
||||||
|
if (sdiodev->pdata->sd_head_align > ALIGNMENT)
|
||||||
|
bus->head_align = sdiodev->pdata->sd_head_align;
|
||||||
|
if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT)
|
||||||
|
bus->sgentry_align = sdiodev->pdata->sd_sgentry_align;
|
||||||
|
}
|
||||||
|
|
||||||
INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
|
INIT_WORK(&bus->datawork, brcmf_sdio_dataworker);
|
||||||
bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq");
|
bus->brcmf_wq = create_singlethread_workqueue("brcmf_wq");
|
||||||
if (bus->brcmf_wq == NULL) {
|
if (bus->brcmf_wq == NULL) {
|
||||||
|
Loading…
Reference in New Issue
Block a user