/* 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) &&
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.
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);
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,
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. */
+}