Commits

Franky Lin  committed 5c80606

net: wireless: bcmdhd: Fix dhd_txcomplete() dead lock

For TX packet dhd_prot_hdrpull does nothing other than pull the prot
header from the skb. Use a NULL ifdix pointer to indicate a handling
of tx packet and skip most of the header parsing routine - we don't
need it for TX packet and we can skip extra unnecessary PROP_TXSTATUS
parsing. It will resloved dead lock case because we just exit
dhd_prot_hdrpull for TX path.

Change-Id: Ic41e1c549036baeb0fabfb0be4b8331a4bf60682
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>

  • Participants
  • Parent commits 9b29a6d
  • Branches android-3.4

Comments (0)

Files changed (2)

File drivers/net/wireless/bcmdhd/dhd_cdc.c

 #ifdef BDC
 	struct bdc_header *h;
 #endif
+	uint8 data_offset = 0;
 
 	DHD_TRACE(("%s: Enter\n", __FUNCTION__));
 
 
 	h = (struct bdc_header *)PKTDATA(dhd->osh, pktbuf);
 
+#if defined(NDIS630)
+	h->dataOffset = 0;
+#endif
+
+	if (!ifidx) {
+		/* for tx packet, skip the analysis and just exit */
+		data_offset = h->dataOffset;
+		PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN);
+		goto exit;
+	}
+
 	if ((*ifidx = BDC_GET_IF_IDX(h)) >= DHD_MAX_IFS) {
 		DHD_ERROR(("%s: rx data ifnum out of range (%d)\n",
 		           __FUNCTION__, *ifidx));
 		return BCME_ERROR;
 	}
 
-#if defined(NDIS630)
-	h->dataOffset = 0;
-#endif
 	if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) {
 		DHD_ERROR(("%s: non-BDC packet received, flags = 0x%x\n",
 		           dhd_ifname(dhd, *ifidx), h->flags));
 	}
 
 	PKTSETPRIO(pktbuf, (h->priority & BDC_PRIORITY_MASK));
+	data_offset = h->dataOffset;
 	PKTPULL(dhd->osh, pktbuf, BDC_HEADER_LEN);
 #endif /* BDC */
 
 		dhd_os_wlfc_unblock(dhd);
 	}
 #endif /* PROP_TXSTATUS */
+exit:
 #if !defined(NDIS630)
 		PKTPULL(dhd->osh, pktbuf, (h->dataOffset << 2));
 #endif

File drivers/net/wireless/bcmdhd/dhd_linux.c

 void
 dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success)
 {
-	uint ifidx;
 	dhd_info_t *dhd = (dhd_info_t *)(dhdp->info);
 	struct ether_header *eh;
 	uint16 type;
 	uint len;
 #endif
 
-	dhd_prot_hdrpull(dhdp, &ifidx, txp, NULL, NULL);
+	dhd_prot_hdrpull(dhdp, NULL, txp, NULL, NULL);
 
 	eh = (struct ether_header *)PKTDATA(dhdp->osh, txp);
 	type  = ntoh16(eh->ether_type);