1 /*
2  * Copyright (c) 2012-2014 Qualcomm Atheros, Inc.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include <linux/moduleparam.h>
18 #include <linux/etherdevice.h>
19 #include <linux/if_arp.h>
20 
21 #include "wil6210.h"
22 #include "txrx.h"
23 #include "wmi.h"
24 #include "trace.h"
25 
26 static uint max_assoc_sta = 1;
27 module_param(max_assoc_sta, uint, S_IRUGO | S_IWUSR);
28 MODULE_PARM_DESC(max_assoc_sta, " Max number of stations associated to the AP");
29 
30 /**
31  * WMI event receiving - theory of operations
32  *
33  * When firmware about to report WMI event, it fills memory area
34  * in the mailbox and raises misc. IRQ. Thread interrupt handler invoked for
35  * the misc IRQ, function @wmi_recv_cmd called by thread IRQ handler.
36  *
37  * @wmi_recv_cmd reads event, allocates memory chunk  and attaches it to the
38  * event list @wil->pending_wmi_ev. Then, work queue @wil->wmi_wq wakes up
39  * and handles events within the @wmi_event_worker. Every event get detached
40  * from list, processed and deleted.
41  *
42  * Purpose for this mechanism is to release IRQ thread; otherwise,
43  * if WMI event handling involves another WMI command flow, this 2-nd flow
44  * won't be completed because of blocked IRQ thread.
45  */
46 
47 /**
48  * Addressing - theory of operations
49  *
50  * There are several buses present on the WIL6210 card.
51  * Same memory areas are visible at different address on
52  * the different busses. There are 3 main bus masters:
53  *  - MAC CPU (ucode)
54  *  - User CPU (firmware)
55  *  - AHB (host)
56  *
57  * On the PCI bus, there is one BAR (BAR0) of 2Mb size, exposing
58  * AHB addresses starting from 0x880000
59  *
60  * Internally, firmware uses addresses that allows faster access but
61  * are invisible from the host. To read from these addresses, alternative
62  * AHB address must be used.
63  *
64  * Memory mapping
65  * Linker address         PCI/Host address
66  *                        0x880000 .. 0xa80000  2Mb BAR0
67  * 0x800000 .. 0x807000   0x900000 .. 0x907000  28k DCCM
68  * 0x840000 .. 0x857000   0x908000 .. 0x91f000  92k PERIPH
69  */
70 
71 /**
72  * @fw_mapping provides memory remapping table
73  *
74  * array size should be in sync with the declaration in the wil6210.h
75  */
76 const struct fw_map fw_mapping[] = {
77 	{0x000000, 0x040000, 0x8c0000, "fw_code"}, /* FW code RAM      256k */
78 	{0x800000, 0x808000, 0x900000, "fw_data"}, /* FW data RAM       32k */
79 	{0x840000, 0x860000, 0x908000, "fw_peri"}, /* periph. data RAM 128k */
80 	{0x880000, 0x88a000, 0x880000, "rgf"},     /* various RGF       40k */
81 	{0x88a000, 0x88b000, 0x88a000, "AGC_tbl"}, /* AGC table          4k */
82 	{0x88b000, 0x88c000, 0x88b000, "rgf_ext"}, /* Pcie_ext_rgf       4k */
83 	{0x8c0000, 0x949000, 0x8c0000, "upper"},   /* upper area       548k */
84 	/*
85 	 * 920000..930000 ucode code RAM
86 	 * 930000..932000 ucode data RAM
87 	 * 932000..949000 back-door debug data
88 	 */
89 };
90 
91 /**
92  * return AHB address for given firmware/ucode internal (linker) address
93  * @x - internal address
94  * If address have no valid AHB mapping, return 0
95  */
96 static u32 wmi_addr_remap(u32 x)
97 {
98 	uint i;
99 
100 	for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
101 		if ((x >= fw_mapping[i].from) && (x < fw_mapping[i].to))
102 			return x + fw_mapping[i].host - fw_mapping[i].from;
103 	}
104 
105 	return 0;
106 }
107 
108 /**
109  * Check address validity for WMI buffer; remap if needed
110  * @ptr - internal (linker) fw/ucode address
111  *
112  * Valid buffer should be DWORD aligned
113  *
114  * return address for accessing buffer from the host;
115  * if buffer is not valid, return NULL.
116  */
117 void __iomem *wmi_buffer(struct wil6210_priv *wil, __le32 ptr_)
118 {
119 	u32 off;
120 	u32 ptr = le32_to_cpu(ptr_);
121 
122 	if (ptr % 4)
123 		return NULL;
124 
125 	ptr = wmi_addr_remap(ptr);
126 	if (ptr < WIL6210_FW_HOST_OFF)
127 		return NULL;
128 
129 	off = HOSTADDR(ptr);
130 	if (off > WIL6210_MEM_SIZE - 4)
131 		return NULL;
132 
133 	return wil->csr + off;
134 }
135 
136 /**
137  * Check address validity
138  */
139 void __iomem *wmi_addr(struct wil6210_priv *wil, u32 ptr)
140 {
141 	u32 off;
142 
143 	if (ptr % 4)
144 		return NULL;
145 
146 	if (ptr < WIL6210_FW_HOST_OFF)
147 		return NULL;
148 
149 	off = HOSTADDR(ptr);
150 	if (off > WIL6210_MEM_SIZE - 4)
151 		return NULL;
152 
153 	return wil->csr + off;
154 }
155 
156 int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr,
157 		 struct wil6210_mbox_hdr *hdr)
158 {
159 	void __iomem *src = wmi_buffer(wil, ptr);
160 
161 	if (!src)
162 		return -EINVAL;
163 
164 	wil_memcpy_fromio_32(hdr, src, sizeof(*hdr));
165 
166 	return 0;
167 }
168 
169 static int __wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
170 {
171 	struct {
172 		struct wil6210_mbox_hdr hdr;
173 		struct wil6210_mbox_hdr_wmi wmi;
174 	} __packed cmd = {
175 		.hdr = {
176 			.type = WIL_MBOX_HDR_TYPE_WMI,
177 			.flags = 0,
178 			.len = cpu_to_le16(sizeof(cmd.wmi) + len),
179 		},
180 		.wmi = {
181 			.mid = 0,
182 			.id = cpu_to_le16(cmdid),
183 		},
184 	};
185 	struct wil6210_mbox_ring *r = &wil->mbox_ctl.tx;
186 	struct wil6210_mbox_ring_desc d_head;
187 	u32 next_head;
188 	void __iomem *dst;
189 	void __iomem *head = wmi_addr(wil, r->head);
190 	uint retry;
191 
192 	if (sizeof(cmd) + len > r->entry_size) {
193 		wil_err(wil, "WMI size too large: %d bytes, max is %d\n",
194 			(int)(sizeof(cmd) + len), r->entry_size);
195 		return -ERANGE;
196 	}
197 
198 	might_sleep();
199 
200 	if (!test_bit(wil_status_fwready, &wil->status)) {
201 		wil_err(wil, "WMI: cannot send command while FW not ready\n");
202 		return -EAGAIN;
203 	}
204 
205 	if (!head) {
206 		wil_err(wil, "WMI head is garbage: 0x%08x\n", r->head);
207 		return -EINVAL;
208 	}
209 	/* read Tx head till it is not busy */
210 	for (retry = 5; retry > 0; retry--) {
211 		wil_memcpy_fromio_32(&d_head, head, sizeof(d_head));
212 		if (d_head.sync == 0)
213 			break;
214 		msleep(20);
215 	}
216 	if (d_head.sync != 0) {
217 		wil_err(wil, "WMI head busy\n");
218 		return -EBUSY;
219 	}
220 	/* next head */
221 	next_head = r->base + ((r->head - r->base + sizeof(d_head)) % r->size);
222 	wil_dbg_wmi(wil, "Head 0x%08x -> 0x%08x\n", r->head, next_head);
223 	/* wait till FW finish with previous command */
224 	for (retry = 5; retry > 0; retry--) {
225 		r->tail = ioread32(wil->csr + HOST_MBOX +
226 				   offsetof(struct wil6210_mbox_ctl, tx.tail));
227 		if (next_head != r->tail)
228 			break;
229 		msleep(20);
230 	}
231 	if (next_head == r->tail) {
232 		wil_err(wil, "WMI ring full\n");
233 		return -EBUSY;
234 	}
235 	dst = wmi_buffer(wil, d_head.addr);
236 	if (!dst) {
237 		wil_err(wil, "invalid WMI buffer: 0x%08x\n",
238 			le32_to_cpu(d_head.addr));
239 		return -EINVAL;
240 	}
241 	cmd.hdr.seq = cpu_to_le16(++wil->wmi_seq);
242 	/* set command */
243 	wil_dbg_wmi(wil, "WMI command 0x%04x [%d]\n", cmdid, len);
244 	wil_hex_dump_wmi("Cmd ", DUMP_PREFIX_OFFSET, 16, 1, &cmd,
245 			 sizeof(cmd), true);
246 	wil_hex_dump_wmi("cmd ", DUMP_PREFIX_OFFSET, 16, 1, buf,
247 			 len, true);
248 	wil_memcpy_toio_32(dst, &cmd, sizeof(cmd));
249 	wil_memcpy_toio_32(dst + sizeof(cmd), buf, len);
250 	/* mark entry as full */
251 	iowrite32(1, wil->csr + HOSTADDR(r->head) +
252 		  offsetof(struct wil6210_mbox_ring_desc, sync));
253 	/* advance next ptr */
254 	iowrite32(r->head = next_head, wil->csr + HOST_MBOX +
255 		  offsetof(struct wil6210_mbox_ctl, tx.head));
256 
257 	trace_wil6210_wmi_cmd(&cmd.wmi, buf, len);
258 
259 	/* interrupt to FW */
260 	iowrite32(SW_INT_MBOX, wil->csr + HOST_SW_INT);
261 
262 	return 0;
263 }
264 
265 int wmi_send(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len)
266 {
267 	int rc;
268 
269 	mutex_lock(&wil->wmi_mutex);
270 	rc = __wmi_send(wil, cmdid, buf, len);
271 	mutex_unlock(&wil->wmi_mutex);
272 
273 	return rc;
274 }
275 
276 /*=== Event handlers ===*/
277 static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
278 {
279 	struct net_device *ndev = wil_to_ndev(wil);
280 	struct wireless_dev *wdev = wil->wdev;
281 	struct wmi_ready_event *evt = d;
282 
283 	wil->fw_version = le32_to_cpu(evt->sw_version);
284 	wil->n_mids = evt->numof_additional_mids;
285 
286 	wil_info(wil, "FW ver. %d; MAC %pM; %d MID's\n", wil->fw_version,
287 		 evt->mac, wil->n_mids);
288 
289 	if (!is_valid_ether_addr(ndev->dev_addr)) {
290 		memcpy(ndev->dev_addr, evt->mac, ETH_ALEN);
291 		memcpy(ndev->perm_addr, evt->mac, ETH_ALEN);
292 	}
293 	snprintf(wdev->wiphy->fw_version, sizeof(wdev->wiphy->fw_version),
294 		 "%d", wil->fw_version);
295 }
296 
297 static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d,
298 			     int len)
299 {
300 	wil_dbg_wmi(wil, "WMI: got FW ready event\n");
301 
302 	wil_set_recovery_state(wil, fw_recovery_idle);
303 	set_bit(wil_status_fwready, &wil->status);
304 	/* let the reset sequence continue */
305 	complete(&wil->wmi_ready);
306 }
307 
308 static void wmi_evt_rx_mgmt(struct wil6210_priv *wil, int id, void *d, int len)
309 {
310 	struct wmi_rx_mgmt_packet_event *data = d;
311 	struct wiphy *wiphy = wil_to_wiphy(wil);
312 	struct ieee80211_mgmt *rx_mgmt_frame =
313 			(struct ieee80211_mgmt *)data->payload;
314 	int ch_no = data->info.channel+1;
315 	u32 freq = ieee80211_channel_to_frequency(ch_no,
316 			IEEE80211_BAND_60GHZ);
317 	struct ieee80211_channel *channel = ieee80211_get_channel(wiphy, freq);
318 	s32 signal = data->info.sqi;
319 	__le16 fc = rx_mgmt_frame->frame_control;
320 	u32 d_len = le32_to_cpu(data->info.len);
321 	u16 d_status = le16_to_cpu(data->info.status);
322 
323 	wil_dbg_wmi(wil, "MGMT: channel %d MCS %d SNR %d SQI %d%%\n",
324 		    data->info.channel, data->info.mcs, data->info.snr,
325 		    data->info.sqi);
326 	wil_dbg_wmi(wil, "status 0x%04x len %d fc 0x%04x\n", d_status, d_len,
327 		    le16_to_cpu(fc));
328 	wil_dbg_wmi(wil, "qid %d mid %d cid %d\n",
329 		    data->info.qid, data->info.mid, data->info.cid);
330 
331 	if (!channel) {
332 		wil_err(wil, "Frame on unsupported channel\n");
333 		return;
334 	}
335 
336 	if (ieee80211_is_beacon(fc) || ieee80211_is_probe_resp(fc)) {
337 		struct cfg80211_bss *bss;
338 		u64 tsf = le64_to_cpu(rx_mgmt_frame->u.beacon.timestamp);
339 		u16 cap = le16_to_cpu(rx_mgmt_frame->u.beacon.capab_info);
340 		u16 bi = le16_to_cpu(rx_mgmt_frame->u.beacon.beacon_int);
341 		const u8 *ie_buf = rx_mgmt_frame->u.beacon.variable;
342 		size_t ie_len = d_len - offsetof(struct ieee80211_mgmt,
343 						 u.beacon.variable);
344 		wil_dbg_wmi(wil, "Capability info : 0x%04x\n", cap);
345 		wil_dbg_wmi(wil, "TSF : 0x%016llx\n", tsf);
346 		wil_dbg_wmi(wil, "Beacon interval : %d\n", bi);
347 		wil_hex_dump_wmi("IE ", DUMP_PREFIX_OFFSET, 16, 1, ie_buf,
348 				 ie_len, true);
349 
350 		bss = cfg80211_inform_bss_frame(wiphy, channel, rx_mgmt_frame,
351 						d_len, signal, GFP_KERNEL);
352 		if (bss) {
353 			wil_dbg_wmi(wil, "Added BSS %pM\n",
354 				    rx_mgmt_frame->bssid);
355 			cfg80211_put_bss(wiphy, bss);
356 		} else {
357 			wil_err(wil, "cfg80211_inform_bss_frame() failed\n");
358 		}
359 	} else {
360 		cfg80211_rx_mgmt(wil->wdev, freq, signal,
361 				 (void *)rx_mgmt_frame, d_len, 0);
362 	}
363 }
364 
365 static void wmi_evt_scan_complete(struct wil6210_priv *wil, int id,
366 				  void *d, int len)
367 {
368 	if (wil->scan_request) {
369 		struct wmi_scan_complete_event *data = d;
370 		bool aborted = (data->status != WMI_SCAN_SUCCESS);
371 
372 		wil_dbg_wmi(wil, "SCAN_COMPLETE(0x%08x)\n", data->status);
373 		wil_dbg_misc(wil, "Complete scan_request 0x%p aborted %d\n",
374 			     wil->scan_request, aborted);
375 
376 		del_timer_sync(&wil->scan_timer);
377 		cfg80211_scan_done(wil->scan_request, aborted);
378 		wil->scan_request = NULL;
379 	} else {
380 		wil_err(wil, "SCAN_COMPLETE while not scanning\n");
381 	}
382 }
383 
384 static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
385 {
386 	struct net_device *ndev = wil_to_ndev(wil);
387 	struct wireless_dev *wdev = wil->wdev;
388 	struct wmi_connect_event *evt = d;
389 	int ch; /* channel number */
390 	struct station_info sinfo;
391 	u8 *assoc_req_ie, *assoc_resp_ie;
392 	size_t assoc_req_ielen, assoc_resp_ielen;
393 	/* capinfo(u16) + listen_interval(u16) + IEs */
394 	const size_t assoc_req_ie_offset = sizeof(u16) * 2;
395 	/* capinfo(u16) + status_code(u16) + associd(u16) + IEs */
396 	const size_t assoc_resp_ie_offset = sizeof(u16) * 3;
397 
398 	if (len < sizeof(*evt)) {
399 		wil_err(wil, "Connect event too short : %d bytes\n", len);
400 		return;
401 	}
402 	if (len != sizeof(*evt) + evt->beacon_ie_len + evt->assoc_req_len +
403 		   evt->assoc_resp_len) {
404 		wil_err(wil,
405 			"Connect event corrupted : %d != %d + %d + %d + %d\n",
406 			len, (int)sizeof(*evt), evt->beacon_ie_len,
407 			evt->assoc_req_len, evt->assoc_resp_len);
408 		return;
409 	}
410 	if (evt->cid >= WIL6210_MAX_CID) {
411 		wil_err(wil, "Connect CID invalid : %d\n", evt->cid);
412 		return;
413 	}
414 
415 	ch = evt->channel + 1;
416 	wil_dbg_wmi(wil, "Connect %pM channel [%d] cid %d\n",
417 		    evt->bssid, ch, evt->cid);
418 	wil_hex_dump_wmi("connect AI : ", DUMP_PREFIX_OFFSET, 16, 1,
419 			 evt->assoc_info, len - sizeof(*evt), true);
420 
421 	/* figure out IE's */
422 	assoc_req_ie = &evt->assoc_info[evt->beacon_ie_len +
423 					assoc_req_ie_offset];
424 	assoc_req_ielen = evt->assoc_req_len - assoc_req_ie_offset;
425 	if (evt->assoc_req_len <= assoc_req_ie_offset) {
426 		assoc_req_ie = NULL;
427 		assoc_req_ielen = 0;
428 	}
429 
430 	assoc_resp_ie = &evt->assoc_info[evt->beacon_ie_len +
431 					 evt->assoc_req_len +
432 					 assoc_resp_ie_offset];
433 	assoc_resp_ielen = evt->assoc_resp_len - assoc_resp_ie_offset;
434 	if (evt->assoc_resp_len <= assoc_resp_ie_offset) {
435 		assoc_resp_ie = NULL;
436 		assoc_resp_ielen = 0;
437 	}
438 
439 	if ((wdev->iftype == NL80211_IFTYPE_STATION) ||
440 	    (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) {
441 		if (!test_bit(wil_status_fwconnecting, &wil->status)) {
442 			wil_err(wil, "Not in connecting state\n");
443 			return;
444 		}
445 		del_timer_sync(&wil->connect_timer);
446 		cfg80211_connect_result(ndev, evt->bssid,
447 					assoc_req_ie, assoc_req_ielen,
448 					assoc_resp_ie, assoc_resp_ielen,
449 					WLAN_STATUS_SUCCESS, GFP_KERNEL);
450 
451 	} else if ((wdev->iftype == NL80211_IFTYPE_AP) ||
452 		   (wdev->iftype == NL80211_IFTYPE_P2P_GO)) {
453 		memset(&sinfo, 0, sizeof(sinfo));
454 
455 		sinfo.generation = wil->sinfo_gen++;
456 
457 		if (assoc_req_ie) {
458 			sinfo.assoc_req_ies = assoc_req_ie;
459 			sinfo.assoc_req_ies_len = assoc_req_ielen;
460 			sinfo.filled |= STATION_INFO_ASSOC_REQ_IES;
461 		}
462 
463 		cfg80211_new_sta(ndev, evt->bssid, &sinfo, GFP_KERNEL);
464 	}
465 	clear_bit(wil_status_fwconnecting, &wil->status);
466 	set_bit(wil_status_fwconnected, &wil->status);
467 
468 	/* FIXME FW can transmit only ucast frames to peer */
469 	/* FIXME real ring_id instead of hard coded 0 */
470 	memcpy(wil->sta[evt->cid].addr, evt->bssid, ETH_ALEN);
471 	wil->sta[evt->cid].status = wil_sta_conn_pending;
472 
473 	wil->pending_connect_cid = evt->cid;
474 	queue_work(wil->wmi_wq_conn, &wil->connect_worker);
475 }
476 
477 static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
478 			       void *d, int len)
479 {
480 	struct wmi_disconnect_event *evt = d;
481 	u16 reason_code = le16_to_cpu(evt->protocol_reason_status);
482 
483 	wil_dbg_wmi(wil, "Disconnect %pM reason [proto %d wmi %d]\n",
484 		    evt->bssid, reason_code, evt->disconnect_reason);
485 
486 	wil->sinfo_gen++;
487 
488 	mutex_lock(&wil->mutex);
489 	wil6210_disconnect(wil, evt->bssid, reason_code, true);
490 	mutex_unlock(&wil->mutex);
491 }
492 
493 /*
494  * Firmware reports EAPOL frame using WME event.
495  * Reconstruct Ethernet frame and deliver it via normal Rx
496  */
497 static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
498 			     void *d, int len)
499 {
500 	struct net_device *ndev = wil_to_ndev(wil);
501 	struct wmi_eapol_rx_event *evt = d;
502 	u16 eapol_len = le16_to_cpu(evt->eapol_len);
503 	int sz = eapol_len + ETH_HLEN;
504 	struct sk_buff *skb;
505 	struct ethhdr *eth;
506 	int cid;
507 	struct wil_net_stats *stats = NULL;
508 
509 	wil_dbg_wmi(wil, "EAPOL len %d from %pM\n", eapol_len,
510 		    evt->src_mac);
511 
512 	cid = wil_find_cid(wil, evt->src_mac);
513 	if (cid >= 0)
514 		stats = &wil->sta[cid].stats;
515 
516 	if (eapol_len > 196) { /* TODO: revisit size limit */
517 		wil_err(wil, "EAPOL too large\n");
518 		return;
519 	}
520 
521 	skb = alloc_skb(sz, GFP_KERNEL);
522 	if (!skb) {
523 		wil_err(wil, "Failed to allocate skb\n");
524 		return;
525 	}
526 
527 	eth = (struct ethhdr *)skb_put(skb, ETH_HLEN);
528 	memcpy(eth->h_dest, ndev->dev_addr, ETH_ALEN);
529 	memcpy(eth->h_source, evt->src_mac, ETH_ALEN);
530 	eth->h_proto = cpu_to_be16(ETH_P_PAE);
531 	memcpy(skb_put(skb, eapol_len), evt->eapol, eapol_len);
532 	skb->protocol = eth_type_trans(skb, ndev);
533 	if (likely(netif_rx_ni(skb) == NET_RX_SUCCESS)) {
534 		ndev->stats.rx_packets++;
535 		ndev->stats.rx_bytes += sz;
536 		if (stats) {
537 			stats->rx_packets++;
538 			stats->rx_bytes += sz;
539 		}
540 	} else {
541 		ndev->stats.rx_dropped++;
542 		if (stats)
543 			stats->rx_dropped++;
544 	}
545 }
546 
547 static void wmi_evt_linkup(struct wil6210_priv *wil, int id, void *d, int len)
548 {
549 	struct net_device *ndev = wil_to_ndev(wil);
550 	struct wmi_data_port_open_event *evt = d;
551 	u8 cid = evt->cid;
552 
553 	wil_dbg_wmi(wil, "Link UP for CID %d\n", cid);
554 
555 	if (cid >= ARRAY_SIZE(wil->sta)) {
556 		wil_err(wil, "Link UP for invalid CID %d\n", cid);
557 		return;
558 	}
559 
560 	wil->sta[cid].data_port_open = true;
561 	netif_carrier_on(ndev);
562 }
563 
564 static void wmi_evt_linkdown(struct wil6210_priv *wil, int id, void *d, int len)
565 {
566 	struct net_device *ndev = wil_to_ndev(wil);
567 	struct wmi_wbe_link_down_event *evt = d;
568 	u8 cid = evt->cid;
569 
570 	wil_dbg_wmi(wil, "Link DOWN for CID %d, reason %d\n",
571 		    cid, le32_to_cpu(evt->reason));
572 
573 	if (cid >= ARRAY_SIZE(wil->sta)) {
574 		wil_err(wil, "Link DOWN for invalid CID %d\n", cid);
575 		return;
576 	}
577 
578 	wil->sta[cid].data_port_open = false;
579 	netif_carrier_off(ndev);
580 }
581 
582 static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d,
583 			      int len)
584 {
585 	struct wmi_vring_ba_status_event *evt = d;
586 	struct wil_sta_info *sta;
587 	uint i, cid;
588 
589 	/* TODO: use Rx BA status, not Tx one */
590 
591 	wil_dbg_wmi(wil, "BACK[%d] %s {%d} timeout %d\n",
592 		    evt->ringid,
593 		    evt->status == WMI_BA_AGREED ? "OK" : "N/A",
594 		    evt->agg_wsize, __le16_to_cpu(evt->ba_timeout));
595 
596 	if (evt->ringid >= WIL6210_MAX_TX_RINGS) {
597 		wil_err(wil, "invalid ring id %d\n", evt->ringid);
598 		return;
599 	}
600 
601 	mutex_lock(&wil->mutex);
602 
603 	cid = wil->vring2cid_tid[evt->ringid][0];
604 	if (cid >= WIL6210_MAX_CID) {
605 		wil_err(wil, "invalid CID %d for vring %d\n", cid, evt->ringid);
606 		goto out;
607 	}
608 
609 	sta = &wil->sta[cid];
610 	if (sta->status == wil_sta_unused) {
611 		wil_err(wil, "CID %d unused\n", cid);
612 		goto out;
613 	}
614 
615 	wil_dbg_wmi(wil, "BACK for CID %d %pM\n", cid, sta->addr);
616 	for (i = 0; i < WIL_STA_TID_NUM; i++) {
617 		struct wil_tid_ampdu_rx *r;
618 		unsigned long flags;
619 
620 		spin_lock_irqsave(&sta->tid_rx_lock, flags);
621 
622 		r = sta->tid_rx[i];
623 		sta->tid_rx[i] = NULL;
624 		wil_tid_ampdu_rx_free(wil, r);
625 
626 		spin_unlock_irqrestore(&sta->tid_rx_lock, flags);
627 
628 		if ((evt->status == WMI_BA_AGREED) && evt->agg_wsize)
629 			sta->tid_rx[i] = wil_tid_ampdu_rx_alloc(wil,
630 						evt->agg_wsize, 0);
631 	}
632 
633 out:
634 	mutex_unlock(&wil->mutex);
635 }
636 
637 static const struct {
638 	int eventid;
639 	void (*handler)(struct wil6210_priv *wil, int eventid,
640 			void *data, int data_len);
641 } wmi_evt_handlers[] = {
642 	{WMI_READY_EVENTID,		wmi_evt_ready},
643 	{WMI_FW_READY_EVENTID,		wmi_evt_fw_ready},
644 	{WMI_RX_MGMT_PACKET_EVENTID,	wmi_evt_rx_mgmt},
645 	{WMI_SCAN_COMPLETE_EVENTID,	wmi_evt_scan_complete},
646 	{WMI_CONNECT_EVENTID,		wmi_evt_connect},
647 	{WMI_DISCONNECT_EVENTID,	wmi_evt_disconnect},
648 	{WMI_EAPOL_RX_EVENTID,		wmi_evt_eapol_rx},
649 	{WMI_DATA_PORT_OPEN_EVENTID,	wmi_evt_linkup},
650 	{WMI_WBE_LINKDOWN_EVENTID,	wmi_evt_linkdown},
651 	{WMI_BA_STATUS_EVENTID,		wmi_evt_ba_status},
652 };
653 
654 /*
655  * Run in IRQ context
656  * Extract WMI command from mailbox. Queue it to the @wil->pending_wmi_ev
657  * that will be eventually handled by the @wmi_event_worker in the thread
658  * context of thread "wil6210_wmi"
659  */
660 void wmi_recv_cmd(struct wil6210_priv *wil)
661 {
662 	struct wil6210_mbox_ring_desc d_tail;
663 	struct wil6210_mbox_hdr hdr;
664 	struct wil6210_mbox_ring *r = &wil->mbox_ctl.rx;
665 	struct pending_wmi_event *evt;
666 	u8 *cmd;
667 	void __iomem *src;
668 	ulong flags;
669 	unsigned n;
670 
671 	if (!test_bit(wil_status_reset_done, &wil->status)) {
672 		wil_err(wil, "Reset in progress. Cannot handle WMI event\n");
673 		return;
674 	}
675 
676 	for (n = 0;; n++) {
677 		u16 len;
678 		bool q;
679 
680 		r->head = ioread32(wil->csr + HOST_MBOX +
681 				   offsetof(struct wil6210_mbox_ctl, rx.head));
682 		if (r->tail == r->head)
683 			break;
684 
685 		wil_dbg_wmi(wil, "Mbox head %08x tail %08x\n",
686 			    r->head, r->tail);
687 		/* read cmd descriptor from tail */
688 		wil_memcpy_fromio_32(&d_tail, wil->csr + HOSTADDR(r->tail),
689 				     sizeof(struct wil6210_mbox_ring_desc));
690 		if (d_tail.sync == 0) {
691 			wil_err(wil, "Mbox evt not owned by FW?\n");
692 			break;
693 		}
694 
695 		/* read cmd header from descriptor */
696 		if (0 != wmi_read_hdr(wil, d_tail.addr, &hdr)) {
697 			wil_err(wil, "Mbox evt at 0x%08x?\n",
698 				le32_to_cpu(d_tail.addr));
699 			break;
700 		}
701 		len = le16_to_cpu(hdr.len);
702 		wil_dbg_wmi(wil, "Mbox evt %04x %04x %04x %02x\n",
703 			    le16_to_cpu(hdr.seq), len, le16_to_cpu(hdr.type),
704 			    hdr.flags);
705 
706 		/* read cmd buffer from descriptor */
707 		src = wmi_buffer(wil, d_tail.addr) +
708 		      sizeof(struct wil6210_mbox_hdr);
709 		evt = kmalloc(ALIGN(offsetof(struct pending_wmi_event,
710 					     event.wmi) + len, 4),
711 			      GFP_KERNEL);
712 		if (!evt)
713 			break;
714 
715 		evt->event.hdr = hdr;
716 		cmd = (void *)&evt->event.wmi;
717 		wil_memcpy_fromio_32(cmd, src, len);
718 		/* mark entry as empty */
719 		iowrite32(0, wil->csr + HOSTADDR(r->tail) +
720 			  offsetof(struct wil6210_mbox_ring_desc, sync));
721 		/* indicate */
722 		if ((hdr.type == WIL_MBOX_HDR_TYPE_WMI) &&
723 		    (len >= sizeof(struct wil6210_mbox_hdr_wmi))) {
724 			struct wil6210_mbox_hdr_wmi *wmi = &evt->event.wmi;
725 			u16 id = le16_to_cpu(wmi->id);
726 			u32 tstamp = le32_to_cpu(wmi->timestamp);
727 
728 			wil_dbg_wmi(wil, "WMI event 0x%04x MID %d @%d msec\n",
729 				    id, wmi->mid, tstamp);
730 			trace_wil6210_wmi_event(wmi, &wmi[1],
731 						len - sizeof(*wmi));
732 		}
733 		wil_hex_dump_wmi("evt ", DUMP_PREFIX_OFFSET, 16, 1,
734 				 &evt->event.hdr, sizeof(hdr) + len, true);
735 
736 		/* advance tail */
737 		r->tail = r->base + ((r->tail - r->base +
738 			  sizeof(struct wil6210_mbox_ring_desc)) % r->size);
739 		iowrite32(r->tail, wil->csr + HOST_MBOX +
740 			  offsetof(struct wil6210_mbox_ctl, rx.tail));
741 
742 		/* add to the pending list */
743 		spin_lock_irqsave(&wil->wmi_ev_lock, flags);
744 		list_add_tail(&evt->list, &wil->pending_wmi_ev);
745 		spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
746 		q = queue_work(wil->wmi_wq, &wil->wmi_event_worker);
747 		wil_dbg_wmi(wil, "queue_work -> %d\n", q);
748 	}
749 	/* normally, 1 event per IRQ should be processed */
750 	wil_dbg_wmi(wil, "%s -> %d events queued\n", __func__, n);
751 }
752 
753 int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
754 	     u16 reply_id, void *reply, u8 reply_size, int to_msec)
755 {
756 	int rc;
757 	int remain;
758 
759 	mutex_lock(&wil->wmi_mutex);
760 
761 	rc = __wmi_send(wil, cmdid, buf, len);
762 	if (rc)
763 		goto out;
764 
765 	wil->reply_id = reply_id;
766 	wil->reply_buf = reply;
767 	wil->reply_size = reply_size;
768 	remain = wait_for_completion_timeout(&wil->wmi_call,
769 					     msecs_to_jiffies(to_msec));
770 	if (0 == remain) {
771 		wil_err(wil, "wmi_call(0x%04x->0x%04x) timeout %d msec\n",
772 			cmdid, reply_id, to_msec);
773 		rc = -ETIME;
774 	} else {
775 		wil_dbg_wmi(wil,
776 			    "wmi_call(0x%04x->0x%04x) completed in %d msec\n",
777 			    cmdid, reply_id,
778 			    to_msec - jiffies_to_msecs(remain));
779 	}
780 	wil->reply_id = 0;
781 	wil->reply_buf = NULL;
782 	wil->reply_size = 0;
783  out:
784 	mutex_unlock(&wil->wmi_mutex);
785 
786 	return rc;
787 }
788 
789 int wmi_echo(struct wil6210_priv *wil)
790 {
791 	struct wmi_echo_cmd cmd = {
792 		.value = cpu_to_le32(0x12345678),
793 	};
794 
795 	return wmi_call(wil, WMI_ECHO_CMDID, &cmd, sizeof(cmd),
796 			 WMI_ECHO_RSP_EVENTID, NULL, 0, 20);
797 }
798 
799 int wmi_set_mac_address(struct wil6210_priv *wil, void *addr)
800 {
801 	struct wmi_set_mac_address_cmd cmd;
802 
803 	memcpy(cmd.mac, addr, ETH_ALEN);
804 
805 	wil_dbg_wmi(wil, "Set MAC %pM\n", addr);
806 
807 	return wmi_send(wil, WMI_SET_MAC_ADDRESS_CMDID, &cmd, sizeof(cmd));
808 }
809 
810 int wmi_pcp_start(struct wil6210_priv *wil, int bi, u8 wmi_nettype, u8 chan)
811 {
812 	int rc;
813 
814 	struct wmi_pcp_start_cmd cmd = {
815 		.bcon_interval = cpu_to_le16(bi),
816 		.network_type = wmi_nettype,
817 		.disable_sec_offload = 1,
818 		.channel = chan - 1,
819 		.pcp_max_assoc_sta = max_assoc_sta,
820 	};
821 	struct {
822 		struct wil6210_mbox_hdr_wmi wmi;
823 		struct wmi_pcp_started_event evt;
824 	} __packed reply;
825 
826 	if (!wil->secure_pcp)
827 		cmd.disable_sec = 1;
828 
829 	if ((cmd.pcp_max_assoc_sta > WIL6210_MAX_CID) ||
830 	    (cmd.pcp_max_assoc_sta <= 0)) {
831 		wil_info(wil,
832 			 "Requested connection limit %u, valid values are 1 - %d. Setting to %d\n",
833 			 max_assoc_sta, WIL6210_MAX_CID, WIL6210_MAX_CID);
834 		cmd.pcp_max_assoc_sta = WIL6210_MAX_CID;
835 	}
836 
837 	/*
838 	 * Processing time may be huge, in case of secure AP it takes about
839 	 * 3500ms for FW to start AP
840 	 */
841 	rc = wmi_call(wil, WMI_PCP_START_CMDID, &cmd, sizeof(cmd),
842 		      WMI_PCP_STARTED_EVENTID, &reply, sizeof(reply), 5000);
843 	if (rc)
844 		return rc;
845 
846 	if (reply.evt.status != WMI_FW_STATUS_SUCCESS)
847 		rc = -EINVAL;
848 
849 	return rc;
850 }
851 
852 int wmi_pcp_stop(struct wil6210_priv *wil)
853 {
854 	return wmi_call(wil, WMI_PCP_STOP_CMDID, NULL, 0,
855 			WMI_PCP_STOPPED_EVENTID, NULL, 0, 20);
856 }
857 
858 int wmi_set_ssid(struct wil6210_priv *wil, u8 ssid_len, const void *ssid)
859 {
860 	struct wmi_set_ssid_cmd cmd = {
861 		.ssid_len = cpu_to_le32(ssid_len),
862 	};
863 
864 	if (ssid_len > sizeof(cmd.ssid))
865 		return -EINVAL;
866 
867 	memcpy(cmd.ssid, ssid, ssid_len);
868 
869 	return wmi_send(wil, WMI_SET_SSID_CMDID, &cmd, sizeof(cmd));
870 }
871 
872 int wmi_get_ssid(struct wil6210_priv *wil, u8 *ssid_len, void *ssid)
873 {
874 	int rc;
875 	struct {
876 		struct wil6210_mbox_hdr_wmi wmi;
877 		struct wmi_set_ssid_cmd cmd;
878 	} __packed reply;
879 	int len; /* reply.cmd.ssid_len in CPU order */
880 
881 	rc = wmi_call(wil, WMI_GET_SSID_CMDID, NULL, 0, WMI_GET_SSID_EVENTID,
882 		      &reply, sizeof(reply), 20);
883 	if (rc)
884 		return rc;
885 
886 	len = le32_to_cpu(reply.cmd.ssid_len);
887 	if (len > sizeof(reply.cmd.ssid))
888 		return -EINVAL;
889 
890 	*ssid_len = len;
891 	memcpy(ssid, reply.cmd.ssid, len);
892 
893 	return 0;
894 }
895 
896 int wmi_set_channel(struct wil6210_priv *wil, int channel)
897 {
898 	struct wmi_set_pcp_channel_cmd cmd = {
899 		.channel = channel - 1,
900 	};
901 
902 	return wmi_send(wil, WMI_SET_PCP_CHANNEL_CMDID, &cmd, sizeof(cmd));
903 }
904 
905 int wmi_get_channel(struct wil6210_priv *wil, int *channel)
906 {
907 	int rc;
908 	struct {
909 		struct wil6210_mbox_hdr_wmi wmi;
910 		struct wmi_set_pcp_channel_cmd cmd;
911 	} __packed reply;
912 
913 	rc = wmi_call(wil, WMI_GET_PCP_CHANNEL_CMDID, NULL, 0,
914 		      WMI_GET_PCP_CHANNEL_EVENTID, &reply, sizeof(reply), 20);
915 	if (rc)
916 		return rc;
917 
918 	if (reply.cmd.channel > 3)
919 		return -EINVAL;
920 
921 	*channel = reply.cmd.channel + 1;
922 
923 	return 0;
924 }
925 
926 int wmi_p2p_cfg(struct wil6210_priv *wil, int channel)
927 {
928 	struct wmi_p2p_cfg_cmd cmd = {
929 		.discovery_mode = WMI_DISCOVERY_MODE_NON_OFFLOAD,
930 		.channel = channel - 1,
931 	};
932 
933 	return wmi_send(wil, WMI_P2P_CFG_CMDID, &cmd, sizeof(cmd));
934 }
935 
936 int wmi_del_cipher_key(struct wil6210_priv *wil, u8 key_index,
937 		       const void *mac_addr)
938 {
939 	struct wmi_delete_cipher_key_cmd cmd = {
940 		.key_index = key_index,
941 	};
942 
943 	if (mac_addr)
944 		memcpy(cmd.mac, mac_addr, WMI_MAC_LEN);
945 
946 	return wmi_send(wil, WMI_DELETE_CIPHER_KEY_CMDID, &cmd, sizeof(cmd));
947 }
948 
949 int wmi_add_cipher_key(struct wil6210_priv *wil, u8 key_index,
950 		       const void *mac_addr, int key_len, const void *key)
951 {
952 	struct wmi_add_cipher_key_cmd cmd = {
953 		.key_index = key_index,
954 		.key_usage = WMI_KEY_USE_PAIRWISE,
955 		.key_len = key_len,
956 	};
957 
958 	if (!key || (key_len > sizeof(cmd.key)))
959 		return -EINVAL;
960 
961 	memcpy(cmd.key, key, key_len);
962 	if (mac_addr)
963 		memcpy(cmd.mac, mac_addr, WMI_MAC_LEN);
964 
965 	return wmi_send(wil, WMI_ADD_CIPHER_KEY_CMDID, &cmd, sizeof(cmd));
966 }
967 
968 int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie)
969 {
970 	int rc;
971 	u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len;
972 	struct wmi_set_appie_cmd *cmd = kzalloc(len, GFP_KERNEL);
973 
974 	if (!cmd)
975 		return -ENOMEM;
976 	if (!ie)
977 		ie_len = 0;
978 
979 	cmd->mgmt_frm_type = type;
980 	/* BUG: FW API define ieLen as u8. Will fix FW */
981 	cmd->ie_len = cpu_to_le16(ie_len);
982 	memcpy(cmd->ie_info, ie, ie_len);
983 	rc = wmi_send(wil, WMI_SET_APPIE_CMDID, cmd, len);
984 	kfree(cmd);
985 
986 	return rc;
987 }
988 
989 /**
990  * wmi_rxon - turn radio on/off
991  * @on:		turn on if true, off otherwise
992  *
993  * Only switch radio. Channel should be set separately.
994  * No timeout for rxon - radio turned on forever unless some other call
995  * turns it off
996  */
997 int wmi_rxon(struct wil6210_priv *wil, bool on)
998 {
999 	int rc;
1000 	struct {
1001 		struct wil6210_mbox_hdr_wmi wmi;
1002 		struct wmi_listen_started_event evt;
1003 	} __packed reply;
1004 
1005 	wil_info(wil, "%s(%s)\n", __func__, on ? "on" : "off");
1006 
1007 	if (on) {
1008 		rc = wmi_call(wil, WMI_START_LISTEN_CMDID, NULL, 0,
1009 			      WMI_LISTEN_STARTED_EVENTID,
1010 			      &reply, sizeof(reply), 100);
1011 		if ((rc == 0) && (reply.evt.status != WMI_FW_STATUS_SUCCESS))
1012 			rc = -EINVAL;
1013 	} else {
1014 		rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, NULL, 0,
1015 			      WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 20);
1016 	}
1017 
1018 	return rc;
1019 }
1020 
1021 int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
1022 {
1023 	struct wireless_dev *wdev = wil->wdev;
1024 	struct net_device *ndev = wil_to_ndev(wil);
1025 	struct wmi_cfg_rx_chain_cmd cmd = {
1026 		.action = WMI_RX_CHAIN_ADD,
1027 		.rx_sw_ring = {
1028 			.max_mpdu_size = cpu_to_le16(mtu_max + ETH_HLEN),
1029 			.ring_mem_base = cpu_to_le64(vring->pa),
1030 			.ring_size = cpu_to_le16(vring->size),
1031 		},
1032 		.mid = 0, /* TODO - what is it? */
1033 		.decap_trans_type = WMI_DECAP_TYPE_802_3,
1034 		.reorder_type = WMI_RX_SW_REORDER,
1035 	};
1036 	struct {
1037 		struct wil6210_mbox_hdr_wmi wmi;
1038 		struct wmi_cfg_rx_chain_done_event evt;
1039 	} __packed evt;
1040 	int rc;
1041 
1042 	if (wdev->iftype == NL80211_IFTYPE_MONITOR) {
1043 		struct ieee80211_channel *ch = wdev->preset_chandef.chan;
1044 
1045 		cmd.sniffer_cfg.mode = cpu_to_le32(WMI_SNIFFER_ON);
1046 		if (ch)
1047 			cmd.sniffer_cfg.channel = ch->hw_value - 1;
1048 		cmd.sniffer_cfg.phy_info_mode =
1049 			cpu_to_le32(ndev->type == ARPHRD_IEEE80211_RADIOTAP);
1050 		cmd.sniffer_cfg.phy_support =
1051 			cpu_to_le32((wil->monitor_flags & MONITOR_FLAG_CONTROL)
1052 				    ? WMI_SNIFFER_CP : WMI_SNIFFER_DP);
1053 	} else {
1054 		/* Initialize offload (in non-sniffer mode).
1055 		 * Linux IP stack always calculates IP checksum
1056 		 * HW always calculate TCP/UDP checksum
1057 		 */
1058 		cmd.l3_l4_ctrl |= (1 << L3_L4_CTRL_TCPIP_CHECKSUM_EN_POS);
1059 	}
1060 	/* typical time for secure PCP is 840ms */
1061 	rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
1062 		      WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000);
1063 	if (rc)
1064 		return rc;
1065 
1066 	vring->hwtail = le32_to_cpu(evt.evt.rx_ring_tail_ptr);
1067 
1068 	wil_dbg_misc(wil, "Rx init: status %d tail 0x%08x\n",
1069 		     le32_to_cpu(evt.evt.status), vring->hwtail);
1070 
1071 	if (le32_to_cpu(evt.evt.status) != WMI_CFG_RX_CHAIN_SUCCESS)
1072 		rc = -EINVAL;
1073 
1074 	return rc;
1075 }
1076 
1077 int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r)
1078 {
1079 	int rc;
1080 	struct wmi_temp_sense_cmd cmd = {
1081 		.measure_marlon_m_en = cpu_to_le32(!!t_m),
1082 		.measure_marlon_r_en = cpu_to_le32(!!t_r),
1083 	};
1084 	struct {
1085 		struct wil6210_mbox_hdr_wmi wmi;
1086 		struct wmi_temp_sense_done_event evt;
1087 	} __packed reply;
1088 
1089 	rc = wmi_call(wil, WMI_TEMP_SENSE_CMDID, &cmd, sizeof(cmd),
1090 		      WMI_TEMP_SENSE_DONE_EVENTID, &reply, sizeof(reply), 100);
1091 	if (rc)
1092 		return rc;
1093 
1094 	if (t_m)
1095 		*t_m = le32_to_cpu(reply.evt.marlon_m_t1000);
1096 	if (t_r)
1097 		*t_r = le32_to_cpu(reply.evt.marlon_r_t1000);
1098 
1099 	return 0;
1100 }
1101 
1102 int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason)
1103 {
1104 	struct wmi_disconnect_sta_cmd cmd = {
1105 		.disconnect_reason = cpu_to_le16(reason),
1106 	};
1107 	memcpy(cmd.dst_mac, mac, ETH_ALEN);
1108 
1109 	wil_dbg_wmi(wil, "%s(%pM, reason %d)\n", __func__, mac, reason);
1110 
1111 	return wmi_send(wil, WMI_DISCONNECT_STA_CMDID, &cmd, sizeof(cmd));
1112 }
1113 
1114 void wmi_event_flush(struct wil6210_priv *wil)
1115 {
1116 	struct pending_wmi_event *evt, *t;
1117 
1118 	wil_dbg_wmi(wil, "%s()\n", __func__);
1119 
1120 	list_for_each_entry_safe(evt, t, &wil->pending_wmi_ev, list) {
1121 		list_del(&evt->list);
1122 		kfree(evt);
1123 	}
1124 }
1125 
1126 static bool wmi_evt_call_handler(struct wil6210_priv *wil, int id,
1127 				 void *d, int len)
1128 {
1129 	uint i;
1130 
1131 	for (i = 0; i < ARRAY_SIZE(wmi_evt_handlers); i++) {
1132 		if (wmi_evt_handlers[i].eventid == id) {
1133 			wmi_evt_handlers[i].handler(wil, id, d, len);
1134 			return true;
1135 		}
1136 	}
1137 
1138 	return false;
1139 }
1140 
1141 static void wmi_event_handle(struct wil6210_priv *wil,
1142 			     struct wil6210_mbox_hdr *hdr)
1143 {
1144 	u16 len = le16_to_cpu(hdr->len);
1145 
1146 	if ((hdr->type == WIL_MBOX_HDR_TYPE_WMI) &&
1147 	    (len >= sizeof(struct wil6210_mbox_hdr_wmi))) {
1148 		struct wil6210_mbox_hdr_wmi *wmi = (void *)(&hdr[1]);
1149 		void *evt_data = (void *)(&wmi[1]);
1150 		u16 id = le16_to_cpu(wmi->id);
1151 
1152 		wil_dbg_wmi(wil, "Handle WMI 0x%04x (reply_id 0x%04x)\n",
1153 			    id, wil->reply_id);
1154 		/* check if someone waits for this event */
1155 		if (wil->reply_id && wil->reply_id == id) {
1156 			if (wil->reply_buf) {
1157 				memcpy(wil->reply_buf, wmi,
1158 				       min(len, wil->reply_size));
1159 			} else {
1160 				wmi_evt_call_handler(wil, id, evt_data,
1161 						     len - sizeof(*wmi));
1162 			}
1163 			wil_dbg_wmi(wil, "Complete WMI 0x%04x\n", id);
1164 			complete(&wil->wmi_call);
1165 			return;
1166 		}
1167 		/* unsolicited event */
1168 		/* search for handler */
1169 		if (!wmi_evt_call_handler(wil, id, evt_data,
1170 					  len - sizeof(*wmi))) {
1171 			wil_err(wil, "Unhandled event 0x%04x\n", id);
1172 		}
1173 	} else {
1174 		wil_err(wil, "Unknown event type\n");
1175 		print_hex_dump(KERN_ERR, "evt?? ", DUMP_PREFIX_OFFSET, 16, 1,
1176 			       hdr, sizeof(*hdr) + len, true);
1177 	}
1178 }
1179 
1180 /*
1181  * Retrieve next WMI event from the pending list
1182  */
1183 static struct list_head *next_wmi_ev(struct wil6210_priv *wil)
1184 {
1185 	ulong flags;
1186 	struct list_head *ret = NULL;
1187 
1188 	spin_lock_irqsave(&wil->wmi_ev_lock, flags);
1189 
1190 	if (!list_empty(&wil->pending_wmi_ev)) {
1191 		ret = wil->pending_wmi_ev.next;
1192 		list_del(ret);
1193 	}
1194 
1195 	spin_unlock_irqrestore(&wil->wmi_ev_lock, flags);
1196 
1197 	return ret;
1198 }
1199 
1200 /*
1201  * Handler for the WMI events
1202  */
1203 void wmi_event_worker(struct work_struct *work)
1204 {
1205 	struct wil6210_priv *wil = container_of(work, struct wil6210_priv,
1206 						 wmi_event_worker);
1207 	struct pending_wmi_event *evt;
1208 	struct list_head *lh;
1209 
1210 	wil_dbg_wmi(wil, "Start %s\n", __func__);
1211 	while ((lh = next_wmi_ev(wil)) != NULL) {
1212 		evt = list_entry(lh, struct pending_wmi_event, list);
1213 		wmi_event_handle(wil, &evt->event.hdr);
1214 		kfree(evt);
1215 	}
1216 	wil_dbg_wmi(wil, "Finished %s\n", __func__);
1217 }
1218