forked from luck/tmp_suning_uos_patched
mac80211: clean up set_key callback
The set_key callback now seems rather odd, passing a MAC address instead of a station struct, and a local address instead of a vif struct. Change that. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: Bob Copeland <me@bobcopeland.com> [ath5k] Acked-by: Ivo van Doorn <ivdoorn@gmail.com> [rt2x00] Acked-by: Christian Lamparter <chunkeey@web.de> [p54] Tested-by: Kalle Valo <kalle.valo@nokia.com> [iwl3945] Tested-by: Samuel Ortiz <samuel@sortiz.org> [iwl3945] Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
b3093664c9
commit
dc822b5db4
|
@ -232,7 +232,7 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
|
|||
int mc_count, struct dev_mc_list *mclist);
|
||||
static int ath5k_set_key(struct ieee80211_hw *hw,
|
||||
enum set_key_cmd cmd,
|
||||
const u8 *local_addr, const u8 *addr,
|
||||
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key);
|
||||
static int ath5k_get_stats(struct ieee80211_hw *hw,
|
||||
struct ieee80211_low_level_stats *stats);
|
||||
|
@ -2991,8 +2991,8 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw,
|
|||
|
||||
static int
|
||||
ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
const u8 *local_addr, const u8 *addr,
|
||||
struct ieee80211_key_conf *key)
|
||||
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key)
|
||||
{
|
||||
struct ath5k_softc *sc = hw->priv;
|
||||
int ret = 0;
|
||||
|
@ -3015,7 +3015,8 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
|
||||
switch (cmd) {
|
||||
case SET_KEY:
|
||||
ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, addr);
|
||||
ret = ath5k_hw_set_key(sc->ah, key->keyidx, key,
|
||||
sta ? sta->addr : NULL);
|
||||
if (ret) {
|
||||
ATH5K_ERR(sc, "can't set the key\n");
|
||||
goto unlock;
|
||||
|
|
|
@ -1139,7 +1139,7 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
|
|||
|
||||
/* MAC may be NULL if it's a broadcast key. In this case no need to
|
||||
* to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
|
||||
if (unlikely(mac == NULL)) {
|
||||
if (!mac) {
|
||||
low_id = 0xffffffff;
|
||||
high_id = 0xffff | AR5K_KEYTABLE_VALID;
|
||||
} else {
|
||||
|
|
|
@ -794,7 +794,7 @@ static int ath_reserve_key_cache_slot(struct ath_softc *sc)
|
|||
}
|
||||
|
||||
static int ath_key_config(struct ath_softc *sc,
|
||||
const u8 *addr,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key)
|
||||
{
|
||||
struct ath9k_keyval hk;
|
||||
|
@ -828,7 +828,10 @@ static int ath_key_config(struct ath_softc *sc,
|
|||
} else if (key->keyidx) {
|
||||
struct ieee80211_vif *vif;
|
||||
|
||||
mac = addr;
|
||||
if (WARN_ON(!sta))
|
||||
return -EOPNOTSUPP;
|
||||
mac = sta->addr;
|
||||
|
||||
vif = sc->sc_vaps[0];
|
||||
if (vif->type != NL80211_IFTYPE_AP) {
|
||||
/* Only keyidx 0 should be used with unicast key, but
|
||||
|
@ -837,7 +840,10 @@ static int ath_key_config(struct ath_softc *sc,
|
|||
} else
|
||||
return -EIO;
|
||||
} else {
|
||||
mac = addr;
|
||||
if (WARN_ON(!sta))
|
||||
return -EOPNOTSUPP;
|
||||
mac = sta->addr;
|
||||
|
||||
if (key->alg == ALG_TKIP)
|
||||
idx = ath_reserve_key_cache_slot_tkip(sc);
|
||||
else
|
||||
|
@ -2320,8 +2326,8 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw,
|
|||
|
||||
static int ath9k_set_key(struct ieee80211_hw *hw,
|
||||
enum set_key_cmd cmd,
|
||||
const u8 *local_addr,
|
||||
const u8 *addr,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key)
|
||||
{
|
||||
struct ath_softc *sc = hw->priv;
|
||||
|
@ -2331,7 +2337,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
|
|||
|
||||
switch (cmd) {
|
||||
case SET_KEY:
|
||||
ret = ath_key_config(sc, addr, key);
|
||||
ret = ath_key_config(sc, sta, key);
|
||||
if (ret >= 0) {
|
||||
key->hw_key_idx = ret;
|
||||
/* push IV and Michael MIC generation to stack */
|
||||
|
|
|
@ -3476,8 +3476,8 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
|
|||
}
|
||||
|
||||
static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
const u8 *local_addr, const u8 *addr,
|
||||
struct ieee80211_key_conf *key)
|
||||
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key)
|
||||
{
|
||||
struct b43_wl *wl = hw_to_b43_wl(hw);
|
||||
struct b43_wldev *dev;
|
||||
|
@ -3542,9 +3542,14 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
}
|
||||
|
||||
if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
|
||||
if (WARN_ON(!sta)) {
|
||||
err = -EOPNOTSUPP;
|
||||
goto out_unlock;
|
||||
}
|
||||
/* Pairwise key with an assigned MAC address. */
|
||||
err = b43_key_write(dev, -1, algorithm,
|
||||
key->key, key->keylen, addr, key);
|
||||
key->key, key->keylen,
|
||||
sta->addr, key);
|
||||
} else {
|
||||
/* Group key */
|
||||
err = b43_key_write(dev, index, algorithm,
|
||||
|
@ -3577,7 +3582,7 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
b43dbg(wl, "%s hardware based encryption for keyidx: %d, "
|
||||
"mac: %pM\n",
|
||||
cmd == SET_KEY ? "Using" : "Disabling", key->keyidx,
|
||||
addr);
|
||||
sta ? sta->addr : "<group key>");
|
||||
b43_dump_keymemory(dev);
|
||||
}
|
||||
write_unlock(&wl->tx_lock);
|
||||
|
|
|
@ -3021,13 +3021,17 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
|
|||
}
|
||||
|
||||
static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
const u8 *local_addr, const u8 *addr,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key)
|
||||
{
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
int ret = 0;
|
||||
u8 sta_id = IWL_INVALID_STATION;
|
||||
u8 is_default_wep_key = 0;
|
||||
static const u8 bcast_addr[ETH_ALEN] =
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, };
|
||||
static const u8 *addr;
|
||||
|
||||
IWL_DEBUG_MAC80211("enter\n");
|
||||
|
||||
|
@ -3036,9 +3040,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (is_zero_ether_addr(addr))
|
||||
/* only support pairwise keys */
|
||||
return -EOPNOTSUPP;
|
||||
addr = sta ? sta->addr : bcast_addr;
|
||||
|
||||
sta_id = iwl_find_station(priv, addr);
|
||||
if (sta_id == IWL_INVALID_STATION) {
|
||||
|
|
|
@ -6546,12 +6546,16 @@ static int iwl3945_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
|
|||
}
|
||||
|
||||
static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
const u8 *local_addr, const u8 *addr,
|
||||
struct ieee80211_key_conf *key)
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key)
|
||||
{
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
const u8 *addr;
|
||||
int rc = 0;
|
||||
u8 sta_id;
|
||||
static const u8 bcast_addr[ETH_ALEN] =
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
IWL_DEBUG_MAC80211("enter\n");
|
||||
|
||||
|
@ -6560,9 +6564,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (is_zero_ether_addr(addr))
|
||||
/* only support pairwise keys */
|
||||
return -EOPNOTSUPP;
|
||||
addr = sta ? sta->addr : bcast_addr;
|
||||
|
||||
sta_id = iwl3945_hw_find_station(priv, addr);
|
||||
if (sta_id == IWL_INVALID_STATION) {
|
||||
|
|
|
@ -2127,7 +2127,7 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
|
|||
}
|
||||
|
||||
static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
|
||||
const u8 *local_address, const u8 *address,
|
||||
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key)
|
||||
{
|
||||
struct p54_common *priv = dev->priv;
|
||||
|
@ -2191,8 +2191,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
|
|||
rxkey->entry = key->keyidx;
|
||||
rxkey->key_id = key->keyidx;
|
||||
rxkey->key_type = algo;
|
||||
if (address)
|
||||
memcpy(rxkey->mac, address, ETH_ALEN);
|
||||
if (sta)
|
||||
memcpy(rxkey->mac, sta->addr, ETH_ALEN);
|
||||
else
|
||||
memset(rxkey->mac, ~0, ETH_ALEN);
|
||||
if (key->alg != ALG_TKIP) {
|
||||
|
|
|
@ -931,7 +931,7 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
|
|||
int mc_count, struct dev_addr_list *mc_list);
|
||||
#ifdef CONFIG_RT2X00_LIB_CRYPTO
|
||||
int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
const u8 *local_address, const u8 *address,
|
||||
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key);
|
||||
#else
|
||||
#define rt2x00mac_set_key NULL
|
||||
|
|
|
@ -502,15 +502,17 @@ static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len)
|
|||
}
|
||||
|
||||
int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
const u8 *local_address, const u8 *address,
|
||||
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key)
|
||||
{
|
||||
struct rt2x00_dev *rt2x00dev = hw->priv;
|
||||
struct ieee80211_sta *sta;
|
||||
struct rt2x00_intf *intf = vif_to_intf(vif);
|
||||
int (*set_key) (struct rt2x00_dev *rt2x00dev,
|
||||
struct rt2x00lib_crypto *crypto,
|
||||
struct ieee80211_key_conf *key);
|
||||
struct rt2x00lib_crypto crypto;
|
||||
static const u8 bcast_addr[ETH_ALEN] =
|
||||
{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, };
|
||||
|
||||
if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
|
||||
return 0;
|
||||
|
@ -528,32 +530,25 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
|||
if (rt2x00dev->intf_sta_count)
|
||||
crypto.bssidx = 0;
|
||||
else
|
||||
crypto.bssidx =
|
||||
local_address[5] & (rt2x00dev->ops->max_ap_intf - 1);
|
||||
crypto.bssidx = intf->mac[5] & (rt2x00dev->ops->max_ap_intf - 1);
|
||||
|
||||
crypto.cipher = rt2x00crypto_key_to_cipher(key);
|
||||
if (crypto.cipher == CIPHER_NONE)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
crypto.cmd = cmd;
|
||||
crypto.address = address;
|
||||
|
||||
if (sta) {
|
||||
/* some drivers need the AID */
|
||||
crypto.aid = sta->aid;
|
||||
crypto.address = sta->addr;
|
||||
} else
|
||||
crypto.address = bcast_addr;
|
||||
|
||||
if (crypto.cipher == CIPHER_TKIP)
|
||||
memcpy_tkip(&crypto, &key->key[0], key->keylen);
|
||||
else
|
||||
memcpy(&crypto.key, &key->key[0], key->keylen);
|
||||
|
||||
/*
|
||||
* Discover the Association ID from mac80211.
|
||||
* Some drivers need this information when updating the
|
||||
* hardware key (either adding or removing).
|
||||
*/
|
||||
rcu_read_lock();
|
||||
sta = ieee80211_find_sta(hw, address);
|
||||
if (sta)
|
||||
crypto.aid = sta->aid;
|
||||
rcu_read_unlock();
|
||||
|
||||
/*
|
||||
* Each BSS has a maximum of 4 shared keys.
|
||||
* Shared key index values:
|
||||
|
|
|
@ -715,8 +715,8 @@ enum ieee80211_key_flags {
|
|||
* - Temporal Encryption Key (128 bits)
|
||||
* - Temporal Authenticator Tx MIC Key (64 bits)
|
||||
* - Temporal Authenticator Rx MIC Key (64 bits)
|
||||
* @icv_len: FIXME
|
||||
* @iv_len: FIXME
|
||||
* @icv_len: The ICV length for this key type
|
||||
* @iv_len: The IV length for this key type
|
||||
*/
|
||||
struct ieee80211_key_conf {
|
||||
enum ieee80211_key_alg alg;
|
||||
|
@ -1019,16 +1019,12 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
|
|||
*
|
||||
* The set_key() callback in the &struct ieee80211_ops for a given
|
||||
* device is called to enable hardware acceleration of encryption and
|
||||
* decryption. The callback takes an @address parameter that will be
|
||||
* the broadcast address for default keys, the other station's hardware
|
||||
* address for individual keys or the zero address for keys that will
|
||||
* be used only for transmission.
|
||||
* decryption. The callback takes a @sta parameter that will be NULL
|
||||
* for default keys or keys used for transmission only, or point to
|
||||
* the station information for the peer for individual keys.
|
||||
* Multiple transmission keys with the same key index may be used when
|
||||
* VLANs are configured for an access point.
|
||||
*
|
||||
* The @local_address parameter will always be set to our own address,
|
||||
* this is only relevant if you support multiple local addresses.
|
||||
*
|
||||
* When transmitting, the TX control data will use the @hw_key_idx
|
||||
* selected by the driver by modifying the &struct ieee80211_key_conf
|
||||
* pointed to by the @key parameter to the set_key() function.
|
||||
|
@ -1233,8 +1229,8 @@ enum ieee80211_ampdu_mlme_action {
|
|||
*
|
||||
* @set_key: See the section "Hardware crypto acceleration"
|
||||
* This callback can sleep, and is only called between add_interface
|
||||
* and remove_interface calls, i.e. while the interface with the
|
||||
* given local_address is enabled.
|
||||
* and remove_interface calls, i.e. while the given virtual interface
|
||||
* is enabled.
|
||||
*
|
||||
* @update_tkip_key: See the section "Hardware crypto acceleration"
|
||||
* This callback will be called in the context of Rx. Called for drivers
|
||||
|
@ -1311,7 +1307,7 @@ struct ieee80211_ops {
|
|||
int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
|
||||
bool set);
|
||||
int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
const u8 *local_address, const u8 *address,
|
||||
struct ieee80211_vif *vif, struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key);
|
||||
void (*update_tkip_key)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_key_conf *conf, const u8 *address,
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
*/
|
||||
|
||||
static const u8 bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static const u8 zero_addr[ETH_ALEN];
|
||||
|
||||
/* key mutex: used to synchronise todo runners */
|
||||
static DEFINE_MUTEX(key_mutex);
|
||||
|
@ -108,29 +107,18 @@ static void assert_key_lock(void)
|
|||
WARN_ON(!mutex_is_locked(&key_mutex));
|
||||
}
|
||||
|
||||
static const u8 *get_mac_for_key(struct ieee80211_key *key)
|
||||
static struct ieee80211_sta *get_sta_for_key(struct ieee80211_key *key)
|
||||
{
|
||||
const u8 *addr = bcast_addr;
|
||||
|
||||
/*
|
||||
* If we're an AP we won't ever receive frames with a non-WEP
|
||||
* group key so we tell the driver that by using the zero MAC
|
||||
* address to indicate a transmit-only key.
|
||||
*/
|
||||
if (key->conf.alg != ALG_WEP &&
|
||||
(key->sdata->vif.type == NL80211_IFTYPE_AP ||
|
||||
key->sdata->vif.type == NL80211_IFTYPE_AP_VLAN))
|
||||
addr = zero_addr;
|
||||
|
||||
if (key->sta)
|
||||
addr = key->sta->sta.addr;
|
||||
return &key->sta->sta;
|
||||
|
||||
return addr;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
|
||||
{
|
||||
const u8 *addr;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_sta *sta;
|
||||
int ret;
|
||||
|
||||
assert_key_lock();
|
||||
|
@ -139,11 +127,16 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
|
|||
if (!key->local->ops->set_key)
|
||||
return;
|
||||
|
||||
addr = get_mac_for_key(key);
|
||||
sta = get_sta_for_key(key);
|
||||
|
||||
sdata = key->sdata;
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||
sdata = container_of(sdata->bss,
|
||||
struct ieee80211_sub_if_data,
|
||||
u.ap);
|
||||
|
||||
ret = key->local->ops->set_key(local_to_hw(key->local), SET_KEY,
|
||||
key->sdata->dev->dev_addr, addr,
|
||||
&key->conf);
|
||||
&sdata->vif, sta, &key->conf);
|
||||
|
||||
if (!ret) {
|
||||
spin_lock(&todo_lock);
|
||||
|
@ -155,12 +148,13 @@ static void ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
|
|||
printk(KERN_ERR "mac80211-%s: failed to set key "
|
||||
"(%d, %pM) to hardware (%d)\n",
|
||||
wiphy_name(key->local->hw.wiphy),
|
||||
key->conf.keyidx, addr, ret);
|
||||
key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
|
||||
}
|
||||
|
||||
static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
|
||||
{
|
||||
const u8 *addr;
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct ieee80211_sta *sta;
|
||||
int ret;
|
||||
|
||||
assert_key_lock();
|
||||
|
@ -176,17 +170,22 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
|
|||
}
|
||||
spin_unlock(&todo_lock);
|
||||
|
||||
addr = get_mac_for_key(key);
|
||||
sta = get_sta_for_key(key);
|
||||
sdata = key->sdata;
|
||||
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
|
||||
sdata = container_of(sdata->bss,
|
||||
struct ieee80211_sub_if_data,
|
||||
u.ap);
|
||||
|
||||
ret = key->local->ops->set_key(local_to_hw(key->local), DISABLE_KEY,
|
||||
key->sdata->dev->dev_addr, addr,
|
||||
&key->conf);
|
||||
&sdata->vif, sta, &key->conf);
|
||||
|
||||
if (ret)
|
||||
printk(KERN_ERR "mac80211-%s: failed to remove key "
|
||||
"(%d, %pM) from hardware (%d)\n",
|
||||
wiphy_name(key->local->hw.wiphy),
|
||||
key->conf.keyidx, addr, ret);
|
||||
key->conf.keyidx, sta ? sta->addr : bcast_addr, ret);
|
||||
|
||||
spin_lock(&todo_lock);
|
||||
key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
|
||||
|
|
Loading…
Reference in New Issue
Block a user