Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCH 1/2] ath: update hardware mac address with bssid mask
@ 2013-04-16 10:51 Felix Fietkau
  2013-04-16 10:51 ` [PATCH 2/2] ath9k: always set common->macaddr to the MAC adress of a virtual interface Felix Fietkau
  0 siblings, 1 reply; 3+ messages in thread
From: Felix Fietkau @ 2013-04-16 10:51 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

Preparation for updating common->macaddr along with virtual interface
MAC address changes.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/hw.c  | 7 +++----
 drivers/net/wireless/ath/ath9k/reg.h | 3 ---
 drivers/net/wireless/ath/hw.c        | 6 ++++++
 drivers/net/wireless/ath/reg.h       | 4 ++++
 4 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8a980a4..10eb6ba 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1698,12 +1698,11 @@ static void ath9k_hw_reset_opmode(struct ath_hw *ah,
 
 	ENABLE_REGWRITE_BUFFER(ah);
 
-	REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
-	REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4)
-		  | macStaId1
+	REG_RMW(ah, AR_STA_ID1, macStaId1
 		  | AR_STA_ID1_RTS_USE_DEF
 		  | (ah->config.ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
-		  | ah->sta_id1_defaults);
+		  | ah->sta_id1_defaults,
+		  ~AR_STA_ID1_SADH_MASK);
 	ath_hw_setbssidmask(common);
 	REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
 	ath9k_hw_write_associd(ah);
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 5929850..5c4ab50 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -1493,9 +1493,6 @@ enum {
 #define AR9271_RADIO_RF_RST			0x20
 #define AR9271_GATE_MAC_CTL			0x4000
 
-#define AR_STA_ID0                 0x8000
-#define AR_STA_ID1                 0x8004
-#define AR_STA_ID1_SADH_MASK       0x0000FFFF
 #define AR_STA_ID1_STA_AP          0x00010000
 #define AR_STA_ID1_ADHOC           0x00020000
 #define AR_STA_ID1_PWR_SAV         0x00040000
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c
index 39e8a59..eae9abf 100644
--- a/drivers/net/wireless/ath/hw.c
+++ b/drivers/net/wireless/ath/hw.c
@@ -118,6 +118,12 @@
 void ath_hw_setbssidmask(struct ath_common *common)
 {
 	void *ah = common->ah;
+	u32 id1;
+
+	REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr));
+	id1 = REG_READ(ah, AR_STA_ID1) & ~AR_STA_ID1_SADH_MASK;
+	id1 |= get_unaligned_le16(common->macaddr + 4);
+	REG_WRITE(ah, AR_STA_ID1, id1);
 
 	REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(common->bssidmask));
 	REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(common->bssidmask + 4));
diff --git a/drivers/net/wireless/ath/reg.h b/drivers/net/wireless/ath/reg.h
index 298e53f..3ad4c77 100644
--- a/drivers/net/wireless/ath/reg.h
+++ b/drivers/net/wireless/ath/reg.h
@@ -23,6 +23,10 @@
 #define AR_MIBC_CMC		0x00000004
 #define AR_MIBC_MCS		0x00000008
 
+#define AR_STA_ID0		0x8000
+#define AR_STA_ID1		0x8004
+#define AR_STA_ID1_SADH_MASK	0x0000ffff
+
 /*
  * BSSID mask registers. See ath_hw_set_bssid_mask()
  * for detailed documentation about these registers.
-- 
1.8.0.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH 2/2] ath9k: always set common->macaddr to the MAC adress of a virtual interface
  2013-04-16 10:51 [PATCH 1/2] ath: update hardware mac address with bssid mask Felix Fietkau
@ 2013-04-16 10:51 ` Felix Fietkau
  2013-04-17 16:39   ` Simon Wunderlich
  0 siblings, 1 reply; 3+ messages in thread
From: Felix Fietkau @ 2013-04-16 10:51 UTC (permalink / raw)
  To: linux-wireless; +Cc: linville, mcgrof

In some cases it can be useful to change the MAC address of a virtual
interface to something that's completely different from the EEPROM
stored MAC address. In this case it is a bad idea to use the EEPROM MAC
address for calculating the BSSID mask, as that would make it too wide.

In one case a few devices have been observed to send ACKs for many
packets on the channel not directed at them, which results in a neat
Denial of Service attack on the channel.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 drivers/net/wireless/ath/ath9k/ath9k.h | 7 +++----
 drivers/net/wireless/ath/ath9k/main.c  | 9 +++++++--
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 86d3572..1915f12 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -658,11 +658,10 @@ enum sc_op_flags {
 struct ath_rate_table;
 
 struct ath9k_vif_iter_data {
-	const u8 *hw_macaddr; /* phy's hardware address, set
-			       * before starting iteration for
-			       * valid bssid mask.
-			       */
+	u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */
 	u8 mask[ETH_ALEN]; /* bssid mask */
+	bool has_hw_macaddr;
+
 	int naps;      /* number of AP vifs */
 	int nmeshes;   /* number of mesh vifs */
 	int nstations; /* number of station vifs */
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a383483..6963862 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -839,10 +839,14 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
 	struct ath9k_vif_iter_data *iter_data = data;
 	int i;
 
-	if (iter_data->hw_macaddr)
+	if (iter_data->has_hw_macaddr) {
 		for (i = 0; i < ETH_ALEN; i++)
 			iter_data->mask[i] &=
 				~(iter_data->hw_macaddr[i] ^ mac[i]);
+	} else {
+		memcpy(iter_data->hw_macaddr, mac, ETH_ALEN);
+		iter_data->has_hw_macaddr = true;
+	}
 
 	switch (vif->type) {
 	case NL80211_IFTYPE_AP:
@@ -891,7 +895,6 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
 	 * together with the BSSID mask when matching addresses.
 	 */
 	memset(iter_data, 0, sizeof(*iter_data));
-	iter_data->hw_macaddr = common->macaddr;
 	memset(&iter_data->mask, 0xff, ETH_ALEN);
 
 	if (vif)
@@ -901,6 +904,8 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
 	ieee80211_iterate_active_interfaces_atomic(
 		sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
 		ath9k_vif_iter, iter_data);
+
+	memcpy(common->macaddr, iter_data->hw_macaddr, ETH_ALEN);
 }
 
 /* Called with sc->mutex held. */
-- 
1.8.0.2


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH 2/2] ath9k: always set common->macaddr to the MAC adress of a virtual interface
  2013-04-16 10:51 ` [PATCH 2/2] ath9k: always set common->macaddr to the MAC adress of a virtual interface Felix Fietkau
@ 2013-04-17 16:39   ` Simon Wunderlich
  0 siblings, 0 replies; 3+ messages in thread
From: Simon Wunderlich @ 2013-04-17 16:39 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: linux-wireless, linville, mcgrof

[-- Attachment #1: Type: text/plain, Size: 3267 bytes --]

On Tue, Apr 16, 2013 at 12:51:57PM +0200, Felix Fietkau wrote:
> In some cases it can be useful to change the MAC address of a virtual
> interface to something that's completely different from the EEPROM
> stored MAC address. In this case it is a bad idea to use the EEPROM MAC
> address for calculating the BSSID mask, as that would make it too wide.
> 
> In one case a few devices have been observed to send ACKs for many
> packets on the channel not directed at them, which results in a neat
> Denial of Service attack on the channel.

This was really giving me a hard time. Thanks a lot for finding the cause
and fixing that. :)

Cheers,
	Simon
> 
> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> ---
>  drivers/net/wireless/ath/ath9k/ath9k.h | 7 +++----
>  drivers/net/wireless/ath/ath9k/main.c  | 9 +++++++--
>  2 files changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
> index 86d3572..1915f12 100644
> --- a/drivers/net/wireless/ath/ath9k/ath9k.h
> +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
> @@ -658,11 +658,10 @@ enum sc_op_flags {
>  struct ath_rate_table;
>  
>  struct ath9k_vif_iter_data {
> -	const u8 *hw_macaddr; /* phy's hardware address, set
> -			       * before starting iteration for
> -			       * valid bssid mask.
> -			       */
> +	u8 hw_macaddr[ETH_ALEN]; /* address of the first vif */
>  	u8 mask[ETH_ALEN]; /* bssid mask */
> +	bool has_hw_macaddr;
> +
>  	int naps;      /* number of AP vifs */
>  	int nmeshes;   /* number of mesh vifs */
>  	int nstations; /* number of station vifs */
> diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
> index a383483..6963862 100644
> --- a/drivers/net/wireless/ath/ath9k/main.c
> +++ b/drivers/net/wireless/ath/ath9k/main.c
> @@ -839,10 +839,14 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
>  	struct ath9k_vif_iter_data *iter_data = data;
>  	int i;
>  
> -	if (iter_data->hw_macaddr)
> +	if (iter_data->has_hw_macaddr) {
>  		for (i = 0; i < ETH_ALEN; i++)
>  			iter_data->mask[i] &=
>  				~(iter_data->hw_macaddr[i] ^ mac[i]);
> +	} else {
> +		memcpy(iter_data->hw_macaddr, mac, ETH_ALEN);
> +		iter_data->has_hw_macaddr = true;
> +	}
>  
>  	switch (vif->type) {
>  	case NL80211_IFTYPE_AP:
> @@ -891,7 +895,6 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
>  	 * together with the BSSID mask when matching addresses.
>  	 */
>  	memset(iter_data, 0, sizeof(*iter_data));
> -	iter_data->hw_macaddr = common->macaddr;
>  	memset(&iter_data->mask, 0xff, ETH_ALEN);
>  
>  	if (vif)
> @@ -901,6 +904,8 @@ void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
>  	ieee80211_iterate_active_interfaces_atomic(
>  		sc->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
>  		ath9k_vif_iter, iter_data);
> +
> +	memcpy(common->macaddr, iter_data->hw_macaddr, ETH_ALEN);
>  }
>  
>  /* Called with sc->mutex held. */
> -- 
> 1.8.0.2
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-04-17 16:39 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-16 10:51 [PATCH 1/2] ath: update hardware mac address with bssid mask Felix Fietkau
2013-04-16 10:51 ` [PATCH 2/2] ath9k: always set common->macaddr to the MAC adress of a virtual interface Felix Fietkau
2013-04-17 16:39   ` Simon Wunderlich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox