diff options
author | Malcolm Priestley <tvboxspy@gmail.com> | 2014-10-29 17:43:37 +0000 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-10-29 11:35:51 -0700 |
commit | fee7506a121a4666aa42b22bcdc2172752b9f65b (patch) | |
tree | 6adcdd10c86750f6eced77e2081ae900b27345fb /drivers/staging/vt6655/key.c | |
parent | 33b1c8c13fb8c9c3c5320345258a4d33806262f4 (diff) |
staging: vt6655: mac80211 conversion: add new key functions
vnt_key_init_table to initialize the table
vnt_set_keys to set the keys
Signed-off-by: Malcolm Priestley <tvboxspy@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/vt6655/key.c')
-rw-r--r-- | drivers/staging/vt6655/key.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/drivers/staging/vt6655/key.c b/drivers/staging/vt6655/key.c index 02caffb06e59..b2fa8125e29d 100644 --- a/drivers/staging/vt6655/key.c +++ b/drivers/staging/vt6655/key.c @@ -790,3 +790,139 @@ bool KeybSetAllGroupKey( } return true; } + +int vnt_key_init_table(struct vnt_private *priv) +{ + u32 i; + + for (i = 0; i < MAX_KEY_TABLE; i++) + MACvDisableKeyEntry(priv->PortOffset, i); + + return 0; +} + +static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr, + struct ieee80211_key_conf *key, u32 key_type, u32 mode, + bool onfly_latch) +{ + struct vnt_private *priv = hw->priv; + u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u16 key_mode = 0; + u32 entry = 0; + u8 *bssid; + u8 key_inx = key->keyidx; + u8 i; + + if (mac_addr) + bssid = mac_addr; + else + bssid = &broadcast[0]; + + if (key_type != VNT_KEY_DEFAULTKEY) { + for (i = 0; i < (MAX_KEY_TABLE - 1); i++) { + if (!test_bit(i, &priv->key_entry_inuse)) { + set_bit(i, &priv->key_entry_inuse); + + key->hw_key_idx = i; + entry = key->hw_key_idx; + break; + } + } + } + + switch (key_type) { + /* fallthrough */ + case VNT_KEY_DEFAULTKEY: + /* default key last entry */ + entry = MAX_KEY_TABLE - 1; + key->hw_key_idx = entry; + case VNT_KEY_ALLGROUP: + key_mode |= VNT_KEY_ALLGROUP; + if (onfly_latch) + key_mode |= VNT_KEY_ONFLY_ALL; + case VNT_KEY_GROUP_ADDRESS: + key_mode |= mode; + case VNT_KEY_GROUP: + key_mode |= (mode << 4); + key_mode |= VNT_KEY_GROUP; + break; + case VNT_KEY_PAIRWISE: + key_mode |= mode; + key_inx = 4; + break; + default: + return -EINVAL; + } + + if (onfly_latch) + key_mode |= VNT_KEY_ONFLY; + + if (mode == KEY_CTL_WEP) { + if (key->keylen == WLAN_KEY_LEN_WEP40) + key->key[15] &= 0x7f; + if (key->keylen == WLAN_KEY_LEN_WEP104) + key->key[15] |= 0x80; + } + + MACvSetKeyEntry(priv->PortOffset, key_mode, entry, key_inx, + bssid, (u32 *)key->key, priv->byLocalID); + + return 0; +} + +int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta, + struct ieee80211_vif *vif, struct ieee80211_key_conf *key) +{ + struct ieee80211_bss_conf *conf = &vif->bss_conf; + struct vnt_private *priv = hw->priv; + u8 *mac_addr = NULL; + u8 key_dec_mode = 0; + int ret = 0; + u32 u; + + if (sta) + mac_addr = &sta->addr[0]; + + switch (key->cipher) { + case 0: + for (u = 0 ; u < MAX_KEY_TABLE; u++) + MACvDisableKeyEntry(priv->PortOffset, u); + return ret; + + case WLAN_CIPHER_SUITE_WEP40: + case WLAN_CIPHER_SUITE_WEP104: + for (u = 0; u < MAX_KEY_TABLE; u++) + MACvDisableKeyEntry(priv->PortOffset, u); + + vnt_set_keymode(hw, mac_addr, + key, VNT_KEY_DEFAULTKEY, KEY_CTL_WEP, true); + + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + + return ret; + case WLAN_CIPHER_SUITE_TKIP: + key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + + key_dec_mode = KEY_CTL_TKIP; + + break; + case WLAN_CIPHER_SUITE_CCMP: + key_dec_mode = KEY_CTL_CCMP; + + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; + } + + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { + vnt_set_keymode(hw, mac_addr, + key, VNT_KEY_PAIRWISE, key_dec_mode, true); + } else { + vnt_set_keymode(hw, mac_addr, + key, VNT_KEY_DEFAULTKEY, key_dec_mode, true); + + vnt_set_keymode(hw, (u8 *)conf->bssid, + key, VNT_KEY_GROUP_ADDRESS, key_dec_mode, true); + } + + return 0; +} |