X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/d80cb30469c1822c8abc8c4693188dd14180771a..c49865f04ebeb8431bd4881c8f773137e84ef13d:/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_xmit.c diff --git a/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_xmit.c b/package/bcm43xx-mac80211/src/bcm43xx/bcm43xx_xmit.c index 0b0dad4ce..a15196b1f 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, @@ -601,3 +622,51 @@ void bcm43xx_handle_hwtxstatus(struct bcm43xx_wldev *dev, bcm43xx_handle_txstatus(dev, &status); } + +/* Stop any TX operation on the device (suspend the hardware queues) */ +void bcm43xx_tx_suspend(struct bcm43xx_wldev *dev) +{ + if (bcm43xx_using_pio(dev)) + bcm43xx_pio_freeze_txqueues(dev); + else + bcm43xx_dma_tx_suspend(dev); +} + +/* Resume any TX operation on the device (resume the hardware queues) */ +void bcm43xx_tx_resume(struct bcm43xx_wldev *dev) +{ + if (bcm43xx_using_pio(dev)) + bcm43xx_pio_thaw_txqueues(dev); + else + bcm43xx_dma_tx_resume(dev); +} + +#if 0 +static void upload_qos_parms(struct bcm43xx_wldev *dev, + const u16 *parms, + u16 offset) +{ + int i; + + for (i = 0; i < BCM43xx_NR_QOSPARMS; i++) { + bcm43xx_shm_write16(dev, BCM43xx_SHM_SHARED, + offset + (i * 2), parms[i]); + } +} +#endif + +/* Initialize the QoS parameters */ +void bcm43xx_qos_init(struct bcm43xx_wldev *dev) +{ + /* FIXME: This function must probably be called from the mac80211 + * config callback. */ +return; + + bcm43xx_hf_write(dev, bcm43xx_hf_read(dev) | BCM43xx_HF_EDCF); + //FIXME kill magic + bcm43xx_write16(dev, 0x688, + bcm43xx_read16(dev, 0x688) | 0x4); + + + /*TODO: We might need some stack support here to get the values. */ +}