GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / net / wireless / realtek / rtw89 / cam.c
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2019-2020  Realtek Corporation
3  */
4
5 #include "cam.h"
6 #include "debug.h"
7 #include "fw.h"
8 #include "mac.h"
9
10 static struct sk_buff *
11 rtw89_cam_get_sec_key_cmd(struct rtw89_dev *rtwdev,
12                           struct rtw89_sec_cam_entry *sec_cam,
13                           bool ext_key)
14 {
15         struct sk_buff *skb;
16         u32 cmd_len = H2C_SEC_CAM_LEN;
17         u32 key32[4];
18         u8 *cmd;
19         int i, j;
20
21         skb = rtw89_fw_h2c_alloc_skb_with_hdr(rtwdev, cmd_len);
22         if (!skb)
23                 return NULL;
24
25         skb_put_zero(skb, cmd_len);
26
27         for (i = 0; i < 4; i++) {
28                 j = i * 4;
29                 j += ext_key ? 16 : 0;
30                 key32[i] = FIELD_PREP(GENMASK(7, 0), sec_cam->key[j + 0]) |
31                            FIELD_PREP(GENMASK(15, 8), sec_cam->key[j + 1]) |
32                            FIELD_PREP(GENMASK(23, 16), sec_cam->key[j + 2]) |
33                            FIELD_PREP(GENMASK(31, 24), sec_cam->key[j + 3]);
34         }
35
36         cmd = skb->data;
37         RTW89_SET_FWCMD_SEC_IDX(cmd, sec_cam->sec_cam_idx + (ext_key ? 1 : 0));
38         RTW89_SET_FWCMD_SEC_OFFSET(cmd, sec_cam->offset);
39         RTW89_SET_FWCMD_SEC_LEN(cmd, sec_cam->len);
40         RTW89_SET_FWCMD_SEC_TYPE(cmd, sec_cam->type);
41         RTW89_SET_FWCMD_SEC_EXT_KEY(cmd, ext_key);
42         RTW89_SET_FWCMD_SEC_SPP_MODE(cmd, sec_cam->spp_mode);
43         RTW89_SET_FWCMD_SEC_KEY0(cmd, key32[0]);
44         RTW89_SET_FWCMD_SEC_KEY1(cmd, key32[1]);
45         RTW89_SET_FWCMD_SEC_KEY2(cmd, key32[2]);
46         RTW89_SET_FWCMD_SEC_KEY3(cmd, key32[3]);
47
48         return skb;
49 }
50
51 static int rtw89_cam_send_sec_key_cmd(struct rtw89_dev *rtwdev,
52                                       struct rtw89_sec_cam_entry *sec_cam)
53 {
54         struct sk_buff *skb, *ext_skb;
55         int ret;
56
57         skb = rtw89_cam_get_sec_key_cmd(rtwdev, sec_cam, false);
58         if (!skb) {
59                 rtw89_err(rtwdev, "failed to get sec key command\n");
60                 return -ENOMEM;
61         }
62
63         rtw89_h2c_pkt_set_hdr(rtwdev, skb,
64                               FWCMD_TYPE_H2C,
65                               H2C_CAT_MAC,
66                               H2C_CL_MAC_SEC_CAM,
67                               H2C_FUNC_MAC_SEC_UPD, 1, 0,
68                               H2C_SEC_CAM_LEN);
69         ret = rtw89_h2c_tx(rtwdev, skb, false);
70         if (ret) {
71                 rtw89_err(rtwdev, "failed to send sec key h2c: %d\n", ret);
72                 dev_kfree_skb(skb);
73                 return ret;
74         }
75
76         if (!sec_cam->ext_key)
77                 return 0;
78
79         ext_skb = rtw89_cam_get_sec_key_cmd(rtwdev, sec_cam, true);
80         if (!ext_skb) {
81                 rtw89_err(rtwdev, "failed to get ext sec key command\n");
82                 return -ENOMEM;
83         }
84
85         rtw89_h2c_pkt_set_hdr(rtwdev, ext_skb,
86                               FWCMD_TYPE_H2C,
87                               H2C_CAT_MAC,
88                               H2C_CL_MAC_SEC_CAM,
89                               H2C_FUNC_MAC_SEC_UPD,
90                               1, 0, H2C_SEC_CAM_LEN);
91         ret = rtw89_h2c_tx(rtwdev, ext_skb, false);
92         if (ret) {
93                 rtw89_err(rtwdev, "failed to send ext sec key h2c: %d\n", ret);
94                 dev_kfree_skb(ext_skb);
95                 return ret;
96         }
97
98         return 0;
99 }
100
101 static int rtw89_cam_get_avail_sec_cam(struct rtw89_dev *rtwdev,
102                                        u8 *sec_cam_idx, bool ext_key)
103 {
104         const struct rtw89_chip_info *chip = rtwdev->chip;
105         struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
106         u8 sec_cam_num = chip->scam_num;
107         u8 idx = 0;
108
109         if (!ext_key) {
110                 idx = find_first_zero_bit(cam_info->sec_cam_map, sec_cam_num);
111                 if (idx >= sec_cam_num)
112                         return -EBUSY;
113
114                 set_bit(idx, cam_info->sec_cam_map);
115                 *sec_cam_idx = idx;
116
117                 return 0;
118         }
119
120 again:
121         idx = find_next_zero_bit(cam_info->sec_cam_map, sec_cam_num, idx);
122         if (idx >= sec_cam_num - 1)
123                 return -EBUSY;
124         /* ext keys need two cam entries for 256-bit key */
125         if (test_bit(idx + 1, cam_info->sec_cam_map)) {
126                 idx++;
127                 goto again;
128         }
129
130         set_bit(idx, cam_info->sec_cam_map);
131         set_bit(idx + 1, cam_info->sec_cam_map);
132         *sec_cam_idx = idx;
133
134         return 0;
135 }
136
137 static int rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry *addr_cam,
138                                           struct rtw89_sec_cam_entry *sec_cam,
139                                           struct ieee80211_key_conf *key,
140                                           u8 *key_idx)
141 {
142         u8 idx;
143
144         /* RTW89_ADDR_CAM_SEC_NONE      : not enabled
145          * RTW89_ADDR_CAM_SEC_ALL_UNI   : 0 - 6 unicast
146          * RTW89_ADDR_CAM_SEC_NORMAL    : 0 - 1 unicast, 2 - 4 group, 5 - 6 BIP
147          * RTW89_ADDR_CAM_SEC_4GROUP    : 0 - 1 unicast, 2 - 5 group, 6 BIP
148          */
149         switch (addr_cam->sec_ent_mode) {
150         case RTW89_ADDR_CAM_SEC_NONE:
151                 return -EINVAL;
152         case RTW89_ADDR_CAM_SEC_ALL_UNI:
153                 if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE))
154                         return -EINVAL;
155                 idx = find_first_zero_bit(addr_cam->sec_cam_map,
156                                           RTW89_SEC_CAM_IN_ADDR_CAM);
157                 if (idx >= RTW89_SEC_CAM_IN_ADDR_CAM)
158                         return -EBUSY;
159                 *key_idx = idx;
160                 break;
161         case RTW89_ADDR_CAM_SEC_NORMAL:
162                 if (sec_cam->type == RTW89_SEC_KEY_TYPE_BIP_CCMP128) {
163                         idx = find_next_zero_bit(addr_cam->sec_cam_map,
164                                                  RTW89_SEC_CAM_IN_ADDR_CAM, 5);
165                         if (idx > 6)
166                                 return -EBUSY;
167                         *key_idx = idx;
168                         break;
169                 }
170
171                 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
172                         idx = find_next_zero_bit(addr_cam->sec_cam_map,
173                                                  RTW89_SEC_CAM_IN_ADDR_CAM, 0);
174                         if (idx > 1)
175                                 return -EBUSY;
176                         *key_idx = idx;
177                         break;
178                 }
179
180                 /* Group keys */
181                 idx = find_next_zero_bit(addr_cam->sec_cam_map,
182                                          RTW89_SEC_CAM_IN_ADDR_CAM, 2);
183                 if (idx > 4)
184                         return -EBUSY;
185                 *key_idx = idx;
186                 break;
187         case RTW89_ADDR_CAM_SEC_4GROUP:
188                 if (sec_cam->type == RTW89_SEC_KEY_TYPE_BIP_CCMP128) {
189                         if (test_bit(6, addr_cam->sec_cam_map))
190                                 return -EINVAL;
191                         *key_idx = 6;
192                         break;
193                 }
194
195                 if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
196                         idx = find_next_zero_bit(addr_cam->sec_cam_map,
197                                                  RTW89_SEC_CAM_IN_ADDR_CAM, 0);
198                         if (idx > 1)
199                                 return -EBUSY;
200                         *key_idx = idx;
201                         break;
202                 }
203
204                 /* Group keys */
205                 idx = find_next_zero_bit(addr_cam->sec_cam_map,
206                                          RTW89_SEC_CAM_IN_ADDR_CAM, 2);
207                 if (idx > 5)
208                         return -EBUSY;
209                 *key_idx = idx;
210                 break;
211         }
212
213         return 0;
214 }
215
216 static int rtw89_cam_attach_sec_cam(struct rtw89_dev *rtwdev,
217                                     struct ieee80211_vif *vif,
218                                     struct ieee80211_sta *sta,
219                                     struct ieee80211_key_conf *key,
220                                     struct rtw89_sec_cam_entry *sec_cam)
221 {
222         struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
223         struct rtw89_vif *rtwvif;
224         struct rtw89_addr_cam_entry *addr_cam;
225         u8 key_idx = 0;
226         int ret;
227
228         if (!vif) {
229                 rtw89_err(rtwdev, "No iface for adding sec cam\n");
230                 return -EINVAL;
231         }
232
233         rtwvif = (struct rtw89_vif *)vif->drv_priv;
234         addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
235         ret = rtw89_cam_get_addr_cam_key_idx(addr_cam, sec_cam, key, &key_idx);
236         if (ret) {
237                 rtw89_err(rtwdev, "failed to get addr cam key idx %d, %d\n",
238                           addr_cam->sec_ent_mode, sec_cam->type);
239                 return ret;
240         }
241
242         key->hw_key_idx = key_idx;
243         addr_cam->sec_ent_keyid[key_idx] = key->keyidx;
244         addr_cam->sec_ent[key_idx] = sec_cam->sec_cam_idx;
245         addr_cam->sec_entries[key_idx] = sec_cam;
246         set_bit(key_idx, addr_cam->sec_cam_map);
247         ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
248         if (ret) {
249                 rtw89_err(rtwdev, "failed to update dctl cam sec entry: %d\n",
250                           ret);
251                 return ret;
252         }
253         ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
254         if (ret) {
255                 rtw89_err(rtwdev, "failed to update addr cam sec entry: %d\n",
256                           ret);
257                 clear_bit(key_idx, addr_cam->sec_cam_map);
258                 addr_cam->sec_entries[key_idx] = NULL;
259                 return ret;
260         }
261
262         return 0;
263 }
264
265 static int rtw89_cam_sec_key_install(struct rtw89_dev *rtwdev,
266                                      struct ieee80211_vif *vif,
267                                      struct ieee80211_sta *sta,
268                                      struct ieee80211_key_conf *key,
269                                      u8 hw_key_type, bool ext_key)
270 {
271         struct rtw89_sec_cam_entry *sec_cam = NULL;
272         struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
273         u8 sec_cam_idx;
274         int ret;
275
276         /* maximum key length 256-bit */
277         if (key->keylen > 32) {
278                 rtw89_err(rtwdev, "invalid sec key length %d\n", key->keylen);
279                 return -EINVAL;
280         }
281
282         ret = rtw89_cam_get_avail_sec_cam(rtwdev, &sec_cam_idx, ext_key);
283         if (ret) {
284                 rtw89_warn(rtwdev, "no available sec cam: %d ext: %d\n",
285                            ret, ext_key);
286                 return ret;
287         }
288
289         sec_cam = kzalloc(sizeof(*sec_cam), GFP_KERNEL);
290         if (!sec_cam) {
291                 ret = -ENOMEM;
292                 goto err_release_cam;
293         }
294
295         sec_cam->sec_cam_idx = sec_cam_idx;
296         sec_cam->type = hw_key_type;
297         sec_cam->len = RTW89_SEC_CAM_LEN;
298         sec_cam->ext_key = ext_key;
299         memcpy(sec_cam->key, key->key, key->keylen);
300         ret = rtw89_cam_send_sec_key_cmd(rtwdev, sec_cam);
301         if (ret) {
302                 rtw89_err(rtwdev, "failed to send sec key cmd: %d\n", ret);
303                 goto err_release_cam;
304         }
305
306         /* associate with addr cam */
307         ret = rtw89_cam_attach_sec_cam(rtwdev, vif, sta, key, sec_cam);
308         if (ret) {
309                 rtw89_err(rtwdev, "failed to attach sec cam: %d\n", ret);
310                 goto err_release_cam;
311         }
312
313         return 0;
314
315 err_release_cam:
316         kfree(sec_cam);
317         clear_bit(sec_cam_idx, cam_info->sec_cam_map);
318         if (ext_key)
319                 clear_bit(sec_cam_idx + 1, cam_info->sec_cam_map);
320
321         return ret;
322 }
323
324 int rtw89_cam_sec_key_add(struct rtw89_dev *rtwdev,
325                           struct ieee80211_vif *vif,
326                           struct ieee80211_sta *sta,
327                           struct ieee80211_key_conf *key)
328 {
329         const struct rtw89_chip_info *chip = rtwdev->chip;
330         u8 hw_key_type;
331         bool ext_key = false;
332         int ret;
333
334         switch (key->cipher) {
335         case WLAN_CIPHER_SUITE_WEP40:
336                 hw_key_type = RTW89_SEC_KEY_TYPE_WEP40;
337                 break;
338         case WLAN_CIPHER_SUITE_WEP104:
339                 hw_key_type = RTW89_SEC_KEY_TYPE_WEP104;
340                 break;
341         case WLAN_CIPHER_SUITE_CCMP:
342                 hw_key_type = RTW89_SEC_KEY_TYPE_CCMP128;
343                 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
344                 break;
345         case WLAN_CIPHER_SUITE_CCMP_256:
346                 hw_key_type = RTW89_SEC_KEY_TYPE_CCMP256;
347                 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
348                 ext_key = true;
349                 break;
350         case WLAN_CIPHER_SUITE_GCMP:
351                 hw_key_type = RTW89_SEC_KEY_TYPE_GCMP128;
352                 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
353                 break;
354         case WLAN_CIPHER_SUITE_GCMP_256:
355                 hw_key_type = RTW89_SEC_KEY_TYPE_GCMP256;
356                 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
357                 ext_key = true;
358                 break;
359         default:
360                 return -EOPNOTSUPP;
361         }
362
363         if (!chip->hw_sec_hdr)
364                 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
365
366         ret = rtw89_cam_sec_key_install(rtwdev, vif, sta, key, hw_key_type,
367                                         ext_key);
368         if (ret) {
369                 rtw89_err(rtwdev, "failed to install key type %d ext %d: %d\n",
370                           hw_key_type, ext_key, ret);
371                 return ret;
372         }
373
374         return 0;
375 }
376
377 int rtw89_cam_sec_key_del(struct rtw89_dev *rtwdev,
378                           struct ieee80211_vif *vif,
379                           struct ieee80211_sta *sta,
380                           struct ieee80211_key_conf *key,
381                           bool inform_fw)
382 {
383         struct rtw89_sta *rtwsta = sta_to_rtwsta_safe(sta);
384         struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
385         struct rtw89_vif *rtwvif;
386         struct rtw89_addr_cam_entry *addr_cam;
387         struct rtw89_sec_cam_entry *sec_cam;
388         u8 key_idx = key->hw_key_idx;
389         u8 sec_cam_idx;
390         int ret = 0;
391
392         if (!vif) {
393                 rtw89_err(rtwdev, "No iface for deleting sec cam\n");
394                 return -EINVAL;
395         }
396
397         rtwvif = (struct rtw89_vif *)vif->drv_priv;
398         addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
399         sec_cam = addr_cam->sec_entries[key_idx];
400         if (!sec_cam)
401                 return -EINVAL;
402
403         /* detach sec cam from addr cam */
404         clear_bit(key_idx, addr_cam->sec_cam_map);
405         addr_cam->sec_entries[key_idx] = NULL;
406         if (inform_fw) {
407                 ret = rtw89_chip_h2c_dctl_sec_cam(rtwdev, rtwvif, rtwsta);
408                 if (ret)
409                         rtw89_err(rtwdev, "failed to update dctl cam del key: %d\n", ret);
410                 ret = rtw89_fw_h2c_cam(rtwdev, rtwvif, rtwsta, NULL);
411                 if (ret)
412                         rtw89_err(rtwdev, "failed to update cam del key: %d\n", ret);
413         }
414
415         /* clear valid bit in addr cam will disable sec cam,
416          * so we don't need to send H2C command again
417          */
418         sec_cam_idx = sec_cam->sec_cam_idx;
419         clear_bit(sec_cam_idx, cam_info->sec_cam_map);
420         if (sec_cam->ext_key)
421                 clear_bit(sec_cam_idx + 1, cam_info->sec_cam_map);
422
423         kfree(sec_cam);
424
425         return ret;
426 }
427
428 static void rtw89_cam_reset_key_iter(struct ieee80211_hw *hw,
429                                      struct ieee80211_vif *vif,
430                                      struct ieee80211_sta *sta,
431                                      struct ieee80211_key_conf *key,
432                                      void *data)
433 {
434         struct rtw89_dev *rtwdev = (struct rtw89_dev *)data;
435
436         rtw89_cam_sec_key_del(rtwdev, vif, sta, key, false);
437 }
438
439 void rtw89_cam_deinit_addr_cam(struct rtw89_dev *rtwdev,
440                                struct rtw89_addr_cam_entry *addr_cam)
441 {
442         struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
443
444         addr_cam->valid = false;
445         clear_bit(addr_cam->addr_cam_idx, cam_info->addr_cam_map);
446 }
447
448 void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
449 {
450         struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
451         struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
452         struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
453
454         rtw89_cam_deinit_addr_cam(rtwdev, addr_cam);
455         bssid_cam->valid = false;
456         clear_bit(bssid_cam->bssid_cam_idx, cam_info->bssid_cam_map);
457 }
458
459 void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev)
460 {
461         rcu_read_lock();
462         ieee80211_iter_keys_rcu(rtwdev->hw, NULL, rtw89_cam_reset_key_iter, rtwdev);
463         rcu_read_unlock();
464 }
465
466 static int rtw89_cam_get_avail_addr_cam(struct rtw89_dev *rtwdev,
467                                         u8 *addr_cam_idx)
468 {
469         const struct rtw89_chip_info *chip = rtwdev->chip;
470         struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
471         u8 addr_cam_num = chip->acam_num;
472         u8 idx;
473
474         idx = find_first_zero_bit(cam_info->addr_cam_map, addr_cam_num);
475         if (idx >= addr_cam_num)
476                 return -EBUSY;
477
478         set_bit(idx, cam_info->addr_cam_map);
479         *addr_cam_idx = idx;
480
481         return 0;
482 }
483
484 int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev,
485                             struct rtw89_addr_cam_entry *addr_cam,
486                             const struct rtw89_bssid_cam_entry *bssid_cam)
487 {
488         u8 addr_cam_idx;
489         int i;
490         int ret;
491
492         if (unlikely(addr_cam->valid)) {
493                 rtw89_debug(rtwdev, RTW89_DBG_FW,
494                             "addr cam is already valid; skip init\n");
495                 return 0;
496         }
497
498         ret = rtw89_cam_get_avail_addr_cam(rtwdev, &addr_cam_idx);
499         if (ret) {
500                 rtw89_err(rtwdev, "failed to get available addr cam\n");
501                 return ret;
502         }
503
504         addr_cam->addr_cam_idx = addr_cam_idx;
505         addr_cam->len = ADDR_CAM_ENT_SIZE;
506         addr_cam->offset = 0;
507         addr_cam->valid = true;
508         addr_cam->addr_mask = 0;
509         addr_cam->mask_sel = RTW89_NO_MSK;
510         addr_cam->sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL;
511         bitmap_zero(addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM);
512
513         for (i = 0; i < RTW89_SEC_CAM_IN_ADDR_CAM; i++) {
514                 addr_cam->sec_ent_keyid[i] = 0;
515                 addr_cam->sec_ent[i] = 0;
516         }
517
518         /* associate addr cam with bssid cam */
519         addr_cam->bssid_cam_idx = bssid_cam->bssid_cam_idx;
520
521         return 0;
522 }
523
524 static int rtw89_cam_get_avail_bssid_cam(struct rtw89_dev *rtwdev,
525                                          u8 *bssid_cam_idx)
526 {
527         const struct rtw89_chip_info *chip = rtwdev->chip;
528         struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
529         u8 bssid_cam_num = chip->bcam_num;
530         u8 idx;
531
532         idx = find_first_zero_bit(cam_info->bssid_cam_map, bssid_cam_num);
533         if (idx >= bssid_cam_num)
534                 return -EBUSY;
535
536         set_bit(idx, cam_info->bssid_cam_map);
537         *bssid_cam_idx = idx;
538
539         return 0;
540 }
541
542 static int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
543                                     struct rtw89_vif *rtwvif)
544 {
545         struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
546         u8 bssid_cam_idx;
547         int ret;
548
549         if (unlikely(bssid_cam->valid)) {
550                 rtw89_debug(rtwdev, RTW89_DBG_FW,
551                             "bssid cam is already valid; skip init\n");
552                 return 0;
553         }
554
555         ret = rtw89_cam_get_avail_bssid_cam(rtwdev, &bssid_cam_idx);
556         if (ret) {
557                 rtw89_err(rtwdev, "failed to get available bssid cam\n");
558                 return ret;
559         }
560
561         bssid_cam->bssid_cam_idx = bssid_cam_idx;
562         bssid_cam->phy_idx = rtwvif->phy_idx;
563         bssid_cam->len = BSSID_CAM_ENT_SIZE;
564         bssid_cam->offset = 0;
565         bssid_cam->valid = true;
566         ether_addr_copy(bssid_cam->bssid, rtwvif->bssid);
567
568         return 0;
569 }
570
571 void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
572 {
573         struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
574
575         ether_addr_copy(bssid_cam->bssid, rtwvif->bssid);
576 }
577
578 int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
579 {
580         struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
581         struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
582         int ret;
583
584         ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif);
585         if (ret) {
586                 rtw89_err(rtwdev, "failed to init bssid cam\n");
587                 return ret;
588         }
589
590         ret = rtw89_cam_init_addr_cam(rtwdev, addr_cam, bssid_cam);
591         if (ret) {
592                 rtw89_err(rtwdev, "failed to init addr cam\n");
593                 return ret;
594         }
595
596         return 0;
597 }
598
599 int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
600                                   struct rtw89_vif *rtwvif, u8 *cmd)
601 {
602         struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
603         struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
604         u8 bss_color = vif->bss_conf.he_bss_color.color;
605
606         FWCMD_SET_ADDR_BSSID_IDX(cmd, bssid_cam->bssid_cam_idx);
607         FWCMD_SET_ADDR_BSSID_OFFSET(cmd, bssid_cam->offset);
608         FWCMD_SET_ADDR_BSSID_LEN(cmd, bssid_cam->len);
609         FWCMD_SET_ADDR_BSSID_VALID(cmd, bssid_cam->valid);
610         FWCMD_SET_ADDR_BSSID_BB_SEL(cmd, bssid_cam->phy_idx);
611         FWCMD_SET_ADDR_BSSID_BSS_COLOR(cmd, bss_color);
612
613         FWCMD_SET_ADDR_BSSID_BSSID0(cmd, bssid_cam->bssid[0]);
614         FWCMD_SET_ADDR_BSSID_BSSID1(cmd, bssid_cam->bssid[1]);
615         FWCMD_SET_ADDR_BSSID_BSSID2(cmd, bssid_cam->bssid[2]);
616         FWCMD_SET_ADDR_BSSID_BSSID3(cmd, bssid_cam->bssid[3]);
617         FWCMD_SET_ADDR_BSSID_BSSID4(cmd, bssid_cam->bssid[4]);
618         FWCMD_SET_ADDR_BSSID_BSSID5(cmd, bssid_cam->bssid[5]);
619
620         return 0;
621 }
622
623 static u8 rtw89_cam_addr_hash(u8 start, const u8 *addr)
624 {
625         u8 hash = 0;
626         u8 i;
627
628         for (i = start; i < ETH_ALEN; i++)
629                 hash ^= addr[i];
630
631         return hash;
632 }
633
634 void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
635                                   struct rtw89_vif *rtwvif,
636                                   struct rtw89_sta *rtwsta,
637                                   const u8 *scan_mac_addr,
638                                   u8 *cmd)
639 {
640         struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
641         struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
642         struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta);
643         const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif->mac_addr;
644         u8 sma_hash, tma_hash, addr_msk_start;
645         u8 sma_start = 0;
646         u8 tma_start = 0;
647         u8 *tma = sta ? sta->addr : rtwvif->bssid;
648
649         if (addr_cam->addr_mask != 0) {
650                 addr_msk_start = __ffs(addr_cam->addr_mask);
651                 if (addr_cam->mask_sel == RTW89_SMA)
652                         sma_start = addr_msk_start;
653                 else if (addr_cam->mask_sel == RTW89_TMA)
654                         tma_start = addr_msk_start;
655         }
656         sma_hash = rtw89_cam_addr_hash(sma_start, sma);
657         tma_hash = rtw89_cam_addr_hash(tma_start, tma);
658
659         FWCMD_SET_ADDR_IDX(cmd, addr_cam->addr_cam_idx);
660         FWCMD_SET_ADDR_OFFSET(cmd, addr_cam->offset);
661         FWCMD_SET_ADDR_LEN(cmd, addr_cam->len);
662
663         FWCMD_SET_ADDR_VALID(cmd, addr_cam->valid);
664         FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif->net_type);
665         FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif->bcn_hit_cond);
666         FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif->hit_rule);
667         FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif->phy_idx);
668         FWCMD_SET_ADDR_ADDR_MASK(cmd, addr_cam->addr_mask);
669         FWCMD_SET_ADDR_MASK_SEL(cmd, addr_cam->mask_sel);
670         FWCMD_SET_ADDR_SMA_HASH(cmd, sma_hash);
671         FWCMD_SET_ADDR_TMA_HASH(cmd, tma_hash);
672
673         FWCMD_SET_ADDR_BSSID_CAM_IDX(cmd, addr_cam->bssid_cam_idx);
674
675         FWCMD_SET_ADDR_SMA0(cmd, sma[0]);
676         FWCMD_SET_ADDR_SMA1(cmd, sma[1]);
677         FWCMD_SET_ADDR_SMA2(cmd, sma[2]);
678         FWCMD_SET_ADDR_SMA3(cmd, sma[3]);
679         FWCMD_SET_ADDR_SMA4(cmd, sma[4]);
680         FWCMD_SET_ADDR_SMA5(cmd, sma[5]);
681
682         FWCMD_SET_ADDR_TMA0(cmd, tma[0]);
683         FWCMD_SET_ADDR_TMA1(cmd, tma[1]);
684         FWCMD_SET_ADDR_TMA2(cmd, tma[2]);
685         FWCMD_SET_ADDR_TMA3(cmd, tma[3]);
686         FWCMD_SET_ADDR_TMA4(cmd, tma[4]);
687         FWCMD_SET_ADDR_TMA5(cmd, tma[5]);
688
689         FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif->port);
690         FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif->port);
691         FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif->trigger);
692         FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif->lsig_txop);
693         FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif->tgt_ind);
694         FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif->frm_tgt_ind);
695         FWCMD_SET_ADDR_MACID(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
696         if (rtwvif->net_type == RTW89_NET_TYPE_INFRA)
697                 FWCMD_SET_ADDR_AID12(cmd, vif->bss_conf.aid & 0xfff);
698         else if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
699                 FWCMD_SET_ADDR_AID12(cmd, sta ? sta->aid & 0xfff : 0);
700         FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif->wowlan_pattern);
701         FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif->wowlan_uc);
702         FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif->wowlan_magic);
703         FWCMD_SET_ADDR_WAPI(cmd, addr_cam->wapi);
704         FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, addr_cam->sec_ent_mode);
705         FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, addr_cam->sec_ent_keyid[0]);
706         FWCMD_SET_ADDR_SEC_ENT1_KEYID(cmd, addr_cam->sec_ent_keyid[1]);
707         FWCMD_SET_ADDR_SEC_ENT2_KEYID(cmd, addr_cam->sec_ent_keyid[2]);
708         FWCMD_SET_ADDR_SEC_ENT3_KEYID(cmd, addr_cam->sec_ent_keyid[3]);
709         FWCMD_SET_ADDR_SEC_ENT4_KEYID(cmd, addr_cam->sec_ent_keyid[4]);
710         FWCMD_SET_ADDR_SEC_ENT5_KEYID(cmd, addr_cam->sec_ent_keyid[5]);
711         FWCMD_SET_ADDR_SEC_ENT6_KEYID(cmd, addr_cam->sec_ent_keyid[6]);
712
713         FWCMD_SET_ADDR_SEC_ENT_VALID(cmd, addr_cam->sec_cam_map[0] & 0xff);
714         FWCMD_SET_ADDR_SEC_ENT0(cmd, addr_cam->sec_ent[0]);
715         FWCMD_SET_ADDR_SEC_ENT1(cmd, addr_cam->sec_ent[1]);
716         FWCMD_SET_ADDR_SEC_ENT2(cmd, addr_cam->sec_ent[2]);
717         FWCMD_SET_ADDR_SEC_ENT3(cmd, addr_cam->sec_ent[3]);
718         FWCMD_SET_ADDR_SEC_ENT4(cmd, addr_cam->sec_ent[4]);
719         FWCMD_SET_ADDR_SEC_ENT5(cmd, addr_cam->sec_ent[5]);
720         FWCMD_SET_ADDR_SEC_ENT6(cmd, addr_cam->sec_ent[6]);
721 }
722
723 void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
724                                          struct rtw89_vif *rtwvif,
725                                          struct rtw89_sta *rtwsta,
726                                          u8 *cmd)
727 {
728         struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
729
730         SET_DCTL_MACID_V1(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
731         SET_DCTL_OPERATION_V1(cmd, 1);
732
733         SET_DCTL_SEC_ENT0_KEYID_V1(cmd, addr_cam->sec_ent_keyid[0]);
734         SET_DCTL_SEC_ENT1_KEYID_V1(cmd, addr_cam->sec_ent_keyid[1]);
735         SET_DCTL_SEC_ENT2_KEYID_V1(cmd, addr_cam->sec_ent_keyid[2]);
736         SET_DCTL_SEC_ENT3_KEYID_V1(cmd, addr_cam->sec_ent_keyid[3]);
737         SET_DCTL_SEC_ENT4_KEYID_V1(cmd, addr_cam->sec_ent_keyid[4]);
738         SET_DCTL_SEC_ENT5_KEYID_V1(cmd, addr_cam->sec_ent_keyid[5]);
739         SET_DCTL_SEC_ENT6_KEYID_V1(cmd, addr_cam->sec_ent_keyid[6]);
740
741         SET_DCTL_SEC_ENT_VALID_V1(cmd, addr_cam->sec_cam_map[0] & 0xff);
742         SET_DCTL_SEC_ENT0_V1(cmd, addr_cam->sec_ent[0]);
743         SET_DCTL_SEC_ENT1_V1(cmd, addr_cam->sec_ent[1]);
744         SET_DCTL_SEC_ENT2_V1(cmd, addr_cam->sec_ent[2]);
745         SET_DCTL_SEC_ENT3_V1(cmd, addr_cam->sec_ent[3]);
746         SET_DCTL_SEC_ENT4_V1(cmd, addr_cam->sec_ent[4]);
747         SET_DCTL_SEC_ENT5_V1(cmd, addr_cam->sec_ent[5]);
748         SET_DCTL_SEC_ENT6_V1(cmd, addr_cam->sec_ent[6]);
749 }