|
@@ -4211,6 +4211,14 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
|
|
case NL80211_IFTYPE_ADHOC:
|
|
|
arvif->vdev_type = WMI_VDEV_TYPE_IBSS;
|
|
|
break;
|
|
|
+ case NL80211_IFTYPE_MESH_POINT:
|
|
|
+ if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
|
|
|
+ ret = -EINVAL;
|
|
|
+ ath10k_warn(ar, "must load driver with rawmode=1 to add mesh interfaces\n");
|
|
|
+ goto err;
|
|
|
+ }
|
|
|
+ arvif->vdev_type = WMI_VDEV_TYPE_AP;
|
|
|
+ break;
|
|
|
case NL80211_IFTYPE_AP:
|
|
|
arvif->vdev_type = WMI_VDEV_TYPE_AP;
|
|
|
|
|
@@ -4251,6 +4259,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
|
|
* become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap.
|
|
|
*/
|
|
|
if (vif->type == NL80211_IFTYPE_ADHOC ||
|
|
|
+ vif->type == NL80211_IFTYPE_MESH_POINT ||
|
|
|
vif->type == NL80211_IFTYPE_AP) {
|
|
|
arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
|
|
|
IEEE80211_MAX_FRAME_LEN,
|
|
@@ -4590,6 +4599,13 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
|
|
|
if (ret)
|
|
|
ath10k_warn(ar, "failed to update beacon template: %d\n",
|
|
|
ret);
|
|
|
+
|
|
|
+ if (ieee80211_vif_is_mesh(vif)) {
|
|
|
+ /* mesh doesn't use SSID but firmware needs it */
|
|
|
+ strncpy(arvif->u.ap.ssid, "mesh",
|
|
|
+ sizeof(arvif->u.ap.ssid));
|
|
|
+ arvif->u.ap.ssid_len = 4;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if (changed & BSS_CHANGED_AP_PROBE_RESP) {
|
|
@@ -5329,6 +5345,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
|
|
|
} else if (old_state == IEEE80211_STA_AUTH &&
|
|
|
new_state == IEEE80211_STA_ASSOC &&
|
|
|
(vif->type == NL80211_IFTYPE_AP ||
|
|
|
+ vif->type == NL80211_IFTYPE_MESH_POINT ||
|
|
|
vif->type == NL80211_IFTYPE_ADHOC)) {
|
|
|
/*
|
|
|
* New association.
|
|
@@ -5364,6 +5381,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
|
|
|
} else if (old_state == IEEE80211_STA_ASSOC &&
|
|
|
new_state == IEEE80211_STA_AUTH &&
|
|
|
(vif->type == NL80211_IFTYPE_AP ||
|
|
|
+ vif->type == NL80211_IFTYPE_MESH_POINT ||
|
|
|
vif->type == NL80211_IFTYPE_ADHOC)) {
|
|
|
/*
|
|
|
* Disassociation.
|
|
@@ -6678,6 +6696,9 @@ static const struct ieee80211_iface_limit ath10k_if_limits[] = {
|
|
|
{
|
|
|
.max = 7,
|
|
|
.types = BIT(NL80211_IFTYPE_AP)
|
|
|
+#ifdef CONFIG_MAC80211_MESH
|
|
|
+ | BIT(NL80211_IFTYPE_MESH_POINT)
|
|
|
+#endif
|
|
|
},
|
|
|
};
|
|
|
|
|
@@ -6685,6 +6706,9 @@ static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
|
|
|
{
|
|
|
.max = 8,
|
|
|
.types = BIT(NL80211_IFTYPE_AP)
|
|
|
+#ifdef CONFIG_MAC80211_MESH
|
|
|
+ | BIT(NL80211_IFTYPE_MESH_POINT)
|
|
|
+#endif
|
|
|
},
|
|
|
};
|
|
|
|
|
@@ -6722,6 +6746,9 @@ static const struct ieee80211_iface_limit ath10k_tlv_if_limit[] = {
|
|
|
{
|
|
|
.max = 2,
|
|
|
.types = BIT(NL80211_IFTYPE_AP) |
|
|
|
+#ifdef CONFIG_MAC80211_MESH
|
|
|
+ BIT(NL80211_IFTYPE_MESH_POINT) |
|
|
|
+#endif
|
|
|
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
|
|
BIT(NL80211_IFTYPE_P2P_GO),
|
|
|
},
|
|
@@ -6743,6 +6770,9 @@ static const struct ieee80211_iface_limit ath10k_tlv_qcs_if_limit[] = {
|
|
|
{
|
|
|
.max = 1,
|
|
|
.types = BIT(NL80211_IFTYPE_AP) |
|
|
|
+#ifdef CONFIG_MAC80211_MESH
|
|
|
+ BIT(NL80211_IFTYPE_MESH_POINT) |
|
|
|
+#endif
|
|
|
BIT(NL80211_IFTYPE_P2P_GO),
|
|
|
},
|
|
|
{
|
|
@@ -6809,6 +6839,9 @@ static const struct ieee80211_iface_limit ath10k_10_4_if_limits[] = {
|
|
|
{
|
|
|
.max = 16,
|
|
|
.types = BIT(NL80211_IFTYPE_AP)
|
|
|
+#ifdef CONFIG_MAC80211_MESH
|
|
|
+ | BIT(NL80211_IFTYPE_MESH_POINT)
|
|
|
+#endif
|
|
|
},
|
|
|
};
|
|
|
|
|
@@ -7033,7 +7066,8 @@ int ath10k_mac_register(struct ath10k *ar)
|
|
|
|
|
|
ar->hw->wiphy->interface_modes =
|
|
|
BIT(NL80211_IFTYPE_STATION) |
|
|
|
- BIT(NL80211_IFTYPE_AP);
|
|
|
+ BIT(NL80211_IFTYPE_AP) |
|
|
|
+ BIT(NL80211_IFTYPE_MESH_POINT);
|
|
|
|
|
|
ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask;
|
|
|
ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask;
|