mac80211: update brcmfmac including missing boardrev workaround
[openwrt.git] / package / kernel / mac80211 / patches / 344-0019-brcmfmac-integrate-add_keyext-in-add_key.patch
1 From: Hante Meuleman <hante.meuleman@broadcom.com>
2 Date: Wed, 17 Feb 2016 11:27:09 +0100
3 Subject: [PATCH] brcmfmac: integrate add_keyext in add_key
4
5 brcmf_add_keyext is called when a key is configured for a specific
6 mac address. This function is very similar to the calling function
7 brcmf_add_key. Integrate this function and also use existing del_key
8 function in case key is to be cleared.
9
10 Reviewed-by: Arend Van Spriel <arend.van@broadcom.com>
11 Reviewed-by: Franky (Zhenhui) Lin <franky.lin@broadcom.com>
12 Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
13 Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
14 Signed-off-by: Arend van Spriel <arend@broadcom.com>
15 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
16 ---
17
18 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
19 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
20 @@ -2073,84 +2073,34 @@ done:
21  }
22  
23  static s32
24 -brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
25 -             u8 key_idx, const u8 *mac_addr, struct key_params *params)
26 +brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
27 +                      u8 key_idx, bool pairwise, const u8 *mac_addr)
28  {
29         struct brcmf_if *ifp = netdev_priv(ndev);
30         struct brcmf_wsec_key key;
31         s32 err = 0;
32 -       u8 keybuf[8];
33 +
34 +       brcmf_dbg(TRACE, "Enter\n");
35 +       if (!check_vif_up(ifp->vif))
36 +               return -EIO;
37 +
38 +       if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
39 +               /* we ignore this key index in this case */
40 +               return -EINVAL;
41 +       }
42  
43         memset(&key, 0, sizeof(key));
44 -       key.index = (u32) key_idx;
45 -       /* Instead of bcast for ea address for default wep keys,
46 -                driver needs it to be Null */
47 -       if (!is_multicast_ether_addr(mac_addr))
48 -               memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
49 -       key.len = (u32) params->key_len;
50 -       /* check for key index change */
51 -       if (key.len == 0) {
52 -               /* key delete */
53 -               err = send_key_to_dongle(ifp, &key);
54 -               if (err)
55 -                       brcmf_err("key delete error (%d)\n", err);
56 -       } else {
57 -               if (key.len > sizeof(key.data)) {
58 -                       brcmf_err("Invalid key length (%d)\n", key.len);
59 -                       return -EINVAL;
60 -               }
61  
62 -               brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
63 -               memcpy(key.data, params->key, key.len);
64 +       key.index = (u32)key_idx;
65 +       key.flags = BRCMF_PRIMARY_KEY;
66 +       key.algo = CRYPTO_ALGO_OFF;
67  
68 -               if (!brcmf_is_apmode(ifp->vif) &&
69 -                   (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
70 -                       brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
71 -                       memcpy(keybuf, &key.data[24], sizeof(keybuf));
72 -                       memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
73 -                       memcpy(&key.data[16], keybuf, sizeof(keybuf));
74 -               }
75 +       brcmf_dbg(CONN, "key index (%d)\n", key_idx);
76  
77 -               /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
78 -               if (params->seq && params->seq_len == 6) {
79 -                       /* rx iv */
80 -                       u8 *ivptr;
81 -                       ivptr = (u8 *) params->seq;
82 -                       key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
83 -                           (ivptr[3] << 8) | ivptr[2];
84 -                       key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
85 -                       key.iv_initialized = true;
86 -               }
87 +       /* Set the new key/index */
88 +       err = send_key_to_dongle(ifp, &key);
89  
90 -               switch (params->cipher) {
91 -               case WLAN_CIPHER_SUITE_WEP40:
92 -                       key.algo = CRYPTO_ALGO_WEP1;
93 -                       brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
94 -                       break;
95 -               case WLAN_CIPHER_SUITE_WEP104:
96 -                       key.algo = CRYPTO_ALGO_WEP128;
97 -                       brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
98 -                       break;
99 -               case WLAN_CIPHER_SUITE_TKIP:
100 -                       key.algo = CRYPTO_ALGO_TKIP;
101 -                       brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
102 -                       break;
103 -               case WLAN_CIPHER_SUITE_AES_CMAC:
104 -                       key.algo = CRYPTO_ALGO_AES_CCM;
105 -                       brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
106 -                       break;
107 -               case WLAN_CIPHER_SUITE_CCMP:
108 -                       key.algo = CRYPTO_ALGO_AES_CCM;
109 -                       brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
110 -                       break;
111 -               default:
112 -                       brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
113 -                       return -EINVAL;
114 -               }
115 -               err = send_key_to_dongle(ifp, &key);
116 -               if (err)
117 -                       brcmf_err("wsec_key error (%d)\n", err);
118 -       }
119 +       brcmf_dbg(TRACE, "Exit\n");
120         return err;
121  }
122  
123 @@ -2163,8 +2113,9 @@ brcmf_cfg80211_add_key(struct wiphy *wip
124         struct brcmf_wsec_key *key;
125         s32 val;
126         s32 wsec;
127 -       s32 err = 0;
128 +       s32 err;
129         u8 keybuf[8];
130 +       bool ext_key;
131  
132         brcmf_dbg(TRACE, "Enter\n");
133         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
134 @@ -2177,27 +2128,32 @@ brcmf_cfg80211_add_key(struct wiphy *wip
135                 return -EINVAL;
136         }
137  
138 -       if (mac_addr &&
139 -               (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
140 -               (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
141 -               brcmf_dbg(TRACE, "Exit");
142 -               return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
143 -       }
144 -
145 -       key = &ifp->vif->profile.key[key_idx];
146 -       memset(key, 0, sizeof(*key));
147 +       if (params->key_len == 0)
148 +               return brcmf_cfg80211_del_key(wiphy, ndev, key_idx, pairwise,
149 +                                             mac_addr);
150  
151         if (params->key_len > sizeof(key->data)) {
152                 brcmf_err("Too long key length (%u)\n", params->key_len);
153 -               err = -EINVAL;
154 -               goto done;
155 +               return -EINVAL;
156 +       }
157 +
158 +       ext_key = false;
159 +       if (mac_addr && (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
160 +           (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
161 +               brcmf_dbg(TRACE, "Ext key, mac %pM", mac_addr);
162 +               ext_key = true;
163         }
164 +
165 +       key = &ifp->vif->profile.key[key_idx];
166 +       memset(key, 0, sizeof(*key));
167 +       if ((ext_key) && (!is_multicast_ether_addr(mac_addr)))
168 +               memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN);
169         key->len = params->key_len;
170         key->index = key_idx;
171 -
172         memcpy(key->data, params->key, key->len);
173 +       if (!ext_key)
174 +               key->flags = BRCMF_PRIMARY_KEY;
175  
176 -       key->flags = BRCMF_PRIMARY_KEY;
177         switch (params->cipher) {
178         case WLAN_CIPHER_SUITE_WEP40:
179                 key->algo = CRYPTO_ALGO_WEP1;
180 @@ -2237,7 +2193,7 @@ brcmf_cfg80211_add_key(struct wiphy *wip
181         }
182  
183         err = send_key_to_dongle(ifp, key);
184 -       if (err)
185 +       if (ext_key || err)
186                 goto done;
187  
188         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
189 @@ -2256,38 +2212,6 @@ done:
190         brcmf_dbg(TRACE, "Exit\n");
191         return err;
192  }
193 -
194 -static s32
195 -brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
196 -                   u8 key_idx, bool pairwise, const u8 *mac_addr)
197 -{
198 -       struct brcmf_if *ifp = netdev_priv(ndev);
199 -       struct brcmf_wsec_key key;
200 -       s32 err = 0;
201 -
202 -       brcmf_dbg(TRACE, "Enter\n");
203 -       if (!check_vif_up(ifp->vif))
204 -               return -EIO;
205 -
206 -       if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
207 -               /* we ignore this key index in this case */
208 -               return -EINVAL;
209 -       }
210 -
211 -       memset(&key, 0, sizeof(key));
212 -
213 -       key.index = (u32) key_idx;
214 -       key.flags = BRCMF_PRIMARY_KEY;
215 -       key.algo = CRYPTO_ALGO_OFF;
216 -
217 -       brcmf_dbg(CONN, "key index (%d)\n", key_idx);
218 -
219 -       /* Set the new key/index */
220 -       err = send_key_to_dongle(ifp, &key);
221 -
222 -       brcmf_dbg(TRACE, "Exit\n");
223 -       return err;
224 -}
225  
226  static s32
227  brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,