1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2012 - 2018 Microchip Technology Inc., and its subsidiaries.
4  * All rights reserved.
5  */
6 
7 #include <linux/if_ether.h>
8 #include <linux/ip.h>
9 #include <net/dsfield.h>
10 #include "cfg80211.h"
11 #include "wlan_cfg.h"
12 
13 static inline bool is_wilc1000(u32 id)
14 {
15 	return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID;
16 }
17 
18 static inline void acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
19 {
20 	mutex_lock(&wilc->hif_cs);
21 	if (acquire == WILC_BUS_ACQUIRE_AND_WAKEUP)
22 		chip_wakeup(wilc);
23 }
24 
25 static inline void release_bus(struct wilc *wilc, enum bus_release release)
26 {
27 	if (release == WILC_BUS_RELEASE_ALLOW_SLEEP)
28 		chip_allow_sleep(wilc);
29 	mutex_unlock(&wilc->hif_cs);
30 }
31 
32 static void wilc_wlan_txq_remove(struct wilc *wilc, u8 q_num,
33 				 struct txq_entry_t *tqe)
34 {
35 	list_del(&tqe->list);
36 	wilc->txq_entries -= 1;
37 	wilc->txq[q_num].count--;
38 }
39 
40 static struct txq_entry_t *
41 wilc_wlan_txq_remove_from_head(struct wilc *wilc, u8 q_num)
42 {
43 	struct txq_entry_t *tqe = NULL;
44 	unsigned long flags;
45 
46 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
47 
48 	if (!list_empty(&wilc->txq[q_num].txq_head.list)) {
49 		tqe = list_first_entry(&wilc->txq[q_num].txq_head.list,
50 				       struct txq_entry_t, list);
51 		list_del(&tqe->list);
52 		wilc->txq_entries -= 1;
53 		wilc->txq[q_num].count--;
54 	}
55 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
56 	return tqe;
57 }
58 
59 static void wilc_wlan_txq_add_to_tail(struct net_device *dev, u8 q_num,
60 				      struct txq_entry_t *tqe)
61 {
62 	unsigned long flags;
63 	struct wilc_vif *vif = netdev_priv(dev);
64 	struct wilc *wilc = vif->wilc;
65 
66 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
67 
68 	list_add_tail(&tqe->list, &wilc->txq[q_num].txq_head.list);
69 	wilc->txq_entries += 1;
70 	wilc->txq[q_num].count++;
71 
72 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
73 
74 	complete(&wilc->txq_event);
75 }
76 
77 static void wilc_wlan_txq_add_to_head(struct wilc_vif *vif, u8 q_num,
78 				      struct txq_entry_t *tqe)
79 {
80 	unsigned long flags;
81 	struct wilc *wilc = vif->wilc;
82 
83 	mutex_lock(&wilc->txq_add_to_head_cs);
84 
85 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
86 
87 	list_add(&tqe->list, &wilc->txq[q_num].txq_head.list);
88 	wilc->txq_entries += 1;
89 	wilc->txq[q_num].count++;
90 
91 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
92 	mutex_unlock(&wilc->txq_add_to_head_cs);
93 	complete(&wilc->txq_event);
94 }
95 
96 #define NOT_TCP_ACK			(-1)
97 
98 static inline void add_tcp_session(struct wilc_vif *vif, u32 src_prt,
99 				   u32 dst_prt, u32 seq)
100 {
101 	struct tcp_ack_filter *f = &vif->ack_filter;
102 
103 	if (f->tcp_session < 2 * MAX_TCP_SESSION) {
104 		f->ack_session_info[f->tcp_session].seq_num = seq;
105 		f->ack_session_info[f->tcp_session].bigger_ack_num = 0;
106 		f->ack_session_info[f->tcp_session].src_port = src_prt;
107 		f->ack_session_info[f->tcp_session].dst_port = dst_prt;
108 		f->tcp_session++;
109 	}
110 }
111 
112 static inline void update_tcp_session(struct wilc_vif *vif, u32 index, u32 ack)
113 {
114 	struct tcp_ack_filter *f = &vif->ack_filter;
115 
116 	if (index < 2 * MAX_TCP_SESSION &&
117 	    ack > f->ack_session_info[index].bigger_ack_num)
118 		f->ack_session_info[index].bigger_ack_num = ack;
119 }
120 
121 static inline void add_tcp_pending_ack(struct wilc_vif *vif, u32 ack,
122 				       u32 session_index,
123 				       struct txq_entry_t *txqe)
124 {
125 	struct tcp_ack_filter *f = &vif->ack_filter;
126 	u32 i = f->pending_base + f->pending_acks_idx;
127 
128 	if (i < MAX_PENDING_ACKS) {
129 		f->pending_acks[i].ack_num = ack;
130 		f->pending_acks[i].txqe = txqe;
131 		f->pending_acks[i].session_index = session_index;
132 		txqe->ack_idx = i;
133 		f->pending_acks_idx++;
134 	}
135 }
136 
137 static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe)
138 {
139 	void *buffer = tqe->buffer;
140 	const struct ethhdr *eth_hdr_ptr = buffer;
141 	int i;
142 	unsigned long flags;
143 	struct wilc_vif *vif = netdev_priv(dev);
144 	struct wilc *wilc = vif->wilc;
145 	struct tcp_ack_filter *f = &vif->ack_filter;
146 	const struct iphdr *ip_hdr_ptr;
147 	const struct tcphdr *tcp_hdr_ptr;
148 	u32 ihl, total_length, data_offset;
149 
150 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
151 
152 	if (eth_hdr_ptr->h_proto != htons(ETH_P_IP))
153 		goto out;
154 
155 	ip_hdr_ptr = buffer + ETH_HLEN;
156 
157 	if (ip_hdr_ptr->protocol != IPPROTO_TCP)
158 		goto out;
159 
160 	ihl = ip_hdr_ptr->ihl << 2;
161 	tcp_hdr_ptr = buffer + ETH_HLEN + ihl;
162 	total_length = ntohs(ip_hdr_ptr->tot_len);
163 
164 	data_offset = tcp_hdr_ptr->doff << 2;
165 	if (total_length == (ihl + data_offset)) {
166 		u32 seq_no, ack_no;
167 
168 		seq_no = ntohl(tcp_hdr_ptr->seq);
169 		ack_no = ntohl(tcp_hdr_ptr->ack_seq);
170 		for (i = 0; i < f->tcp_session; i++) {
171 			u32 j = f->ack_session_info[i].seq_num;
172 
173 			if (i < 2 * MAX_TCP_SESSION &&
174 			    j == seq_no) {
175 				update_tcp_session(vif, i, ack_no);
176 				break;
177 			}
178 		}
179 		if (i == f->tcp_session)
180 			add_tcp_session(vif, 0, 0, seq_no);
181 
182 		add_tcp_pending_ack(vif, ack_no, i, tqe);
183 	}
184 
185 out:
186 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
187 }
188 
189 static void wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
190 {
191 	struct wilc_vif *vif = netdev_priv(dev);
192 	struct wilc *wilc = vif->wilc;
193 	struct tcp_ack_filter *f = &vif->ack_filter;
194 	u32 i = 0;
195 	u32 dropped = 0;
196 	unsigned long flags;
197 
198 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
199 	for (i = f->pending_base;
200 	     i < (f->pending_base + f->pending_acks_idx); i++) {
201 		u32 index;
202 		u32 bigger_ack_num;
203 
204 		if (i >= MAX_PENDING_ACKS)
205 			break;
206 
207 		index = f->pending_acks[i].session_index;
208 
209 		if (index >= 2 * MAX_TCP_SESSION)
210 			break;
211 
212 		bigger_ack_num = f->ack_session_info[index].bigger_ack_num;
213 
214 		if (f->pending_acks[i].ack_num < bigger_ack_num) {
215 			struct txq_entry_t *tqe;
216 
217 			tqe = f->pending_acks[i].txqe;
218 			if (tqe) {
219 				wilc_wlan_txq_remove(wilc, tqe->q_num, tqe);
220 				tqe->status = 1;
221 				if (tqe->tx_complete_func)
222 					tqe->tx_complete_func(tqe->priv,
223 							      tqe->status);
224 				kfree(tqe);
225 				dropped++;
226 			}
227 		}
228 	}
229 	f->pending_acks_idx = 0;
230 	f->tcp_session = 0;
231 
232 	if (f->pending_base == 0)
233 		f->pending_base = MAX_TCP_SESSION;
234 	else
235 		f->pending_base = 0;
236 
237 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
238 
239 	while (dropped > 0) {
240 		wait_for_completion_timeout(&wilc->txq_event,
241 					    msecs_to_jiffies(1));
242 		dropped--;
243 	}
244 }
245 
246 void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value)
247 {
248 	vif->ack_filter.enabled = value;
249 }
250 
251 static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
252 				     u32 buffer_size)
253 {
254 	struct txq_entry_t *tqe;
255 	struct wilc *wilc = vif->wilc;
256 
257 	netdev_dbg(vif->ndev, "Adding config packet ...\n");
258 	if (wilc->quit) {
259 		netdev_dbg(vif->ndev, "Return due to clear function\n");
260 		complete(&wilc->cfg_event);
261 		return 0;
262 	}
263 
264 	tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
265 	if (!tqe) {
266 		complete(&wilc->cfg_event);
267 		return 0;
268 	}
269 
270 	tqe->type = WILC_CFG_PKT;
271 	tqe->buffer = buffer;
272 	tqe->buffer_size = buffer_size;
273 	tqe->tx_complete_func = NULL;
274 	tqe->priv = NULL;
275 	tqe->q_num = AC_VO_Q;
276 	tqe->ack_idx = NOT_TCP_ACK;
277 	tqe->vif = vif;
278 
279 	wilc_wlan_txq_add_to_head(vif, AC_VO_Q, tqe);
280 
281 	return 1;
282 }
283 
284 static bool is_ac_q_limit(struct wilc *wl, u8 q_num)
285 {
286 	u8 factors[NQUEUES] = {1, 1, 1, 1};
287 	u16 i;
288 	unsigned long flags;
289 	struct wilc_tx_queue_status *q = &wl->tx_q_limit;
290 	u8 end_index;
291 	u8 q_limit;
292 	bool ret = false;
293 
294 	spin_lock_irqsave(&wl->txq_spinlock, flags);
295 	if (!q->initialized) {
296 		for (i = 0; i < AC_BUFFER_SIZE; i++)
297 			q->buffer[i] = i % NQUEUES;
298 
299 		for (i = 0; i < NQUEUES; i++) {
300 			q->cnt[i] = AC_BUFFER_SIZE * factors[i] / NQUEUES;
301 			q->sum += q->cnt[i];
302 		}
303 		q->end_index = AC_BUFFER_SIZE - 1;
304 		q->initialized = 1;
305 	}
306 
307 	end_index = q->end_index;
308 	q->cnt[q->buffer[end_index]] -= factors[q->buffer[end_index]];
309 	q->cnt[q_num] += factors[q_num];
310 	q->sum += (factors[q_num] - factors[q->buffer[end_index]]);
311 
312 	q->buffer[end_index] = q_num;
313 	if (end_index > 0)
314 		q->end_index--;
315 	else
316 		q->end_index = AC_BUFFER_SIZE - 1;
317 
318 	if (!q->sum)
319 		q_limit = 1;
320 	else
321 		q_limit = (q->cnt[q_num] * FLOW_CONTROL_UPPER_THRESHOLD / q->sum) + 1;
322 
323 	if (wl->txq[q_num].count <= q_limit)
324 		ret = true;
325 
326 	spin_unlock_irqrestore(&wl->txq_spinlock, flags);
327 
328 	return ret;
329 }
330 
331 static inline u8 ac_classify(struct wilc *wilc, struct sk_buff *skb)
332 {
333 	u8 q_num = AC_BE_Q;
334 	u8 dscp;
335 
336 	switch (skb->protocol) {
337 	case htons(ETH_P_IP):
338 		dscp = ipv4_get_dsfield(ip_hdr(skb)) & 0xfc;
339 		break;
340 	case htons(ETH_P_IPV6):
341 		dscp = ipv6_get_dsfield(ipv6_hdr(skb)) & 0xfc;
342 		break;
343 	default:
344 		return q_num;
345 	}
346 
347 	switch (dscp) {
348 	case 0x08:
349 	case 0x20:
350 	case 0x40:
351 		q_num = AC_BK_Q;
352 		break;
353 	case 0x80:
354 	case 0xA0:
355 	case 0x28:
356 		q_num = AC_VI_Q;
357 		break;
358 	case 0xC0:
359 	case 0xD0:
360 	case 0xE0:
361 	case 0x88:
362 	case 0xB8:
363 		q_num = AC_VO_Q;
364 		break;
365 	}
366 
367 	return q_num;
368 }
369 
370 static inline int ac_balance(struct wilc *wl, u8 *ratio)
371 {
372 	u8 i, max_count = 0;
373 
374 	if (!ratio)
375 		return -EINVAL;
376 
377 	for (i = 0; i < NQUEUES; i++)
378 		if (wl->txq[i].fw.count > max_count)
379 			max_count = wl->txq[i].fw.count;
380 
381 	for (i = 0; i < NQUEUES; i++)
382 		ratio[i] = max_count - wl->txq[i].fw.count;
383 
384 	return 0;
385 }
386 
387 static inline void ac_update_fw_ac_pkt_info(struct wilc *wl, u32 reg)
388 {
389 	wl->txq[AC_BK_Q].fw.count = FIELD_GET(BK_AC_COUNT_FIELD, reg);
390 	wl->txq[AC_BE_Q].fw.count = FIELD_GET(BE_AC_COUNT_FIELD, reg);
391 	wl->txq[AC_VI_Q].fw.count = FIELD_GET(VI_AC_COUNT_FIELD, reg);
392 	wl->txq[AC_VO_Q].fw.count = FIELD_GET(VO_AC_COUNT_FIELD, reg);
393 
394 	wl->txq[AC_BK_Q].fw.acm = FIELD_GET(BK_AC_ACM_STAT_FIELD, reg);
395 	wl->txq[AC_BE_Q].fw.acm = FIELD_GET(BE_AC_ACM_STAT_FIELD, reg);
396 	wl->txq[AC_VI_Q].fw.acm = FIELD_GET(VI_AC_ACM_STAT_FIELD, reg);
397 	wl->txq[AC_VO_Q].fw.acm = FIELD_GET(VO_AC_ACM_STAT_FIELD, reg);
398 }
399 
400 static inline u8 ac_change(struct wilc *wilc, u8 *ac)
401 {
402 	do {
403 		if (wilc->txq[*ac].fw.acm == 0)
404 			return 0;
405 		(*ac)++;
406 	} while (*ac < NQUEUES);
407 
408 	return 1;
409 }
410 
411 int wilc_wlan_txq_add_net_pkt(struct net_device *dev,
412 			      struct tx_complete_data *tx_data, u8 *buffer,
413 			      u32 buffer_size,
414 			      void (*tx_complete_fn)(void *, int))
415 {
416 	struct txq_entry_t *tqe;
417 	struct wilc_vif *vif = netdev_priv(dev);
418 	struct wilc *wilc;
419 	u8 q_num;
420 
421 	wilc = vif->wilc;
422 
423 	if (wilc->quit) {
424 		tx_complete_fn(tx_data, 0);
425 		return 0;
426 	}
427 
428 	tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
429 
430 	if (!tqe) {
431 		tx_complete_fn(tx_data, 0);
432 		return 0;
433 	}
434 	tqe->type = WILC_NET_PKT;
435 	tqe->buffer = buffer;
436 	tqe->buffer_size = buffer_size;
437 	tqe->tx_complete_func = tx_complete_fn;
438 	tqe->priv = tx_data;
439 	tqe->vif = vif;
440 
441 	q_num = ac_classify(wilc, tx_data->skb);
442 	tqe->q_num = q_num;
443 	if (ac_change(wilc, &q_num)) {
444 		tx_complete_fn(tx_data, 0);
445 		kfree(tqe);
446 		return 0;
447 	}
448 
449 	if (is_ac_q_limit(wilc, q_num)) {
450 		tqe->ack_idx = NOT_TCP_ACK;
451 		if (vif->ack_filter.enabled)
452 			tcp_process(dev, tqe);
453 		wilc_wlan_txq_add_to_tail(dev, q_num, tqe);
454 	} else {
455 		tx_complete_fn(tx_data, 0);
456 		kfree(tqe);
457 	}
458 
459 	return wilc->txq_entries;
460 }
461 
462 int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
463 			       u32 buffer_size,
464 			       void (*tx_complete_fn)(void *, int))
465 {
466 	struct txq_entry_t *tqe;
467 	struct wilc_vif *vif = netdev_priv(dev);
468 	struct wilc *wilc;
469 
470 	wilc = vif->wilc;
471 
472 	if (wilc->quit) {
473 		tx_complete_fn(priv, 0);
474 		return 0;
475 	}
476 
477 	tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
478 
479 	if (!tqe) {
480 		tx_complete_fn(priv, 0);
481 		return 0;
482 	}
483 	tqe->type = WILC_MGMT_PKT;
484 	tqe->buffer = buffer;
485 	tqe->buffer_size = buffer_size;
486 	tqe->tx_complete_func = tx_complete_fn;
487 	tqe->priv = priv;
488 	tqe->q_num = AC_BE_Q;
489 	tqe->ack_idx = NOT_TCP_ACK;
490 	tqe->vif = vif;
491 	wilc_wlan_txq_add_to_tail(dev, AC_VO_Q, tqe);
492 	return 1;
493 }
494 
495 static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc, u8 q_num)
496 {
497 	struct txq_entry_t *tqe = NULL;
498 	unsigned long flags;
499 
500 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
501 
502 	if (!list_empty(&wilc->txq[q_num].txq_head.list))
503 		tqe = list_first_entry(&wilc->txq[q_num].txq_head.list,
504 				       struct txq_entry_t, list);
505 
506 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
507 
508 	return tqe;
509 }
510 
511 static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc,
512 						  struct txq_entry_t *tqe,
513 						  u8 q_num)
514 {
515 	unsigned long flags;
516 
517 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
518 
519 	if (!list_is_last(&tqe->list, &wilc->txq[q_num].txq_head.list))
520 		tqe = list_next_entry(tqe, list);
521 	else
522 		tqe = NULL;
523 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
524 
525 	return tqe;
526 }
527 
528 static void wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe)
529 {
530 	if (wilc->quit)
531 		return;
532 
533 	mutex_lock(&wilc->rxq_cs);
534 	list_add_tail(&rqe->list, &wilc->rxq_head.list);
535 	mutex_unlock(&wilc->rxq_cs);
536 }
537 
538 static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
539 {
540 	struct rxq_entry_t *rqe = NULL;
541 
542 	mutex_lock(&wilc->rxq_cs);
543 	if (!list_empty(&wilc->rxq_head.list)) {
544 		rqe = list_first_entry(&wilc->rxq_head.list, struct rxq_entry_t,
545 				       list);
546 		list_del(&rqe->list);
547 	}
548 	mutex_unlock(&wilc->rxq_cs);
549 	return rqe;
550 }
551 
552 void chip_allow_sleep(struct wilc *wilc)
553 {
554 	u32 reg = 0;
555 
556 	wilc->hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, &reg);
557 
558 	wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
559 				      reg & ~WILC_SDIO_WAKEUP_BIT);
560 	wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG, 0);
561 }
562 EXPORT_SYMBOL_GPL(chip_allow_sleep);
563 
564 void chip_wakeup(struct wilc *wilc)
565 {
566 	u32 reg, clk_status_reg;
567 	const struct wilc_hif_func *h = wilc->hif_func;
568 
569 	if (wilc->io_type == WILC_HIF_SPI) {
570 		do {
571 			h->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, &reg);
572 			h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
573 					 reg | WILC_SPI_WAKEUP_BIT);
574 			h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
575 					 reg & ~WILC_SPI_WAKEUP_BIT);
576 
577 			do {
578 				usleep_range(2000, 2500);
579 				wilc_get_chipid(wilc, true);
580 			} while (wilc_get_chipid(wilc, true) == 0);
581 		} while (wilc_get_chipid(wilc, true) == 0);
582 	} else if (wilc->io_type == WILC_HIF_SDIO) {
583 		h->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG,
584 				 WILC_SDIO_HOST_TO_FW_BIT);
585 		usleep_range(200, 400);
586 		h->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, &reg);
587 		do {
588 			h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
589 					 reg | WILC_SDIO_WAKEUP_BIT);
590 			h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
591 					&clk_status_reg);
592 
593 			while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
594 				usleep_range(2000, 2500);
595 
596 				h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
597 						&clk_status_reg);
598 			}
599 			if (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
600 				h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
601 						 reg & ~WILC_SDIO_WAKEUP_BIT);
602 			}
603 		} while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT));
604 	}
605 
606 	if (wilc->chip_ps_state == WILC_CHIP_SLEEPING_MANUAL) {
607 		if (wilc_get_chipid(wilc, false) < WILC_1000_BASE_ID_2B) {
608 			u32 val32;
609 
610 			h->hif_read_reg(wilc, WILC_REG_4_TO_1_RX, &val32);
611 			val32 |= BIT(6);
612 			h->hif_write_reg(wilc, WILC_REG_4_TO_1_RX, val32);
613 
614 			h->hif_read_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, &val32);
615 			val32 |= BIT(6);
616 			h->hif_write_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, val32);
617 		}
618 	}
619 	wilc->chip_ps_state = WILC_CHIP_WAKEDUP;
620 }
621 EXPORT_SYMBOL_GPL(chip_wakeup);
622 
623 void host_wakeup_notify(struct wilc *wilc)
624 {
625 	acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
626 	wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_2, 1);
627 	release_bus(wilc, WILC_BUS_RELEASE_ONLY);
628 }
629 EXPORT_SYMBOL_GPL(host_wakeup_notify);
630 
631 void host_sleep_notify(struct wilc *wilc)
632 {
633 	acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
634 	wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_1, 1);
635 	release_bus(wilc, WILC_BUS_RELEASE_ONLY);
636 }
637 EXPORT_SYMBOL_GPL(host_sleep_notify);
638 
639 int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
640 {
641 	int i, entries = 0;
642 	u8 k, ac;
643 	u32 sum;
644 	u32 reg;
645 	u8 ac_desired_ratio[NQUEUES] = {0, 0, 0, 0};
646 	u8 ac_preserve_ratio[NQUEUES] = {1, 1, 1, 1};
647 	u8 *num_pkts_to_add;
648 	u8 vmm_entries_ac[WILC_VMM_TBL_SIZE];
649 	u32 offset = 0;
650 	bool max_size_over = 0, ac_exist = 0;
651 	int vmm_sz = 0;
652 	struct txq_entry_t *tqe_q[NQUEUES];
653 	int ret = 0;
654 	int counter;
655 	int timeout;
656 	u32 vmm_table[WILC_VMM_TBL_SIZE];
657 	u8 ac_pkt_num_to_chip[NQUEUES] = {0, 0, 0, 0};
658 	const struct wilc_hif_func *func;
659 	int srcu_idx;
660 	u8 *txb = wilc->tx_buffer;
661 	struct wilc_vif *vif;
662 
663 	if (wilc->quit)
664 		goto out_update_cnt;
665 
666 	if (ac_balance(wilc, ac_desired_ratio))
667 		return -EINVAL;
668 
669 	mutex_lock(&wilc->txq_add_to_head_cs);
670 
671 	srcu_idx = srcu_read_lock(&wilc->srcu);
672 	list_for_each_entry_rcu(vif, &wilc->vif_list, list)
673 		wilc_wlan_txq_filter_dup_tcp_ack(vif->ndev);
674 	srcu_read_unlock(&wilc->srcu, srcu_idx);
675 
676 	for (ac = 0; ac < NQUEUES; ac++)
677 		tqe_q[ac] = wilc_wlan_txq_get_first(wilc, ac);
678 
679 	i = 0;
680 	sum = 0;
681 	max_size_over = 0;
682 	num_pkts_to_add = ac_desired_ratio;
683 	do {
684 		ac_exist = 0;
685 		for (ac = 0; (ac < NQUEUES) && (!max_size_over); ac++) {
686 			if (!tqe_q[ac])
687 				continue;
688 
689 			ac_exist = 1;
690 			for (k = 0; (k < num_pkts_to_add[ac]) &&
691 			     (!max_size_over) && tqe_q[ac]; k++) {
692 				if (i >= (WILC_VMM_TBL_SIZE - 1)) {
693 					max_size_over = 1;
694 					break;
695 				}
696 
697 				if (tqe_q[ac]->type == WILC_CFG_PKT)
698 					vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
699 				else if (tqe_q[ac]->type == WILC_NET_PKT)
700 					vmm_sz = ETH_ETHERNET_HDR_OFFSET;
701 				else
702 					vmm_sz = HOST_HDR_OFFSET;
703 
704 				vmm_sz += tqe_q[ac]->buffer_size;
705 				vmm_sz = ALIGN(vmm_sz, 4);
706 
707 				if ((sum + vmm_sz) > WILC_TX_BUFF_SIZE) {
708 					max_size_over = 1;
709 					break;
710 				}
711 				vmm_table[i] = vmm_sz / 4;
712 				if (tqe_q[ac]->type == WILC_CFG_PKT)
713 					vmm_table[i] |= BIT(10);
714 
715 				cpu_to_le32s(&vmm_table[i]);
716 				vmm_entries_ac[i] = ac;
717 
718 				i++;
719 				sum += vmm_sz;
720 				tqe_q[ac] = wilc_wlan_txq_get_next(wilc,
721 								   tqe_q[ac],
722 								   ac);
723 			}
724 		}
725 		num_pkts_to_add = ac_preserve_ratio;
726 	} while (!max_size_over && ac_exist);
727 
728 	if (i == 0)
729 		goto out_unlock;
730 	vmm_table[i] = 0x0;
731 
732 	acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
733 	counter = 0;
734 	func = wilc->hif_func;
735 	do {
736 		ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
737 		if (ret)
738 			break;
739 
740 		if ((reg & 0x1) == 0) {
741 			ac_update_fw_ac_pkt_info(wilc, reg);
742 			break;
743 		}
744 
745 		counter++;
746 		if (counter > 200) {
747 			counter = 0;
748 			ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0);
749 			break;
750 		}
751 	} while (!wilc->quit);
752 
753 	if (ret)
754 		goto out_release_bus;
755 
756 	timeout = 200;
757 	do {
758 		ret = func->hif_block_tx(wilc,
759 					 WILC_VMM_TBL_RX_SHADOW_BASE,
760 					 (u8 *)vmm_table,
761 					 ((i + 1) * 4));
762 		if (ret)
763 			break;
764 
765 		ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
766 		if (ret)
767 			break;
768 
769 		do {
770 			ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
771 			if (ret)
772 				break;
773 			if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) {
774 				entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
775 				break;
776 			}
777 		} while (--timeout);
778 		if (timeout <= 0) {
779 			ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
780 			break;
781 		}
782 
783 		if (ret)
784 			break;
785 
786 		if (entries == 0) {
787 			ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
788 			if (ret)
789 				break;
790 			reg &= ~BIT(0);
791 			ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg);
792 		}
793 	} while (0);
794 
795 	if (ret)
796 		goto out_release_bus;
797 
798 	if (entries == 0) {
799 		/*
800 		 * No VMM space available in firmware so retry to transmit
801 		 * the packet from tx queue.
802 		 */
803 		ret = WILC_VMM_ENTRY_FULL_RETRY;
804 		goto out_release_bus;
805 	}
806 
807 	release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
808 
809 	offset = 0;
810 	i = 0;
811 	do {
812 		struct txq_entry_t *tqe;
813 		u32 header, buffer_offset;
814 		char *bssid;
815 		u8 mgmt_ptk = 0;
816 
817 		tqe = wilc_wlan_txq_remove_from_head(wilc, vmm_entries_ac[i]);
818 		ac_pkt_num_to_chip[vmm_entries_ac[i]]++;
819 		if (!tqe)
820 			break;
821 
822 		vif = tqe->vif;
823 		if (vmm_table[i] == 0)
824 			break;
825 
826 		le32_to_cpus(&vmm_table[i]);
827 		vmm_sz = FIELD_GET(WILC_VMM_BUFFER_SIZE, vmm_table[i]);
828 		vmm_sz *= 4;
829 
830 		if (tqe->type == WILC_MGMT_PKT)
831 			mgmt_ptk = 1;
832 
833 		header = (FIELD_PREP(WILC_VMM_HDR_TYPE, tqe->type) |
834 			  FIELD_PREP(WILC_VMM_HDR_MGMT_FIELD, mgmt_ptk) |
835 			  FIELD_PREP(WILC_VMM_HDR_PKT_SIZE, tqe->buffer_size) |
836 			  FIELD_PREP(WILC_VMM_HDR_BUFF_SIZE, vmm_sz));
837 
838 		cpu_to_le32s(&header);
839 		memcpy(&txb[offset], &header, 4);
840 		if (tqe->type == WILC_CFG_PKT) {
841 			buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
842 		} else if (tqe->type == WILC_NET_PKT) {
843 			int prio = tqe->q_num;
844 
845 			bssid = tqe->vif->bssid;
846 			buffer_offset = ETH_ETHERNET_HDR_OFFSET;
847 			memcpy(&txb[offset + 4], &prio, sizeof(prio));
848 			memcpy(&txb[offset + 8], bssid, 6);
849 		} else {
850 			buffer_offset = HOST_HDR_OFFSET;
851 		}
852 
853 		memcpy(&txb[offset + buffer_offset],
854 		       tqe->buffer, tqe->buffer_size);
855 		offset += vmm_sz;
856 		i++;
857 		tqe->status = 1;
858 		if (tqe->tx_complete_func)
859 			tqe->tx_complete_func(tqe->priv, tqe->status);
860 		if (tqe->ack_idx != NOT_TCP_ACK &&
861 		    tqe->ack_idx < MAX_PENDING_ACKS)
862 			vif->ack_filter.pending_acks[tqe->ack_idx].txqe = NULL;
863 		kfree(tqe);
864 	} while (--entries);
865 	for (i = 0; i < NQUEUES; i++)
866 		wilc->txq[i].fw.count += ac_pkt_num_to_chip[i];
867 
868 	acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
869 
870 	ret = func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
871 	if (ret)
872 		goto out_release_bus;
873 
874 	ret = func->hif_block_tx_ext(wilc, 0, txb, offset);
875 
876 out_release_bus:
877 	release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
878 
879 out_unlock:
880 	mutex_unlock(&wilc->txq_add_to_head_cs);
881 
882 out_update_cnt:
883 	*txq_count = wilc->txq_entries;
884 	return ret;
885 }
886 
887 static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size)
888 {
889 	int offset = 0;
890 	u32 header;
891 	u32 pkt_len, pkt_offset, tp_len;
892 	int is_cfg_packet;
893 	u8 *buff_ptr;
894 
895 	do {
896 		buff_ptr = buffer + offset;
897 		header = get_unaligned_le32(buff_ptr);
898 
899 		is_cfg_packet = FIELD_GET(WILC_PKT_HDR_CONFIG_FIELD, header);
900 		pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
901 		tp_len = FIELD_GET(WILC_PKT_HDR_TOTAL_LEN_FIELD, header);
902 		pkt_len = FIELD_GET(WILC_PKT_HDR_LEN_FIELD, header);
903 
904 		if (pkt_len == 0 || tp_len == 0)
905 			break;
906 
907 		if (pkt_offset & IS_MANAGMEMENT) {
908 			buff_ptr += HOST_HDR_OFFSET;
909 			wilc_wfi_mgmt_rx(wilc, buff_ptr, pkt_len);
910 		} else {
911 			if (!is_cfg_packet) {
912 				wilc_frmw_to_host(wilc, buff_ptr, pkt_len,
913 						  pkt_offset);
914 			} else {
915 				struct wilc_cfg_rsp rsp;
916 
917 				buff_ptr += pkt_offset;
918 
919 				wilc_wlan_cfg_indicate_rx(wilc, buff_ptr,
920 							  pkt_len,
921 							  &rsp);
922 				if (rsp.type == WILC_CFG_RSP) {
923 					if (wilc->cfg_seq_no == rsp.seq_no)
924 						complete(&wilc->cfg_event);
925 				} else if (rsp.type == WILC_CFG_RSP_STATUS) {
926 					wilc_mac_indicate(wilc);
927 				}
928 			}
929 		}
930 		offset += tp_len;
931 	} while (offset < size);
932 }
933 
934 static void wilc_wlan_handle_rxq(struct wilc *wilc)
935 {
936 	int size;
937 	u8 *buffer;
938 	struct rxq_entry_t *rqe;
939 
940 	while (!wilc->quit) {
941 		rqe = wilc_wlan_rxq_remove(wilc);
942 		if (!rqe)
943 			break;
944 
945 		buffer = rqe->buffer;
946 		size = rqe->buffer_size;
947 		wilc_wlan_handle_rx_buff(wilc, buffer, size);
948 
949 		kfree(rqe);
950 	}
951 	if (wilc->quit)
952 		complete(&wilc->cfg_event);
953 }
954 
955 static void wilc_unknown_isr_ext(struct wilc *wilc)
956 {
957 	wilc->hif_func->hif_clear_int_ext(wilc, 0);
958 }
959 
960 static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
961 {
962 	u32 offset = wilc->rx_buffer_offset;
963 	u8 *buffer = NULL;
964 	u32 size;
965 	u32 retries = 0;
966 	int ret = 0;
967 	struct rxq_entry_t *rqe;
968 
969 	size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, int_status) << 2;
970 
971 	while (!size && retries < 10) {
972 		wilc->hif_func->hif_read_size(wilc, &size);
973 		size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, size) << 2;
974 		retries++;
975 	}
976 
977 	if (size <= 0)
978 		return;
979 
980 	if (WILC_RX_BUFF_SIZE - offset < size)
981 		offset = 0;
982 
983 	buffer = &wilc->rx_buffer[offset];
984 
985 	wilc->hif_func->hif_clear_int_ext(wilc, DATA_INT_CLR | ENABLE_RX_VMM);
986 	ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size);
987 	if (ret)
988 		return;
989 
990 	offset += size;
991 	wilc->rx_buffer_offset = offset;
992 	rqe = kmalloc(sizeof(*rqe), GFP_KERNEL);
993 	if (!rqe)
994 		return;
995 
996 	rqe->buffer = buffer;
997 	rqe->buffer_size = size;
998 	wilc_wlan_rxq_add(wilc, rqe);
999 	wilc_wlan_handle_rxq(wilc);
1000 }
1001 
1002 void wilc_handle_isr(struct wilc *wilc)
1003 {
1004 	u32 int_status;
1005 
1006 	acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
1007 	wilc->hif_func->hif_read_int(wilc, &int_status);
1008 
1009 	if (int_status & DATA_INT_EXT)
1010 		wilc_wlan_handle_isr_ext(wilc, int_status);
1011 
1012 	if (!(int_status & (ALL_INT_EXT)))
1013 		wilc_unknown_isr_ext(wilc);
1014 
1015 	release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1016 }
1017 EXPORT_SYMBOL_GPL(wilc_handle_isr);
1018 
1019 int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
1020 				u32 buffer_size)
1021 {
1022 	u32 offset;
1023 	u32 addr, size, size2, blksz;
1024 	u8 *dma_buffer;
1025 	int ret = 0;
1026 
1027 	blksz = BIT(12);
1028 
1029 	dma_buffer = kmalloc(blksz, GFP_KERNEL);
1030 	if (!dma_buffer)
1031 		return -EIO;
1032 
1033 	offset = 0;
1034 	do {
1035 		addr = get_unaligned_le32(&buffer[offset]);
1036 		size = get_unaligned_le32(&buffer[offset + 4]);
1037 		acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
1038 		offset += 8;
1039 		while (((int)size) && (offset < buffer_size)) {
1040 			if (size <= blksz)
1041 				size2 = size;
1042 			else
1043 				size2 = blksz;
1044 
1045 			memcpy(dma_buffer, &buffer[offset], size2);
1046 			ret = wilc->hif_func->hif_block_tx(wilc, addr,
1047 							   dma_buffer, size2);
1048 			if (ret)
1049 				break;
1050 
1051 			addr += size2;
1052 			offset += size2;
1053 			size -= size2;
1054 		}
1055 		release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1056 
1057 		if (ret)
1058 			goto fail;
1059 	} while (offset < buffer_size);
1060 
1061 fail:
1062 
1063 	kfree(dma_buffer);
1064 
1065 	return ret;
1066 }
1067 
1068 int wilc_wlan_start(struct wilc *wilc)
1069 {
1070 	u32 reg = 0;
1071 	int ret;
1072 	u32 chipid;
1073 
1074 	if (wilc->io_type == WILC_HIF_SDIO) {
1075 		reg = 0;
1076 		reg |= BIT(3);
1077 	} else if (wilc->io_type == WILC_HIF_SPI) {
1078 		reg = 1;
1079 	}
1080 	acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
1081 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
1082 	if (ret) {
1083 		release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1084 		return ret;
1085 	}
1086 	reg = 0;
1087 	if (wilc->io_type == WILC_HIF_SDIO && wilc->dev_irq_num)
1088 		reg |= WILC_HAVE_SDIO_IRQ_GPIO;
1089 
1090 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
1091 	if (ret) {
1092 		release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1093 		return ret;
1094 	}
1095 
1096 	wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT);
1097 
1098 	ret = wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
1099 	if (ret) {
1100 		release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1101 		return ret;
1102 	}
1103 
1104 	wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1105 	if ((reg & BIT(10)) == BIT(10)) {
1106 		reg &= ~BIT(10);
1107 		wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1108 		wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1109 	}
1110 
1111 	reg |= BIT(10);
1112 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1113 	wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1114 	release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1115 
1116 	return ret;
1117 }
1118 
1119 int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
1120 {
1121 	u32 reg = 0;
1122 	int ret;
1123 
1124 	acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
1125 
1126 	ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, &reg);
1127 	if (ret) {
1128 		netdev_err(vif->ndev, "Error while reading reg\n");
1129 		release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1130 		return ret;
1131 	}
1132 
1133 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0,
1134 					(reg | WILC_ABORT_REQ_BIT));
1135 	if (ret) {
1136 		netdev_err(vif->ndev, "Error while writing reg\n");
1137 		release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1138 		return ret;
1139 	}
1140 
1141 	ret = wilc->hif_func->hif_read_reg(wilc, WILC_FW_HOST_COMM, &reg);
1142 	if (ret) {
1143 		netdev_err(vif->ndev, "Error while reading reg\n");
1144 		release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1145 		return ret;
1146 	}
1147 	reg = BIT(0);
1148 
1149 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_FW_HOST_COMM, reg);
1150 	if (ret) {
1151 		netdev_err(vif->ndev, "Error while writing reg\n");
1152 		release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1153 		return ret;
1154 	}
1155 
1156 	release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1157 
1158 	return 0;
1159 }
1160 
1161 void wilc_wlan_cleanup(struct net_device *dev)
1162 {
1163 	struct txq_entry_t *tqe;
1164 	struct rxq_entry_t *rqe;
1165 	u8 ac;
1166 	struct wilc_vif *vif = netdev_priv(dev);
1167 	struct wilc *wilc = vif->wilc;
1168 
1169 	wilc->quit = 1;
1170 	for (ac = 0; ac < NQUEUES; ac++) {
1171 		while ((tqe = wilc_wlan_txq_remove_from_head(wilc, ac))) {
1172 			if (tqe->tx_complete_func)
1173 				tqe->tx_complete_func(tqe->priv, 0);
1174 			kfree(tqe);
1175 		}
1176 	}
1177 
1178 	while ((rqe = wilc_wlan_rxq_remove(wilc)))
1179 		kfree(rqe);
1180 
1181 	kfree(wilc->rx_buffer);
1182 	wilc->rx_buffer = NULL;
1183 	kfree(wilc->tx_buffer);
1184 	wilc->tx_buffer = NULL;
1185 	wilc->hif_func->hif_deinit(NULL);
1186 }
1187 
1188 static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type,
1189 				u32 drv_handler)
1190 {
1191 	struct wilc *wilc = vif->wilc;
1192 	struct wilc_cfg_frame *cfg = &wilc->cfg_frame;
1193 	int t_len = wilc->cfg_frame_offset + sizeof(struct wilc_cfg_cmd_hdr);
1194 
1195 	if (type == WILC_CFG_SET)
1196 		cfg->hdr.cmd_type = 'W';
1197 	else
1198 		cfg->hdr.cmd_type = 'Q';
1199 
1200 	cfg->hdr.seq_no = wilc->cfg_seq_no % 256;
1201 	cfg->hdr.total_len = cpu_to_le16(t_len);
1202 	cfg->hdr.driver_handler = cpu_to_le32(drv_handler);
1203 	wilc->cfg_seq_no = cfg->hdr.seq_no;
1204 
1205 	if (!wilc_wlan_txq_add_cfg_pkt(vif, (u8 *)&cfg->hdr, t_len))
1206 		return -1;
1207 
1208 	return 0;
1209 }
1210 
1211 int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
1212 		      u32 buffer_size, int commit, u32 drv_handler)
1213 {
1214 	u32 offset;
1215 	int ret_size;
1216 	struct wilc *wilc = vif->wilc;
1217 
1218 	mutex_lock(&wilc->cfg_cmd_lock);
1219 
1220 	if (start)
1221 		wilc->cfg_frame_offset = 0;
1222 
1223 	offset = wilc->cfg_frame_offset;
1224 	ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset,
1225 					 wid, buffer, buffer_size);
1226 	offset += ret_size;
1227 	wilc->cfg_frame_offset = offset;
1228 
1229 	if (!commit) {
1230 		mutex_unlock(&wilc->cfg_cmd_lock);
1231 		return ret_size;
1232 	}
1233 
1234 	netdev_dbg(vif->ndev, "%s: seqno[%d]\n", __func__, wilc->cfg_seq_no);
1235 
1236 	if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler))
1237 		ret_size = 0;
1238 
1239 	if (!wait_for_completion_timeout(&wilc->cfg_event,
1240 					 WILC_CFG_PKTS_TIMEOUT)) {
1241 		netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
1242 		ret_size = 0;
1243 	}
1244 
1245 	wilc->cfg_frame_offset = 0;
1246 	wilc->cfg_seq_no += 1;
1247 	mutex_unlock(&wilc->cfg_cmd_lock);
1248 
1249 	return ret_size;
1250 }
1251 
1252 int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit,
1253 		      u32 drv_handler)
1254 {
1255 	u32 offset;
1256 	int ret_size;
1257 	struct wilc *wilc = vif->wilc;
1258 
1259 	mutex_lock(&wilc->cfg_cmd_lock);
1260 
1261 	if (start)
1262 		wilc->cfg_frame_offset = 0;
1263 
1264 	offset = wilc->cfg_frame_offset;
1265 	ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset, wid);
1266 	offset += ret_size;
1267 	wilc->cfg_frame_offset = offset;
1268 
1269 	if (!commit) {
1270 		mutex_unlock(&wilc->cfg_cmd_lock);
1271 		return ret_size;
1272 	}
1273 
1274 	if (wilc_wlan_cfg_commit(vif, WILC_CFG_QUERY, drv_handler))
1275 		ret_size = 0;
1276 
1277 	if (!wait_for_completion_timeout(&wilc->cfg_event,
1278 					 WILC_CFG_PKTS_TIMEOUT)) {
1279 		netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
1280 		ret_size = 0;
1281 	}
1282 	wilc->cfg_frame_offset = 0;
1283 	wilc->cfg_seq_no += 1;
1284 	mutex_unlock(&wilc->cfg_cmd_lock);
1285 
1286 	return ret_size;
1287 }
1288 
1289 int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
1290 			 u32 count)
1291 {
1292 	int i;
1293 	int ret = 0;
1294 	u32 drv = wilc_get_vif_idx(vif);
1295 
1296 	if (mode == WILC_GET_CFG) {
1297 		for (i = 0; i < count; i++) {
1298 			if (!wilc_wlan_cfg_get(vif, !i,
1299 					       wids[i].id,
1300 					       (i == count - 1),
1301 					       drv)) {
1302 				ret = -ETIMEDOUT;
1303 				break;
1304 			}
1305 		}
1306 		for (i = 0; i < count; i++) {
1307 			wids[i].size = wilc_wlan_cfg_get_val(vif->wilc,
1308 							     wids[i].id,
1309 							     wids[i].val,
1310 							     wids[i].size);
1311 		}
1312 	} else if (mode == WILC_SET_CFG) {
1313 		for (i = 0; i < count; i++) {
1314 			if (!wilc_wlan_cfg_set(vif, !i,
1315 					       wids[i].id,
1316 					       wids[i].val,
1317 					       wids[i].size,
1318 					       (i == count - 1),
1319 					       drv)) {
1320 				ret = -ETIMEDOUT;
1321 				break;
1322 			}
1323 		}
1324 	}
1325 
1326 	return ret;
1327 }
1328 
1329 static int init_chip(struct net_device *dev)
1330 {
1331 	u32 chipid;
1332 	u32 reg;
1333 	int ret = 0;
1334 	struct wilc_vif *vif = netdev_priv(dev);
1335 	struct wilc *wilc = vif->wilc;
1336 
1337 	acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
1338 
1339 	chipid = wilc_get_chipid(wilc, true);
1340 
1341 	if ((chipid & 0xfff) != 0xa0) {
1342 		ret = wilc->hif_func->hif_read_reg(wilc,
1343 						   WILC_CORTUS_RESET_MUX_SEL,
1344 						   &reg);
1345 		if (ret) {
1346 			netdev_err(dev, "fail read reg 0x1118\n");
1347 			goto release;
1348 		}
1349 		reg |= BIT(0);
1350 		ret = wilc->hif_func->hif_write_reg(wilc,
1351 						    WILC_CORTUS_RESET_MUX_SEL,
1352 						    reg);
1353 		if (ret) {
1354 			netdev_err(dev, "fail write reg 0x1118\n");
1355 			goto release;
1356 		}
1357 		ret = wilc->hif_func->hif_write_reg(wilc,
1358 						    WILC_CORTUS_BOOT_REGISTER,
1359 						    WILC_CORTUS_BOOT_FROM_IRAM);
1360 		if (ret) {
1361 			netdev_err(dev, "fail write reg 0xc0000\n");
1362 			goto release;
1363 		}
1364 	}
1365 
1366 release:
1367 	release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1368 
1369 	return ret;
1370 }
1371 
1372 u32 wilc_get_chipid(struct wilc *wilc, bool update)
1373 {
1374 	static u32 chipid;
1375 	u32 tempchipid = 0;
1376 	u32 rfrevid = 0;
1377 
1378 	if (chipid == 0 || update) {
1379 		wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &tempchipid);
1380 		wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID,
1381 					     &rfrevid);
1382 		if (!is_wilc1000(tempchipid)) {
1383 			chipid = 0;
1384 			return chipid;
1385 		}
1386 		if (tempchipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */
1387 			if (rfrevid != 0x1)
1388 				tempchipid = WILC_1000_BASE_ID_2A_REV1;
1389 		} else if (tempchipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */
1390 			if (rfrevid == 0x4)
1391 				tempchipid = WILC_1000_BASE_ID_2B_REV1;
1392 			else if (rfrevid != 0x3)
1393 				tempchipid = WILC_1000_BASE_ID_2B_REV2;
1394 		}
1395 
1396 		chipid = tempchipid;
1397 	}
1398 	return chipid;
1399 }
1400 
1401 int wilc_wlan_init(struct net_device *dev)
1402 {
1403 	int ret = 0;
1404 	struct wilc_vif *vif = netdev_priv(dev);
1405 	struct wilc *wilc;
1406 
1407 	wilc = vif->wilc;
1408 
1409 	wilc->quit = 0;
1410 
1411 	if (wilc->hif_func->hif_init(wilc, false)) {
1412 		ret = -EIO;
1413 		goto fail;
1414 	}
1415 
1416 	if (!wilc->tx_buffer)
1417 		wilc->tx_buffer = kmalloc(WILC_TX_BUFF_SIZE, GFP_KERNEL);
1418 
1419 	if (!wilc->tx_buffer) {
1420 		ret = -ENOBUFS;
1421 		goto fail;
1422 	}
1423 
1424 	if (!wilc->rx_buffer)
1425 		wilc->rx_buffer = kmalloc(WILC_RX_BUFF_SIZE, GFP_KERNEL);
1426 
1427 	if (!wilc->rx_buffer) {
1428 		ret = -ENOBUFS;
1429 		goto fail;
1430 	}
1431 
1432 	if (init_chip(dev)) {
1433 		ret = -EIO;
1434 		goto fail;
1435 	}
1436 
1437 	return 0;
1438 
1439 fail:
1440 
1441 	kfree(wilc->rx_buffer);
1442 	wilc->rx_buffer = NULL;
1443 	kfree(wilc->tx_buffer);
1444 	wilc->tx_buffer = NULL;
1445 
1446 	return ret;
1447 }
1448