Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 594e65b6 authored by Javier Cardona's avatar Javier Cardona Committed by John W. Linville
Browse files

ath9k_htc: Add support for mesh interfaces



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

Coexistence with a virtual STA interface was tested as
working fine.

Signed-off-by: default avatarJavier Cardona <javier@cozybit.com>
[rebase, add iface combinations]
Signed-off-by: default avatarThomas Pedersen <thomas@cozybit.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 7ca7c776
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -208,6 +208,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;			\
		}				\
@@ -224,6 +227,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;			\
		}				\
@@ -450,6 +456,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;
+4 −1
Original line number Diff line number Diff line
@@ -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;
@@ -628,6 +629,7 @@ 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:
	case NL80211_IFTYPE_AP:
		ath9k_htc_beacon_config_ap(priv, cur_conf);
		break;
@@ -649,6 +651,7 @@ void ath9k_htc_beacon_reconfig(struct ath9k_htc_priv *priv)
	case NL80211_IFTYPE_ADHOC:
		ath9k_htc_beacon_config_adhoc(priv, cur_conf);
		break;
	case NL80211_IFTYPE_MESH_POINT:
	case NL80211_IFTYPE_AP:
		ath9k_htc_beacon_config_ap(priv, cur_conf);
		break;
+4 −2
Original line number Diff line number Diff line
@@ -698,7 +698,8 @@ static const struct ieee80211_iface_limit if_limits[] = {
	{ .max = 2,	.types = BIT(NL80211_IFTYPE_STATION) |
				 BIT(NL80211_IFTYPE_P2P_CLIENT) },
	{ .max = 2,	.types = BIT(NL80211_IFTYPE_AP) |
				 BIT(NL80211_IFTYPE_P2P_GO) },
				 BIT(NL80211_IFTYPE_P2P_GO) |
				 BIT(NL80211_IFTYPE_MESH_POINT) },
};

static const struct ieee80211_iface_combination if_comb = {
@@ -728,7 +729,8 @@ 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->iface_combinations = &if_comb;
	hw->wiphy->n_iface_combinations = 1;
+21 −8
Original line number Diff line number Diff line
@@ -113,7 +113,9 @@ static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
	struct ath9k_htc_priv *priv = data;
	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;

	if ((vif->type == NL80211_IFTYPE_AP) && bss_conf->enable_beacon)
	if ((vif->type == NL80211_IFTYPE_AP ||
	     vif->type == NL80211_IFTYPE_MESH_POINT) &&
	    bss_conf->enable_beacon)
		priv->reconfig_beacon = true;

	if (bss_conf->assoc) {
@@ -180,6 +182,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;

@@ -1052,6 +1056,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);
@@ -1084,6 +1091,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);

@@ -1134,6 +1142,7 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
	DEC_VIF(priv, vif->type);

	if ((vif->type == NL80211_IFTYPE_AP) ||
	     vif->type == NL80211_IFTYPE_MESH_POINT ||
	    (vif->type == NL80211_IFTYPE_ADHOC))
		ath9k_htc_remove_bslot(priv, vif);

@@ -1525,9 +1534,10 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
	if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) {
		/*
		 * Disable SWBA interrupt only if there are no
		 * AP/IBSS interfaces.
		 * concurrent AP/mesh or IBSS interfaces.
		 */
		if ((priv->num_ap_vif <= 1) || priv->num_ibss_vif) {
		if ((priv->num_ap_vif + priv->num_mbss_vif <= 1) ||
		     priv->num_ibss_vif) {
			ath_dbg(common, CONFIG,
				"Beacon disabled for BSS: %pM\n",
				bss_conf->bssid);
@@ -1538,12 +1548,15 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,

	if (changed & BSS_CHANGED_BEACON_INT) {
		/*
		 * Reset the HW TSF for the first AP interface.
		 * Reset the HW TSF for the first AP or mesh interface.
		 */
		if ((priv->ah->opmode == NL80211_IFTYPE_AP) &&
		    (priv->nvifs == 1) &&
		    (priv->num_ap_vif == 1) &&
		    (vif->type == NL80211_IFTYPE_AP)) {
		if (priv->nvifs == 1 &&
		    ((priv->ah->opmode == NL80211_IFTYPE_AP &&
		      vif->type == NL80211_IFTYPE_AP &&
		      priv->num_ap_vif == 1) ||
		    (priv->ah->opmode == NL80211_IFTYPE_MESH_POINT &&
		      vif->type == NL80211_IFTYPE_MESH_POINT &&
		      priv->num_mbss_vif == 1))) {
			set_bit(OP_TSF_RESET, &priv->op_flags);
		}
		ath_dbg(common, CONFIG,
+1 −1
Original line number Diff line number Diff line
@@ -887,7 +887,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;