xref: /linux/drivers/net/wireless/nxp/nxpwifi/util.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * NXP Wireless LAN device driver: utility functions
4  *
5  * Copyright 2011-2024 NXP
6  */
7 
8 #include "cfg.h"
9 #include "util.h"
10 #include "fw.h"
11 #include "main.h"
12 #include "cmdevt.h"
13 #include "wmm.h"
14 #include "11n.h"
15 #include <net/netlink.h>
16 #include <linux/mmc/sdio_ids.h>
17 #include <linux/mmc/sdio_func.h>
18 #include <linux/bitfield.h>
19 #include <net/ieee80211_radiotap.h>
20 
21 #define RX_RATE_FORMAT_MASK   GENMASK(1, 0)
22 #define RX_RATE_BW_MASK       GENMASK(3, 2)
23 #define RX_RATE_GI_MASK       BIT(4)
24 #define RX_RATE_STBC_MASK     BIT(5)
25 #define RX_RATE_LDPC_MASK     BIT(6)
26 
27 static struct nxpwifi_debug_data items[] = {
28 	{"debug_mask", item_size(debug_mask),
29 	 item_addr(debug_mask), 1},
30 	{"int_counter", item_size(int_counter),
31 	 item_addr(int_counter), 1},
32 	{"wmm_ac_vo", item_size(packets_out[WMM_AC_VO]),
33 	 item_addr(packets_out[WMM_AC_VO]), 1},
34 	{"wmm_ac_vi", item_size(packets_out[WMM_AC_VI]),
35 	 item_addr(packets_out[WMM_AC_VI]), 1},
36 	{"wmm_ac_be", item_size(packets_out[WMM_AC_BE]),
37 	 item_addr(packets_out[WMM_AC_BE]), 1},
38 	{"wmm_ac_bk", item_size(packets_out[WMM_AC_BK]),
39 	 item_addr(packets_out[WMM_AC_BK]), 1},
40 	{"tx_buf_size", item_size(tx_buf_size),
41 	 item_addr(tx_buf_size), 1},
42 	{"curr_tx_buf_size", item_size(curr_tx_buf_size),
43 	 item_addr(curr_tx_buf_size), 1},
44 	{"ps_mode", item_size(ps_mode),
45 	 item_addr(ps_mode), 1},
46 	{"ps_state", item_size(ps_state),
47 	 item_addr(ps_state), 1},
48 	{"is_deep_sleep", item_size(is_deep_sleep),
49 	 item_addr(is_deep_sleep), 1},
50 	{"wakeup_dev_req", item_size(pm_wakeup_card_req),
51 	 item_addr(pm_wakeup_card_req), 1},
52 	{"wakeup_tries", item_size(pm_wakeup_fw_try),
53 	 item_addr(pm_wakeup_fw_try), 1},
54 	{"hs_configured", item_size(is_hs_configured),
55 	 item_addr(is_hs_configured), 1},
56 	{"hs_activated", item_size(hs_activated),
57 	 item_addr(hs_activated), 1},
58 	{"num_tx_timeout", item_size(num_tx_timeout),
59 	 item_addr(num_tx_timeout), 1},
60 	{"is_cmd_timedout", item_size(is_cmd_timedout),
61 	 item_addr(is_cmd_timedout), 1},
62 	{"timeout_cmd_id", item_size(timeout_cmd_id),
63 	 item_addr(timeout_cmd_id), 1},
64 	{"timeout_cmd_act", item_size(timeout_cmd_act),
65 	 item_addr(timeout_cmd_act), 1},
66 	{"last_cmd_id", item_size(last_cmd_id),
67 	 item_addr(last_cmd_id), DBG_CMD_NUM},
68 	{"last_cmd_act", item_size(last_cmd_act),
69 	 item_addr(last_cmd_act), DBG_CMD_NUM},
70 	{"last_cmd_index", item_size(last_cmd_index),
71 	 item_addr(last_cmd_index), 1},
72 	{"last_cmd_resp_id", item_size(last_cmd_resp_id),
73 	 item_addr(last_cmd_resp_id), DBG_CMD_NUM},
74 	{"last_cmd_resp_index", item_size(last_cmd_resp_index),
75 	 item_addr(last_cmd_resp_index), 1},
76 	{"last_event", item_size(last_event),
77 	 item_addr(last_event), DBG_CMD_NUM},
78 	{"last_event_index", item_size(last_event_index),
79 	 item_addr(last_event_index), 1},
80 	{"last_mp_wr_bitmap", item_size(last_mp_wr_bitmap),
81 	 item_addr(last_mp_wr_bitmap), NXPWIFI_DBG_SDIO_MP_NUM},
82 	{"last_mp_wr_ports", item_size(last_mp_wr_ports),
83 	 item_addr(last_mp_wr_ports), NXPWIFI_DBG_SDIO_MP_NUM},
84 	{"last_mp_wr_len", item_size(last_mp_wr_len),
85 	 item_addr(last_mp_wr_len), NXPWIFI_DBG_SDIO_MP_NUM},
86 	{"last_mp_curr_wr_port", item_size(last_mp_curr_wr_port),
87 	 item_addr(last_mp_curr_wr_port), NXPWIFI_DBG_SDIO_MP_NUM},
88 	{"last_sdio_mp_index", item_size(last_sdio_mp_index),
89 	 item_addr(last_sdio_mp_index), 1},
90 	{"num_cmd_h2c_fail", item_size(num_cmd_host_to_card_failure),
91 	 item_addr(num_cmd_host_to_card_failure), 1},
92 	{"num_cmd_sleep_cfm_fail",
93 	 item_size(num_cmd_sleep_cfm_host_to_card_failure),
94 	 item_addr(num_cmd_sleep_cfm_host_to_card_failure), 1},
95 	{"num_tx_h2c_fail", item_size(num_tx_host_to_card_failure),
96 	 item_addr(num_tx_host_to_card_failure), 1},
97 	{"num_evt_deauth", item_size(num_event_deauth),
98 	 item_addr(num_event_deauth), 1},
99 	{"num_evt_disassoc", item_size(num_event_disassoc),
100 	 item_addr(num_event_disassoc), 1},
101 	{"num_evt_link_lost", item_size(num_event_link_lost),
102 	 item_addr(num_event_link_lost), 1},
103 	{"num_cmd_deauth", item_size(num_cmd_deauth),
104 	 item_addr(num_cmd_deauth), 1},
105 	{"num_cmd_assoc_ok", item_size(num_cmd_assoc_success),
106 	 item_addr(num_cmd_assoc_success), 1},
107 	{"num_cmd_assoc_fail", item_size(num_cmd_assoc_failure),
108 	 item_addr(num_cmd_assoc_failure), 1},
109 	{"cmd_sent", item_size(cmd_sent),
110 	 item_addr(cmd_sent), 1},
111 	{"data_sent", item_size(data_sent),
112 	 item_addr(data_sent), 1},
113 	{"cmd_resp_received", item_size(cmd_resp_received),
114 	 item_addr(cmd_resp_received), 1},
115 	{"event_received", item_size(event_received),
116 	 item_addr(event_received), 1},
117 
118 	/* variables defined in struct nxpwifi_adapter */
119 	{"cmd_pending", adapter_item_size(cmd_pending),
120 	 adapter_item_addr(cmd_pending), 1},
121 	{"tx_pending", adapter_item_size(tx_pending),
122 	 adapter_item_addr(tx_pending), 1},
123 	{"rx_pending", adapter_item_size(rx_pending),
124 	 adapter_item_addr(rx_pending), 1},
125 };
126 
127 static int num_of_items = ARRAY_SIZE(items);
128 
129 /* Send init or shutdown command to firmware. */
nxpwifi_init_shutdown_fw(struct nxpwifi_private * priv,u32 func_init_shutdown)130 int nxpwifi_init_shutdown_fw(struct nxpwifi_private *priv,
131 			     u32 func_init_shutdown)
132 {
133 	u16 cmd;
134 
135 	if (func_init_shutdown == NXPWIFI_FUNC_INIT) {
136 		cmd = HOST_CMD_FUNC_INIT;
137 	} else if (func_init_shutdown == NXPWIFI_FUNC_SHUTDOWN) {
138 		cmd = HOST_CMD_FUNC_SHUTDOWN;
139 	} else {
140 		nxpwifi_dbg(priv->adapter, ERROR,
141 			    "unsupported parameter\n");
142 		return -EINVAL;
143 	}
144 
145 	return nxpwifi_send_cmd(priv, cmd, HOST_ACT_GEN_SET, 0, NULL, true);
146 }
147 EXPORT_SYMBOL_GPL(nxpwifi_init_shutdown_fw);
148 
149 /* Handle IOCTL get/set of debug info across driver structures. */
nxpwifi_get_debug_info(struct nxpwifi_private * priv,struct nxpwifi_debug_info * info)150 int nxpwifi_get_debug_info(struct nxpwifi_private *priv,
151 			   struct nxpwifi_debug_info *info)
152 {
153 	struct nxpwifi_adapter *adapter = priv->adapter;
154 
155 	if (info) {
156 		info->debug_mask = adapter->debug_mask;
157 		memcpy(info->packets_out,
158 		       priv->wmm.packets_out,
159 		       sizeof(priv->wmm.packets_out));
160 		info->curr_tx_buf_size = (u32)adapter->curr_tx_buf_size;
161 		info->tx_buf_size = (u32)adapter->tx_buf_size;
162 		info->rx_tbl_num = nxpwifi_get_rx_reorder_tbl(priv,
163 							      info->rx_tbl);
164 		info->tx_tbl_num = nxpwifi_get_tx_ba_stream_tbl(priv,
165 								info->tx_tbl);
166 		info->ps_mode = adapter->ps_mode;
167 		info->ps_state = adapter->ps_state;
168 		info->is_deep_sleep = adapter->is_deep_sleep;
169 		info->pm_wakeup_card_req = adapter->pm_wakeup_card_req;
170 		info->pm_wakeup_fw_try = adapter->pm_wakeup_fw_try;
171 		info->is_hs_configured = test_bit(NXPWIFI_IS_HS_CONFIGURED,
172 						  &adapter->work_flags);
173 		info->hs_activated = adapter->hs_activated;
174 		info->is_cmd_timedout = test_bit(NXPWIFI_IS_CMD_TIMEDOUT,
175 						 &adapter->work_flags);
176 		info->num_cmd_host_to_card_failure =
177 			adapter->dbg.num_cmd_host_to_card_failure;
178 		info->num_cmd_sleep_cfm_host_to_card_failure =
179 			adapter->dbg.num_cmd_sleep_cfm_host_to_card_failure;
180 		info->num_tx_host_to_card_failure =
181 			adapter->dbg.num_tx_host_to_card_failure;
182 		info->num_event_deauth = adapter->dbg.num_event_deauth;
183 		info->num_event_disassoc = adapter->dbg.num_event_disassoc;
184 		info->num_event_link_lost = adapter->dbg.num_event_link_lost;
185 		info->num_cmd_deauth = adapter->dbg.num_cmd_deauth;
186 		info->num_cmd_assoc_success =
187 			adapter->dbg.num_cmd_assoc_success;
188 		info->num_cmd_assoc_failure =
189 			adapter->dbg.num_cmd_assoc_failure;
190 		info->num_tx_timeout = adapter->dbg.num_tx_timeout;
191 		info->timeout_cmd_id = adapter->dbg.timeout_cmd_id;
192 		info->timeout_cmd_act = adapter->dbg.timeout_cmd_act;
193 		memcpy(info->last_cmd_id, adapter->dbg.last_cmd_id,
194 		       sizeof(adapter->dbg.last_cmd_id));
195 		memcpy(info->last_cmd_act, adapter->dbg.last_cmd_act,
196 		       sizeof(adapter->dbg.last_cmd_act));
197 		info->last_cmd_index = adapter->dbg.last_cmd_index;
198 		memcpy(info->last_cmd_resp_id, adapter->dbg.last_cmd_resp_id,
199 		       sizeof(adapter->dbg.last_cmd_resp_id));
200 		info->last_cmd_resp_index = adapter->dbg.last_cmd_resp_index;
201 		memcpy(info->last_event, adapter->dbg.last_event,
202 		       sizeof(adapter->dbg.last_event));
203 		info->last_event_index = adapter->dbg.last_event_index;
204 		memcpy(info->last_mp_wr_bitmap, adapter->dbg.last_mp_wr_bitmap,
205 		       sizeof(adapter->dbg.last_mp_wr_bitmap));
206 		memcpy(info->last_mp_wr_ports, adapter->dbg.last_mp_wr_ports,
207 		       sizeof(adapter->dbg.last_mp_wr_ports));
208 		memcpy(info->last_mp_curr_wr_port,
209 		       adapter->dbg.last_mp_curr_wr_port,
210 		       sizeof(adapter->dbg.last_mp_curr_wr_port));
211 		memcpy(info->last_mp_wr_len, adapter->dbg.last_mp_wr_len,
212 		       sizeof(adapter->dbg.last_mp_wr_len));
213 		info->last_sdio_mp_index = adapter->dbg.last_sdio_mp_index;
214 		info->data_sent = adapter->data_sent;
215 		info->cmd_sent = adapter->cmd_sent;
216 		info->cmd_resp_received = adapter->cmd_resp_received;
217 	}
218 
219 	return 0;
220 }
221 
nxpwifi_debug_info_to_buffer(struct nxpwifi_private * priv,char * buf,struct nxpwifi_debug_info * info)222 int nxpwifi_debug_info_to_buffer(struct nxpwifi_private *priv, char *buf,
223 				 struct nxpwifi_debug_info *info)
224 {
225 	char *p = buf;
226 	struct nxpwifi_debug_data *d = &items[0];
227 	size_t size, addr;
228 	long val;
229 	int i, j;
230 
231 	if (!info)
232 		return 0;
233 
234 	for (i = 0; i < num_of_items; i++) {
235 		p += sprintf(p, "%s=", d[i].name);
236 
237 		size = d[i].size / d[i].num;
238 
239 		if (i < (num_of_items - 3))
240 			addr = d[i].addr + (size_t)info;
241 		else /* The last 3 items are struct nxpwifi_adapter variables */
242 			addr = d[i].addr + (size_t)priv->adapter;
243 
244 		for (j = 0; j < d[i].num; j++) {
245 			switch (size) {
246 			case 1:
247 				val = *((u8 *)addr);
248 				break;
249 			case 2:
250 				val = get_unaligned((u16 *)addr);
251 				break;
252 			case 4:
253 				val = get_unaligned((u32 *)addr);
254 				break;
255 			case 8:
256 				val = get_unaligned((long long *)addr);
257 				break;
258 			default:
259 				val = -1;
260 				break;
261 			}
262 
263 			p += sprintf(p, "%#lx ", val);
264 			addr += size;
265 		}
266 
267 		p += sprintf(p, "\n");
268 	}
269 
270 	if (info->tx_tbl_num) {
271 		p += sprintf(p, "Tx BA stream table:\n");
272 		for (i = 0; i < info->tx_tbl_num; i++)
273 			p += sprintf(p, "tid = %d, ra = %pM\n",
274 				     info->tx_tbl[i].tid, info->tx_tbl[i].ra);
275 	}
276 
277 	if (info->rx_tbl_num) {
278 		p += sprintf(p, "Rx reorder table:\n");
279 		for (i = 0; i < info->rx_tbl_num; i++) {
280 			p += sprintf(p, "tid = %d, ta = %pM, ",
281 				     info->rx_tbl[i].tid,
282 				     info->rx_tbl[i].ta);
283 			p += sprintf(p, "start_win = %d, ",
284 				     info->rx_tbl[i].start_win);
285 			p += sprintf(p, "win_size = %d, buffer: ",
286 				     info->rx_tbl[i].win_size);
287 
288 			for (j = 0; j < info->rx_tbl[i].win_size; j++)
289 				p += sprintf(p, "%c ",
290 					     info->rx_tbl[i].buffer[j] ?
291 					     '1' : '0');
292 
293 			p += sprintf(p, "\n");
294 		}
295 	}
296 
297 	return p - buf;
298 }
299 
nxpwifi_is_channel_setting_allowable(struct nxpwifi_private * priv,struct ieee80211_channel * check_chan)300 bool nxpwifi_is_channel_setting_allowable(struct nxpwifi_private *priv,
301 					  struct ieee80211_channel *check_chan)
302 {
303 	struct nxpwifi_adapter *adapter = priv->adapter;
304 	int i;
305 	struct nxpwifi_private *tmp_priv;
306 	u8 bss_role = GET_BSS_ROLE(priv);
307 	struct ieee80211_channel *set_chan;
308 
309 	for (i = 0; i < adapter->priv_num; i++) {
310 		tmp_priv = adapter->priv[i];
311 		if (tmp_priv == priv)
312 			continue;
313 
314 		set_chan = NULL;
315 		if (bss_role == NXPWIFI_BSS_ROLE_STA) {
316 			if (GET_BSS_ROLE(tmp_priv) == NXPWIFI_BSS_ROLE_UAP &&
317 			    netif_carrier_ok(tmp_priv->netdev) &&
318 			    cfg80211_chandef_valid(&tmp_priv->bss_chandef))
319 				set_chan = tmp_priv->bss_chandef.chan;
320 		} else if (bss_role == NXPWIFI_BSS_ROLE_UAP) {
321 			struct nxpwifi_current_bss_params *bss_params =
322 				&tmp_priv->curr_bss_params;
323 			int channel = bss_params->bss_descriptor.channel;
324 			enum nl80211_band band =
325 				nxpwifi_band_to_radio_type(bss_params->band);
326 			int freq =
327 				ieee80211_channel_to_frequency(channel, band);
328 
329 			if (GET_BSS_ROLE(tmp_priv) == NXPWIFI_BSS_ROLE_STA &&
330 			    tmp_priv->media_connected)
331 				set_chan = ieee80211_get_channel(adapter->wiphy, freq);
332 		}
333 
334 		if (set_chan && !ieee80211_channel_equal(check_chan, set_chan)) {
335 			nxpwifi_dbg(adapter, ERROR,
336 				    "AP/STA must run on the same channel\n");
337 			return false;
338 		}
339 	}
340 
341 	return true;
342 }
343 
nxpwifi_convert_chan_to_band_cfg(struct nxpwifi_private * priv,u8 * band_cfg,struct cfg80211_chan_def * chan_def)344 void nxpwifi_convert_chan_to_band_cfg(struct nxpwifi_private *priv,
345 				      u8 *band_cfg,
346 				      struct cfg80211_chan_def *chan_def)
347 {
348 	u8 chan_band = 0, chan_width = 0, chan2_offset = 0;
349 
350 	switch (chan_def->chan->band) {
351 	case NL80211_BAND_2GHZ:
352 		chan_band = BAND_2GHZ;
353 		break;
354 	case NL80211_BAND_5GHZ:
355 		chan_band = BAND_5GHZ;
356 		break;
357 	default:
358 		break;
359 	}
360 
361 	switch (chan_def->width) {
362 	case NL80211_CHAN_WIDTH_20_NOHT:
363 	case NL80211_CHAN_WIDTH_20:
364 		chan_width = CHAN_BW_20MHZ;
365 		break;
366 	case NL80211_CHAN_WIDTH_40:
367 		chan_width = CHAN_BW_40MHZ;
368 		if (chan_def->center_freq1 > chan_def->chan->center_freq)
369 			chan2_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
370 		else
371 			chan2_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
372 		break;
373 	case NL80211_CHAN_WIDTH_80:
374 		chan2_offset =
375 			nxpwifi_get_sec_chan_offset(chan_def->chan->hw_value);
376 		chan_width = CHAN_BW_80MHZ;
377 		break;
378 	case NL80211_CHAN_WIDTH_80P80:
379 	case NL80211_CHAN_WIDTH_160:
380 	default:
381 		nxpwifi_dbg(priv->adapter,
382 			    WARN, "Unknown channel width: %d\n",
383 			    chan_def->width);
384 		break;
385 	}
386 
387 	*band_cfg = ((chan2_offset << BAND_CFG_CHAN2_SHIFT_BIT) &
388 		     BAND_CFG_CHAN2_OFFSET_MASK) |
389 		    ((chan_width << BAND_CFG_CHAN_WIDTH_SHIFT_BIT) &
390 		     BAND_CFG_CHAN_WIDTH_MASK) |
391 		    ((chan_band << BAND_CFG_CHAN_BAND_SHIFT_BIT) &
392 		     BAND_CFG_CHAN_BAND_MASK);
393 }
394 
395 static int
nxpwifi_parse_mgmt_packet(struct nxpwifi_private * priv,u8 * payload,u16 len,struct rxpd * rx_pd)396 nxpwifi_parse_mgmt_packet(struct nxpwifi_private *priv, u8 *payload, u16 len,
397 			  struct rxpd *rx_pd)
398 {
399 	u16 stype;
400 	u8 category;
401 	struct ieee80211_hdr *ieee_hdr = (void *)payload;
402 
403 	stype = (le16_to_cpu(ieee_hdr->frame_control) & IEEE80211_FCTL_STYPE);
404 
405 	switch (stype) {
406 	case IEEE80211_STYPE_ACTION:
407 		category = *(payload + sizeof(struct ieee80211_hdr));
408 		switch (category) {
409 		case WLAN_CATEGORY_BACK:
410 			/*we dont indicate BACK action frames to cfg80211*/
411 			nxpwifi_dbg(priv->adapter, INFO,
412 				    "drop BACK action frames");
413 			return -EINVAL;
414 		default:
415 			nxpwifi_dbg(priv->adapter, INFO,
416 				    "unknown public action frame category %d\n",
417 				    category);
418 		}
419 		break;
420 	default:
421 		nxpwifi_dbg(priv->adapter, INFO,
422 			    "unknown mgmt frame subtype %#x\n", stype);
423 		return 0;
424 	}
425 
426 	return 0;
427 }
428 
429 /* Send deauth frame to cfg80211. */
nxpwifi_host_mlme_disconnect(struct nxpwifi_private * priv,u16 reason_code,u8 * sa)430 void nxpwifi_host_mlme_disconnect(struct nxpwifi_private *priv,
431 				  u16 reason_code, u8 *sa)
432 {
433 	u8 frame_buf[100];
434 	struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)frame_buf;
435 
436 	memset(frame_buf, 0, sizeof(frame_buf));
437 	mgmt->frame_control = cpu_to_le16(IEEE80211_STYPE_DEAUTH);
438 	mgmt->duration = 0;
439 	mgmt->seq_ctrl = 0;
440 	mgmt->u.deauth.reason_code = cpu_to_le16(reason_code);
441 
442 	if (GET_BSS_ROLE(priv) == NXPWIFI_BSS_ROLE_STA) {
443 		eth_broadcast_addr(mgmt->da);
444 		memcpy(mgmt->sa,
445 		       priv->curr_bss_params.bss_descriptor.mac_address,
446 		       ETH_ALEN);
447 		memcpy(mgmt->bssid, priv->cfg_bssid, ETH_ALEN);
448 		priv->auth_flag = 0;
449 		priv->auth_alg = WLAN_AUTH_NONE;
450 	} else {
451 		memcpy(mgmt->da, priv->curr_addr, ETH_ALEN);
452 		memcpy(mgmt->sa, sa, ETH_ALEN);
453 		memcpy(mgmt->bssid, priv->curr_addr, ETH_ALEN);
454 	}
455 
456 	if (GET_BSS_ROLE(priv) != NXPWIFI_BSS_ROLE_UAP) {
457 		cfg80211_rx_mlme_mgmt(priv->netdev, frame_buf, 26);
458 	} else {
459 		cfg80211_rx_mgmt(&priv->wdev,
460 				 priv->bss_chandef.chan->center_freq,
461 				 0, frame_buf, 26, 0);
462 	}
463 }
464 
465 /* Parse and forward received management packet to cfg80211. */
466 int
nxpwifi_process_mgmt_packet(struct nxpwifi_private * priv,struct sk_buff * skb)467 nxpwifi_process_mgmt_packet(struct nxpwifi_private *priv,
468 			    struct sk_buff *skb)
469 {
470 	struct nxpwifi_adapter *adapter = priv->adapter;
471 	struct rxpd *rx_pd;
472 	u16 pkt_len;
473 	struct ieee80211_hdr *ieee_hdr;
474 	int ret;
475 
476 	if (!skb)
477 		return -ENOMEM;
478 
479 	if (!priv->mgmt_frame_mask ||
480 	    priv->wdev.iftype == NL80211_IFTYPE_UNSPECIFIED) {
481 		nxpwifi_dbg(adapter, ERROR,
482 			    "do not receive mgmt frames on uninitialized intf");
483 		return -EINVAL;
484 	}
485 
486 	rx_pd = (struct rxpd *)skb->data;
487 	pkt_len = le16_to_cpu(rx_pd->rx_pkt_length);
488 	if (pkt_len < sizeof(struct ieee80211_hdr) + sizeof(pkt_len)) {
489 		nxpwifi_dbg(adapter, ERROR, "invalid rx_pkt_length");
490 		return -EINVAL;
491 	}
492 
493 	skb_pull(skb, le16_to_cpu(rx_pd->rx_pkt_offset));
494 	skb_pull(skb, sizeof(pkt_len));
495 	pkt_len -= sizeof(pkt_len);
496 
497 	ieee_hdr = (void *)skb->data;
498 	if (ieee80211_is_mgmt(ieee_hdr->frame_control)) {
499 		ret = nxpwifi_parse_mgmt_packet(priv, (u8 *)ieee_hdr,
500 						pkt_len, rx_pd);
501 		if (ret)
502 			return ret;
503 	}
504 	/* Remove address4 */
505 	memmove(skb->data + sizeof(struct ieee80211_hdr_3addr),
506 		skb->data + sizeof(struct ieee80211_hdr),
507 		pkt_len - sizeof(struct ieee80211_hdr));
508 
509 	pkt_len -= ETH_ALEN;
510 	rx_pd->rx_pkt_length = cpu_to_le16(pkt_len);
511 
512 	if (priv->host_mlme_reg &&
513 	    (GET_BSS_ROLE(priv) != NXPWIFI_BSS_ROLE_UAP) &&
514 	    (ieee80211_is_auth(ieee_hdr->frame_control) ||
515 	     ieee80211_is_deauth(ieee_hdr->frame_control) ||
516 	     ieee80211_is_disassoc(ieee_hdr->frame_control))) {
517 		struct nxpwifi_rxinfo *rx_info;
518 
519 		if (ieee80211_is_auth(ieee_hdr->frame_control)) {
520 			if (priv->auth_flag & HOST_MLME_AUTH_PENDING) {
521 				if (priv->auth_alg != WLAN_AUTH_SAE) {
522 					priv->auth_flag &=
523 						~HOST_MLME_AUTH_PENDING;
524 					priv->auth_flag |=
525 						HOST_MLME_AUTH_DONE;
526 				}
527 			} else {
528 				return 0;
529 			}
530 
531 			nxpwifi_dbg(adapter, MSG,
532 				    "auth: receive authentication from %pM\n",
533 				    ieee_hdr->addr3);
534 		} else {
535 			if (!priv->wdev.connected)
536 				return 0;
537 
538 			if (ieee80211_is_deauth(ieee_hdr->frame_control)) {
539 				nxpwifi_dbg(adapter, MSG,
540 					    "auth: receive deauth from %pM\n",
541 					    ieee_hdr->addr3);
542 				priv->auth_flag = 0;
543 				priv->auth_alg = WLAN_AUTH_NONE;
544 			} else {
545 				nxpwifi_dbg(adapter, MSG,
546 					    "assoc: receive disassoc from %pM\n",
547 					    ieee_hdr->addr3);
548 			}
549 		}
550 
551 		rx_info = NXPWIFI_SKB_RXCB(skb);
552 		rx_info->pkt_len = pkt_len;
553 		skb_queue_tail(&adapter->rx_mlme_q, skb);
554 		nxpwifi_queue_wiphy_work(adapter, &adapter->host_mlme_work);
555 		return -EINPROGRESS;
556 	}
557 
558 	if (GET_BSS_ROLE(priv) == NXPWIFI_BSS_ROLE_UAP) {
559 		if (ieee80211_is_auth(ieee_hdr->frame_control))
560 			nxpwifi_dbg(adapter, MSG,
561 				    "auth: receive auth from %pM\n",
562 				    ieee_hdr->addr2);
563 		if (ieee80211_is_deauth(ieee_hdr->frame_control))
564 			nxpwifi_dbg(adapter, MSG,
565 				    "auth: receive deauth from %pM\n",
566 				    ieee_hdr->addr2);
567 		if (ieee80211_is_disassoc(ieee_hdr->frame_control))
568 			nxpwifi_dbg(adapter, MSG,
569 				    "assoc: receive disassoc from %pM\n",
570 				    ieee_hdr->addr2);
571 		if (ieee80211_is_assoc_req(ieee_hdr->frame_control))
572 			nxpwifi_dbg(adapter, MSG,
573 				    "assoc: receive assoc req from %pM\n",
574 				    ieee_hdr->addr2);
575 		if (ieee80211_is_reassoc_req(ieee_hdr->frame_control))
576 			nxpwifi_dbg(adapter, MSG,
577 				    "assoc: receive reassoc req from %pM\n",
578 				    ieee_hdr->addr2);
579 	}
580 
581 	cfg80211_rx_mgmt(&priv->wdev, priv->roc_cfg.chan.center_freq,
582 			 CAL_RSSI(rx_pd->snr, rx_pd->nf), skb->data, pkt_len,
583 			 0);
584 
585 	return 0;
586 }
587 
588 #define RTAP_MAX_LEN 128
589 
nxpwifi_recv_packet_to_monif(struct nxpwifi_private * priv,struct sk_buff * skb)590 int nxpwifi_recv_packet_to_monif(struct nxpwifi_private *priv,
591 				 struct sk_buff *skb)
592 {
593 	struct rxpd *rxpd;
594 	struct rxpd_extra_info ext;
595 	struct ieee80211_hdr *dot11;
596 	struct ieee80211_radiotap_header *hdr;
597 	int freq, band;
598 	bool has_ext = false, has_ts = false, use_tsft = false;
599 	u16 rx_flags = 0, off, chan_flags, rx_pkt_offset;
600 	__le16 freq_le, flags_le;
601 	u8 rthdr[RTAP_MAX_LEN] = {0};
602 	s8 signal, noise;
603 	u8 flags = 0, chan, ant, format, bw, gi, ldpc, mcs, nss, stbc;
604 
605 	if (!skb)
606 		return -EINVAL;
607 
608 	rxpd = (struct rxpd *)skb->data;
609 	rx_pkt_offset = le16_to_cpu(rxpd->rx_pkt_offset);
610 
611 	if (rx_pkt_offset > skb->len || rx_pkt_offset < sizeof(struct rxpd))
612 		return -EINVAL;
613 
614 	if (skb->len - rx_pkt_offset < sizeof(struct ieee80211_hdr))
615 		return -EINVAL;
616 
617 	has_ext = rxpd->flags & RXPD_FLAG_EXTRA_HEADER;
618 
619 	if (has_ext)
620 		memcpy((void *)&ext, (void *)(rxpd + 1), sizeof(ext));
621 
622 	dot11 = (void *)skb->data + rx_pkt_offset;
623 	memset(rthdr, 0, sizeof(rthdr));
624 	hdr = (void *)rthdr;
625 	hdr->it_version = 0;
626 	hdr->it_pad = 0;
627 	hdr->it_present = 0;
628 	off = sizeof(*hdr);
629 	hdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_FLAGS));
630 
631 	if (has_ext) {
632 		has_ts = true;
633 		use_tsft = (ext.timestamp.position == 0);
634 
635 		if (has_ts) {
636 			if (use_tsft)
637 				hdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_TSFT));
638 			else
639 				hdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_TIMESTAMP));
640 		}
641 
642 		flags = ext.flags & ~IEEE80211_RADIOTAP_F_BADFCS;
643 		/* reverse fail fcs, 1 means pass FCS in FW,
644 		 * but means fail FCS in radiotap
645 		 */
646 		flags &= ~((~ext.flags) & IEEE80211_RADIOTAP_F_BADFCS);
647 
648 		if (ext.plcp_crc_failed)
649 			rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP;
650 	}
651 
652 	if (has_ts && use_tsft) {
653 		off = ALIGN(off, 8);
654 		memcpy(rthdr + off, &ext.timestamp.device_timestamp, 8);
655 		off += 8;
656 	}
657 
658 	if (ieee80211_has_morefrags(dot11->frame_control))
659 		flags |= IEEE80211_RADIOTAP_F_FRAG;
660 
661 	if (ieee80211_has_protected(dot11->frame_control))
662 		flags |= IEEE80211_RADIOTAP_F_WEP;
663 
664 	rthdr[off++] = flags;
665 	off = ALIGN(off, 2);
666 	hdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_CHANNEL));
667 	chan = (le32_to_cpu(rxpd->rx_info) >> 5) & 0xff;
668 	band = (chan <= 14) ? NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
669 	freq = ieee80211_channel_to_frequency(chan, band);
670 
671 	if (has_ext)
672 		chan_flags = ext.channel_flags;
673 	else if (band == NL80211_BAND_2GHZ)
674 		chan_flags = IEEE80211_CHAN_2GHZ;
675 	else
676 		chan_flags = IEEE80211_CHAN_5GHZ;
677 
678 	freq_le  = cpu_to_le16(freq);
679 	flags_le = cpu_to_le16(chan_flags);
680 	memcpy(rthdr + off, &freq_le, 2);
681 	off += 2;
682 	memcpy(rthdr + off, &flags_le, 2);
683 	off += 2;
684 	hdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_DBM_ANTSIGNAL));
685 	signal = -(rxpd->nf - rxpd->snr);
686 	rthdr[off++] = signal;
687 	hdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_DBM_ANTNOISE));
688 	noise = -rxpd->nf;
689 	rthdr[off++] = noise;
690 	hdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_ANTENNA));
691 	ant = rxpd->antenna >> 1;
692 	rthdr[off++] = ant;
693 
694 	if (rx_flags) {
695 		hdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_RX_FLAGS));
696 		off = ALIGN(off, 2);
697 		memcpy(rthdr + off, &rx_flags, 2);
698 		off += 2;
699 	}
700 
701 	format = FIELD_GET(RX_RATE_FORMAT_MASK, rxpd->rate_info);
702 	bw = FIELD_GET(RX_RATE_BW_MASK, rxpd->rate_info);
703 	ldpc = FIELD_GET(RX_RATE_LDPC_MASK, rxpd->rate_info) ? 1 : 0;
704 	stbc = FIELD_GET(RX_RATE_STBC_MASK, rxpd->rate_info) ? 1 : 0;
705 
706 	if (format == NXPWIFI_RATE_FORMAT_HE) {
707 		gi = ((rxpd->rate_info >> 7) & 0x1) << 1 |
708 			((rxpd->rate_info >> 4) & 0x1);
709 	} else {
710 		gi = FIELD_GET(RX_RATE_GI_MASK, rxpd->rate_info);
711 	}
712 
713 	mcs = rxpd->rx_rate & 0xf;
714 	nss = ((rxpd->rx_rate >> 4) & 0xf) + 1;
715 
716 	if (format == NXPWIFI_RATE_FORMAT_HT) {
717 		u8 mcs_flags = 0;
718 
719 		hdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_MCS));
720 		rthdr[off++] = IEEE80211_RADIOTAP_MCS_HAVE_MCS |
721 					IEEE80211_RADIOTAP_MCS_HAVE_BW |
722 					IEEE80211_RADIOTAP_MCS_HAVE_GI;
723 
724 		if (bw == 1)
725 			mcs_flags |= IEEE80211_RADIOTAP_MCS_BW_40;
726 
727 		if (gi)
728 			mcs_flags |= IEEE80211_RADIOTAP_MCS_SGI;
729 
730 		if (ldpc)
731 			mcs_flags |= IEEE80211_RADIOTAP_MCS_FEC_LDPC;
732 
733 		if (stbc)
734 			mcs_flags |= (1 << IEEE80211_RADIOTAP_MCS_STBC_SHIFT);
735 
736 		rthdr[off++] = mcs_flags;
737 		rthdr[off++] = mcs;
738 	}
739 
740 	if (format == NXPWIFI_RATE_FORMAT_VHT && has_ext) {
741 		struct ieee80211_radiotap_vht vht = {0};
742 		u32 vht_sig1 = 0, vht_sig2 = 0;
743 		__le16 partial_aid = 0;
744 		u8 bw_field = 0;
745 
746 		vht_sig1 = ext.vht_he_sig1;
747 		vht_sig2 = ext.vht_he_sig2;
748 		hdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_VHT));
749 		vht.known = cpu_to_le16(IEEE80211_RADIOTAP_VHT_KNOWN_GI |
750 					IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH |
751 					IEEE80211_RADIOTAP_VHT_KNOWN_STBC |
752 					IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED |
753 					IEEE80211_RADIOTAP_VHT_KNOWN_GROUP_ID);
754 
755 		if (stbc)
756 			vht.flags |= IEEE80211_RADIOTAP_VHT_FLAG_STBC;
757 
758 		if (gi)
759 			vht.flags |= IEEE80211_RADIOTAP_VHT_FLAG_SGI;
760 
761 		if (vht_sig2 & BIT(1))
762 			vht.flags |= IEEE80211_RADIOTAP_VHT_FLAG_SGI_NSYM_M10_9;
763 
764 		if (vht_sig2 & BIT(8))
765 			vht.flags |= IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED;
766 
767 		switch (bw) {
768 		case 1:
769 			bw_field = 1; /* 40 MHz */
770 			break;
771 		case 2:
772 			bw_field = 4; /* 80 MHz */
773 			break;
774 		case 3:
775 			bw_field = 11; /* 160 MHz */
776 			break;
777 		default:
778 			bw_field = 0; /* 20 MHz */
779 		}
780 
781 		vht.bandwidth = bw_field;
782 		vht.mcs_nss[0] = (nss & 0xf) | (mcs << 4);
783 
784 		if (vht_sig2 & BIT(2))
785 			vht.coding |= IEEE80211_RADIOTAP_CODING_LDPC_USER0;
786 
787 		vht.group_id = (vht_sig1 >> 4) & 0x3f;
788 		memcpy(&vht.partial_aid, &partial_aid, 2);
789 		off = ALIGN(off, 2);
790 		memcpy(rthdr + off, &vht, sizeof(vht));
791 		off += sizeof(vht);
792 	}
793 
794 	/* TIMESTAMP */
795 	if (has_ts && !use_tsft) {
796 		u64 ts;
797 		__le64 ts_le;
798 		u16 accuracy = 0;
799 		__le16 acc_le;
800 		u8 flags = 0;
801 
802 		hdr->it_present |=
803 			cpu_to_le32(BIT(IEEE80211_RADIOTAP_TIMESTAMP));
804 		off = ALIGN(off, 8);
805 
806 		if (ext.timestamp.flags & 0x01) {
807 			flags |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT;
808 			ts = (u32)ext.timestamp.device_timestamp;
809 		} else {
810 			flags |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_64BIT;
811 			ts = ext.timestamp.device_timestamp;
812 		}
813 
814 		ts_le = cpu_to_le64(ts);
815 		memcpy(rthdr + off, &ts_le, sizeof(ts_le));
816 		off += sizeof(ts_le);
817 
818 		if (ext.timestamp.flags & 0x02) {
819 			accuracy = ext.timestamp.accuracy;
820 			flags |= IEEE80211_RADIOTAP_TIMESTAMP_FLAG_ACCURACY;
821 		}
822 
823 		acc_le = cpu_to_le16(accuracy);
824 		memcpy(rthdr + off, &acc_le, sizeof(acc_le));
825 		off += sizeof(acc_le);
826 		rthdr[off++] = (ext.timestamp.unit & 0x0f) |
827 				((ext.timestamp.position & 0x0f) << 4);
828 		rthdr[off++] = flags;
829 	}
830 
831 	if (format == NXPWIFI_RATE_FORMAT_HE && has_ext) {
832 		struct ieee80211_radiotap_he he = {0};
833 		u16 data1 = 0, data2 = 0, data3 = 0, data5 = 0, data6 = 0;
834 		u8 bw_val = 0;
835 
836 		memcpy((void *)&ext, (void *)(rxpd + 1), sizeof(ext));
837 
838 		off = ALIGN(off, 2);
839 		hdr->it_present |= cpu_to_le32(BIT(IEEE80211_RADIOTAP_HE));
840 		data1 |= IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN;
841 		data1 |= IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN;
842 		data1 |= IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN;
843 		data1 |= IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN;
844 		data2 |= IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN;
845 		data3 = mcs << 8;
846 		data3 |= FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS, mcs);
847 
848 		if (stbc)
849 			data3 |= IEEE80211_RADIOTAP_HE_DATA3_STBC;
850 
851 		switch (bw) {
852 		case 0:
853 			bw_val |= IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_20MHZ;
854 			break;
855 		case 1:
856 			bw_val |= IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_40MHZ;
857 			break;
858 		case 2:
859 			bw_val |= IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_80MHZ;
860 			break;
861 		case 3:
862 			bw_val |= IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC_160MHZ;
863 			break;
864 		}
865 
866 		data5 |= FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC,
867 						    bw_val);
868 
869 		switch (gi) {
870 		case 0:
871 			data5 |= IEEE80211_RADIOTAP_HE_DATA5_GI_0_8;
872 			break;
873 		case 1:
874 			data5 |= IEEE80211_RADIOTAP_HE_DATA5_GI_1_6;
875 			break;
876 		case 2:
877 			data5 |= IEEE80211_RADIOTAP_HE_DATA5_GI_3_2;
878 			break;
879 		}
880 
881 		data6 |= FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_NSTS, nss);
882 		he.data1 = cpu_to_le16(data1);
883 		he.data2 = cpu_to_le16(data2);
884 		he.data3 = cpu_to_le16(data3);
885 		he.data5 = cpu_to_le16(data5);
886 		he.data6 = cpu_to_le16(data6);
887 		memcpy(rthdr + off, &he, sizeof(he));
888 		off += sizeof(he);
889 	}
890 
891 	hdr->it_len = cpu_to_le16(off);
892 
893 	if (off > sizeof(rthdr))
894 		return -EINVAL;
895 
896 	/* Remove RXPD */
897 	skb_pull(skb, rx_pkt_offset);
898 
899 	/* Ensure enough headroom */
900 	if (skb_cow_head(skb, off))
901 		return -ENOMEM;
902 
903 	/* Push radiotap header */
904 	skb_push(skb, off);
905 	memcpy(skb->data, rthdr, off);
906 	skb_reset_mac_header(skb);
907 	skb->ip_summed = CHECKSUM_NONE;
908 	skb->pkt_type  = PACKET_OTHERHOST;
909 	skb->dev       = priv->netdev;
910 	skb->protocol  = htons(ETH_P_802_2);
911 	netif_rx(skb);
912 	return 0;
913 }
914 
915 /* Process received packet and pass to net stack; reuse or build skb as needed. */
nxpwifi_recv_packet(struct nxpwifi_private * priv,struct sk_buff * skb)916 int nxpwifi_recv_packet(struct nxpwifi_private *priv, struct sk_buff *skb)
917 {
918 	struct nxpwifi_sta_node *src_node;
919 	struct ethhdr *p_ethhdr;
920 
921 	if (!skb)
922 		return -ENOMEM;
923 
924 	priv->stats.rx_bytes += skb->len;
925 	priv->stats.rx_packets++;
926 
927 	if (GET_BSS_ROLE(priv) == NXPWIFI_BSS_ROLE_UAP) {
928 		p_ethhdr = (void *)skb->data;
929 		rcu_read_lock();
930 		src_node = nxpwifi_get_sta_entry(priv, p_ethhdr->h_source);
931 		if (src_node) {
932 			src_node->stats.last_rx = jiffies;
933 			src_node->stats.rx_bytes += skb->len;
934 			src_node->stats.rx_packets++;
935 		}
936 		rcu_read_unlock();
937 	}
938 
939 	skb->dev = priv->netdev;
940 	skb->protocol = eth_type_trans(skb, priv->netdev);
941 	skb->ip_summed = CHECKSUM_NONE;
942 
943 	netif_rx(skb);
944 	return 0;
945 }
946 
947 /* IOCTL completion callback: wake waiters or process response as needed. */
nxpwifi_complete_cmd(struct nxpwifi_adapter * adapter,struct cmd_ctrl_node * cmd_node)948 int nxpwifi_complete_cmd(struct nxpwifi_adapter *adapter,
949 			 struct cmd_ctrl_node *cmd_node)
950 {
951 	WARN_ON(!cmd_node->wait_q_enabled);
952 	nxpwifi_dbg(adapter, CMD, "cmd completed: status=%d\n",
953 		    adapter->cmd_wait_q.status);
954 
955 	*cmd_node->condition = true;
956 	wake_up_interruptible(&adapter->cmd_wait_q.wait);
957 
958 	return 0;
959 }
960 
961 /* Find STA entry by MAC under rcu_read_lock(); return NULL if not found. */
962 struct nxpwifi_sta_node *
nxpwifi_get_sta_entry(struct nxpwifi_private * priv,const u8 * mac)963 nxpwifi_get_sta_entry(struct nxpwifi_private *priv, const u8 *mac)
964 {
965 	struct nxpwifi_sta_node *node;
966 	struct nxpwifi_sta_node *found = NULL;
967 
968 	if (!mac)
969 		return NULL;
970 	list_for_each_entry_rcu(node, &priv->sta_list, list) {
971 		if (!memcmp(node->mac_addr, mac, ETH_ALEN)) {
972 			found = node;
973 			break;
974 		}
975 	}
976 
977 	return found;
978 }
979 
980 struct nxpwifi_sta_node *
nxpwifi_get_sta_entry_rcu(struct nxpwifi_private * priv,const u8 * mac)981 nxpwifi_get_sta_entry_rcu(struct nxpwifi_private *priv, const u8 *mac)
982 {
983 	struct nxpwifi_sta_node *node;
984 
985 	rcu_read_lock();
986 	node = nxpwifi_get_sta_entry(priv, mac);
987 	rcu_read_unlock();
988 
989 	return node;
990 }
991 
992 /* Add STA entry by MAC; return existing entry or NULL on invalid MAC. */
993 struct nxpwifi_sta_node *
nxpwifi_add_sta_entry(struct nxpwifi_private * priv,const u8 * mac)994 nxpwifi_add_sta_entry(struct nxpwifi_private *priv, const u8 *mac)
995 {
996 	struct nxpwifi_sta_node *node;
997 
998 	if (!mac)
999 		return NULL;
1000 
1001 	spin_lock_bh(&priv->sta_list_spinlock);
1002 	node = nxpwifi_get_sta_entry_rcu(priv, mac);
1003 
1004 	if (node)
1005 		goto done;
1006 
1007 	node = kzalloc_obj(*node, GFP_ATOMIC);
1008 	if (!node)
1009 		goto done;
1010 
1011 	memcpy(node->mac_addr, mac, ETH_ALEN);
1012 	list_add_tail_rcu(&node->list, &priv->sta_list);
1013 
1014 done:
1015 	spin_unlock_bh(&priv->sta_list_spinlock);
1016 	return node;
1017 }
1018 
1019 /* Parse HT cap IE from association IEs and set STA HT parameters. */
1020 void
nxpwifi_set_sta_ht_cap(struct nxpwifi_private * priv,const u8 * ies,int ies_len,struct nxpwifi_sta_node * node)1021 nxpwifi_set_sta_ht_cap(struct nxpwifi_private *priv, const u8 *ies,
1022 		       int ies_len, struct nxpwifi_sta_node *node)
1023 {
1024 	struct element *ht_cap_ie;
1025 	const struct ieee80211_ht_cap *ht_cap;
1026 
1027 	if (!ies)
1028 		return;
1029 
1030 	ht_cap_ie = (void *)cfg80211_find_ie(WLAN_EID_HT_CAPABILITY, ies,
1031 					     ies_len);
1032 	if (ht_cap_ie) {
1033 		ht_cap = (void *)(ht_cap_ie + 1);
1034 		node->is_11n_enabled = 1;
1035 		node->max_amsdu = le16_to_cpu(ht_cap->cap_info) &
1036 				  IEEE80211_HT_CAP_MAX_AMSDU ?
1037 				  NXPWIFI_TX_DATA_BUF_SIZE_8K :
1038 				  NXPWIFI_TX_DATA_BUF_SIZE_4K;
1039 	} else {
1040 		node->is_11n_enabled = 0;
1041 	}
1042 }
1043 
1044 /* Delete a station from list; called under cfg80211 mutex. */
1045 
nxpwifi_del_sta_entry(struct nxpwifi_private * priv,const u8 * mac)1046 void nxpwifi_del_sta_entry(struct nxpwifi_private *priv, const u8 *mac)
1047 {
1048 	struct nxpwifi_sta_node *node;
1049 
1050 	list_for_each_entry_rcu(node, &priv->sta_list, list) {
1051 		if (!memcmp(node->mac_addr, mac, ETH_ALEN)) {
1052 			list_del_rcu(&node->list);
1053 			kfree_rcu(node, rcu);
1054 			break;
1055 		}
1056 	}
1057 }
1058 
1059 /* Delete all stations from list. */
nxpwifi_del_all_sta_list(struct nxpwifi_private * priv)1060 void nxpwifi_del_all_sta_list(struct nxpwifi_private *priv)
1061 {
1062 	struct nxpwifi_sta_node *node, *tmp;
1063 
1064 	spin_lock_bh(&priv->sta_list_spinlock);
1065 
1066 	list_for_each_entry_safe(node, tmp, &priv->sta_list, list) {
1067 		list_del_rcu(&node->list);
1068 		kfree_rcu(node, rcu);
1069 	}
1070 
1071 	INIT_LIST_HEAD(&priv->sta_list);
1072 	spin_unlock_bh(&priv->sta_list_spinlock);
1073 }
1074 
1075 /* Add one histogram sample. */
nxpwifi_hist_data_add(struct nxpwifi_private * priv,u8 rx_rate,s8 snr,s8 nflr)1076 void nxpwifi_hist_data_add(struct nxpwifi_private *priv,
1077 			   u8 rx_rate, s8 snr, s8 nflr)
1078 {
1079 	struct nxpwifi_histogram_data *phist_data = priv->hist_data;
1080 
1081 	if (atomic_read(&phist_data->num_samples) > NXPWIFI_HIST_MAX_SAMPLES)
1082 		nxpwifi_hist_data_reset(priv);
1083 	nxpwifi_hist_data_set(priv, rx_rate, snr, nflr);
1084 }
1085 
1086 /* function to add histogram record */
nxpwifi_hist_data_set(struct nxpwifi_private * priv,u8 rx_rate,s8 snr,s8 nflr)1087 void nxpwifi_hist_data_set(struct nxpwifi_private *priv, u8 rx_rate, s8 snr,
1088 			   s8 nflr)
1089 {
1090 	struct nxpwifi_histogram_data *phist_data = priv->hist_data;
1091 	s8 nf   = -nflr;
1092 	s8 rssi = snr - nflr;
1093 
1094 	atomic_inc(&phist_data->num_samples);
1095 	atomic_inc(&phist_data->rx_rate[rx_rate]);
1096 	atomic_inc(&phist_data->snr[snr + 128]);
1097 	atomic_inc(&phist_data->noise_flr[nf + 128]);
1098 	atomic_inc(&phist_data->sig_str[rssi + 128]);
1099 }
1100 
1101 /* function to reset histogram data during init/reset */
nxpwifi_hist_data_reset(struct nxpwifi_private * priv)1102 void nxpwifi_hist_data_reset(struct nxpwifi_private *priv)
1103 {
1104 	int ix;
1105 	struct nxpwifi_histogram_data *phist_data = priv->hist_data;
1106 
1107 	atomic_set(&phist_data->num_samples, 0);
1108 	for (ix = 0; ix < NXPWIFI_MAX_AC_RX_RATES; ix++)
1109 		atomic_set(&phist_data->rx_rate[ix], 0);
1110 	for (ix = 0; ix < NXPWIFI_MAX_SNR; ix++)
1111 		atomic_set(&phist_data->snr[ix], 0);
1112 	for (ix = 0; ix < NXPWIFI_MAX_NOISE_FLR; ix++)
1113 		atomic_set(&phist_data->noise_flr[ix], 0);
1114 	for (ix = 0; ix < NXPWIFI_MAX_SIG_STRENGTH; ix++)
1115 		atomic_set(&phist_data->sig_str[ix], 0);
1116 }
1117 
nxpwifi_alloc_dma_align_buf(int rx_len,gfp_t flags)1118 void *nxpwifi_alloc_dma_align_buf(int rx_len, gfp_t flags)
1119 {
1120 	struct sk_buff *skb;
1121 	int buf_len, pad;
1122 
1123 	buf_len = rx_len + NXPWIFI_RX_HEADROOM + NXPWIFI_DMA_ALIGN_SZ;
1124 
1125 	skb = __dev_alloc_skb(buf_len, flags);
1126 
1127 	if (!skb)
1128 		return NULL;
1129 
1130 	skb_reserve(skb, NXPWIFI_RX_HEADROOM);
1131 
1132 	pad = NXPWIFI_ALIGN_ADDR(skb->data, NXPWIFI_DMA_ALIGN_SZ) -
1133 	      (long)skb->data;
1134 
1135 	skb_reserve(skb, pad);
1136 
1137 	return skb;
1138 }
1139 EXPORT_SYMBOL_GPL(nxpwifi_alloc_dma_align_buf);
1140 
nxpwifi_fw_dump_event(struct nxpwifi_private * priv)1141 void nxpwifi_fw_dump_event(struct nxpwifi_private *priv)
1142 {
1143 	nxpwifi_send_cmd(priv, HOST_CMD_FW_DUMP_EVENT, HOST_ACT_GEN_SET,
1144 			 0, NULL, true);
1145 }
1146 EXPORT_SYMBOL_GPL(nxpwifi_fw_dump_event);
1147 
nxpwifi_append_data_tlv(u16 id,u8 * data,int len,u8 * pos,u8 * cmd_end)1148 int nxpwifi_append_data_tlv(u16 id, u8 *data, int len, u8 *pos, u8 *cmd_end)
1149 {
1150 	struct nxpwifi_ie_types_data *tlv;
1151 	u16 header_len = sizeof(struct nxpwifi_ie_types_header);
1152 
1153 	tlv = (struct nxpwifi_ie_types_data *)pos;
1154 	tlv->header.len = cpu_to_le16(len);
1155 
1156 	if (id == WLAN_EID_EXT_HE_CAPABILITY) {
1157 		if ((pos + header_len + len + 1) > cmd_end)
1158 			return 0;
1159 
1160 		tlv->header.type = cpu_to_le16(WLAN_EID_EXTENSION);
1161 		tlv->data[0] = WLAN_EID_EXT_HE_CAPABILITY;
1162 		memcpy(tlv->data + 1, data, len);
1163 	} else {
1164 		if ((pos + header_len + len) > cmd_end)
1165 			return 0;
1166 
1167 		tlv->header.type = cpu_to_le16(id);
1168 		memcpy(tlv->data, data, len);
1169 	}
1170 
1171 	return (header_len + len);
1172 }
1173 
nxpwifi_get_vdll_image(struct nxpwifi_adapter * adapter,u32 vdll_len)1174 static int nxpwifi_get_vdll_image(struct nxpwifi_adapter *adapter, u32 vdll_len)
1175 {
1176 	struct vdll_dnld_ctrl *ctrl = &adapter->vdll_ctrl;
1177 	bool req_fw = false;
1178 	u32 offset;
1179 
1180 	if (ctrl->vdll_mem) {
1181 		nxpwifi_dbg(adapter, EVENT,
1182 			    "VDLL mem is not empty: %p old_len=%d new_len=%d\n",
1183 			    ctrl->vdll_mem, ctrl->vdll_len, vdll_len);
1184 		vfree(ctrl->vdll_mem);
1185 		ctrl->vdll_mem = NULL;
1186 		ctrl->vdll_len = 0;
1187 	}
1188 
1189 	ctrl->vdll_mem = vmalloc(vdll_len);
1190 	if (!ctrl->vdll_mem)
1191 		return -ENOMEM;
1192 
1193 	if (!adapter->firmware) {
1194 		req_fw = true;
1195 		if (request_firmware(&adapter->firmware, adapter->fw_name,
1196 				     adapter->dev))
1197 			return -ENOENT;
1198 	}
1199 
1200 	if (adapter->firmware) {
1201 		if (vdll_len < adapter->firmware->size) {
1202 			offset = adapter->firmware->size - vdll_len;
1203 			memcpy(ctrl->vdll_mem, adapter->firmware->data + offset,
1204 			       vdll_len);
1205 		} else {
1206 			nxpwifi_dbg(adapter, ERROR,
1207 				    "Invalid VDLL length = %d, fw_len=%d\n",
1208 				    vdll_len, (int)adapter->firmware->size);
1209 			return -EINVAL;
1210 		}
1211 		if (req_fw) {
1212 			release_firmware(adapter->firmware);
1213 			adapter->firmware = NULL;
1214 		}
1215 	}
1216 
1217 	ctrl->vdll_len = vdll_len;
1218 	nxpwifi_dbg(adapter, MSG, "VDLL image: len=%d\n", ctrl->vdll_len);
1219 
1220 	return 0;
1221 }
1222 
nxpwifi_download_vdll_block(struct nxpwifi_adapter * adapter,u8 * block,u16 block_len)1223 int nxpwifi_download_vdll_block(struct nxpwifi_adapter *adapter,
1224 				u8 *block, u16 block_len)
1225 {
1226 	struct vdll_dnld_ctrl *ctrl = &adapter->vdll_ctrl;
1227 	struct host_cmd_ds_command *host_cmd;
1228 	u16 msg_len = block_len + S_DS_GEN;
1229 	int ret = 0;
1230 
1231 	skb_trim(ctrl->skb, 0);
1232 	skb_put_zero(ctrl->skb, msg_len);
1233 
1234 	host_cmd = (struct host_cmd_ds_command *)(ctrl->skb->data);
1235 
1236 	host_cmd->command = cpu_to_le16(HOST_CMD_VDLL);
1237 	host_cmd->seq_num = cpu_to_le16(0xFF00);
1238 	host_cmd->size = cpu_to_le16(msg_len);
1239 	memcpy(ctrl->skb->data + S_DS_GEN, block, block_len);
1240 
1241 	skb_push(ctrl->skb, adapter->intf_hdr_len);
1242 	ret = adapter->if_ops.host_to_card(adapter, NXPWIFI_TYPE_VDLL,
1243 					   ctrl->skb, NULL);
1244 	skb_pull(ctrl->skb, adapter->intf_hdr_len);
1245 
1246 	if (ret)
1247 		nxpwifi_dbg(adapter, ERROR,
1248 			    "Fail to download VDLL: block: %p, len: %d\n",
1249 			    block, block_len);
1250 
1251 	return ret;
1252 }
1253 
nxpwifi_process_vdll_event(struct nxpwifi_private * priv,struct sk_buff * skb)1254 int nxpwifi_process_vdll_event(struct nxpwifi_private *priv,
1255 			       struct sk_buff *skb)
1256 {
1257 	struct nxpwifi_adapter *adapter = priv->adapter;
1258 	struct vdll_ind_event *vdll_evt =
1259 		(struct vdll_ind_event *)(skb->data + sizeof(u32));
1260 	u16 type = le16_to_cpu(vdll_evt->type);
1261 	u16 vdll_id = le16_to_cpu(vdll_evt->vdll_id);
1262 	u32 offset = le32_to_cpu(vdll_evt->offset);
1263 	u16 block_len = le16_to_cpu(vdll_evt->block_len);
1264 	struct vdll_dnld_ctrl *ctrl = &adapter->vdll_ctrl;
1265 	int ret = 0;
1266 
1267 	switch (type) {
1268 	case VDLL_IND_TYPE_REQ:
1269 		nxpwifi_dbg(adapter, EVENT,
1270 			    "VDLL IND (REG): ID: %d, offset: %#x, len: %d\n",
1271 			    vdll_id, offset, block_len);
1272 		if (offset <= ctrl->vdll_len) {
1273 			block_len =
1274 				min((u32)block_len, ctrl->vdll_len - offset);
1275 			if (!adapter->cmd_sent) {
1276 				ret = nxpwifi_download_vdll_block(adapter,
1277 								  ctrl->vdll_mem
1278 								  + offset,
1279 								  block_len);
1280 				if (ret)
1281 					nxpwifi_dbg(adapter, ERROR,
1282 						    "Download VDLL failed\n");
1283 			} else {
1284 				nxpwifi_dbg(adapter, EVENT,
1285 					    "Delay download VDLL block\n");
1286 				ctrl->pending_block_len = block_len;
1287 				ctrl->pending_block = ctrl->vdll_mem + offset;
1288 			}
1289 		} else {
1290 			nxpwifi_dbg(adapter, ERROR,
1291 				    "Err Req: offset=%#x, len=%d, vdll_len=%d\n",
1292 				    offset, block_len, ctrl->vdll_len);
1293 			ret = -EINVAL;
1294 		}
1295 		break;
1296 	case VDLL_IND_TYPE_OFFSET:
1297 		nxpwifi_dbg(adapter, EVENT,
1298 			    "VDLL IND (OFFSET): offset: %#x\n", offset);
1299 		ret = nxpwifi_get_vdll_image(adapter, offset);
1300 		break;
1301 	case VDLL_IND_TYPE_ERR_SIG:
1302 	case VDLL_IND_TYPE_ERR_ID:
1303 	case VDLL_IND_TYPE_SEC_ERR_ID:
1304 		nxpwifi_dbg(adapter, ERROR, "VDLL IND: error: %d\n", type);
1305 		break;
1306 	case VDLL_IND_TYPE_INTF_RESET:
1307 		nxpwifi_dbg(adapter, EVENT, "VDLL IND: interface reset\n");
1308 		break;
1309 	default:
1310 		nxpwifi_dbg(adapter, ERROR, "VDLL IND: unknown type: %d", type);
1311 		ret = -EINVAL;
1312 		break;
1313 	}
1314 
1315 	return ret;
1316 }
1317 
nxpwifi_roc_cookie(struct nxpwifi_adapter * adapter)1318 u64 nxpwifi_roc_cookie(struct nxpwifi_adapter *adapter)
1319 {
1320 	adapter->roc_cookie_counter++;
1321 
1322 	/* wow, you wrapped 64 bits ... more likely a bug */
1323 	if (WARN_ON(adapter->roc_cookie_counter == 0))
1324 		adapter->roc_cookie_counter++;
1325 
1326 	return adapter->roc_cookie_counter;
1327 }
1328 
nxpwifi_can_queue_work(struct nxpwifi_adapter * adapter)1329 static bool nxpwifi_can_queue_work(struct nxpwifi_adapter *adapter)
1330 {
1331 	if (test_bit(NXPWIFI_SURPRISE_REMOVED, &adapter->work_flags) ||
1332 	    test_bit(NXPWIFI_IS_CMD_TIMEDOUT, &adapter->work_flags) ||
1333 	    test_bit(NXPWIFI_IS_SUSPENDED, &adapter->work_flags)) {
1334 		nxpwifi_dbg(adapter, WARN,
1335 			    "queueing nxpwifi work while going to suspend\n");
1336 		return false;
1337 	}
1338 
1339 	return true;
1340 }
1341 
nxpwifi_queue_work(struct nxpwifi_adapter * adapter,struct work_struct * work)1342 void nxpwifi_queue_work(struct nxpwifi_adapter *adapter,
1343 			struct work_struct *work)
1344 {
1345 	if (!nxpwifi_can_queue_work(adapter))
1346 		return;
1347 
1348 	queue_work(adapter->workqueue, work);
1349 }
1350 EXPORT_SYMBOL(nxpwifi_queue_work);
1351 
nxpwifi_queue_delayed_work(struct nxpwifi_adapter * adapter,struct delayed_work * dwork,unsigned long delay)1352 void nxpwifi_queue_delayed_work(struct nxpwifi_adapter *adapter,
1353 				struct delayed_work *dwork,
1354 				unsigned long delay)
1355 {
1356 	if (!nxpwifi_can_queue_work(adapter))
1357 		return;
1358 
1359 	queue_delayed_work(adapter->workqueue, dwork, delay);
1360 }
1361 EXPORT_SYMBOL(nxpwifi_queue_delayed_work);
1362 
nxpwifi_queue_wiphy_work(struct nxpwifi_adapter * adapter,struct wiphy_work * work)1363 void nxpwifi_queue_wiphy_work(struct nxpwifi_adapter *adapter,
1364 			      struct wiphy_work *work)
1365 {
1366 	if (!nxpwifi_can_queue_work(adapter))
1367 		return;
1368 
1369 	wiphy_work_queue(adapter->wiphy, work);
1370 }
1371 
nxpwifi_queue_delayed_wiphy_work(struct nxpwifi_adapter * adapter,struct wiphy_delayed_work * dwork,unsigned long delay)1372 void nxpwifi_queue_delayed_wiphy_work(struct nxpwifi_adapter *adapter,
1373 				      struct wiphy_delayed_work *dwork,
1374 				      unsigned long delay)
1375 {
1376 	if (!nxpwifi_can_queue_work(adapter))
1377 		return;
1378 
1379 	wiphy_delayed_work_queue(adapter->wiphy, dwork, delay);
1380 }
1381