Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 134133
b: refs/heads/master
c: b6ea035
h: refs/heads/master
i:
  134131: f22dcdc
v: v3
  • Loading branch information
Bob Copeland authored and John W. Linville committed Jan 29, 2009
1 parent db6c859 commit e5c6491
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 33 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 138ab2e44e99a9544aad60cf137b8ac1f54131c5
refs/heads/master: b6ea03562f04382776ad825624daefe27f5d3f9c
85 changes: 53 additions & 32 deletions trunk/drivers/net/wireless/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1096,44 +1096,54 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
* Buffers setup *
\***************/

static
struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
{
struct sk_buff *skb;
unsigned int off;

/*
* Allocate buffer with headroom_needed space for the
* fake physical layer header at the start.
*/
skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);

if (!skb) {
ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
sc->rxbufsize + sc->cachelsz - 1);
return NULL;
}
/*
* Cache-line-align. This is important (for the
* 5210 at least) as not doing so causes bogus data
* in rx'd frames.
*/
off = ((unsigned long)skb->data) % sc->cachelsz;
if (off != 0)
skb_reserve(skb, sc->cachelsz - off);

*skb_addr = pci_map_single(sc->pdev,
skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
if (unlikely(pci_dma_mapping_error(sc->pdev, *skb_addr))) {
ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
dev_kfree_skb(skb);
return NULL;
}
return skb;
}

static int
ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
{
struct ath5k_hw *ah = sc->ah;
struct sk_buff *skb = bf->skb;
struct ath5k_desc *ds;

if (likely(skb == NULL)) {
unsigned int off;

/*
* Allocate buffer with headroom_needed space for the
* fake physical layer header at the start.
*/
skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);
if (unlikely(skb == NULL)) {
ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
sc->rxbufsize + sc->cachelsz - 1);
if (!skb) {
skb = ath5k_rx_skb_alloc(sc, &bf->skbaddr);
if (!skb)
return -ENOMEM;
}
/*
* Cache-line-align. This is important (for the
* 5210 at least) as not doing so causes bogus data
* in rx'd frames.
*/
off = ((unsigned long)skb->data) % sc->cachelsz;
if (off != 0)
skb_reserve(skb, sc->cachelsz - off);

bf->skb = skb;
bf->skbaddr = pci_map_single(sc->pdev,
skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
if (unlikely(pci_dma_mapping_error(sc->pdev, bf->skbaddr))) {
ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
dev_kfree_skb(skb);
bf->skb = NULL;
return -ENOMEM;
}
}

/*
Expand Down Expand Up @@ -1662,7 +1672,8 @@ ath5k_tasklet_rx(unsigned long data)
{
struct ieee80211_rx_status rxs = {};
struct ath5k_rx_status rs = {};
struct sk_buff *skb;
struct sk_buff *skb, *next_skb;
dma_addr_t next_skb_addr;
struct ath5k_softc *sc = (void *)data;
struct ath5k_buf *bf, *bf_last;
struct ath5k_desc *ds;
Expand Down Expand Up @@ -1747,10 +1758,17 @@ ath5k_tasklet_rx(unsigned long data)
goto next;
}
accept:
next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr);

/*
* If we can't replace bf->skb with a new skb under memory
* pressure, just skip this packet
*/
if (!next_skb)
goto next;

pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
PCI_DMA_FROMDEVICE);
bf->skb = NULL;

skb_put(skb, rs.rs_datalen);

/* The MAC header is padded to have 32-bit boundary if the
Expand Down Expand Up @@ -1823,6 +1841,9 @@ ath5k_tasklet_rx(unsigned long data)
ath5k_check_ibss_tsf(sc, skb, &rxs);

__ieee80211_rx(sc->hw, skb, &rxs);

bf->skb = next_skb;
bf->skbaddr = next_skb_addr;
next:
list_move_tail(&bf->list, &sc->rxbuf);
} while (ath5k_rxbuf_setup(sc, bf) == 0);
Expand Down

0 comments on commit e5c6491

Please sign in to comment.