More specifically, enable AP-style beaconing on mesh ifaces, honor
FIF_OTHER_BSS filter and change the hw capabilities to reflect mesh
support.

Also enable IEEE80211_HW_SUPPORTS_PER_STA_GTK, IEEE80211_HW_MFP_CAPABLE
and WIPHY_FLAG_IBSS_RSN.  Probably these should depend on the
capabilities of the hardware but I don't know which hardware supports
what.

These are required for secured mesh.  We were able to establish secured mesh
links between two TL-WN821N cards with this patch.

Signed-off-by: Javier Cardona <jav...@cozybit.com>
---
 drivers/net/wireless/ath/ath9k/htc.h            |    7 +++++++
 drivers/net/wireless/ath/ath9k/htc_drv_beacon.c |    9 ++++++++-
 drivers/net/wireless/ath/ath9k/htc_drv_init.c   |    6 +++++-
 drivers/net/wireless/ath/ath9k/htc_drv_main.c   |   13 +++++++++++++
 drivers/net/wireless/ath/ath9k/htc_drv_txrx.c   |    2 +-
 5 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/htc.h 
b/drivers/net/wireless/ath/ath9k/htc.h
index 5bc0220..9398667 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -207,6 +207,9 @@ struct ath9k_htc_target_rx_stats {
                case NL80211_IFTYPE_AP:         \
                        _priv->num_ap_vif++;    \
                        break;                  \
+               case NL80211_IFTYPE_MESH_POINT: \
+                       _priv->num_mbss_vif++;  \
+                       break;                  \
                default:                        \
                        break;                  \
                }                               \
@@ -223,6 +226,9 @@ struct ath9k_htc_target_rx_stats {
                case NL80211_IFTYPE_AP:         \
                        _priv->num_ap_vif--;    \
                        break;                  \
+               case NL80211_IFTYPE_MESH_POINT: \
+                       _priv->num_mbss_vif--;  \
+                       break;                  \
                default:                        \
                        break;                  \
                }                               \
@@ -437,6 +443,7 @@ struct ath9k_htc_priv {
        u8 sta_slot;
        u8 vif_sta_pos[ATH9K_HTC_MAX_VIF];
        u8 num_ibss_vif;
+       u8 num_mbss_vif;
        u8 num_sta_vif;
        u8 num_sta_assoc_vif;
        u8 num_ap_vif;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c 
b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 57fe22b..cd9c0c0 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -28,7 +28,8 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
 
        ath9k_hw_get_txq_props(ah, priv->beaconq, &qi);
 
-       if (priv->ah->opmode == NL80211_IFTYPE_AP) {
+       if (priv->ah->opmode == NL80211_IFTYPE_AP ||
+               priv->ah->opmode == NL80211_IFTYPE_MESH_POINT) {
                qi.tqi_aifs = 1;
                qi.tqi_cwmin = 0;
                qi.tqi_cwmax = 0;
@@ -633,6 +634,12 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
        case NL80211_IFTYPE_ADHOC:
                ath9k_htc_beacon_config_adhoc(priv, cur_conf);
                break;
+       case NL80211_IFTYPE_MESH_POINT:
+               /* 802.11s defines a different beaconing method for
+                * mesh points that closely resembles AP-style
+                * beaconing.  Until that is implemented, just use
+                * AP-style beaconing for mesh points. */
+               /* Fall through */
        case NL80211_IFTYPE_AP:
                ath9k_htc_beacon_config_ap(priv, cur_conf);
                break;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c 
b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index 61e6d39..a2c5d53 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -754,6 +754,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
                IEEE80211_HW_RX_INCLUDES_FCS |
                IEEE80211_HW_SUPPORTS_PS |
                IEEE80211_HW_PS_NULLFUNC_STACK |
+               IEEE80211_HW_SUPPORTS_PER_STA_GTK |
+               IEEE80211_HW_MFP_CAPABLE |
                IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING;
 
        hw->wiphy->interface_modes =
@@ -761,9 +763,11 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
                BIT(NL80211_IFTYPE_ADHOC) |
                BIT(NL80211_IFTYPE_AP) |
                BIT(NL80211_IFTYPE_P2P_GO) |
-               BIT(NL80211_IFTYPE_P2P_CLIENT);
+               BIT(NL80211_IFTYPE_P2P_CLIENT) |
+               BIT(NL80211_IFTYPE_MESH_POINT);
 
        hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
+       hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
 
        hw->queues = 4;
        hw->channel_change_time = 5000;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c 
b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 7b77968..64aaee2 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -173,6 +173,8 @@ static void ath9k_htc_set_opmode(struct ath9k_htc_priv 
*priv)
                priv->ah->opmode = NL80211_IFTYPE_ADHOC;
        else if (priv->num_ap_vif)
                priv->ah->opmode = NL80211_IFTYPE_AP;
+       else if (priv->num_mbss_vif)
+               priv->ah->opmode = NL80211_IFTYPE_MESH_POINT;
        else
                priv->ah->opmode = NL80211_IFTYPE_STATION;
 
@@ -1055,6 +1057,13 @@ static int ath9k_htc_add_interface(struct ieee80211_hw 
*hw,
                return -ENOBUFS;
        }
 
+       if (priv->num_mbss_vif ||
+           (priv->nvifs && vif->type == NL80211_IFTYPE_MESH_POINT)) {
+               ath_err(common, "Mesh BSS coexistence with other modes is not 
allowed\n");
+               mutex_unlock(&priv->mutex);
+               return -ENOBUFS;
+       }
+
        if (((vif->type == NL80211_IFTYPE_AP) ||
             (vif->type == NL80211_IFTYPE_ADHOC)) &&
            ((priv->num_ap_vif + priv->num_ibss_vif) >= ATH9K_HTC_MAX_BCN_VIF)) 
{
@@ -1077,6 +1086,9 @@ static int ath9k_htc_add_interface(struct ieee80211_hw 
*hw,
        case NL80211_IFTYPE_AP:
                hvif.opmode = HTC_M_HOSTAP;
                break;
+       case NL80211_IFTYPE_MESH_POINT:
+               hvif.opmode = HTC_M_WDS;        /* close enough */
+               break;
        default:
                ath_err(common,
                        "Interface type %d not yet supported\n", vif->type);
@@ -1109,6 +1121,7 @@ static int ath9k_htc_add_interface(struct ieee80211_hw 
*hw,
        INC_VIF(priv, vif->type);
 
        if ((vif->type == NL80211_IFTYPE_AP) ||
+           (vif->type == NL80211_IFTYPE_MESH_POINT) ||
            (vif->type == NL80211_IFTYPE_ADHOC))
                ath9k_htc_assign_bslot(priv, vif);
 
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c 
b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 2d81c70..f66f2ae 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -889,7 +889,7 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv)
        if (priv->rxfilter & FIF_PSPOLL)
                rfilt |= ATH9K_RX_FILTER_PSPOLL;
 
-       if (priv->nvifs > 1)
+       if (priv->nvifs > 1 || priv->rxfilter & FIF_OTHER_BSS)
                rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
 
        return rfilt;
-- 
1.7.1

_______________________________________________
Devel mailing list
Devel@lists.open80211s.org
http://open80211s.com/mailman/listinfo/devel

Reply via email to