diff options
| -rw-r--r-- | package/mac80211/patches/571-ath9k_assign_unencrypted_ps_keyidx.patch | 119 | 
1 files changed, 119 insertions, 0 deletions
diff --git a/package/mac80211/patches/571-ath9k_assign_unencrypted_ps_keyidx.patch b/package/mac80211/patches/571-ath9k_assign_unencrypted_ps_keyidx.patch new file mode 100644 index 000000000..7996f33f6 --- /dev/null +++ b/package/mac80211/patches/571-ath9k_assign_unencrypted_ps_keyidx.patch @@ -0,0 +1,119 @@ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -256,6 +256,8 @@ struct ath_node { + #endif + 	struct ath_atx_tid tid[WME_NUM_TID]; + 	struct ath_atx_ac ac[WME_NUM_AC]; ++	int ps_key; ++ + 	u16 maxampdu; + 	u8 mpdudensity; +  +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1775,18 +1775,37 @@ static int ath9k_sta_add(struct ieee8021 + 			 struct ieee80211_sta *sta) + { + 	struct ath_softc *sc = hw->priv; ++	struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++	struct ath_node *an = (struct ath_node *) sta->drv_priv; ++	struct ieee80211_key_conf ps_key = { }; +  + 	ath_node_attach(sc, sta); ++	an->ps_key = ath_key_config(common, vif, sta, &ps_key); +  + 	return 0; + } +  ++static void ath9k_del_ps_key(struct ath_softc *sc, ++			     struct ieee80211_vif *vif, ++			     struct ieee80211_sta *sta) ++{ ++	struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++	struct ath_node *an = (struct ath_node *) sta->drv_priv; ++	struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key }; ++ ++	if (!an->ps_key) ++	    return; ++ ++	ath_key_delete(common, &ps_key); ++} ++ + static int ath9k_sta_remove(struct ieee80211_hw *hw, + 			    struct ieee80211_vif *vif, + 			    struct ieee80211_sta *sta) + { + 	struct ath_softc *sc = hw->priv; +  ++	ath9k_del_ps_key(sc, vif, sta); + 	ath_node_detach(sc, sta); +  + 	return 0; +@@ -1889,6 +1908,9 @@ static int ath9k_set_key(struct ieee8021 +  + 	switch (cmd) { + 	case SET_KEY: ++		if (sta) ++			ath9k_del_ps_key(sc, vif, sta); ++ + 		ret = ath_key_config(common, vif, sta, key); + 		if (ret >= 0) { + 			key->hw_key_idx = ret; +--- a/drivers/net/wireless/ath/key.c ++++ b/drivers/net/wireless/ath/key.c +@@ -483,6 +483,9 @@ int ath_key_config(struct ath_common *co + 	memset(&hk, 0, sizeof(hk)); +  + 	switch (key->cipher) { ++	case 0: ++		hk.kv_type = ATH_CIPHER_CLR; ++		break; + 	case WLAN_CIPHER_SUITE_WEP40: + 	case WLAN_CIPHER_SUITE_WEP104: + 		hk.kv_type = ATH_CIPHER_WEP; +@@ -498,7 +501,8 @@ int ath_key_config(struct ath_common *co + 	} +  + 	hk.kv_len = key->keylen; +-	memcpy(hk.kv_val, key->key, key->keylen); ++	if (key->keylen) ++		memcpy(hk.kv_val, key->key, key->keylen); +  + 	if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + 		switch (vif->type) { +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -1526,7 +1526,7 @@ static void setup_frame_info(struct ieee + 	struct ieee80211_key_conf *hw_key = tx_info->control.hw_key; + 	struct ieee80211_hdr *hdr; + 	struct ath_frame_info *fi = get_frame_info(skb); +-	struct ath_node *an; ++	struct ath_node *an = NULL; + 	struct ath_atx_tid *tid; + 	enum ath9k_key_type keytype; + 	u16 seqno = 0; +@@ -1534,11 +1534,13 @@ static void setup_frame_info(struct ieee +  + 	keytype = ath9k_cmn_get_hw_crypto_keytype(skb); +  ++	if (sta) ++		an = (struct ath_node *) sta->drv_priv; ++ + 	hdr = (struct ieee80211_hdr *)skb->data; +-	if (sta && ieee80211_is_data_qos(hdr->frame_control) && ++	if (an && ieee80211_is_data_qos(hdr->frame_control) && + 		conf_is_ht(&hw->conf) && (sc->sc_flags & SC_OP_TXAGGR)) { +  +-		an = (struct ath_node *) sta->drv_priv; + 		tidno = ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; +  + 		/* +@@ -1554,6 +1556,8 @@ static void setup_frame_info(struct ieee + 	memset(fi, 0, sizeof(*fi)); + 	if (hw_key) + 		fi->keyix = hw_key->hw_key_idx; ++	else if (an && ieee80211_is_data(hdr->frame_control) && an->ps_key > 0) ++		fi->keyix = an->ps_key; + 	else + 		fi->keyix = ATH9K_TXKEYIX_INVALID; + 	fi->keytype = keytype;  | 
