These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / net / wireless / ti / wlcore / main.c
index 0be8079..ec7f6af 100644 (file)
@@ -1792,6 +1792,9 @@ static int wl1271_op_suspend(struct ieee80211_hw *hw,
 
        wl->wow_enabled = true;
        wl12xx_for_each_wlvif(wl, wlvif) {
+               if (wlcore_is_p2p_mgmt(wlvif))
+                       continue;
+
                ret = wl1271_configure_suspend(wl, wlvif, wow);
                if (ret < 0) {
                        mutex_unlock(&wl->mutex);
@@ -1901,6 +1904,9 @@ static int wl1271_op_resume(struct ieee80211_hw *hw)
                goto out;
 
        wl12xx_for_each_wlvif(wl, wlvif) {
+               if (wlcore_is_p2p_mgmt(wlvif))
+                       continue;
+
                wl1271_configure_resume(wl, wlvif);
        }
 
@@ -2256,6 +2262,7 @@ static int wl12xx_init_vif_data(struct wl1271 *wl, struct ieee80211_vif *vif)
                wlvif->p2p = 1;
                /* fall-through */
        case NL80211_IFTYPE_STATION:
+       case NL80211_IFTYPE_P2P_DEVICE:
                wlvif->bss_type = BSS_TYPE_STA_BSS;
                break;
        case NL80211_IFTYPE_ADHOC:
@@ -2477,7 +2484,8 @@ static void wlcore_hw_queue_iter(void *data, u8 *mac,
 {
        struct wlcore_hw_queue_iter_data *iter_data = data;
 
-       if (WARN_ON_ONCE(vif->hw_queue[0] == IEEE80211_INVAL_HW_QUEUE))
+       if (vif->type == NL80211_IFTYPE_P2P_DEVICE ||
+           WARN_ON_ONCE(vif->hw_queue[0] == IEEE80211_INVAL_HW_QUEUE))
                return;
 
        if (iter_data->cur_running || vif == iter_data->vif) {
@@ -2495,6 +2503,11 @@ static int wlcore_allocate_hw_queue_base(struct wl1271 *wl,
        struct wlcore_hw_queue_iter_data iter_data = {};
        int i, q_base;
 
+       if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
+               vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
+               return 0;
+       }
+
        iter_data.vif = vif;
 
        /* mark all bits taken by active interfaces */
@@ -2618,14 +2631,27 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw,
                        goto out;
        }
 
-       ret = wl12xx_cmd_role_enable(wl, vif->addr,
-                                    role_type, &wlvif->role_id);
-       if (ret < 0)
-               goto out;
+       if (!wlcore_is_p2p_mgmt(wlvif)) {
+               ret = wl12xx_cmd_role_enable(wl, vif->addr,
+                                            role_type, &wlvif->role_id);
+               if (ret < 0)
+                       goto out;
 
-       ret = wl1271_init_vif_specific(wl, vif);
-       if (ret < 0)
-               goto out;
+               ret = wl1271_init_vif_specific(wl, vif);
+               if (ret < 0)
+                       goto out;
+
+       } else {
+               ret = wl12xx_cmd_role_enable(wl, vif->addr, WL1271_ROLE_DEVICE,
+                                            &wlvif->dev_role_id);
+               if (ret < 0)
+                       goto out;
+
+               /* needed mainly for configuring rate policies */
+               ret = wl1271_sta_hw_init(wl, wlvif);
+               if (ret < 0)
+                       goto out;
+       }
 
        list_add(&wlvif->list, &wl->wlvif_list);
        set_bit(WLVIF_FLAG_INITIALIZED, &wlvif->flags);
@@ -2696,9 +2722,15 @@ static void __wl1271_op_remove_interface(struct wl1271 *wl,
                                wl12xx_stop_dev(wl, wlvif);
                }
 
-               ret = wl12xx_cmd_role_disable(wl, &wlvif->role_id);
-               if (ret < 0)
-                       goto deinit;
+               if (!wlcore_is_p2p_mgmt(wlvif)) {
+                       ret = wl12xx_cmd_role_disable(wl, &wlvif->role_id);
+                       if (ret < 0)
+                               goto deinit;
+               } else {
+                       ret = wl12xx_cmd_role_disable(wl, &wlvif->dev_role_id);
+                       if (ret < 0)
+                               goto deinit;
+               }
 
                wl1271_ps_elp_sleep(wl);
        }
@@ -3088,6 +3120,9 @@ static int wl12xx_config_vif(struct wl1271 *wl, struct wl12xx_vif *wlvif,
 {
        int ret;
 
+       if (wlcore_is_p2p_mgmt(wlvif))
+               return 0;
+
        if (conf->power_level != wlvif->power_level) {
                ret = wl1271_acx_tx_power(wl, wlvif, conf->power_level);
                if (ret < 0)
@@ -3175,8 +3210,7 @@ static u64 wl1271_op_prepare_multicast(struct ieee80211_hw *hw,
        return (u64)(unsigned long)fp;
 }
 
-#define WL1271_SUPPORTED_FILTERS (FIF_PROMISC_IN_BSS | \
-                                 FIF_ALLMULTI | \
+#define WL1271_SUPPORTED_FILTERS (FIF_ALLMULTI | \
                                  FIF_FCSFAIL | \
                                  FIF_BCN_PRBRESP_PROMISC | \
                                  FIF_CONTROL | \
@@ -3208,6 +3242,9 @@ static void wl1271_op_configure_filter(struct ieee80211_hw *hw,
                goto out;
 
        wl12xx_for_each_wlvif(wl, wlvif) {
+               if (wlcore_is_p2p_mgmt(wlvif))
+                       continue;
+
                if (wlvif->bss_type != BSS_TYPE_AP_BSS) {
                        if (*total & FIF_ALLMULTI)
                                ret = wl1271_acx_group_address_tbl(wl, wlvif,
@@ -4838,6 +4875,9 @@ static int wl1271_op_conf_tx(struct ieee80211_hw *hw,
        u8 ps_scheme;
        int ret = 0;
 
+       if (wlcore_is_p2p_mgmt(wlvif))
+               return 0;
+
        mutex_lock(&wl->mutex);
 
        wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);
@@ -5223,7 +5263,7 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
                                  struct ieee80211_vif *vif,
                                  enum ieee80211_ampdu_mlme_action action,
                                  struct ieee80211_sta *sta, u16 tid, u16 *ssn,
-                                 u8 buf_size)
+                                 u8 buf_size, bool amsdu)
 {
        struct wl1271 *wl = hw->priv;
        struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
@@ -5966,10 +6006,6 @@ static int wl12xx_get_hw_info(struct wl1271 *wl)
 {
        int ret;
 
-       ret = wl12xx_set_power_on(wl);
-       if (ret < 0)
-               return ret;
-
        ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &wl->chip.id);
        if (ret < 0)
                goto out;
@@ -5985,7 +6021,6 @@ static int wl12xx_get_hw_info(struct wl1271 *wl)
                ret = wl->ops->get_mac(wl);
 
 out:
-       wl1271_power_off(wl);
        return ret;
 }
 
@@ -6066,25 +6101,28 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
        /* FIXME: find a proper value */
        wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval;
 
-       wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
-               IEEE80211_HW_SUPPORTS_PS |
-               IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
-               IEEE80211_HW_HAS_RATE_CONTROL |
-               IEEE80211_HW_CONNECTION_MONITOR |
-               IEEE80211_HW_REPORTS_TX_ACK_STATUS |
-               IEEE80211_HW_SPECTRUM_MGMT |
-               IEEE80211_HW_AP_LINK_PS |
-               IEEE80211_HW_AMPDU_AGGREGATION |
-               IEEE80211_HW_TX_AMPDU_SETUP_IN_HW |
-               IEEE80211_HW_QUEUE_CONTROL |
-               IEEE80211_HW_CHANCTX_STA_CSA;
+       ieee80211_hw_set(wl->hw, SUPPORT_FAST_XMIT);
+       ieee80211_hw_set(wl->hw, CHANCTX_STA_CSA);
+       ieee80211_hw_set(wl->hw, QUEUE_CONTROL);
+       ieee80211_hw_set(wl->hw, TX_AMPDU_SETUP_IN_HW);
+       ieee80211_hw_set(wl->hw, AMPDU_AGGREGATION);
+       ieee80211_hw_set(wl->hw, AP_LINK_PS);
+       ieee80211_hw_set(wl->hw, SPECTRUM_MGMT);
+       ieee80211_hw_set(wl->hw, REPORTS_TX_ACK_STATUS);
+       ieee80211_hw_set(wl->hw, CONNECTION_MONITOR);
+       ieee80211_hw_set(wl->hw, HAS_RATE_CONTROL);
+       ieee80211_hw_set(wl->hw, SUPPORTS_DYNAMIC_PS);
+       ieee80211_hw_set(wl->hw, SIGNAL_DBM);
+       ieee80211_hw_set(wl->hw, SUPPORTS_PS);
 
        wl->hw->wiphy->cipher_suites = cipher_suites;
        wl->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
 
        wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
-               BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) |
-               BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO);
+                                        BIT(NL80211_IFTYPE_AP) |
+                                        BIT(NL80211_IFTYPE_P2P_DEVICE) |
+                                        BIT(NL80211_IFTYPE_P2P_CLIENT) |
+                                        BIT(NL80211_IFTYPE_P2P_GO);
        wl->hw->wiphy->max_scan_ssids = 1;
        wl->hw->wiphy->max_sched_scan_ssids = 16;
        wl->hw->wiphy->max_match_sets = 16;
@@ -6432,10 +6470,22 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
        else
                wl->irq_flags |= IRQF_ONESHOT;
 
+       ret = wl12xx_set_power_on(wl);
+       if (ret < 0)
+               goto out_free_nvs;
+
+       ret = wl12xx_get_hw_info(wl);
+       if (ret < 0) {
+               wl1271_error("couldn't get hw info");
+               wl1271_power_off(wl);
+               goto out_free_nvs;
+       }
+
        ret = request_threaded_irq(wl->irq, hardirq_fn, wlcore_irq,
                                   wl->irq_flags, pdev->name, wl);
        if (ret < 0) {
-               wl1271_error("request_irq() failed: %d", ret);
+               wl1271_error("interrupt configuration failed");
+               wl1271_power_off(wl);
                goto out_free_nvs;
        }
 
@@ -6449,12 +6499,7 @@ static void wlcore_nvs_cb(const struct firmware *fw, void *context)
        }
 #endif
        disable_irq(wl->irq);
-
-       ret = wl12xx_get_hw_info(wl);
-       if (ret < 0) {
-               wl1271_error("couldn't get hw info");
-               goto out_irq;
-       }
+       wl1271_power_off(wl);
 
        ret = wl->ops->identify_chip(wl);
        if (ret < 0)