diff options
Diffstat (limited to 'package/bcm43xx-mac80211')
5 files changed, 75 insertions, 57 deletions
diff --git a/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_debugfs.c b/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_debugfs.c index 3ea9d08a27..e623cfd05e 100644 --- a/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_debugfs.c +++ b/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_debugfs.c @@ -437,6 +437,7 @@ static void bcm43xx_add_dynamic_debug(struct bcm43xx_wldev *dev) add_dyn_dbg("debug_xmitpower", BCM43xx_DBG_XMITPOWER, 0); add_dyn_dbg("debug_dmaoverflow", BCM43xx_DBG_DMAOVERFLOW, 0); + add_dyn_dbg("debug_dmaverbose", BCM43xx_DBG_DMAVERBOSE, 0); add_dyn_dbg("debug_pwork_fast", BCM43xx_DBG_PWORK_FAST, 0); add_dyn_dbg("debug_pwork_stop", BCM43xx_DBG_PWORK_STOP, 0); diff --git a/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_debugfs.h b/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_debugfs.h index 892299d550..bf31754b0c 100644 --- a/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_debugfs.h +++ b/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_debugfs.h @@ -7,6 +7,7 @@ struct bcm43xx_txstatus; enum bcm43xx_dyndbg { /* Dynamic debugging features */ BCM43xx_DBG_XMITPOWER, BCM43xx_DBG_DMAOVERFLOW, + BCM43xx_DBG_DMAVERBOSE, BCM43xx_DBG_PWORK_FAST, BCM43xx_DBG_PWORK_STOP, __BCM43xx_NR_DYNDBG, diff --git a/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_dma.c b/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_dma.c index c8b5cddc3b..814e1ad075 100644 --- a/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_dma.c +++ b/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_dma.c @@ -259,6 +259,28 @@ static inline int prev_slot(struct bcm43xx_dmaring *ring, int slot) return slot - 1; } +#ifdef CONFIG_BCM43XX_MAC80211_DEBUG +static void update_max_used_slots(struct bcm43xx_dmaring *ring, + int current_used_slots) +{ + if (current_used_slots <= ring->max_used_slots) + return; + ring->max_used_slots = current_used_slots; + if (bcm43xx_debug(ring->dev, BCM43xx_DBG_DMAVERBOSE)) { + dprintk(KERN_DEBUG PFX + "max_used_slots increased to %d on %s ring %d\n", + ring->max_used_slots, + ring->tx ? "TX" : "RX", + ring->index); + } +} +#else +static inline +void update_max_used_slots(struct bcm43xx_dmaring *ring, + int current_used_slots) +{ } +#endif /* DEBUG */ + /* Request a slot for usage. */ static inline int request_slot(struct bcm43xx_dmaring *ring) @@ -273,23 +295,11 @@ int request_slot(struct bcm43xx_dmaring *ring) ring->current_slot = slot; ring->used_slots++; -#ifdef CONFIG_BCM43XX_MAC80211_DEBUG - if (ring->used_slots > ring->max_used_slots) - ring->max_used_slots = ring->used_slots; -#endif /* CONFIG_BCM43XX_MAC80211_DEBUG*/ + update_max_used_slots(ring, ring->used_slots); return slot; } -/* Return a slot to the free slots. */ -static inline -void return_slot(struct bcm43xx_dmaring *ring, int slot) -{ - assert(ring->tx); - - ring->used_slots--; -} - /* Mac80211-queue to bcm43xx-ring mapping */ static struct bcm43xx_dmaring * priority_to_txring(struct bcm43xx_wldev *dev, int queue_priority) @@ -1254,6 +1264,10 @@ int bcm43xx_dma_tx(struct bcm43xx_wldev *dev, /* This TX ring is full. */ ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring)); ring->stopped = 1; + if (bcm43xx_debug(dev, BCM43xx_DBG_DMAVERBOSE)) { + dprintk(KERN_DEBUG PFX "Stopped TX ring %d\n", + ring->index); + } } out_unlock: spin_unlock_irqrestore(&ring->lock, flags); @@ -1305,10 +1319,9 @@ void bcm43xx_dma_handle_txstatus(struct bcm43xx_wldev *dev, */ assert(meta->skb == NULL); } - /* Everything belonging to the slot is unmapped - * and freed, so we can return it. - */ - return_slot(ring, slot); + + /* Everything unmapped and free'd. So it's not used anymore. */ + ring->used_slots--; if (meta->is_last_fragment) break; @@ -1319,6 +1332,10 @@ void bcm43xx_dma_handle_txstatus(struct bcm43xx_wldev *dev, assert(free_slots(ring) >= SLOTS_PER_PACKET); ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring)); ring->stopped = 0; + if (bcm43xx_debug(dev, BCM43xx_DBG_DMAVERBOSE)) { + dprintk(KERN_DEBUG PFX "Woke up TX ring %d\n", + ring->index); + } } spin_unlock(&ring->lock); @@ -1445,9 +1462,7 @@ void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring) { const struct bcm43xx_dma_ops *ops = ring->ops; int slot, current_slot; -#ifdef CONFIG_BCM43XX_MAC80211_DEBUG int used_slots = 0; -#endif assert(!ring->tx); current_slot = ops->get_current_rxslot(ring); @@ -1456,10 +1471,7 @@ void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring) slot = ring->current_slot; for ( ; slot != current_slot; slot = next_slot(ring, slot)) { dma_rx(ring, &slot); -#ifdef CONFIG_BCM43XX_MAC80211_DEBUG - if (++used_slots > ring->max_used_slots) - ring->max_used_slots = used_slots; -#endif + update_max_used_slots(ring, ++used_slots); } ops->set_current_rxslot(ring, slot); ring->current_slot = slot; diff --git a/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_main.c b/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_main.c index 5b7ff9293d..e13c1168ef 100644 --- a/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_main.c +++ b/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_main.c @@ -1080,21 +1080,13 @@ static void bcm43xx_write_probe_resp_plcp(struct bcm43xx_wldev *dev, { struct bcm43xx_plcp_hdr4 plcp; u32 tmp; - u16 packet_time; + __le16 dur; plcp.data = 0; bcm43xx_generate_plcp_hdr(&plcp, size + FCS_LEN, rate); - /* - * 144 + 48 + 10 = preamble + PLCP + SIFS, - * taken from mac80211 timings calculation. - * - * FIXME: long preamble assumed! - * - */ - packet_time = 202 + (size + FCS_LEN) * 16 / rate; - if ((size + FCS_LEN) * 16 % rate >= rate / 2) - ++packet_time; - + dur = ieee80211_generic_frame_duration(dev->wl->hw, + size, + BCM43xx_RATE_TO_BASE100KBPS(rate)); /* Write PLCP in two parts and timing for packet transfer */ tmp = le32_to_cpu(plcp.data); bcm43xx_shm_write16(dev, BCM43xx_SHM_SHARED, shm_offset, @@ -1102,7 +1094,7 @@ static void bcm43xx_write_probe_resp_plcp(struct bcm43xx_wldev *dev, bcm43xx_shm_write16(dev, BCM43xx_SHM_SHARED, shm_offset + 2, tmp >> 16); bcm43xx_shm_write16(dev, BCM43xx_SHM_SHARED, shm_offset + 6, - packet_time); + le16_to_cpu(dur)); } /* Instead of using custom probe response template, this function @@ -1116,7 +1108,9 @@ static u8 * bcm43xx_generate_probe_resp(struct bcm43xx_wldev *dev, { const u8 *src_data; u8 *dest_data; - u16 src_size, elem_size, src_pos, dest_pos, tmp; + u16 src_size, elem_size, src_pos, dest_pos; + __le16 dur; + struct ieee80211_hdr *hdr; assert(dev->cached_beacon); src_size = dev->cached_beacon->len; @@ -1146,26 +1140,15 @@ static u8 * bcm43xx_generate_probe_resp(struct bcm43xx_wldev *dev, } } *dest_size = dest_pos; + hdr = (struct ieee80211_hdr *)dest_data; /* Set the frame control. */ - dest_data[0] = (IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_PROBE_RESP); - dest_data[1] = 0; - - /* Set the duration field. - * - * 144 + 48 + 10 = preamble + PLCP + SIFS, - * taken from mac80211 timings calculation. - * - * FIXME: long preamble assumed! - * - */ - tmp = 202 + (14 + FCS_LEN) * 16 / rate; - if ((14 + FCS_LEN) * 16 % rate >= rate / 2) - ++tmp; - - dest_data[2] = tmp & 0xFF; - dest_data[3] = (tmp >> 8) & 0xFF; + hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | + IEEE80211_STYPE_PROBE_RESP); + dur = ieee80211_generic_frame_duration(dev->wl->hw, + *dest_size, + BCM43xx_RATE_TO_BASE100KBPS(rate)); + hdr->duration_id = dur; return dest_data; } diff --git a/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_xmit.c b/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_xmit.c index 8ad39386cf..a15196b1ff 100644 --- a/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_xmit.c +++ b/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_xmit.c @@ -466,12 +466,19 @@ void bcm43xx_rx(struct bcm43xx_wldev *dev, /* Skip PLCP and padding */ padding = (macstat & BCM43xx_RX_MAC_PADDING) ? 2 : 0; + if (unlikely(skb->len < (sizeof(struct bcm43xx_plcp_hdr6) + padding))) { + dprintkl(KERN_DEBUG PFX "RX: Packet size underrun (1)\n"); + goto drop; + } plcp = (struct bcm43xx_plcp_hdr6 *)(skb->data + padding); skb_pull(skb, sizeof(struct bcm43xx_plcp_hdr6) + padding); /* The skb contains the Wireless Header + payload data now */ + if (unlikely(skb->len < (2+2+6/*minimum hdr*/ + FCS_LEN))) { + dprintkl(KERN_DEBUG PFX "RX: Packet size underrun (2)\n"); + goto drop; + } wlhdr = (struct ieee80211_hdr *)(skb->data); fctl = le16_to_cpu(wlhdr->frame_control); - skb_trim(skb, skb->len - FCS_LEN); if ((macstat & BCM43xx_RX_MAC_DEC) && @@ -496,6 +503,11 @@ void bcm43xx_rx(struct bcm43xx_wldev *dev, wlhdr->frame_control = cpu_to_le16(fctl); wlhdr_len = ieee80211_get_hdrlen(fctl); + if (unlikely(skb->len < (wlhdr_len + 3))) { + dprintkl(KERN_DEBUG PFX + "RX: Packet size underrun (3)\n"); + goto drop; + } if (skb->data[wlhdr_len + 3] & (1 << 5)) { /* The Ext-IV Bit is set in the "KeyID" * octet of the IV. @@ -506,7 +518,11 @@ void bcm43xx_rx(struct bcm43xx_wldev *dev, iv_len = 4; icv_len = 4; } - + if (unlikely(skb->len < (wlhdr_len + iv_len + icv_len))) { + dprintkl(KERN_DEBUG PFX + "RX: Packet size underrun (4)\n"); + goto drop; + } /* Remove the IV */ memmove(skb->data + iv_len, skb->data, wlhdr_len); skb_pull(skb, iv_len); @@ -553,6 +569,11 @@ void bcm43xx_rx(struct bcm43xx_wldev *dev, dev->stats.last_rx = jiffies; ieee80211_rx_irqsafe(dev->wl->hw, skb, &status); + + return; +drop: + dprintkl(KERN_DEBUG PFX "RX: Packet dropped\n"); + dev_kfree_skb_any(skb); } void bcm43xx_handle_txstatus(struct bcm43xx_wldev *dev, |