Skip to content

Commit

Permalink
ath10k: add support of mesh point
Browse files Browse the repository at this point in the history
This patch supports the mesh or 802.11s to the ath10k driver
with the following assumption:

Use IBSS mode as replacement of mesh in the firmware since
mesh mode is not supported by the firmware.

Issues:
IBSS mode restricted the beacon reception to only those
matching the BSSID. This is problematic to mesh since mesh
requires the beacon reception with SSID set to the MAC
address of the peer mesh STA.

* Tested with AP mode and the fw immediately crashed whenever
  peer is added by the firmware.

Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@gmail.com>
  • Loading branch information
chunyeow committed Jan 13, 2015
1 parent da96aeb commit c09a7ef
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 11 deletions.
33 changes: 28 additions & 5 deletions drivers/net/wireless/ath/ath10k/mac.c
Expand Up @@ -890,7 +890,8 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, bool restart)
/* For now allow DFS for AP mode */
arg.channel.chan_radar =
!!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
} else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS) {
} else if (arvif->vdev_type == WMI_VDEV_TYPE_IBSS ||
arvif->vdev_type == WMI_VDEV_TYPE_MESH) {
arg.ssid = arvif->vif->bss_conf.ssid;
arg.ssid_len = arvif->vif->bss_conf.ssid_len;
}
Expand Down Expand Up @@ -1475,6 +1476,10 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
if (sta->wme)
arg->peer_flags |= WMI_PEER_QOS;
break;
case WMI_VDEV_TYPE_MESH:
if (sta->wme)
arg->peer_flags |= WMI_PEER_QOS;
break;
default:
break;
}
Expand Down Expand Up @@ -2999,6 +3004,9 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
case NL80211_IFTYPE_MONITOR:
arvif->vdev_type = WMI_VDEV_TYPE_MONITOR;
break;
case NL80211_IFTYPE_MESH_POINT:
arvif->vdev_type = WMI_VDEV_TYPE_MESH;
break;
default:
WARN_ON(1);
break;
Expand All @@ -3021,7 +3029,8 @@ 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_AP) {
vif->type == NL80211_IFTYPE_AP ||
vif->type == NL80211_IFTYPE_MESH_POINT) {
arvif->beacon_buf = dma_zalloc_coherent(ar->dev,
IEEE80211_MAX_FRAME_LEN,
&arvif->beacon_paddr,
Expand All @@ -3038,8 +3047,15 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype,
arvif->beacon_buf ? "single-buf" : "per-skb");

ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type,
arvif->vdev_subtype, vif->addr);
/* Use IBSS mode for Mesh Point, AP mode causes fw crashed */
if (vif->type == NL80211_IFTYPE_MESH_POINT)
ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id,
WMI_VDEV_TYPE_IBSS,
arvif->vdev_subtype, vif->addr);
else
ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id,
arvif->vdev_type,
arvif->vdev_subtype, vif->addr);
if (ret) {
ath10k_warn(ar, "failed to create WMI vdev %i: %d\n",
arvif->vdev_id, ret);
Expand Down Expand Up @@ -3082,7 +3098,8 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
}
}

if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
if (arvif->vdev_type == WMI_VDEV_TYPE_AP ||
arvif->vdev_type == WMI_VDEV_TYPE_MESH) {
ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr);
if (ret) {
ath10k_warn(ar, "failed to create vdev %i peer for AP: %d\n",
Expand Down Expand Up @@ -3688,6 +3705,7 @@ static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif)
lockdep_assert_held(&ar->conf_mutex);

if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
arvif->vdev_type != WMI_VDEV_TYPE_MESH &&
arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
return 0;

Expand All @@ -3706,6 +3724,7 @@ static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif)
lockdep_assert_held(&ar->conf_mutex);

if (arvif->vdev_type != WMI_VDEV_TYPE_AP &&
arvif->vdev_type != WMI_VDEV_TYPE_MESH &&
arvif->vdev_type != WMI_VDEV_TYPE_IBSS)
return;

Expand Down Expand Up @@ -3807,6 +3826,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.
Expand All @@ -3821,6 +3841,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.
Expand Down Expand Up @@ -5152,6 +5173,8 @@ int ath10k_mac_register(struct ath10k *ar)
ar->hw->wiphy->n_iface_combinations =
ARRAY_SIZE(ath10k_if_comb);
ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
ar->hw->wiphy->interface_modes |=
BIT(NL80211_IFTYPE_MESH_POINT);
break;
case ATH10K_FW_WMI_OP_VERSION_10_1:
case ATH10K_FW_WMI_OP_VERSION_10_2:
Expand Down
17 changes: 11 additions & 6 deletions drivers/net/wireless/ath/ath10k/wmi.c
Expand Up @@ -4083,17 +4083,22 @@ ath10k_wmi_op_gen_vdev_start(struct ath10k *ar,
const struct wmi_vdev_start_request_arg *arg,
bool restart)
{
struct ath10k_vif *arvif;
struct wmi_vdev_start_request_cmd *cmd;
struct sk_buff *skb;
const char *cmdname;
u32 flags = 0;

if (WARN_ON(arg->ssid && arg->ssid_len == 0))
return ERR_PTR(-EINVAL);
if (WARN_ON(arg->hidden_ssid && !arg->ssid))
return ERR_PTR(-EINVAL);
if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
return ERR_PTR(-EINVAL);
list_for_each_entry(arvif, &ar->arvifs, list) {
if (arvif->vdev_type != WMI_VDEV_TYPE_MESH) {
if (WARN_ON(arg->ssid && arg->ssid_len == 0))
return ERR_PTR(-EINVAL);
if (WARN_ON(arg->hidden_ssid && !arg->ssid))
return ERR_PTR(-EINVAL);
if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid)))
return ERR_PTR(-EINVAL);
}
}

if (restart)
cmdname = "restart";
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath10k/wmi.h
Expand Up @@ -3187,6 +3187,7 @@ enum wmi_vdev_type {
WMI_VDEV_TYPE_STA = 2,
WMI_VDEV_TYPE_IBSS = 3,
WMI_VDEV_TYPE_MONITOR = 4,
WMI_VDEV_TYPE_MESH = 5,
};

enum wmi_vdev_subtype {
Expand Down

0 comments on commit c09a7ef

Please sign in to comment.