]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
iwlwifi: mvm: add IBSS support
[karo-tx-linux.git] / drivers / net / wireless / iwlwifi / mvm / mac-ctxt.c
index 4d1c82271d55e8efa19fa1e6a61c51a2794909f4..ab5a7ac90dcd68948882cc245cd8df04e62df37c 100644 (file)
@@ -242,9 +242,17 @@ static int iwl_mvm_mac_ctxt_allocate_resources(struct iwl_mvm *mvm,
         * that we should share it with another interface.
         */
 
-       /* Currently, MAC ID 0 should be used only for the managed vif */
-       if (vif->type != NL80211_IFTYPE_STATION || vif->p2p)
+       /* Currently, MAC ID 0 should be used only for the managed/IBSS vif */
+       switch (vif->type) {
+       case NL80211_IFTYPE_ADHOC:
+               break;
+       case NL80211_IFTYPE_STATION:
+               if (!vif->p2p)
+                       break;
+               /* fall through */
+       default:
                __clear_bit(0, data.available_mac_ids);
+       }
 
        ieee80211_iterate_active_interfaces_atomic(
                mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
@@ -716,6 +724,31 @@ static int iwl_mvm_mac_ctxt_cmd_listener(struct iwl_mvm *mvm,
        return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
 }
 
+static int iwl_mvm_mac_ctxt_cmd_ibss(struct iwl_mvm *mvm,
+                                    struct ieee80211_vif *vif,
+                                    u32 action)
+{
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       struct iwl_mac_ctx_cmd cmd = {};
+
+       WARN_ON(vif->type != NL80211_IFTYPE_ADHOC);
+
+       iwl_mvm_mac_ctxt_cmd_common(mvm, vif, &cmd, action);
+
+       cmd.filter_flags = cpu_to_le32(MAC_FILTER_IN_BEACON |
+                                      MAC_FILTER_IN_PROBE_REQUEST);
+
+       /* cmd.ibss.beacon_time/cmd.ibss.beacon_tsf are curently ignored */
+       cmd.ibss.bi = cpu_to_le32(vif->bss_conf.beacon_int);
+       cmd.ibss.bi_reciprocal =
+               cpu_to_le32(iwl_mvm_reciprocal(vif->bss_conf.beacon_int));
+
+       /* TODO: Assumes that the beacon id == mac context id */
+       cmd.ibss.beacon_template = cpu_to_le32(mvmvif->id);
+
+       return iwl_mvm_mac_ctxt_send_cmd(mvm, &cmd);
+}
+
 struct iwl_mvm_go_iterator_data {
        bool go_active;
 };
@@ -725,7 +758,8 @@ static void iwl_mvm_go_iterator(void *_data, u8 *mac, struct ieee80211_vif *vif)
        struct iwl_mvm_go_iterator_data *data = _data;
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
-       if (vif->type == NL80211_IFTYPE_AP && vif->p2p && mvmvif->ap_active)
+       if (vif->type == NL80211_IFTYPE_AP && vif->p2p &&
+           mvmvif->ap_ibss_active)
                data->go_active = true;
 }
 
@@ -837,9 +871,10 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
                cpu_to_le32(iwl_mvm_mac80211_idx_to_hwrate(rate));
 
        /* Set up TX beacon command fields */
-       iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd,
-                                beacon->data,
-                                beacon_skb_len);
+       if (vif->type == NL80211_IFTYPE_AP)
+               iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd,
+                                        beacon->data,
+                                        beacon_skb_len);
 
        /* Submit command */
        cmd.len[0] = sizeof(beacon_cmd);
@@ -852,14 +887,15 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
        return iwl_mvm_send_cmd(mvm, &cmd);
 }
 
-/* The beacon template for the AP/GO context has changed and needs update */
+/* The beacon template for the AP/GO/IBSS has changed and needs update */
 int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
                                    struct ieee80211_vif *vif)
 {
        struct sk_buff *beacon;
        int ret;
 
-       WARN_ON(vif->type != NL80211_IFTYPE_AP);
+       WARN_ON(vif->type != NL80211_IFTYPE_AP &&
+               vif->type != NL80211_IFTYPE_ADHOC);
 
        beacon = ieee80211_beacon_get(mvm->hw, vif);
        if (!beacon)
@@ -1022,6 +1058,8 @@ static int iwl_mvm_mac_ctx_send(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                return iwl_mvm_mac_ctxt_cmd_listener(mvm, vif, action);
        case NL80211_IFTYPE_P2P_DEVICE:
                return iwl_mvm_mac_ctxt_cmd_p2p_device(mvm, vif, action);
+       case NL80211_IFTYPE_ADHOC:
+               return iwl_mvm_mac_ctxt_cmd_ibss(mvm, vif, action);
        default:
                break;
        }