1
2
3
4
5
6
7
8
9
10
11
12
13
14#include "tmacro.h"
15#include "key.h"
16#include "mac.h"
17
18static int vnt_set_keymode(struct ieee80211_hw *hw, u8 *mac_addr,
19 struct ieee80211_key_conf *key, u32 key_type,
20 u32 mode, bool onfly_latch)
21{
22 struct vnt_private *priv = hw->priv;
23 u8 broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
24 u16 key_mode = 0;
25 u32 entry = 0;
26 u8 *bssid;
27 u8 key_inx = key->keyidx;
28 u8 i;
29
30 if (mac_addr)
31 bssid = mac_addr;
32 else
33 bssid = &broadcast[0];
34
35 if (key_type != VNT_KEY_DEFAULTKEY) {
36 for (i = 0; i < (MAX_KEY_TABLE - 1); i++) {
37 if (!test_bit(i, &priv->key_entry_inuse)) {
38 set_bit(i, &priv->key_entry_inuse);
39
40 key->hw_key_idx = i;
41 entry = key->hw_key_idx;
42 break;
43 }
44 }
45 }
46
47 switch (key_type) {
48 case VNT_KEY_DEFAULTKEY:
49
50 entry = MAX_KEY_TABLE - 1;
51 key->hw_key_idx = entry;
52 fallthrough;
53 case VNT_KEY_ALLGROUP:
54 key_mode |= VNT_KEY_ALLGROUP;
55 if (onfly_latch)
56 key_mode |= VNT_KEY_ONFLY_ALL;
57 fallthrough;
58 case VNT_KEY_GROUP_ADDRESS:
59 key_mode |= mode;
60 fallthrough;
61 case VNT_KEY_GROUP:
62 key_mode |= (mode << 4);
63 key_mode |= VNT_KEY_GROUP;
64 break;
65 case VNT_KEY_PAIRWISE:
66 key_mode |= mode;
67 key_inx = 4;
68 break;
69 default:
70 return -EINVAL;
71 }
72
73 if (onfly_latch)
74 key_mode |= VNT_KEY_ONFLY;
75
76 if (mode == KEY_CTL_WEP) {
77 if (key->keylen == WLAN_KEY_LEN_WEP40)
78 key->key[15] &= 0x7f;
79 if (key->keylen == WLAN_KEY_LEN_WEP104)
80 key->key[15] |= 0x80;
81 }
82
83 MACvSetKeyEntry(priv, key_mode, entry, key_inx,
84 bssid, (u32 *)key->key, priv->byLocalID);
85
86 return 0;
87}
88
89int vnt_set_keys(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
90 struct ieee80211_vif *vif, struct ieee80211_key_conf *key)
91{
92 struct ieee80211_bss_conf *conf = &vif->bss_conf;
93 struct vnt_private *priv = hw->priv;
94 u8 *mac_addr = NULL;
95 u8 key_dec_mode = 0;
96 int ret = 0;
97 u32 u;
98
99 if (sta)
100 mac_addr = &sta->addr[0];
101
102 switch (key->cipher) {
103 case 0:
104 for (u = 0 ; u < MAX_KEY_TABLE; u++)
105 MACvDisableKeyEntry(priv, u);
106 return ret;
107
108 case WLAN_CIPHER_SUITE_WEP40:
109 case WLAN_CIPHER_SUITE_WEP104:
110 for (u = 0; u < MAX_KEY_TABLE; u++)
111 MACvDisableKeyEntry(priv, u);
112
113 vnt_set_keymode(hw, mac_addr,
114 key, VNT_KEY_DEFAULTKEY, KEY_CTL_WEP, true);
115
116 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
117
118 return ret;
119 case WLAN_CIPHER_SUITE_TKIP:
120 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
121 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
122
123 key_dec_mode = KEY_CTL_TKIP;
124
125 break;
126 case WLAN_CIPHER_SUITE_CCMP:
127 key_dec_mode = KEY_CTL_CCMP;
128
129 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
130 }
131
132 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
133 vnt_set_keymode(hw, mac_addr,
134 key, VNT_KEY_PAIRWISE, key_dec_mode, true);
135 } else {
136 vnt_set_keymode(hw, mac_addr,
137 key, VNT_KEY_DEFAULTKEY, key_dec_mode, true);
138
139 vnt_set_keymode(hw, (u8 *)conf->bssid,
140 key, VNT_KEY_GROUP_ADDRESS, key_dec_mode, true);
141 }
142
143 return 0;
144}
145