mwl8k: dma header manipulations can't fail
[GitHub/MotorolaMobilityLLC/kernel-slsi.git] / drivers / net / wireless / mwl8k.c
index 301d2a20d42b40bbee25dbad53f6264e3cb9b586..5aa80420c0d134962a8bb5059e7938d1767a4220 100644 (file)
@@ -111,17 +111,6 @@ struct mwl8k_rx_queue {
        struct sk_buff **rx_skb;
 };
 
-struct mwl8k_skb {
-       /*
-        * The DMA engine requires a modification to the payload.
-        * If the skbuff is shared/cloned, it needs to be unshared.
-        * This method is used to ensure the stack always gets back
-        * the skbuff it sent for transmission.
-        */
-       struct sk_buff *clone;
-       struct sk_buff *skb;
-};
-
 struct mwl8k_tx_queue {
        /* hw transmits here */
        int tx_head;
@@ -132,7 +121,7 @@ struct mwl8k_tx_queue {
        struct ieee80211_tx_queue_stats tx_stats;
        struct mwl8k_tx_desc *tx_desc_area;
        dma_addr_t tx_desc_dma;
-       struct mwl8k_skb *tx_skb;
+       struct sk_buff **tx_skb;
 };
 
 /* Pointers to the firmware data and meta information about it.  */
@@ -714,12 +703,11 @@ struct mwl8k_dma_data {
 } __attribute__((packed));
 
 /* Routines to add/remove DMA header from skb.  */
-static inline int mwl8k_remove_dma_header(struct sk_buff *skb)
+static inline void mwl8k_remove_dma_header(struct sk_buff *skb)
 {
-       struct mwl8k_dma_data *tr = (struct mwl8k_dma_data *)(skb->data);
+       struct mwl8k_dma_data *tr = (struct mwl8k_dma_data *)skb->data;
        void *dst, *src = &tr->wh;
-       __le16 fc = tr->wh.frame_control;
-       int hdrlen = ieee80211_hdrlen(fc);
+       int hdrlen = ieee80211_hdrlen(tr->wh.frame_control);
        u16 space = sizeof(struct mwl8k_dma_data) - hdrlen;
 
        dst = (void *)tr + space;
@@ -727,11 +715,9 @@ static inline int mwl8k_remove_dma_header(struct sk_buff *skb)
                memmove(dst, src, hdrlen);
                skb_pull(skb, space);
        }
-
-       return 0;
 }
 
-static inline struct sk_buff *mwl8k_add_dma_header(struct sk_buff *skb)
+static inline void mwl8k_add_dma_header(struct sk_buff *skb)
 {
        struct ieee80211_hdr *wh;
        u32 hdrlen, pktlen;
@@ -763,8 +749,6 @@ static inline struct sk_buff *mwl8k_add_dma_header(struct sk_buff *skb)
         * This includes all crypto material including the MIC.
         */
        tr->fwlen = cpu_to_le16(pktlen - hdrlen);
-
-       return skb;
 }
 
 
@@ -967,10 +951,7 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
                                        MWL8K_RX_MAXSZ, PCI_DMA_FROMDEVICE);
 
                skb_put(skb, le16_to_cpu(rx_desc->pkt_len));
-               if (mwl8k_remove_dma_header(skb)) {
-                       dev_kfree_skb(skb);
-                       continue;
-               }
+               mwl8k_remove_dma_header(skb);
 
                wh = (struct ieee80211_hdr *)skb->data;
 
@@ -1224,7 +1205,6 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
 
        while (txq->tx_stats.len > 0) {
                int tx;
-               int rc;
                struct mwl8k_tx_desc *tx_desc;
                unsigned long addr;
                int size;
@@ -1232,7 +1212,6 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
                struct ieee80211_tx_info *info;
                u32 status;
 
-               rc = 0;
                tx = txq->tx_head;
                tx_desc = txq->tx_desc_area + tx;
 
@@ -1252,40 +1231,18 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
 
                addr = le32_to_cpu(tx_desc->pkt_phys_addr);
                size = le16_to_cpu(tx_desc->pkt_len);
-               skb = txq->tx_skb[tx].skb;
-               txq->tx_skb[tx].skb = NULL;
+               skb = txq->tx_skb[tx];
+               txq->tx_skb[tx] = NULL;
 
                BUG_ON(skb == NULL);
                pci_unmap_single(priv->pdev, addr, size, PCI_DMA_TODEVICE);
 
-               rc = mwl8k_remove_dma_header(skb);
+               mwl8k_remove_dma_header(skb);
 
                /* Mark descriptor as unused */
                tx_desc->pkt_phys_addr = 0;
                tx_desc->pkt_len = 0;
 
-               if (txq->tx_skb[tx].clone) {
-                       /* Replace with original skb
-                        * before returning to stack
-                        * as buffer has been cloned
-                        */
-                       dev_kfree_skb(skb);
-                       skb = txq->tx_skb[tx].clone;
-                       txq->tx_skb[tx].clone = NULL;
-               }
-
-               if (rc) {
-                       /* Something has gone wrong here.
-                        * Failed to remove DMA header.
-                        * Print error message and drop packet.
-                        */
-                       printk(KERN_ERR "%s: Error removing DMA header from "
-                                       "tx skb 0x%p.\n", priv->name, skb);
-
-                       dev_kfree_skb(skb);
-                       continue;
-               }
-
                info = IEEE80211_SKB_CB(skb);
                ieee80211_tx_info_clear_status(info);
                if (MWL8K_TXD_SUCCESS(status))
@@ -1327,7 +1284,6 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
        struct mwl8k_tx_desc *tx;
        struct mwl8k_dma_data *tr;
        struct mwl8k_vif *mwl8k_vif;
-       struct sk_buff *org_skb = skb;
        dma_addr_t dma;
        u16 qos = 0;
        bool qosframe = false, ampduframe = false;
@@ -1338,21 +1294,12 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
        txq = priv->txq + index;
        tx = txq->tx_desc_area + txq->tx_tail;
 
-       BUG_ON(txq->tx_skb[txq->tx_tail].skb != NULL);
+       BUG_ON(txq->tx_skb[txq->tx_tail] != NULL);
 
        /*
-        * Append HW DMA header to start of packet.  Drop packet if
-        * there is not enough space or a failure to unshare/unclone
-        * the skb.
+        * Append HW DMA header to start of packet.
         */
-       skb = mwl8k_add_dma_header(skb);
-
-       if (skb == NULL) {
-               printk(KERN_DEBUG "%s: failed to prepend HW DMA "
-                       "header, dropping TX frame.\n", priv->name);
-               dev_kfree_skb(org_skb);
-               return NETDEV_TX_OK;
-       }
+       mwl8k_add_dma_header(skb);
 
        tx_info = IEEE80211_SKB_CB(skb);
        mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
@@ -1380,8 +1327,6 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
                printk(KERN_DEBUG "%s: failed to dma map skb, "
                        "dropping TX frame.\n", priv->name);
 
-               if (org_skb != NULL)
-                       dev_kfree_skb(org_skb);
                if (skb != NULL)
                        dev_kfree_skb(skb);
                return NETDEV_TX_OK;
@@ -1437,9 +1382,7 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
        tx->pkt_phys_addr = cpu_to_le32(dma);
        tx->pkt_len = cpu_to_le16(skb->len);
 
-       txq->tx_skb[txq->tx_tail].skb = skb;
-       txq->tx_skb[txq->tx_tail].clone =
-               skb == org_skb ? NULL : org_skb;
+       txq->tx_skb[txq->tx_tail] = skb;
 
        spin_lock_bh(&priv->tx_lock);