xref: /linux/drivers/net/wireless/realtek/rtw88/mac80211.c (revision d2912cb15bdda8ba4a5dd73396ad62641af2f520)
1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
2 /* Copyright(c) 2018-2019  Realtek Corporation
3  */
4 
5 #include "main.h"
6 #include "sec.h"
7 #include "tx.h"
8 #include "fw.h"
9 #include "mac.h"
10 #include "ps.h"
11 #include "reg.h"
12 #include "debug.h"
13 
14 static void rtw_ops_tx(struct ieee80211_hw *hw,
15 		       struct ieee80211_tx_control *control,
16 		       struct sk_buff *skb)
17 {
18 	struct rtw_dev *rtwdev = hw->priv;
19 	struct rtw_tx_pkt_info pkt_info = {0};
20 
21 	if (!rtw_flag_check(rtwdev, RTW_FLAG_RUNNING))
22 		goto out;
23 
24 	rtw_tx_pkt_info_update(rtwdev, &pkt_info, control, skb);
25 	if (rtw_hci_tx(rtwdev, &pkt_info, skb))
26 		goto out;
27 
28 	return;
29 
30 out:
31 	ieee80211_free_txskb(hw, skb);
32 }
33 
34 static int rtw_ops_start(struct ieee80211_hw *hw)
35 {
36 	struct rtw_dev *rtwdev = hw->priv;
37 	int ret;
38 
39 	mutex_lock(&rtwdev->mutex);
40 	ret = rtw_core_start(rtwdev);
41 	mutex_unlock(&rtwdev->mutex);
42 
43 	return ret;
44 }
45 
46 static void rtw_ops_stop(struct ieee80211_hw *hw)
47 {
48 	struct rtw_dev *rtwdev = hw->priv;
49 
50 	mutex_lock(&rtwdev->mutex);
51 	rtw_core_stop(rtwdev);
52 	mutex_unlock(&rtwdev->mutex);
53 }
54 
55 static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
56 {
57 	struct rtw_dev *rtwdev = hw->priv;
58 	int ret = 0;
59 
60 	mutex_lock(&rtwdev->mutex);
61 
62 	if (changed & IEEE80211_CONF_CHANGE_IDLE) {
63 		if (hw->conf.flags & IEEE80211_CONF_IDLE) {
64 			rtw_enter_ips(rtwdev);
65 		} else {
66 			ret = rtw_leave_ips(rtwdev);
67 			if (ret) {
68 				rtw_err(rtwdev, "failed to leave idle state\n");
69 				goto out;
70 			}
71 		}
72 	}
73 
74 	if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
75 		rtw_set_channel(rtwdev);
76 
77 out:
78 	mutex_unlock(&rtwdev->mutex);
79 	return ret;
80 }
81 
82 static const struct rtw_vif_port rtw_vif_port[] = {
83 	[0] = {
84 		.mac_addr	= {.addr = 0x0610},
85 		.bssid		= {.addr = 0x0618},
86 		.net_type	= {.addr = 0x0100, .mask = 0x30000},
87 		.aid		= {.addr = 0x06a8, .mask = 0x7ff},
88 	},
89 	[1] = {
90 		.mac_addr	= {.addr = 0x0700},
91 		.bssid		= {.addr = 0x0708},
92 		.net_type	= {.addr = 0x0100, .mask = 0xc0000},
93 		.aid		= {.addr = 0x0710, .mask = 0x7ff},
94 	},
95 	[2] = {
96 		.mac_addr	= {.addr = 0x1620},
97 		.bssid		= {.addr = 0x1628},
98 		.net_type	= {.addr = 0x1100, .mask = 0x3},
99 		.aid		= {.addr = 0x1600, .mask = 0x7ff},
100 	},
101 	[3] = {
102 		.mac_addr	= {.addr = 0x1630},
103 		.bssid		= {.addr = 0x1638},
104 		.net_type	= {.addr = 0x1100, .mask = 0xc},
105 		.aid		= {.addr = 0x1604, .mask = 0x7ff},
106 	},
107 	[4] = {
108 		.mac_addr	= {.addr = 0x1640},
109 		.bssid		= {.addr = 0x1648},
110 		.net_type	= {.addr = 0x1100, .mask = 0x30},
111 		.aid		= {.addr = 0x1608, .mask = 0x7ff},
112 	},
113 };
114 
115 static int rtw_ops_add_interface(struct ieee80211_hw *hw,
116 				 struct ieee80211_vif *vif)
117 {
118 	struct rtw_dev *rtwdev = hw->priv;
119 	struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
120 	enum rtw_net_type net_type;
121 	u32 config = 0;
122 	u8 port = 0;
123 
124 	rtwvif->port = port;
125 	rtwvif->vif = vif;
126 	rtwvif->stats.tx_unicast = 0;
127 	rtwvif->stats.rx_unicast = 0;
128 	rtwvif->stats.tx_cnt = 0;
129 	rtwvif->stats.rx_cnt = 0;
130 	rtwvif->in_lps = false;
131 	rtwvif->conf = &rtw_vif_port[port];
132 
133 	mutex_lock(&rtwdev->mutex);
134 
135 	switch (vif->type) {
136 	case NL80211_IFTYPE_AP:
137 	case NL80211_IFTYPE_MESH_POINT:
138 		net_type = RTW_NET_AP_MODE;
139 		break;
140 	case NL80211_IFTYPE_ADHOC:
141 		net_type = RTW_NET_AD_HOC;
142 		break;
143 	case NL80211_IFTYPE_STATION:
144 	default:
145 		net_type = RTW_NET_NO_LINK;
146 		break;
147 	}
148 
149 	ether_addr_copy(rtwvif->mac_addr, vif->addr);
150 	config |= PORT_SET_MAC_ADDR;
151 	rtwvif->net_type = net_type;
152 	config |= PORT_SET_NET_TYPE;
153 	rtw_vif_port_config(rtwdev, rtwvif, config);
154 
155 	mutex_unlock(&rtwdev->mutex);
156 
157 	rtw_info(rtwdev, "start vif %pM on port %d\n", vif->addr, rtwvif->port);
158 	return 0;
159 }
160 
161 static void rtw_ops_remove_interface(struct ieee80211_hw *hw,
162 				     struct ieee80211_vif *vif)
163 {
164 	struct rtw_dev *rtwdev = hw->priv;
165 	struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
166 	u32 config = 0;
167 
168 	rtw_info(rtwdev, "stop vif %pM on port %d\n", vif->addr, rtwvif->port);
169 
170 	mutex_lock(&rtwdev->mutex);
171 
172 	eth_zero_addr(rtwvif->mac_addr);
173 	config |= PORT_SET_MAC_ADDR;
174 	rtwvif->net_type = RTW_NET_NO_LINK;
175 	config |= PORT_SET_NET_TYPE;
176 	rtw_vif_port_config(rtwdev, rtwvif, config);
177 
178 	mutex_unlock(&rtwdev->mutex);
179 }
180 
181 static void rtw_ops_configure_filter(struct ieee80211_hw *hw,
182 				     unsigned int changed_flags,
183 				     unsigned int *new_flags,
184 				     u64 multicast)
185 {
186 	struct rtw_dev *rtwdev = hw->priv;
187 
188 	*new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL |
189 		      FIF_BCN_PRBRESP_PROMISC;
190 
191 	mutex_lock(&rtwdev->mutex);
192 
193 	if (changed_flags & FIF_ALLMULTI) {
194 		if (*new_flags & FIF_ALLMULTI)
195 			rtwdev->hal.rcr |= BIT_AM | BIT_AB;
196 		else
197 			rtwdev->hal.rcr &= ~(BIT_AM | BIT_AB);
198 	}
199 	if (changed_flags & FIF_FCSFAIL) {
200 		if (*new_flags & FIF_FCSFAIL)
201 			rtwdev->hal.rcr |= BIT_ACRC32;
202 		else
203 			rtwdev->hal.rcr &= ~(BIT_ACRC32);
204 	}
205 	if (changed_flags & FIF_OTHER_BSS) {
206 		if (*new_flags & FIF_OTHER_BSS)
207 			rtwdev->hal.rcr |= BIT_AAP;
208 		else
209 			rtwdev->hal.rcr &= ~(BIT_AAP);
210 	}
211 	if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
212 		if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
213 			rtwdev->hal.rcr &= ~(BIT_CBSSID_BCN | BIT_CBSSID_DATA);
214 		else
215 			rtwdev->hal.rcr |= BIT_CBSSID_BCN;
216 	}
217 
218 	rtw_dbg(rtwdev, RTW_DBG_RX,
219 		"config rx filter, changed=0x%08x, new=0x%08x, rcr=0x%08x\n",
220 		changed_flags, *new_flags, rtwdev->hal.rcr);
221 
222 	rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr);
223 
224 	mutex_unlock(&rtwdev->mutex);
225 }
226 
227 static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
228 				     struct ieee80211_vif *vif,
229 				     struct ieee80211_bss_conf *conf,
230 				     u32 changed)
231 {
232 	struct rtw_dev *rtwdev = hw->priv;
233 	struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
234 	u32 config = 0;
235 
236 	mutex_lock(&rtwdev->mutex);
237 
238 	if (changed & BSS_CHANGED_ASSOC) {
239 		struct rtw_chip_info *chip = rtwdev->chip;
240 		enum rtw_net_type net_type;
241 
242 		if (conf->assoc) {
243 			net_type = RTW_NET_MGD_LINKED;
244 			chip->ops->do_iqk(rtwdev);
245 
246 			rtwvif->aid = conf->aid;
247 			rtw_add_rsvd_page(rtwdev, RSVD_PS_POLL, true);
248 			rtw_add_rsvd_page(rtwdev, RSVD_QOS_NULL, true);
249 			rtw_add_rsvd_page(rtwdev, RSVD_NULL, true);
250 			rtw_fw_download_rsvd_page(rtwdev, vif);
251 			rtw_send_rsvd_page_h2c(rtwdev);
252 		} else {
253 			net_type = RTW_NET_NO_LINK;
254 			rtwvif->aid = 0;
255 			rtw_reset_rsvd_page(rtwdev);
256 		}
257 
258 		rtwvif->net_type = net_type;
259 		config |= PORT_SET_NET_TYPE;
260 		config |= PORT_SET_AID;
261 	}
262 
263 	if (changed & BSS_CHANGED_BSSID) {
264 		ether_addr_copy(rtwvif->bssid, conf->bssid);
265 		config |= PORT_SET_BSSID;
266 	}
267 
268 	if (changed & BSS_CHANGED_BEACON)
269 		rtw_fw_download_rsvd_page(rtwdev, vif);
270 
271 	rtw_vif_port_config(rtwdev, rtwvif, config);
272 
273 	mutex_unlock(&rtwdev->mutex);
274 }
275 
276 static u8 rtw_acquire_macid(struct rtw_dev *rtwdev)
277 {
278 	unsigned long mac_id;
279 
280 	mac_id = find_first_zero_bit(rtwdev->mac_id_map, RTW_MAX_MAC_ID_NUM);
281 	if (mac_id < RTW_MAX_MAC_ID_NUM)
282 		set_bit(mac_id, rtwdev->mac_id_map);
283 
284 	return mac_id;
285 }
286 
287 static void rtw_release_macid(struct rtw_dev *rtwdev, u8 mac_id)
288 {
289 	clear_bit(mac_id, rtwdev->mac_id_map);
290 }
291 
292 static int rtw_ops_sta_add(struct ieee80211_hw *hw,
293 			   struct ieee80211_vif *vif,
294 			   struct ieee80211_sta *sta)
295 {
296 	struct rtw_dev *rtwdev = hw->priv;
297 	struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
298 	int ret = 0;
299 
300 	mutex_lock(&rtwdev->mutex);
301 
302 	si->mac_id = rtw_acquire_macid(rtwdev);
303 	if (si->mac_id >= RTW_MAX_MAC_ID_NUM) {
304 		ret = -ENOSPC;
305 		goto out;
306 	}
307 
308 	si->sta = sta;
309 	si->vif = vif;
310 	si->init_ra_lv = 1;
311 	ewma_rssi_init(&si->avg_rssi);
312 
313 	rtw_update_sta_info(rtwdev, si);
314 	rtw_fw_media_status_report(rtwdev, si->mac_id, true);
315 
316 	rtwdev->sta_cnt++;
317 
318 	rtw_info(rtwdev, "sta %pM joined with macid %d\n",
319 		 sta->addr, si->mac_id);
320 
321 out:
322 	mutex_unlock(&rtwdev->mutex);
323 	return ret;
324 }
325 
326 static int rtw_ops_sta_remove(struct ieee80211_hw *hw,
327 			      struct ieee80211_vif *vif,
328 			      struct ieee80211_sta *sta)
329 {
330 	struct rtw_dev *rtwdev = hw->priv;
331 	struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
332 
333 	mutex_lock(&rtwdev->mutex);
334 
335 	rtw_release_macid(rtwdev, si->mac_id);
336 	rtw_fw_media_status_report(rtwdev, si->mac_id, false);
337 
338 	rtwdev->sta_cnt--;
339 
340 	rtw_info(rtwdev, "sta %pM with macid %d left\n",
341 		 sta->addr, si->mac_id);
342 
343 	mutex_unlock(&rtwdev->mutex);
344 	return 0;
345 }
346 
347 static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
348 			   struct ieee80211_vif *vif, struct ieee80211_sta *sta,
349 			   struct ieee80211_key_conf *key)
350 {
351 	struct rtw_dev *rtwdev = hw->priv;
352 	struct rtw_sec_desc *sec = &rtwdev->sec;
353 	u8 hw_key_type;
354 	u8 hw_key_idx;
355 	int ret = 0;
356 
357 	switch (key->cipher) {
358 	case WLAN_CIPHER_SUITE_WEP40:
359 		hw_key_type = RTW_CAM_WEP40;
360 		break;
361 	case WLAN_CIPHER_SUITE_WEP104:
362 		hw_key_type = RTW_CAM_WEP104;
363 		break;
364 	case WLAN_CIPHER_SUITE_TKIP:
365 		hw_key_type = RTW_CAM_TKIP;
366 		key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
367 		break;
368 	case WLAN_CIPHER_SUITE_CCMP:
369 		hw_key_type = RTW_CAM_AES;
370 		key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
371 		break;
372 	case WLAN_CIPHER_SUITE_AES_CMAC:
373 	case WLAN_CIPHER_SUITE_BIP_CMAC_256:
374 	case WLAN_CIPHER_SUITE_BIP_GMAC_128:
375 	case WLAN_CIPHER_SUITE_BIP_GMAC_256:
376 		/* suppress error messages */
377 		return -EOPNOTSUPP;
378 	default:
379 		return -ENOTSUPP;
380 	}
381 
382 	mutex_lock(&rtwdev->mutex);
383 
384 	if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
385 		hw_key_idx = rtw_sec_get_free_cam(sec);
386 	} else {
387 		/* multiple interfaces? */
388 		hw_key_idx = key->keyidx;
389 	}
390 
391 	if (hw_key_idx > sec->total_cam_num) {
392 		ret = -ENOSPC;
393 		goto out;
394 	}
395 
396 	switch (cmd) {
397 	case SET_KEY:
398 		/* need sw generated IV */
399 		key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
400 		key->hw_key_idx = hw_key_idx;
401 		rtw_sec_write_cam(rtwdev, sec, sta, key,
402 				  hw_key_type, hw_key_idx);
403 		break;
404 	case DISABLE_KEY:
405 		rtw_sec_clear_cam(rtwdev, sec, key->hw_key_idx);
406 		break;
407 	}
408 
409 out:
410 	mutex_unlock(&rtwdev->mutex);
411 
412 	return ret;
413 }
414 
415 static int rtw_ops_ampdu_action(struct ieee80211_hw *hw,
416 				struct ieee80211_vif *vif,
417 				struct ieee80211_ampdu_params *params)
418 {
419 	struct ieee80211_sta *sta = params->sta;
420 	u16 tid = params->tid;
421 
422 	switch (params->action) {
423 	case IEEE80211_AMPDU_TX_START:
424 		ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
425 		break;
426 	case IEEE80211_AMPDU_TX_STOP_CONT:
427 	case IEEE80211_AMPDU_TX_STOP_FLUSH:
428 	case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
429 		ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
430 		break;
431 	case IEEE80211_AMPDU_TX_OPERATIONAL:
432 	case IEEE80211_AMPDU_RX_START:
433 	case IEEE80211_AMPDU_RX_STOP:
434 		break;
435 	default:
436 		WARN_ON(1);
437 		return -ENOTSUPP;
438 	}
439 
440 	return 0;
441 }
442 
443 static void rtw_ops_sw_scan_start(struct ieee80211_hw *hw,
444 				  struct ieee80211_vif *vif,
445 				  const u8 *mac_addr)
446 {
447 	struct rtw_dev *rtwdev = hw->priv;
448 	struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
449 
450 	rtw_leave_lps(rtwdev, rtwvif);
451 
452 	rtw_flag_set(rtwdev, RTW_FLAG_DIG_DISABLE);
453 	rtw_flag_set(rtwdev, RTW_FLAG_SCANNING);
454 }
455 
456 static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw,
457 				     struct ieee80211_vif *vif)
458 {
459 	struct rtw_dev *rtwdev = hw->priv;
460 
461 	rtw_flag_clear(rtwdev, RTW_FLAG_SCANNING);
462 	rtw_flag_clear(rtwdev, RTW_FLAG_DIG_DISABLE);
463 }
464 
465 const struct ieee80211_ops rtw_ops = {
466 	.tx			= rtw_ops_tx,
467 	.start			= rtw_ops_start,
468 	.stop			= rtw_ops_stop,
469 	.config			= rtw_ops_config,
470 	.add_interface		= rtw_ops_add_interface,
471 	.remove_interface	= rtw_ops_remove_interface,
472 	.configure_filter	= rtw_ops_configure_filter,
473 	.bss_info_changed	= rtw_ops_bss_info_changed,
474 	.sta_add		= rtw_ops_sta_add,
475 	.sta_remove		= rtw_ops_sta_remove,
476 	.set_key		= rtw_ops_set_key,
477 	.ampdu_action		= rtw_ops_ampdu_action,
478 	.sw_scan_start		= rtw_ops_sw_scan_start,
479 	.sw_scan_complete	= rtw_ops_sw_scan_complete,
480 };
481 EXPORT_SYMBOL(rtw_ops);
482