]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/iwlwifi/mvm/mac80211.c
Merge remote-tracking branch 'sound/for-next'
[karo-tx-linux.git] / drivers / net / wireless / iwlwifi / mvm / mac80211.c
index 8c619151c467cfe5ec6d0652baa7e7028fd0dfe6..f40685c3764ea8b211ad9fa7affb8ed675ef1ddd 100644 (file)
@@ -167,7 +167,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
                    IEEE80211_HW_SUPPORTS_STATIC_SMPS |
                    IEEE80211_HW_SUPPORTS_UAPSD;
 
-       hw->queues = IWL_MVM_FIRST_AGG_QUEUE;
+       hw->queues = mvm->first_agg_queue;
        hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
        hw->rate_control_algorithm = "iwl-mvm-rs";
 
@@ -190,6 +190,10 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
                BIT(NL80211_IFTYPE_P2P_GO) |
                BIT(NL80211_IFTYPE_P2P_DEVICE);
 
+       /* IBSS has bugs in older versions */
+       if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 8)
+               hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
+
        hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
                            WIPHY_FLAG_DISABLE_BEACON_HINTS |
                            WIPHY_FLAG_IBSS_RSN;
@@ -565,7 +569,8 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
         * In short: there's not much we can do at this point, other than
         * allocating resources :)
         */
-       if (vif->type == NL80211_IFTYPE_AP) {
+       if (vif->type == NL80211_IFTYPE_AP ||
+           vif->type == NL80211_IFTYPE_ADHOC) {
                u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif);
                ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta,
                                               qmask);
@@ -715,7 +720,8 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
         * For AP/GO interface, the tear down of the resources allocated to the
         * interface is be handled as part of the stop_ap flow.
         */
-       if (vif->type == NL80211_IFTYPE_AP) {
+       if (vif->type == NL80211_IFTYPE_AP ||
+           vif->type == NL80211_IFTYPE_ADHOC) {
 #ifdef CONFIG_NL80211_TESTMODE
                if (vif == mvm->noa_vif) {
                        mvm->noa_vif = NULL;
@@ -863,7 +869,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
                        if (ret)
                                IWL_ERR(mvm, "failed to update power mode\n");
                }
-               iwl_mvm_bt_coex_vif_assoc(mvm, vif);
+               iwl_mvm_bt_coex_vif_change(mvm);
        } else if (changes & BSS_CHANGED_BEACON_INFO) {
                /*
                 * We received a beacon _after_ association so
@@ -892,7 +898,8 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
        }
 }
 
-static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
+                                struct ieee80211_vif *vif)
 {
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@@ -915,7 +922,7 @@ static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
        if (ret)
                goto out_remove;
 
-       mvmvif->ap_active = true;
+       mvmvif->ap_ibss_active = true;
 
        /* Send the bcast station. At this stage the TBTT and DTIM time events
         * are added and applied to the scheduler */
@@ -927,10 +934,12 @@ static int iwl_mvm_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
        if (ret)
                goto out_rm_bcast;
 
-       /* Need to update the P2P Device MAC */
+       /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
        if (vif->p2p && mvm->p2p_device_vif)
                iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
 
+       iwl_mvm_bt_coex_vif_change(mvm);
+
        mutex_unlock(&mvm->mutex);
        return 0;
 
@@ -945,7 +954,8 @@ out_unlock:
        return ret;
 }
 
-static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
+                                struct ieee80211_vif *vif)
 {
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
@@ -954,9 +964,11 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
 
        mutex_lock(&mvm->mutex);
 
-       mvmvif->ap_active = false;
+       mvmvif->ap_ibss_active = false;
+
+       iwl_mvm_bt_coex_vif_change(mvm);
 
-       /* Need to update the P2P Device MAC */
+       /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */
        if (vif->p2p && mvm->p2p_device_vif)
                iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif);
 
@@ -968,10 +980,11 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
        mutex_unlock(&mvm->mutex);
 }
 
-static void iwl_mvm_bss_info_changed_ap(struct iwl_mvm *mvm,
-                                       struct ieee80211_vif *vif,
-                                       struct ieee80211_bss_conf *bss_conf,
-                                       u32 changes)
+static void
+iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
+                                struct ieee80211_vif *vif,
+                                struct ieee80211_bss_conf *bss_conf,
+                                u32 changes)
 {
        /* Need to send a new beacon template to the FW */
        if (changes & BSS_CHANGED_BEACON) {
@@ -994,7 +1007,8 @@ static void iwl_mvm_bss_info_changed(struct ieee80211_hw *hw,
                iwl_mvm_bss_info_changed_station(mvm, vif, bss_conf, changes);
                break;
        case NL80211_IFTYPE_AP:
-               iwl_mvm_bss_info_changed_ap(mvm, vif, bss_conf, changes);
+       case NL80211_IFTYPE_ADHOC:
+               iwl_mvm_bss_info_changed_ap_ibss(mvm, vif, bss_conf, changes);
                break;
        default:
                /* shouldn't happen */
@@ -1298,8 +1312,13 @@ static int iwl_mvm_mac_set_key(struct ieee80211_hw *hw,
 
        switch (cmd) {
        case SET_KEY:
-               if (vif->type == NL80211_IFTYPE_AP && !sta) {
-                       /* GTK on AP interface is a TX-only key, return 0 */
+               if ((vif->type == NL80211_IFTYPE_ADHOC ||
+                    vif->type == NL80211_IFTYPE_AP) && !sta) {
+                       /*
+                        * GTK on AP interface is a TX-only key, return 0;
+                        * on IBSS they're per-station and because we're lazy
+                        * we don't support them for RX, so do the same.
+                        */
                        ret = 0;
                        key->hw_key_idx = STA_KEY_IDX_INVALID;
                        break;
@@ -1343,6 +1362,9 @@ static void iwl_mvm_mac_update_tkip_key(struct ieee80211_hw *hw,
 {
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
 
+       if (keyconf->hw_key_idx == STA_KEY_IDX_INVALID)
+               return;
+
        iwl_mvm_update_tkip_key(mvm, vif, keyconf, sta, iv32, phase1key);
 }
 
@@ -1536,6 +1558,7 @@ static void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
        iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx->def,
                                 ctx->rx_chains_static,
                                 ctx->rx_chains_dynamic);
+       iwl_mvm_bt_coex_vif_change(mvm);
        mutex_unlock(&mvm->mutex);
 }
 
@@ -1555,14 +1578,14 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
 
        switch (vif->type) {
        case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_ADHOC:
                /*
                 * The AP binding flow is handled as part of the start_ap flow
-                * (in bss_info_changed).
+                * (in bss_info_changed), similarly for IBSS.
                 */
                ret = 0;
                goto out_unlock;
        case NL80211_IFTYPE_STATION:
-       case NL80211_IFTYPE_ADHOC:
        case NL80211_IFTYPE_MONITOR:
                break;
        default:
@@ -1608,10 +1631,10 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
 
        iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
 
-       if (vif->type == NL80211_IFTYPE_AP)
-               goto out_unlock;
-
        switch (vif->type) {
+       case NL80211_IFTYPE_AP:
+       case NL80211_IFTYPE_ADHOC:
+               goto out_unlock;
        case NL80211_IFTYPE_MONITOR:
                mvmvif->monitor_active = false;
                iwl_mvm_update_quotas(mvm, NULL);
@@ -1739,8 +1762,10 @@ struct ieee80211_ops iwl_mvm_hw_ops = {
        .assign_vif_chanctx = iwl_mvm_assign_vif_chanctx,
        .unassign_vif_chanctx = iwl_mvm_unassign_vif_chanctx,
 
-       .start_ap = iwl_mvm_start_ap,
-       .stop_ap = iwl_mvm_stop_ap,
+       .start_ap = iwl_mvm_start_ap_ibss,
+       .stop_ap = iwl_mvm_stop_ap_ibss,
+       .join_ibss = iwl_mvm_start_ap_ibss,
+       .leave_ibss = iwl_mvm_stop_ap_ibss,
 
        .set_tim = iwl_mvm_set_tim,