Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / iwlegacy / common.c
index 90b8970eadf0fa7c296be194c2d18ef9266b1043..3613b3a81ad2f17cd6762320929f0eb4d8eeed1a 100644 (file)
@@ -1122,7 +1122,7 @@ il_set_power(struct il_priv *il, struct il_powertable_cmd *cmd)
                               sizeof(struct il_powertable_cmd), cmd);
 }
 
-int
+static int
 il_power_set_mode(struct il_priv *il, struct il_powertable_cmd *cmd, bool force)
 {
        int ret;
@@ -1830,32 +1830,30 @@ il_set_ht_add_station(struct il_priv *il, u8 idx, struct ieee80211_sta *sta)
 {
        struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;
        __le32 sta_flags;
-       u8 mimo_ps_mode;
 
        if (!sta || !sta_ht_inf->ht_supported)
                goto done;
 
-       mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;
        D_ASSOC("spatial multiplexing power save mode: %s\n",
-               (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ? "static" :
-               (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ? "dynamic" :
+               (sta->smps_mode == IEEE80211_SMPS_STATIC) ? "static" :
+               (sta->smps_mode == IEEE80211_SMPS_DYNAMIC) ? "dynamic" :
                "disabled");
 
        sta_flags = il->stations[idx].sta.station_flags;
 
        sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);
 
-       switch (mimo_ps_mode) {
-       case WLAN_HT_CAP_SM_PS_STATIC:
+       switch (sta->smps_mode) {
+       case IEEE80211_SMPS_STATIC:
                sta_flags |= STA_FLG_MIMO_DIS_MSK;
                break;
-       case WLAN_HT_CAP_SM_PS_DYNAMIC:
+       case IEEE80211_SMPS_DYNAMIC:
                sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;
                break;
-       case WLAN_HT_CAP_SM_PS_DISABLED:
+       case IEEE80211_SMPS_OFF:
                break;
        default:
-               IL_WARN("Invalid MIMO PS mode %d\n", mimo_ps_mode);
+               IL_WARN("Invalid MIMO PS mode %d\n", sta->smps_mode);
                break;
        }
 
@@ -2568,15 +2566,13 @@ il_rx_queue_alloc(struct il_priv *il)
        INIT_LIST_HEAD(&rxq->rx_used);
 
        /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */
-       rxq->bd =
-           dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma,
-                              GFP_KERNEL);
+       rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->bd_dma,
+                                    GFP_KERNEL);
        if (!rxq->bd)
                goto err_bd;
 
-       rxq->rb_stts =
-           dma_alloc_coherent(dev, sizeof(struct il_rb_status),
-                              &rxq->rb_stts_dma, GFP_KERNEL);
+       rxq->rb_stts = dma_alloc_coherent(dev, sizeof(struct il_rb_status),
+                                         &rxq->rb_stts_dma, GFP_KERNEL);
        if (!rxq->rb_stts)
                goto err_rb;
 
@@ -2943,10 +2939,9 @@ il_tx_queue_alloc(struct il_priv *il, struct il_tx_queue *txq, u32 id)
         * shared with device */
        txq->tfds =
            dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL);
-       if (!txq->tfds) {
-               IL_ERR("Fail to alloc TFDs\n");
+       if (!txq->tfds)
                goto error;
-       }
+
        txq->q.id = id;
 
        return 0;
@@ -3162,18 +3157,23 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
                     idx, il->cmd_queue);
        }
 #endif
-       txq->need_update = 1;
-
-       if (il->ops->txq_update_byte_cnt_tbl)
-               /* Set up entry in queue's byte count circular buffer */
-               il->ops->txq_update_byte_cnt_tbl(il, txq, 0);
 
        phys_addr =
            pci_map_single(il->pci_dev, &out_cmd->hdr, fix_size,
                           PCI_DMA_BIDIRECTIONAL);
+       if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr))) {
+               idx = -ENOMEM;
+               goto out;
+       }
        dma_unmap_addr_set(out_meta, mapping, phys_addr);
        dma_unmap_len_set(out_meta, len, fix_size);
 
+       txq->need_update = 1;
+
+       if (il->ops->txq_update_byte_cnt_tbl)
+               /* Set up entry in queue's byte count circular buffer */
+               il->ops->txq_update_byte_cnt_tbl(il, txq, 0);
+
        il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, fix_size, 1,
                                            U32_PAD(cmd->len));
 
@@ -3181,6 +3181,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
        q->write_ptr = il_queue_inc_wrap(q->write_ptr, q->n_bd);
        il_txq_update_write_ptr(il, txq);
 
+out:
        spin_unlock_irqrestore(&il->hcmd_lock, flags);
        return idx;
 }
@@ -4700,6 +4701,41 @@ out:
 }
 EXPORT_SYMBOL(il_mac_change_interface);
 
+void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
+{
+       struct il_priv *il = hw->priv;
+       unsigned long timeout = jiffies + msecs_to_jiffies(500);
+       int i;
+
+       mutex_lock(&il->mutex);
+       D_MAC80211("enter\n");
+
+       if (il->txq == NULL)
+               goto out;
+
+       for (i = 0; i < il->hw_params.max_txq_num; i++) {
+               struct il_queue *q;
+
+               if (i == il->cmd_queue)
+                       continue;
+
+               q = &il->txq[i].q;
+               if (q->read_ptr == q->write_ptr)
+                       continue;
+
+               if (time_after(jiffies, timeout)) {
+                       IL_ERR("Failed to flush queue %d\n", q->id);
+                       break;
+               }
+
+               msleep(20);
+       }
+out:
+       D_MAC80211("leave\n");
+       mutex_unlock(&il->mutex);
+}
+EXPORT_SYMBOL(il_mac_flush);
+
 /*
  * On every watchdog tick we check (latest) time stamp. If it does not
  * change during timeout period and queue is not empty we reset firmware.
@@ -4851,7 +4887,7 @@ il_add_beacon_time(struct il_priv *il, u32 base, u32 addon,
 }
 EXPORT_SYMBOL(il_add_beacon_time);
 
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
 
 static int
 il_pci_suspend(struct device *device)
@@ -4902,7 +4938,7 @@ il_pci_resume(struct device *device)
 SIMPLE_DEV_PM_OPS(il_pm_ops, il_pci_suspend, il_pci_resume);
 EXPORT_SYMBOL(il_pm_ops);
 
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static void
 il_update_qos(struct il_priv *il)