diff options
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 52 |
1 files changed, 19 insertions, 33 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 2c593570497..8e8975562ec 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -179,7 +179,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb, struct brcmf_pub *drvr = ifp->drvr; struct ethhdr *eh; - brcmf_dbg(TRACE, "Enter, idx=%d\n", ifp->bssidx); + brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx); /* Can the device send data? */ if (drvr->bus_if->state != BRCMF_BUS_DATA) { @@ -240,11 +240,15 @@ done: void brcmf_txflowblock_if(struct brcmf_if *ifp, enum brcmf_netif_stop_reason reason, bool state) { + unsigned long flags; + if (!ifp) return; brcmf_dbg(TRACE, "enter: idx=%d stop=0x%X reason=%d state=%d\n", ifp->bssidx, ifp->netif_stop, reason, state); + + spin_lock_irqsave(&ifp->netif_stop_lock, flags); if (state) { if (!ifp->netif_stop) netif_stop_queue(ifp->ndev); @@ -254,6 +258,7 @@ void brcmf_txflowblock_if(struct brcmf_if *ifp, if (!ifp->netif_stop) netif_wake_queue(ifp->ndev); } + spin_unlock_irqrestore(&ifp->netif_stop_lock, flags); } void brcmf_txflowblock(struct device *dev, bool state) @@ -264,15 +269,18 @@ void brcmf_txflowblock(struct device *dev, bool state) brcmf_dbg(TRACE, "Enter\n"); - for (i = 0; i < BRCMF_MAX_IFS; i++) - brcmf_txflowblock_if(drvr->iflist[i], - BRCMF_NETIF_STOP_REASON_BLOCK_BUS, state); + if (brcmf_fws_fc_active(drvr->fws)) { + brcmf_fws_bus_blocked(drvr, state); + } else { + for (i = 0; i < BRCMF_MAX_IFS; i++) + brcmf_txflowblock_if(drvr->iflist[i], + BRCMF_NETIF_STOP_REASON_BLOCK_BUS, + state); + } } void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) { - unsigned char *eth; - uint len; struct sk_buff *skb, *pnext; struct brcmf_if *ifp; struct brcmf_bus *bus_if = dev_get_drvdata(dev); @@ -280,7 +288,7 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) u8 ifidx; int ret; - brcmf_dbg(TRACE, "Enter\n"); + brcmf_dbg(DATA, "Enter\n"); skb_queue_walk_safe(skb_list, skb, pnext) { skb_unlink(skb, skb_list); @@ -296,33 +304,12 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) continue; } - /* Get the protocol, maintain skb around eth_type_trans() - * The main reason for this hack is for the limitation of - * Linux 2.4 where 'eth_type_trans' uses the - * 'net->hard_header_len' - * to perform skb_pull inside vs ETH_HLEN. Since to avoid - * coping of the packet coming from the network stack to add - * BDC, Hardware header etc, during network interface - * registration - * we set the 'net->hard_header_len' to ETH_HLEN + extra space - * required - * for BDC, Hardware header etc. and not just the ETH_HLEN - */ - eth = skb->data; - len = skb->len; - skb->dev = ifp->ndev; skb->protocol = eth_type_trans(skb, skb->dev); if (skb->pkt_type == PACKET_MULTICAST) ifp->stats.multicast++; - skb->data = eth; - skb->len = len; - - /* Strip header, count, deliver upward */ - skb_pull(skb, ETH_HLEN); - /* Process special event packets */ brcmf_fweh_process_skb(drvr, skb); @@ -338,10 +325,8 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) netif_rx(skb); else /* If the receive is not processed inside an ISR, - * the softirqd must be woken explicitly to service - * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled - * by netif_rx_ni(), but in earlier kernels, we need - * to do it manually. + * the softirqd must be woken explicitly to service the + * NET_RX_SOFTIRQ. This is handled by netif_rx_ni(). */ netif_rx_ni(skb); } @@ -630,7 +615,7 @@ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked) /* set appropriate operations */ ndev->netdev_ops = &brcmf_netdev_ops_pri; - ndev->hard_header_len = ETH_HLEN + drvr->hdrlen; + ndev->hard_header_len += drvr->hdrlen; ndev->ethtool_ops = &brcmf_ethtool_ops; drvr->rxsz = ndev->mtu + ndev->hard_header_len + @@ -779,6 +764,7 @@ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx, ifp->bssidx = bssidx; init_waitqueue_head(&ifp->pend_8021x_wait); + spin_lock_init(&ifp->netif_stop_lock); if (mac_addr != NULL) memcpy(ifp->mac_addr, mac_addr, ETH_ALEN); |