summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/bcmdhd/dhd_cdc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/bcmdhd/dhd_cdc.c')
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_cdc.c37
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd_cdc.c b/drivers/net/wireless/bcmdhd/dhd_cdc.c
index 33ebeb559059..820bbade720c 100644
--- a/drivers/net/wireless/bcmdhd/dhd_cdc.c
+++ b/drivers/net/wireless/bcmdhd/dhd_cdc.c
@@ -21,7 +21,7 @@
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
*
- * $Id: dhd_cdc.c 353370 2012-08-27 09:10:22Z $
+ * $Id: dhd_cdc.c 355825 2012-09-10 03:22:40Z $
*
* BDC is like CDC, except it includes a header for data packets to convey
* packet priority over the bus, and flags (e.g. to indicate checksum status
@@ -854,6 +854,12 @@ _dhd_wlfc_pullheader(athost_wl_status_info_t* ctx, void* pktbuf)
/* pull BDC header */
PKTPULL(ctx->osh, pktbuf, BDC_HEADER_LEN);
+
+ if (PKTLEN(ctx->osh, pktbuf) < (h->dataOffset << 2)) {
+ WLFC_DBGMESG(("%s: rx data too short (%d < %d)\n", __FUNCTION__,
+ PKTLEN(ctx->osh, pktbuf), (h->dataOffset << 2)));
+ return BCME_ERROR;
+ }
/* pull wl-header */
PKTPULL(ctx->osh, pktbuf, (h->dataOffset << 2));
return BCME_OK;
@@ -916,7 +922,15 @@ _dhd_wlfc_rollback_packet_toq(athost_wl_status_info_t* ctx,
}
else {
/* remove header first */
- _dhd_wlfc_pullheader(ctx, p);
+ rc = _dhd_wlfc_pullheader(ctx, p);
+ if (rc != BCME_OK) {
+ WLFC_DBGMESG(("Error: %s():%d\n", __FUNCTION__, __LINE__));
+ /* free the hanger slot */
+ dhd_wlfc_hanger_poppkt(ctx->hanger, hslot, &pktout, 1);
+ PKTFREE(ctx->osh, p, TRUE);
+ rc = BCME_ERROR;
+ return rc;
+ }
if (pkt_type == eWLFC_PKTTYPE_DELAYED) {
/* delay-q packets are going to delay-q */
@@ -1166,16 +1180,17 @@ _dhd_wlfc_pretx_pktprocess(athost_wl_status_info_t* ctx,
int gen;
/* remove old header */
- _dhd_wlfc_pullheader(ctx, p);
-
- hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
- dhd_wlfc_hanger_get_genbit(ctx->hanger, p, hslot, &gen);
+ rc = _dhd_wlfc_pullheader(ctx, p);
+ if (rc == BCME_OK) {
+ hslot = WLFC_PKTID_HSLOT_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
+ dhd_wlfc_hanger_get_genbit(ctx->hanger, p, hslot, &gen);
- WLFC_PKTFLAG_SET_GENERATION(htod, gen);
- free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
- /* push new header */
- _dhd_wlfc_pushheader(ctx, p, send_tim_update,
- entry->traffic_lastreported_bmp, entry->mac_handle, htod);
+ WLFC_PKTFLAG_SET_GENERATION(htod, gen);
+ free_ctr = WLFC_PKTID_FREERUNCTR_GET(DHD_PKTTAG_H2DTAG(PKTTAG(p)));
+ /* push new header */
+ _dhd_wlfc_pushheader(ctx, p, send_tim_update,
+ entry->traffic_lastreported_bmp, entry->mac_handle, htod);
+ }
}
*slot = hslot;
return rc;