xref: /openbmc/linux/drivers/net/wireless/realtek/rtw89/cam.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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 *
rtw89_cam_get_sec_key_cmd(struct rtw89_dev * rtwdev,struct rtw89_sec_cam_entry * sec_cam,bool ext_key)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  
rtw89_cam_send_sec_key_cmd(struct rtw89_dev * rtwdev,struct rtw89_sec_cam_entry * sec_cam)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  
rtw89_cam_get_avail_sec_cam(struct rtw89_dev * rtwdev,u8 * sec_cam_idx,bool ext_key)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  
rtw89_cam_get_addr_cam_key_idx(struct rtw89_addr_cam_entry * addr_cam,struct rtw89_sec_cam_entry * sec_cam,struct ieee80211_key_conf * key,u8 * key_idx)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  
rtw89_cam_attach_sec_cam(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_key_conf * key,struct rtw89_sec_cam_entry * sec_cam)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  
rtw89_cam_sec_key_install(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_key_conf * key,u8 hw_key_type,bool ext_key)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  
rtw89_cam_sec_key_add(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_key_conf * key)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  
rtw89_cam_sec_key_del(struct rtw89_dev * rtwdev,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_key_conf * key,bool inform_fw)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  
rtw89_cam_reset_key_iter(struct ieee80211_hw * hw,struct ieee80211_vif * vif,struct ieee80211_sta * sta,struct ieee80211_key_conf * key,void * data)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  
rtw89_cam_deinit_addr_cam(struct rtw89_dev * rtwdev,struct rtw89_addr_cam_entry * addr_cam)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  
rtw89_cam_deinit_bssid_cam(struct rtw89_dev * rtwdev,struct rtw89_bssid_cam_entry * bssid_cam)448  void rtw89_cam_deinit_bssid_cam(struct rtw89_dev *rtwdev,
449  				struct rtw89_bssid_cam_entry *bssid_cam)
450  {
451  	struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
452  
453  	bssid_cam->valid = false;
454  	clear_bit(bssid_cam->bssid_cam_idx, cam_info->bssid_cam_map);
455  }
456  
rtw89_cam_deinit(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif)457  void rtw89_cam_deinit(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
458  {
459  	struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
460  	struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
461  
462  	rtw89_cam_deinit_addr_cam(rtwdev, addr_cam);
463  	rtw89_cam_deinit_bssid_cam(rtwdev, bssid_cam);
464  }
465  
rtw89_cam_reset_keys(struct rtw89_dev * rtwdev)466  void rtw89_cam_reset_keys(struct rtw89_dev *rtwdev)
467  {
468  	rcu_read_lock();
469  	ieee80211_iter_keys_rcu(rtwdev->hw, NULL, rtw89_cam_reset_key_iter, rtwdev);
470  	rcu_read_unlock();
471  }
472  
rtw89_cam_get_avail_addr_cam(struct rtw89_dev * rtwdev,u8 * addr_cam_idx)473  static int rtw89_cam_get_avail_addr_cam(struct rtw89_dev *rtwdev,
474  					u8 *addr_cam_idx)
475  {
476  	const struct rtw89_chip_info *chip = rtwdev->chip;
477  	struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
478  	u8 addr_cam_num = chip->acam_num;
479  	u8 idx;
480  
481  	idx = find_first_zero_bit(cam_info->addr_cam_map, addr_cam_num);
482  	if (idx >= addr_cam_num)
483  		return -EBUSY;
484  
485  	set_bit(idx, cam_info->addr_cam_map);
486  	*addr_cam_idx = idx;
487  
488  	return 0;
489  }
490  
rtw89_cam_init_addr_cam(struct rtw89_dev * rtwdev,struct rtw89_addr_cam_entry * addr_cam,const struct rtw89_bssid_cam_entry * bssid_cam)491  int rtw89_cam_init_addr_cam(struct rtw89_dev *rtwdev,
492  			    struct rtw89_addr_cam_entry *addr_cam,
493  			    const struct rtw89_bssid_cam_entry *bssid_cam)
494  {
495  	u8 addr_cam_idx;
496  	int i;
497  	int ret;
498  
499  	if (unlikely(addr_cam->valid)) {
500  		rtw89_debug(rtwdev, RTW89_DBG_FW,
501  			    "addr cam is already valid; skip init\n");
502  		return 0;
503  	}
504  
505  	ret = rtw89_cam_get_avail_addr_cam(rtwdev, &addr_cam_idx);
506  	if (ret) {
507  		rtw89_err(rtwdev, "failed to get available addr cam\n");
508  		return ret;
509  	}
510  
511  	addr_cam->addr_cam_idx = addr_cam_idx;
512  	addr_cam->len = ADDR_CAM_ENT_SIZE;
513  	addr_cam->offset = 0;
514  	addr_cam->valid = true;
515  	addr_cam->addr_mask = 0;
516  	addr_cam->mask_sel = RTW89_NO_MSK;
517  	addr_cam->sec_ent_mode = RTW89_ADDR_CAM_SEC_NORMAL;
518  	bitmap_zero(addr_cam->sec_cam_map, RTW89_SEC_CAM_IN_ADDR_CAM);
519  
520  	for (i = 0; i < RTW89_SEC_CAM_IN_ADDR_CAM; i++) {
521  		addr_cam->sec_ent_keyid[i] = 0;
522  		addr_cam->sec_ent[i] = 0;
523  	}
524  
525  	/* associate addr cam with bssid cam */
526  	addr_cam->bssid_cam_idx = bssid_cam->bssid_cam_idx;
527  
528  	return 0;
529  }
530  
rtw89_cam_get_avail_bssid_cam(struct rtw89_dev * rtwdev,u8 * bssid_cam_idx)531  static int rtw89_cam_get_avail_bssid_cam(struct rtw89_dev *rtwdev,
532  					 u8 *bssid_cam_idx)
533  {
534  	const struct rtw89_chip_info *chip = rtwdev->chip;
535  	struct rtw89_cam_info *cam_info = &rtwdev->cam_info;
536  	u8 bssid_cam_num = chip->bcam_num;
537  	u8 idx;
538  
539  	idx = find_first_zero_bit(cam_info->bssid_cam_map, bssid_cam_num);
540  	if (idx >= bssid_cam_num)
541  		return -EBUSY;
542  
543  	set_bit(idx, cam_info->bssid_cam_map);
544  	*bssid_cam_idx = idx;
545  
546  	return 0;
547  }
548  
rtw89_cam_init_bssid_cam(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_bssid_cam_entry * bssid_cam,const u8 * bssid)549  int rtw89_cam_init_bssid_cam(struct rtw89_dev *rtwdev,
550  			     struct rtw89_vif *rtwvif,
551  			     struct rtw89_bssid_cam_entry *bssid_cam,
552  			     const u8 *bssid)
553  {
554  	u8 bssid_cam_idx;
555  	int ret;
556  
557  	if (unlikely(bssid_cam->valid)) {
558  		rtw89_debug(rtwdev, RTW89_DBG_FW,
559  			    "bssid cam is already valid; skip init\n");
560  		return 0;
561  	}
562  
563  	ret = rtw89_cam_get_avail_bssid_cam(rtwdev, &bssid_cam_idx);
564  	if (ret) {
565  		rtw89_err(rtwdev, "failed to get available bssid cam\n");
566  		return ret;
567  	}
568  
569  	bssid_cam->bssid_cam_idx = bssid_cam_idx;
570  	bssid_cam->phy_idx = rtwvif->phy_idx;
571  	bssid_cam->len = BSSID_CAM_ENT_SIZE;
572  	bssid_cam->offset = 0;
573  	bssid_cam->valid = true;
574  	ether_addr_copy(bssid_cam->bssid, bssid);
575  
576  	return 0;
577  }
578  
rtw89_cam_bssid_changed(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif)579  void rtw89_cam_bssid_changed(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
580  {
581  	struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
582  
583  	ether_addr_copy(bssid_cam->bssid, rtwvif->bssid);
584  }
585  
rtw89_cam_init(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif)586  int rtw89_cam_init(struct rtw89_dev *rtwdev, struct rtw89_vif *rtwvif)
587  {
588  	struct rtw89_addr_cam_entry *addr_cam = &rtwvif->addr_cam;
589  	struct rtw89_bssid_cam_entry *bssid_cam = &rtwvif->bssid_cam;
590  	int ret;
591  
592  	ret = rtw89_cam_init_bssid_cam(rtwdev, rtwvif, bssid_cam, rtwvif->bssid);
593  	if (ret) {
594  		rtw89_err(rtwdev, "failed to init bssid cam\n");
595  		return ret;
596  	}
597  
598  	ret = rtw89_cam_init_addr_cam(rtwdev, addr_cam, bssid_cam);
599  	if (ret) {
600  		rtw89_err(rtwdev, "failed to init addr cam\n");
601  		return ret;
602  	}
603  
604  	return 0;
605  }
606  
rtw89_cam_fill_bssid_cam_info(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_sta * rtwsta,u8 * cmd)607  int rtw89_cam_fill_bssid_cam_info(struct rtw89_dev *rtwdev,
608  				  struct rtw89_vif *rtwvif,
609  				  struct rtw89_sta *rtwsta, u8 *cmd)
610  {
611  	struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
612  	struct rtw89_bssid_cam_entry *bssid_cam = rtw89_get_bssid_cam_of(rtwvif, rtwsta);
613  	u8 bss_color = vif->bss_conf.he_bss_color.color;
614  	u8 bss_mask;
615  
616  	if (vif->bss_conf.nontransmitted)
617  		bss_mask = RTW89_BSSID_MATCH_5_BYTES;
618  	else
619  		bss_mask = RTW89_BSSID_MATCH_ALL;
620  
621  	FWCMD_SET_ADDR_BSSID_IDX(cmd, bssid_cam->bssid_cam_idx);
622  	FWCMD_SET_ADDR_BSSID_OFFSET(cmd, bssid_cam->offset);
623  	FWCMD_SET_ADDR_BSSID_LEN(cmd, bssid_cam->len);
624  	FWCMD_SET_ADDR_BSSID_VALID(cmd, bssid_cam->valid);
625  	FWCMD_SET_ADDR_BSSID_MASK(cmd, bss_mask);
626  	FWCMD_SET_ADDR_BSSID_BB_SEL(cmd, bssid_cam->phy_idx);
627  	FWCMD_SET_ADDR_BSSID_BSS_COLOR(cmd, bss_color);
628  
629  	FWCMD_SET_ADDR_BSSID_BSSID0(cmd, bssid_cam->bssid[0]);
630  	FWCMD_SET_ADDR_BSSID_BSSID1(cmd, bssid_cam->bssid[1]);
631  	FWCMD_SET_ADDR_BSSID_BSSID2(cmd, bssid_cam->bssid[2]);
632  	FWCMD_SET_ADDR_BSSID_BSSID3(cmd, bssid_cam->bssid[3]);
633  	FWCMD_SET_ADDR_BSSID_BSSID4(cmd, bssid_cam->bssid[4]);
634  	FWCMD_SET_ADDR_BSSID_BSSID5(cmd, bssid_cam->bssid[5]);
635  
636  	return 0;
637  }
638  
rtw89_cam_addr_hash(u8 start,const u8 * addr)639  static u8 rtw89_cam_addr_hash(u8 start, const u8 *addr)
640  {
641  	u8 hash = 0;
642  	u8 i;
643  
644  	for (i = start; i < ETH_ALEN; i++)
645  		hash ^= addr[i];
646  
647  	return hash;
648  }
649  
rtw89_cam_fill_addr_cam_info(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_sta * rtwsta,const u8 * scan_mac_addr,u8 * cmd)650  void rtw89_cam_fill_addr_cam_info(struct rtw89_dev *rtwdev,
651  				  struct rtw89_vif *rtwvif,
652  				  struct rtw89_sta *rtwsta,
653  				  const u8 *scan_mac_addr,
654  				  u8 *cmd)
655  {
656  	struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
657  	struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
658  	struct ieee80211_sta *sta = rtwsta_to_sta_safe(rtwsta);
659  	const u8 *sma = scan_mac_addr ? scan_mac_addr : rtwvif->mac_addr;
660  	u8 sma_hash, tma_hash, addr_msk_start;
661  	u8 sma_start = 0;
662  	u8 tma_start = 0;
663  	u8 *tma = sta ? sta->addr : rtwvif->bssid;
664  
665  	if (addr_cam->addr_mask != 0) {
666  		addr_msk_start = __ffs(addr_cam->addr_mask);
667  		if (addr_cam->mask_sel == RTW89_SMA)
668  			sma_start = addr_msk_start;
669  		else if (addr_cam->mask_sel == RTW89_TMA)
670  			tma_start = addr_msk_start;
671  	}
672  	sma_hash = rtw89_cam_addr_hash(sma_start, sma);
673  	tma_hash = rtw89_cam_addr_hash(tma_start, tma);
674  
675  	FWCMD_SET_ADDR_IDX(cmd, addr_cam->addr_cam_idx);
676  	FWCMD_SET_ADDR_OFFSET(cmd, addr_cam->offset);
677  	FWCMD_SET_ADDR_LEN(cmd, addr_cam->len);
678  
679  	FWCMD_SET_ADDR_VALID(cmd, addr_cam->valid);
680  	FWCMD_SET_ADDR_NET_TYPE(cmd, rtwvif->net_type);
681  	FWCMD_SET_ADDR_BCN_HIT_COND(cmd, rtwvif->bcn_hit_cond);
682  	FWCMD_SET_ADDR_HIT_RULE(cmd, rtwvif->hit_rule);
683  	FWCMD_SET_ADDR_BB_SEL(cmd, rtwvif->phy_idx);
684  	FWCMD_SET_ADDR_ADDR_MASK(cmd, addr_cam->addr_mask);
685  	FWCMD_SET_ADDR_MASK_SEL(cmd, addr_cam->mask_sel);
686  	FWCMD_SET_ADDR_SMA_HASH(cmd, sma_hash);
687  	FWCMD_SET_ADDR_TMA_HASH(cmd, tma_hash);
688  
689  	FWCMD_SET_ADDR_BSSID_CAM_IDX(cmd, addr_cam->bssid_cam_idx);
690  
691  	FWCMD_SET_ADDR_SMA0(cmd, sma[0]);
692  	FWCMD_SET_ADDR_SMA1(cmd, sma[1]);
693  	FWCMD_SET_ADDR_SMA2(cmd, sma[2]);
694  	FWCMD_SET_ADDR_SMA3(cmd, sma[3]);
695  	FWCMD_SET_ADDR_SMA4(cmd, sma[4]);
696  	FWCMD_SET_ADDR_SMA5(cmd, sma[5]);
697  
698  	FWCMD_SET_ADDR_TMA0(cmd, tma[0]);
699  	FWCMD_SET_ADDR_TMA1(cmd, tma[1]);
700  	FWCMD_SET_ADDR_TMA2(cmd, tma[2]);
701  	FWCMD_SET_ADDR_TMA3(cmd, tma[3]);
702  	FWCMD_SET_ADDR_TMA4(cmd, tma[4]);
703  	FWCMD_SET_ADDR_TMA5(cmd, tma[5]);
704  
705  	FWCMD_SET_ADDR_PORT_INT(cmd, rtwvif->port);
706  	FWCMD_SET_ADDR_TSF_SYNC(cmd, rtwvif->port);
707  	FWCMD_SET_ADDR_TF_TRS(cmd, rtwvif->trigger);
708  	FWCMD_SET_ADDR_LSIG_TXOP(cmd, rtwvif->lsig_txop);
709  	FWCMD_SET_ADDR_TGT_IND(cmd, rtwvif->tgt_ind);
710  	FWCMD_SET_ADDR_FRM_TGT_IND(cmd, rtwvif->frm_tgt_ind);
711  	FWCMD_SET_ADDR_MACID(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
712  	if (rtwvif->net_type == RTW89_NET_TYPE_INFRA)
713  		FWCMD_SET_ADDR_AID12(cmd, vif->cfg.aid & 0xfff);
714  	else if (rtwvif->net_type == RTW89_NET_TYPE_AP_MODE)
715  		FWCMD_SET_ADDR_AID12(cmd, sta ? sta->aid & 0xfff : 0);
716  	FWCMD_SET_ADDR_WOL_PATTERN(cmd, rtwvif->wowlan_pattern);
717  	FWCMD_SET_ADDR_WOL_UC(cmd, rtwvif->wowlan_uc);
718  	FWCMD_SET_ADDR_WOL_MAGIC(cmd, rtwvif->wowlan_magic);
719  	FWCMD_SET_ADDR_WAPI(cmd, addr_cam->wapi);
720  	FWCMD_SET_ADDR_SEC_ENT_MODE(cmd, addr_cam->sec_ent_mode);
721  	FWCMD_SET_ADDR_SEC_ENT0_KEYID(cmd, addr_cam->sec_ent_keyid[0]);
722  	FWCMD_SET_ADDR_SEC_ENT1_KEYID(cmd, addr_cam->sec_ent_keyid[1]);
723  	FWCMD_SET_ADDR_SEC_ENT2_KEYID(cmd, addr_cam->sec_ent_keyid[2]);
724  	FWCMD_SET_ADDR_SEC_ENT3_KEYID(cmd, addr_cam->sec_ent_keyid[3]);
725  	FWCMD_SET_ADDR_SEC_ENT4_KEYID(cmd, addr_cam->sec_ent_keyid[4]);
726  	FWCMD_SET_ADDR_SEC_ENT5_KEYID(cmd, addr_cam->sec_ent_keyid[5]);
727  	FWCMD_SET_ADDR_SEC_ENT6_KEYID(cmd, addr_cam->sec_ent_keyid[6]);
728  
729  	FWCMD_SET_ADDR_SEC_ENT_VALID(cmd, addr_cam->sec_cam_map[0] & 0xff);
730  	FWCMD_SET_ADDR_SEC_ENT0(cmd, addr_cam->sec_ent[0]);
731  	FWCMD_SET_ADDR_SEC_ENT1(cmd, addr_cam->sec_ent[1]);
732  	FWCMD_SET_ADDR_SEC_ENT2(cmd, addr_cam->sec_ent[2]);
733  	FWCMD_SET_ADDR_SEC_ENT3(cmd, addr_cam->sec_ent[3]);
734  	FWCMD_SET_ADDR_SEC_ENT4(cmd, addr_cam->sec_ent[4]);
735  	FWCMD_SET_ADDR_SEC_ENT5(cmd, addr_cam->sec_ent[5]);
736  	FWCMD_SET_ADDR_SEC_ENT6(cmd, addr_cam->sec_ent[6]);
737  }
738  
rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev * rtwdev,struct rtw89_vif * rtwvif,struct rtw89_sta * rtwsta,u8 * cmd)739  void rtw89_cam_fill_dctl_sec_cam_info_v1(struct rtw89_dev *rtwdev,
740  					 struct rtw89_vif *rtwvif,
741  					 struct rtw89_sta *rtwsta,
742  					 u8 *cmd)
743  {
744  	struct rtw89_addr_cam_entry *addr_cam = rtw89_get_addr_cam_of(rtwvif, rtwsta);
745  
746  	SET_DCTL_MACID_V1(cmd, rtwsta ? rtwsta->mac_id : rtwvif->mac_id);
747  	SET_DCTL_OPERATION_V1(cmd, 1);
748  
749  	SET_DCTL_SEC_ENT0_KEYID_V1(cmd, addr_cam->sec_ent_keyid[0]);
750  	SET_DCTL_SEC_ENT1_KEYID_V1(cmd, addr_cam->sec_ent_keyid[1]);
751  	SET_DCTL_SEC_ENT2_KEYID_V1(cmd, addr_cam->sec_ent_keyid[2]);
752  	SET_DCTL_SEC_ENT3_KEYID_V1(cmd, addr_cam->sec_ent_keyid[3]);
753  	SET_DCTL_SEC_ENT4_KEYID_V1(cmd, addr_cam->sec_ent_keyid[4]);
754  	SET_DCTL_SEC_ENT5_KEYID_V1(cmd, addr_cam->sec_ent_keyid[5]);
755  	SET_DCTL_SEC_ENT6_KEYID_V1(cmd, addr_cam->sec_ent_keyid[6]);
756  
757  	SET_DCTL_SEC_ENT_VALID_V1(cmd, addr_cam->sec_cam_map[0] & 0xff);
758  	SET_DCTL_SEC_ENT0_V1(cmd, addr_cam->sec_ent[0]);
759  	SET_DCTL_SEC_ENT1_V1(cmd, addr_cam->sec_ent[1]);
760  	SET_DCTL_SEC_ENT2_V1(cmd, addr_cam->sec_ent[2]);
761  	SET_DCTL_SEC_ENT3_V1(cmd, addr_cam->sec_ent[3]);
762  	SET_DCTL_SEC_ENT4_V1(cmd, addr_cam->sec_ent[4]);
763  	SET_DCTL_SEC_ENT5_V1(cmd, addr_cam->sec_ent[5]);
764  	SET_DCTL_SEC_ENT6_V1(cmd, addr_cam->sec_ent[6]);
765  }
766