Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / drivers / staging / vt6655 / device_main.c
index 6b2f813..ecd7c0f 100644 (file)
@@ -912,7 +912,11 @@ static int vnt_int_report_rate(struct vnt_private *priv,
 
        if (!(tsr1 & TSR1_TERR)) {
                info->status.rates[0].idx = idx;
-               info->flags |= IEEE80211_TX_STAT_ACK;
+
+               if (info->flags & IEEE80211_TX_CTL_NO_ACK)
+                       info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
+               else
+                       info->flags |= IEEE80211_TX_STAT_ACK;
        }
 
        return 0;
@@ -937,9 +941,6 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx)
                /* Only the status of first TD in the chain is correct */
                if (pTD->m_td1TD1.byTCR & TCR_STP) {
                        if ((pTD->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB) != 0) {
-
-                               vnt_int_report_rate(pDevice, pTD->pTDInfo, byTsr0, byTsr1);
-
                                if (!(byTsr1 & TSR1_TERR)) {
                                        if (byTsr0 != 0) {
                                                pr_debug(" Tx[%d] OK but has error. tsr1[%02X] tsr0[%02X]\n",
@@ -958,6 +959,9 @@ static int device_tx_srv(struct vnt_private *pDevice, unsigned int uIdx)
                                                 (int)uIdx, byTsr1, byTsr0);
                                }
                        }
+
+                       vnt_int_report_rate(pDevice, pTD->pTDInfo, byTsr0, byTsr1);
+
                        device_free_tx_buf(pDevice, pTD);
                        pDevice->iTDUsed[uIdx]--;
                }
@@ -989,10 +993,8 @@ static void device_free_tx_buf(struct vnt_private *pDevice, PSTxDesc pDesc)
                                 skb->len, DMA_TO_DEVICE);
        }
 
-       if (pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)
+       if (skb)
                ieee80211_tx_status_irqsafe(pDevice->hw, skb);
-       else
-               dev_kfree_skb_irq(skb);
 
        pTDInfo->skb_dma = 0;
        pTDInfo->skb = NULL;
@@ -1204,14 +1206,6 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
        if (dma_idx == TYPE_AC0DMA)
                head_td->pTDInfo->byFlags = TD_FLAGS_NETIF_SKB;
 
-       priv->iTDUsed[dma_idx]++;
-
-       /* Take ownership */
-       wmb();
-       head_td->m_td0TD0.f1Owner = OWNED_BY_NIC;
-
-       /* get Next */
-       wmb();
        priv->apCurrTD[dma_idx] = head_td->next;
 
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -1232,11 +1226,18 @@ static int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb)
 
        head_td->buff_addr = cpu_to_le32(head_td->pTDInfo->skb_dma);
 
+       /* Poll Transmit the adapter */
+       wmb();
+       head_td->m_td0TD0.f1Owner = OWNED_BY_NIC;
+       wmb(); /* second memory barrier */
+
        if (head_td->pTDInfo->byFlags & TD_FLAGS_NETIF_SKB)
                MACvTransmitAC0(priv->PortOffset);
        else
                MACvTransmit0(priv->PortOffset);
 
+       priv->iTDUsed[dma_idx]++;
+
        spin_unlock_irqrestore(&priv->lock, flags);
 
        return 0;
@@ -1416,9 +1417,16 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
 
        priv->current_aid = conf->aid;
 
-       if (changed & BSS_CHANGED_BSSID)
+       if (changed & BSS_CHANGED_BSSID) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&priv->lock, flags);
+
                MACvWriteBSSIDAddress(priv->PortOffset, (u8 *)conf->bssid);
 
+               spin_unlock_irqrestore(&priv->lock, flags);
+       }
+
        if (changed & BSS_CHANGED_BASIC_RATES) {
                priv->basic_rates = conf->basic_rates;
 
@@ -1477,7 +1485,7 @@ static void vnt_bss_info_changed(struct ieee80211_hw *hw,
        if (changed & BSS_CHANGED_ASSOC && priv->op_mode != NL80211_IFTYPE_AP) {
                if (conf->assoc) {
                        CARDbUpdateTSF(priv, conf->beacon_rate->hw_value,
-                                      conf->sync_device_ts, conf->sync_tsf);
+                                      conf->sync_tsf);
 
                        CARDbSetBeaconPeriod(priv, conf->beacon_int);