zbuf_t* zfGetAmsduSubFrame(zdev_t* dev, zbuf_t* buf, u16_t* offset) { u16_t subframeLen; u16_t amsduLen = zfwBufGetSize(dev, buf); zbuf_t* newBuf; ZM_PERFORMANCE_RX_AMSDU(dev, buf, amsduLen); /* Verify A-MSDU length */ if (amsduLen < (*offset + 14)) { return NULL; } /* Locate A-MSDU subframe by offset and verify subframe length */ subframeLen = (zmw_buf_readb(dev, buf, *offset + 12) << 8) + zmw_buf_readb(dev, buf, *offset + 13); if (subframeLen == 0) { return NULL; } /* Verify A-MSDU subframe length */ if ((*offset+14+subframeLen) <= amsduLen) { /* Allocate a new buffer */ if ((newBuf = zfwBufAllocate(dev, 24+2+subframeLen)) != NULL) { #ifdef ZM_ENABLE_NATIVE_WIFI /* Copy and convert subframe to wlan frame format */ /* SHALL NOT INCLUDE QOS and AMSDU header. Ray 20070807 For Vista */ zfRxBufferCopy(dev, newBuf, buf, 0, 0, 24); zfRxBufferCopy(dev, newBuf, buf, 24, *offset+14, subframeLen); zfwBufSetSize(dev, newBuf, 24+subframeLen); #else /* Copy subframe to new buffer */ zfRxBufferCopy(dev, newBuf, buf, 0, *offset, 14+subframeLen); zfwBufSetSize(dev, newBuf, 14+subframeLen); #endif /* Update offset */ *offset += (((14+subframeLen)+3) & 0xfffc); /* Return buffer pointer */ return newBuf; } } return NULL; }
zbuf_t *zfGetAmsduSubFrame(zdev_t *dev, zbuf_t *buf, u16_t *offset) { u16_t subframeLen; u16_t amsduLen = zfwBufGetSize(dev, buf); zbuf_t *newBuf; ZM_PERFORMANCE_RX_AMSDU(dev, buf, amsduLen); if (amsduLen < (*offset + 14)) return NULL; subframeLen = (zmw_buf_readb(dev, buf, *offset + 12) << 8) + zmw_buf_readb(dev, buf, *offset + 13); if (subframeLen == 0) return NULL; if ((*offset+14+subframeLen) <= amsduLen) { newBuf = zfwBufAllocate(dev, 24+2+subframeLen); if (newBuf != NULL) { #ifdef ZM_ENABLE_NATIVE_WIFI zfRxBufferCopy(dev, newBuf, buf, 0, 0, 24); zfRxBufferCopy(dev, newBuf, buf, 24, *offset+14, subframeLen); zfwBufSetSize(dev, newBuf, 24+subframeLen); #else zfRxBufferCopy(dev, newBuf, buf, 0, *offset, 14+subframeLen); zfwBufSetSize(dev, newBuf, 14+subframeLen); #endif *offset += (((14+subframeLen)+3) & 0xfffc); return newBuf; } } return NULL; }