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, void *priv, u8 *buffer,
412 			      u32 buffer_size,
413 			      void (*tx_complete_fn)(void *, int))
414 {
415 	struct txq_entry_t *tqe;
416 	struct wilc_vif *vif = netdev_priv(dev);
417 	struct wilc *wilc;
418 	u8 q_num;
419 
420 	wilc = vif->wilc;
421 
422 	if (wilc->quit) {
423 		tx_complete_fn(priv, 0);
424 		return 0;
425 	}
426 
427 	tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
428 
429 	if (!tqe) {
430 		tx_complete_fn(priv, 0);
431 		return 0;
432 	}
433 	tqe->type = WILC_NET_PKT;
434 	tqe->buffer = buffer;
435 	tqe->buffer_size = buffer_size;
436 	tqe->tx_complete_func = tx_complete_fn;
437 	tqe->priv = priv;
438 	tqe->vif = vif;
439 
440 	q_num = ac_classify(wilc, priv);
441 	tqe->q_num = q_num;
442 	if (ac_change(wilc, &q_num)) {
443 		tx_complete_fn(priv, 0);
444 		kfree(tqe);
445 		return 0;
446 	}
447 
448 	if (is_ac_q_limit(wilc, q_num)) {
449 		tqe->ack_idx = NOT_TCP_ACK;
450 		if (vif->ack_filter.enabled)
451 			tcp_process(dev, tqe);
452 		wilc_wlan_txq_add_to_tail(dev, q_num, tqe);
453 	} else {
454 		tx_complete_fn(priv, 0);
455 		kfree(tqe);
456 	}
457 
458 	return wilc->txq_entries;
459 }
460 
461 int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
462 			       u32 buffer_size,
463 			       void (*tx_complete_fn)(void *, int))
464 {
465 	struct txq_entry_t *tqe;
466 	struct wilc_vif *vif = netdev_priv(dev);
467 	struct wilc *wilc;
468 
469 	wilc = vif->wilc;
470 
471 	if (wilc->quit) {
472 		tx_complete_fn(priv, 0);
473 		return 0;
474 	}
475 
476 	tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
477 
478 	if (!tqe) {
479 		tx_complete_fn(priv, 0);
480 		return 0;
481 	}
482 	tqe->type = WILC_MGMT_PKT;
483 	tqe->buffer = buffer;
484 	tqe->buffer_size = buffer_size;
485 	tqe->tx_complete_func = tx_complete_fn;
486 	tqe->priv = priv;
487 	tqe->q_num = AC_BE_Q;
488 	tqe->ack_idx = NOT_TCP_ACK;
489 	tqe->vif = vif;
490 	wilc_wlan_txq_add_to_tail(dev, AC_VO_Q, tqe);
491 	return 1;
492 }
493 
494 static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc, u8 q_num)
495 {
496 	struct txq_entry_t *tqe = NULL;
497 	unsigned long flags;
498 
499 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
500 
501 	if (!list_empty(&wilc->txq[q_num].txq_head.list))
502 		tqe = list_first_entry(&wilc->txq[q_num].txq_head.list,
503 				       struct txq_entry_t, list);
504 
505 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
506 
507 	return tqe;
508 }
509 
510 static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc,
511 						  struct txq_entry_t *tqe,
512 						  u8 q_num)
513 {
514 	unsigned long flags;
515 
516 	spin_lock_irqsave(&wilc->txq_spinlock, flags);
517 
518 	if (!list_is_last(&tqe->list, &wilc->txq[q_num].txq_head.list))
519 		tqe = list_next_entry(tqe, list);
520 	else
521 		tqe = NULL;
522 	spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
523 
524 	return tqe;
525 }
526 
527 static void wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe)
528 {
529 	if (wilc->quit)
530 		return;
531 
532 	mutex_lock(&wilc->rxq_cs);
533 	list_add_tail(&rqe->list, &wilc->rxq_head.list);
534 	mutex_unlock(&wilc->rxq_cs);
535 }
536 
537 static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
538 {
539 	struct rxq_entry_t *rqe = NULL;
540 
541 	mutex_lock(&wilc->rxq_cs);
542 	if (!list_empty(&wilc->rxq_head.list)) {
543 		rqe = list_first_entry(&wilc->rxq_head.list, struct rxq_entry_t,
544 				       list);
545 		list_del(&rqe->list);
546 	}
547 	mutex_unlock(&wilc->rxq_cs);
548 	return rqe;
549 }
550 
551 void chip_allow_sleep(struct wilc *wilc)
552 {
553 	u32 reg = 0;
554 
555 	wilc->hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, &reg);
556 
557 	wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
558 				      reg & ~WILC_SDIO_WAKEUP_BIT);
559 	wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG, 0);
560 }
561 EXPORT_SYMBOL_GPL(chip_allow_sleep);
562 
563 void chip_wakeup(struct wilc *wilc)
564 {
565 	u32 reg, clk_status_reg;
566 	const struct wilc_hif_func *h = wilc->hif_func;
567 
568 	if (wilc->io_type == WILC_HIF_SPI) {
569 		do {
570 			h->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, &reg);
571 			h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
572 					 reg | WILC_SPI_WAKEUP_BIT);
573 			h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
574 					 reg & ~WILC_SPI_WAKEUP_BIT);
575 
576 			do {
577 				usleep_range(2000, 2500);
578 				wilc_get_chipid(wilc, true);
579 			} while (wilc_get_chipid(wilc, true) == 0);
580 		} while (wilc_get_chipid(wilc, true) == 0);
581 	} else if (wilc->io_type == WILC_HIF_SDIO) {
582 		h->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG,
583 				 WILC_SDIO_HOST_TO_FW_BIT);
584 		usleep_range(200, 400);
585 		h->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, &reg);
586 		do {
587 			h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
588 					 reg | WILC_SDIO_WAKEUP_BIT);
589 			h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
590 					&clk_status_reg);
591 
592 			while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
593 				usleep_range(2000, 2500);
594 
595 				h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
596 						&clk_status_reg);
597 			}
598 			if (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
599 				h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
600 						 reg & ~WILC_SDIO_WAKEUP_BIT);
601 			}
602 		} while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT));
603 	}
604 
605 	if (wilc->chip_ps_state == WILC_CHIP_SLEEPING_MANUAL) {
606 		if (wilc_get_chipid(wilc, false) < WILC_1000_BASE_ID_2B) {
607 			u32 val32;
608 
609 			h->hif_read_reg(wilc, WILC_REG_4_TO_1_RX, &val32);
610 			val32 |= BIT(6);
611 			h->hif_write_reg(wilc, WILC_REG_4_TO_1_RX, val32);
612 
613 			h->hif_read_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, &val32);
614 			val32 |= BIT(6);
615 			h->hif_write_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, val32);
616 		}
617 	}
618 	wilc->chip_ps_state = WILC_CHIP_WAKEDUP;
619 }
620 EXPORT_SYMBOL_GPL(chip_wakeup);
621 
622 void host_wakeup_notify(struct wilc *wilc)
623 {
624 	acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
625 	wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_2, 1);
626 	release_bus(wilc, WILC_BUS_RELEASE_ONLY);
627 }
628 EXPORT_SYMBOL_GPL(host_wakeup_notify);
629 
630 void host_sleep_notify(struct wilc *wilc)
631 {
632 	acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
633 	wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_1, 1);
634 	release_bus(wilc, WILC_BUS_RELEASE_ONLY);
635 }
636 EXPORT_SYMBOL_GPL(host_sleep_notify);
637 
638 int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
639 {
640 	int i, entries = 0;
641 	u8 k, ac;
642 	u32 sum;
643 	u32 reg;
644 	u8 ac_desired_ratio[NQUEUES] = {0, 0, 0, 0};
645 	u8 ac_preserve_ratio[NQUEUES] = {1, 1, 1, 1};
646 	u8 *num_pkts_to_add;
647 	u8 vmm_entries_ac[WILC_VMM_TBL_SIZE];
648 	u32 offset = 0;
649 	bool max_size_over = 0, ac_exist = 0;
650 	int vmm_sz = 0;
651 	struct txq_entry_t *tqe_q[NQUEUES];
652 	int ret = 0;
653 	int counter;
654 	int timeout;
655 	u32 vmm_table[WILC_VMM_TBL_SIZE];
656 	u8 ac_pkt_num_to_chip[NQUEUES] = {0, 0, 0, 0};
657 	const struct wilc_hif_func *func;
658 	int srcu_idx;
659 	u8 *txb = wilc->tx_buffer;
660 	struct wilc_vif *vif;
661 
662 	if (wilc->quit)
663 		goto out_update_cnt;
664 
665 	if (ac_balance(wilc, ac_desired_ratio))
666 		return -EINVAL;
667 
668 	mutex_lock(&wilc->txq_add_to_head_cs);
669 
670 	srcu_idx = srcu_read_lock(&wilc->srcu);
671 	list_for_each_entry_rcu(vif, &wilc->vif_list, list)
672 		wilc_wlan_txq_filter_dup_tcp_ack(vif->ndev);
673 	srcu_read_unlock(&wilc->srcu, srcu_idx);
674 
675 	for (ac = 0; ac < NQUEUES; ac++)
676 		tqe_q[ac] = wilc_wlan_txq_get_first(wilc, ac);
677 
678 	i = 0;
679 	sum = 0;
680 	max_size_over = 0;
681 	num_pkts_to_add = ac_desired_ratio;
682 	do {
683 		ac_exist = 0;
684 		for (ac = 0; (ac < NQUEUES) && (!max_size_over); ac++) {
685 			if (!tqe_q[ac])
686 				continue;
687 
688 			ac_exist = 1;
689 			for (k = 0; (k < num_pkts_to_add[ac]) &&
690 			     (!max_size_over) && tqe_q[ac]; k++) {
691 				if (i >= (WILC_VMM_TBL_SIZE - 1)) {
692 					max_size_over = 1;
693 					break;
694 				}
695 
696 				if (tqe_q[ac]->type == WILC_CFG_PKT)
697 					vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
698 				else if (tqe_q[ac]->type == WILC_NET_PKT)
699 					vmm_sz = ETH_ETHERNET_HDR_OFFSET;
700 				else
701 					vmm_sz = HOST_HDR_OFFSET;
702 
703 				vmm_sz += tqe_q[ac]->buffer_size;
704 				vmm_sz = ALIGN(vmm_sz, 4);
705 
706 				if ((sum + vmm_sz) > WILC_TX_BUFF_SIZE) {
707 					max_size_over = 1;
708 					break;
709 				}
710 				vmm_table[i] = vmm_sz / 4;
711 				if (tqe_q[ac]->type == WILC_CFG_PKT)
712 					vmm_table[i] |= BIT(10);
713 
714 				cpu_to_le32s(&vmm_table[i]);
715 				vmm_entries_ac[i] = ac;
716 
717 				i++;
718 				sum += vmm_sz;
719 				tqe_q[ac] = wilc_wlan_txq_get_next(wilc,
720 								   tqe_q[ac],
721 								   ac);
722 			}
723 		}
724 		num_pkts_to_add = ac_preserve_ratio;
725 	} while (!max_size_over && ac_exist);
726 
727 	if (i == 0)
728 		goto out_unlock;
729 	vmm_table[i] = 0x0;
730 
731 	acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
732 	counter = 0;
733 	func = wilc->hif_func;
734 	do {
735 		ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
736 		if (ret)
737 			break;
738 
739 		if ((reg & 0x1) == 0) {
740 			ac_update_fw_ac_pkt_info(wilc, reg);
741 			break;
742 		}
743 
744 		counter++;
745 		if (counter > 200) {
746 			counter = 0;
747 			ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0);
748 			break;
749 		}
750 	} while (!wilc->quit);
751 
752 	if (ret)
753 		goto out_release_bus;
754 
755 	timeout = 200;
756 	do {
757 		ret = func->hif_block_tx(wilc,
758 					 WILC_VMM_TBL_RX_SHADOW_BASE,
759 					 (u8 *)vmm_table,
760 					 ((i + 1) * 4));
761 		if (ret)
762 			break;
763 
764 		ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
765 		if (ret)
766 			break;
767 
768 		do {
769 			ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
770 			if (ret)
771 				break;
772 			if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) {
773 				entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
774 				break;
775 			}
776 		} while (--timeout);
777 		if (timeout <= 0) {
778 			ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
779 			break;
780 		}
781 
782 		if (ret)
783 			break;
784 
785 		if (entries == 0) {
786 			ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
787 			if (ret)
788 				break;
789 			reg &= ~BIT(0);
790 			ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg);
791 		}
792 	} while (0);
793 
794 	if (ret)
795 		goto out_release_bus;
796 
797 	if (entries == 0) {
798 		/*
799 		 * No VMM space available in firmware so retry to transmit
800 		 * the packet from tx queue.
801 		 */
802 		ret = WILC_VMM_ENTRY_FULL_RETRY;
803 		goto out_release_bus;
804 	}
805 
806 	release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
807 
808 	offset = 0;
809 	i = 0;
810 	do {
811 		struct txq_entry_t *tqe;
812 		u32 header, buffer_offset;
813 		char *bssid;
814 		u8 mgmt_ptk = 0;
815 
816 		tqe = wilc_wlan_txq_remove_from_head(wilc, vmm_entries_ac[i]);
817 		ac_pkt_num_to_chip[vmm_entries_ac[i]]++;
818 		if (!tqe)
819 			break;
820 
821 		vif = tqe->vif;
822 		if (vmm_table[i] == 0)
823 			break;
824 
825 		le32_to_cpus(&vmm_table[i]);
826 		vmm_sz = FIELD_GET(WILC_VMM_BUFFER_SIZE, vmm_table[i]);
827 		vmm_sz *= 4;
828 
829 		if (tqe->type == WILC_MGMT_PKT)
830 			mgmt_ptk = 1;
831 
832 		header = (FIELD_PREP(WILC_VMM_HDR_TYPE, tqe->type) |
833 			  FIELD_PREP(WILC_VMM_HDR_MGMT_FIELD, mgmt_ptk) |
834 			  FIELD_PREP(WILC_VMM_HDR_PKT_SIZE, tqe->buffer_size) |
835 			  FIELD_PREP(WILC_VMM_HDR_BUFF_SIZE, vmm_sz));
836 
837 		cpu_to_le32s(&header);
838 		memcpy(&txb[offset], &header, 4);
839 		if (tqe->type == WILC_CFG_PKT) {
840 			buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
841 		} else if (tqe->type == WILC_NET_PKT) {
842 			int prio = tqe->q_num;
843 
844 			bssid = tqe->vif->bssid;
845 			buffer_offset = ETH_ETHERNET_HDR_OFFSET;
846 			memcpy(&txb[offset + 4], &prio, sizeof(prio));
847 			memcpy(&txb[offset + 8], bssid, 6);
848 		} else {
849 			buffer_offset = HOST_HDR_OFFSET;
850 		}
851 
852 		memcpy(&txb[offset + buffer_offset],
853 		       tqe->buffer, tqe->buffer_size);
854 		offset += vmm_sz;
855 		i++;
856 		tqe->status = 1;
857 		if (tqe->tx_complete_func)
858 			tqe->tx_complete_func(tqe->priv, tqe->status);
859 		if (tqe->ack_idx != NOT_TCP_ACK &&
860 		    tqe->ack_idx < MAX_PENDING_ACKS)
861 			vif->ack_filter.pending_acks[tqe->ack_idx].txqe = NULL;
862 		kfree(tqe);
863 	} while (--entries);
864 	for (i = 0; i < NQUEUES; i++)
865 		wilc->txq[i].fw.count += ac_pkt_num_to_chip[i];
866 
867 	acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
868 
869 	ret = func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
870 	if (ret)
871 		goto out_release_bus;
872 
873 	ret = func->hif_block_tx_ext(wilc, 0, txb, offset);
874 
875 out_release_bus:
876 	release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
877 
878 out_unlock:
879 	mutex_unlock(&wilc->txq_add_to_head_cs);
880 
881 out_update_cnt:
882 	*txq_count = wilc->txq_entries;
883 	return ret;
884 }
885 
886 static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size)
887 {
888 	int offset = 0;
889 	u32 header;
890 	u32 pkt_len, pkt_offset, tp_len;
891 	int is_cfg_packet;
892 	u8 *buff_ptr;
893 
894 	do {
895 		buff_ptr = buffer + offset;
896 		header = get_unaligned_le32(buff_ptr);
897 
898 		is_cfg_packet = FIELD_GET(WILC_PKT_HDR_CONFIG_FIELD, header);
899 		pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
900 		tp_len = FIELD_GET(WILC_PKT_HDR_TOTAL_LEN_FIELD, header);
901 		pkt_len = FIELD_GET(WILC_PKT_HDR_LEN_FIELD, header);
902 
903 		if (pkt_len == 0 || tp_len == 0)
904 			break;
905 
906 		if (pkt_offset & IS_MANAGMEMENT) {
907 			buff_ptr += HOST_HDR_OFFSET;
908 			wilc_wfi_mgmt_rx(wilc, buff_ptr, pkt_len);
909 		} else {
910 			if (!is_cfg_packet) {
911 				wilc_frmw_to_host(wilc, buff_ptr, pkt_len,
912 						  pkt_offset);
913 			} else {
914 				struct wilc_cfg_rsp rsp;
915 
916 				buff_ptr += pkt_offset;
917 
918 				wilc_wlan_cfg_indicate_rx(wilc, buff_ptr,
919 							  pkt_len,
920 							  &rsp);
921 				if (rsp.type == WILC_CFG_RSP) {
922 					if (wilc->cfg_seq_no == rsp.seq_no)
923 						complete(&wilc->cfg_event);
924 				} else if (rsp.type == WILC_CFG_RSP_STATUS) {
925 					wilc_mac_indicate(wilc);
926 				}
927 			}
928 		}
929 		offset += tp_len;
930 	} while (offset < size);
931 }
932 
933 static void wilc_wlan_handle_rxq(struct wilc *wilc)
934 {
935 	int size;
936 	u8 *buffer;
937 	struct rxq_entry_t *rqe;
938 
939 	while (!wilc->quit) {
940 		rqe = wilc_wlan_rxq_remove(wilc);
941 		if (!rqe)
942 			break;
943 
944 		buffer = rqe->buffer;
945 		size = rqe->buffer_size;
946 		wilc_wlan_handle_rx_buff(wilc, buffer, size);
947 
948 		kfree(rqe);
949 	}
950 	if (wilc->quit)
951 		complete(&wilc->cfg_event);
952 }
953 
954 static void wilc_unknown_isr_ext(struct wilc *wilc)
955 {
956 	wilc->hif_func->hif_clear_int_ext(wilc, 0);
957 }
958 
959 static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
960 {
961 	u32 offset = wilc->rx_buffer_offset;
962 	u8 *buffer = NULL;
963 	u32 size;
964 	u32 retries = 0;
965 	int ret = 0;
966 	struct rxq_entry_t *rqe;
967 
968 	size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, int_status) << 2;
969 
970 	while (!size && retries < 10) {
971 		wilc->hif_func->hif_read_size(wilc, &size);
972 		size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, size) << 2;
973 		retries++;
974 	}
975 
976 	if (size <= 0)
977 		return;
978 
979 	if (WILC_RX_BUFF_SIZE - offset < size)
980 		offset = 0;
981 
982 	buffer = &wilc->rx_buffer[offset];
983 
984 	wilc->hif_func->hif_clear_int_ext(wilc, DATA_INT_CLR | ENABLE_RX_VMM);
985 	ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size);
986 	if (ret)
987 		return;
988 
989 	offset += size;
990 	wilc->rx_buffer_offset = offset;
991 	rqe = kmalloc(sizeof(*rqe), GFP_KERNEL);
992 	if (!rqe)
993 		return;
994 
995 	rqe->buffer = buffer;
996 	rqe->buffer_size = size;
997 	wilc_wlan_rxq_add(wilc, rqe);
998 	wilc_wlan_handle_rxq(wilc);
999 }
1000 
1001 void wilc_handle_isr(struct wilc *wilc)
1002 {
1003 	u32 int_status;
1004 
1005 	acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
1006 	wilc->hif_func->hif_read_int(wilc, &int_status);
1007 
1008 	if (int_status & DATA_INT_EXT)
1009 		wilc_wlan_handle_isr_ext(wilc, int_status);
1010 
1011 	if (!(int_status & (ALL_INT_EXT)))
1012 		wilc_unknown_isr_ext(wilc);
1013 
1014 	release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1015 }
1016 EXPORT_SYMBOL_GPL(wilc_handle_isr);
1017 
1018 int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
1019 				u32 buffer_size)
1020 {
1021 	u32 offset;
1022 	u32 addr, size, size2, blksz;
1023 	u8 *dma_buffer;
1024 	int ret = 0;
1025 
1026 	blksz = BIT(12);
1027 
1028 	dma_buffer = kmalloc(blksz, GFP_KERNEL);
1029 	if (!dma_buffer)
1030 		return -EIO;
1031 
1032 	offset = 0;
1033 	do {
1034 		addr = get_unaligned_le32(&buffer[offset]);
1035 		size = get_unaligned_le32(&buffer[offset + 4]);
1036 		acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
1037 		offset += 8;
1038 		while (((int)size) && (offset < buffer_size)) {
1039 			if (size <= blksz)
1040 				size2 = size;
1041 			else
1042 				size2 = blksz;
1043 
1044 			memcpy(dma_buffer, &buffer[offset], size2);
1045 			ret = wilc->hif_func->hif_block_tx(wilc, addr,
1046 							   dma_buffer, size2);
1047 			if (ret)
1048 				break;
1049 
1050 			addr += size2;
1051 			offset += size2;
1052 			size -= size2;
1053 		}
1054 		release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1055 
1056 		if (ret)
1057 			goto fail;
1058 	} while (offset < buffer_size);
1059 
1060 fail:
1061 
1062 	kfree(dma_buffer);
1063 
1064 	return ret;
1065 }
1066 
1067 int wilc_wlan_start(struct wilc *wilc)
1068 {
1069 	u32 reg = 0;
1070 	int ret;
1071 	u32 chipid;
1072 
1073 	if (wilc->io_type == WILC_HIF_SDIO) {
1074 		reg = 0;
1075 		reg |= BIT(3);
1076 	} else if (wilc->io_type == WILC_HIF_SPI) {
1077 		reg = 1;
1078 	}
1079 	acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
1080 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
1081 	if (ret) {
1082 		release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1083 		return ret;
1084 	}
1085 	reg = 0;
1086 	if (wilc->io_type == WILC_HIF_SDIO && wilc->dev_irq_num)
1087 		reg |= WILC_HAVE_SDIO_IRQ_GPIO;
1088 
1089 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
1090 	if (ret) {
1091 		release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1092 		return ret;
1093 	}
1094 
1095 	wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT);
1096 
1097 	ret = wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
1098 	if (ret) {
1099 		release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1100 		return ret;
1101 	}
1102 
1103 	wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1104 	if ((reg & BIT(10)) == BIT(10)) {
1105 		reg &= ~BIT(10);
1106 		wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1107 		wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1108 	}
1109 
1110 	reg |= BIT(10);
1111 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1112 	wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1113 	release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1114 
1115 	return ret;
1116 }
1117 
1118 int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
1119 {
1120 	u32 reg = 0;
1121 	int ret;
1122 
1123 	acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
1124 
1125 	ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, &reg);
1126 	if (ret) {
1127 		netdev_err(vif->ndev, "Error while reading reg\n");
1128 		release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1129 		return ret;
1130 	}
1131 
1132 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0,
1133 					(reg | WILC_ABORT_REQ_BIT));
1134 	if (ret) {
1135 		netdev_err(vif->ndev, "Error while writing reg\n");
1136 		release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1137 		return ret;
1138 	}
1139 
1140 	ret = wilc->hif_func->hif_read_reg(wilc, WILC_FW_HOST_COMM, &reg);
1141 	if (ret) {
1142 		netdev_err(vif->ndev, "Error while reading reg\n");
1143 		release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1144 		return ret;
1145 	}
1146 	reg = BIT(0);
1147 
1148 	ret = wilc->hif_func->hif_write_reg(wilc, WILC_FW_HOST_COMM, reg);
1149 	if (ret) {
1150 		netdev_err(vif->ndev, "Error while writing reg\n");
1151 		release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1152 		return ret;
1153 	}
1154 
1155 	release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1156 
1157 	return 0;
1158 }
1159 
1160 void wilc_wlan_cleanup(struct net_device *dev)
1161 {
1162 	struct txq_entry_t *tqe;
1163 	struct rxq_entry_t *rqe;
1164 	u8 ac;
1165 	struct wilc_vif *vif = netdev_priv(dev);
1166 	struct wilc *wilc = vif->wilc;
1167 
1168 	wilc->quit = 1;
1169 	for (ac = 0; ac < NQUEUES; ac++) {
1170 		while ((tqe = wilc_wlan_txq_remove_from_head(wilc, ac))) {
1171 			if (tqe->tx_complete_func)
1172 				tqe->tx_complete_func(tqe->priv, 0);
1173 			kfree(tqe);
1174 		}
1175 	}
1176 
1177 	while ((rqe = wilc_wlan_rxq_remove(wilc)))
1178 		kfree(rqe);
1179 
1180 	kfree(wilc->rx_buffer);
1181 	wilc->rx_buffer = NULL;
1182 	kfree(wilc->tx_buffer);
1183 	wilc->tx_buffer = NULL;
1184 	wilc->hif_func->hif_deinit(NULL);
1185 }
1186 
1187 static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type,
1188 				u32 drv_handler)
1189 {
1190 	struct wilc *wilc = vif->wilc;
1191 	struct wilc_cfg_frame *cfg = &wilc->cfg_frame;
1192 	int t_len = wilc->cfg_frame_offset + sizeof(struct wilc_cfg_cmd_hdr);
1193 
1194 	if (type == WILC_CFG_SET)
1195 		cfg->hdr.cmd_type = 'W';
1196 	else
1197 		cfg->hdr.cmd_type = 'Q';
1198 
1199 	cfg->hdr.seq_no = wilc->cfg_seq_no % 256;
1200 	cfg->hdr.total_len = cpu_to_le16(t_len);
1201 	cfg->hdr.driver_handler = cpu_to_le32(drv_handler);
1202 	wilc->cfg_seq_no = cfg->hdr.seq_no;
1203 
1204 	if (!wilc_wlan_txq_add_cfg_pkt(vif, (u8 *)&cfg->hdr, t_len))
1205 		return -1;
1206 
1207 	return 0;
1208 }
1209 
1210 int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
1211 		      u32 buffer_size, int commit, u32 drv_handler)
1212 {
1213 	u32 offset;
1214 	int ret_size;
1215 	struct wilc *wilc = vif->wilc;
1216 
1217 	mutex_lock(&wilc->cfg_cmd_lock);
1218 
1219 	if (start)
1220 		wilc->cfg_frame_offset = 0;
1221 
1222 	offset = wilc->cfg_frame_offset;
1223 	ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset,
1224 					 wid, buffer, buffer_size);
1225 	offset += ret_size;
1226 	wilc->cfg_frame_offset = offset;
1227 
1228 	if (!commit) {
1229 		mutex_unlock(&wilc->cfg_cmd_lock);
1230 		return ret_size;
1231 	}
1232 
1233 	netdev_dbg(vif->ndev, "%s: seqno[%d]\n", __func__, wilc->cfg_seq_no);
1234 
1235 	if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler))
1236 		ret_size = 0;
1237 
1238 	if (!wait_for_completion_timeout(&wilc->cfg_event,
1239 					 WILC_CFG_PKTS_TIMEOUT)) {
1240 		netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
1241 		ret_size = 0;
1242 	}
1243 
1244 	wilc->cfg_frame_offset = 0;
1245 	wilc->cfg_seq_no += 1;
1246 	mutex_unlock(&wilc->cfg_cmd_lock);
1247 
1248 	return ret_size;
1249 }
1250 
1251 int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit,
1252 		      u32 drv_handler)
1253 {
1254 	u32 offset;
1255 	int ret_size;
1256 	struct wilc *wilc = vif->wilc;
1257 
1258 	mutex_lock(&wilc->cfg_cmd_lock);
1259 
1260 	if (start)
1261 		wilc->cfg_frame_offset = 0;
1262 
1263 	offset = wilc->cfg_frame_offset;
1264 	ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset, wid);
1265 	offset += ret_size;
1266 	wilc->cfg_frame_offset = offset;
1267 
1268 	if (!commit) {
1269 		mutex_unlock(&wilc->cfg_cmd_lock);
1270 		return ret_size;
1271 	}
1272 
1273 	if (wilc_wlan_cfg_commit(vif, WILC_CFG_QUERY, drv_handler))
1274 		ret_size = 0;
1275 
1276 	if (!wait_for_completion_timeout(&wilc->cfg_event,
1277 					 WILC_CFG_PKTS_TIMEOUT)) {
1278 		netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
1279 		ret_size = 0;
1280 	}
1281 	wilc->cfg_frame_offset = 0;
1282 	wilc->cfg_seq_no += 1;
1283 	mutex_unlock(&wilc->cfg_cmd_lock);
1284 
1285 	return ret_size;
1286 }
1287 
1288 int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
1289 			 u32 count)
1290 {
1291 	int i;
1292 	int ret = 0;
1293 	u32 drv = wilc_get_vif_idx(vif);
1294 
1295 	if (mode == WILC_GET_CFG) {
1296 		for (i = 0; i < count; i++) {
1297 			if (!wilc_wlan_cfg_get(vif, !i,
1298 					       wids[i].id,
1299 					       (i == count - 1),
1300 					       drv)) {
1301 				ret = -ETIMEDOUT;
1302 				break;
1303 			}
1304 		}
1305 		for (i = 0; i < count; i++) {
1306 			wids[i].size = wilc_wlan_cfg_get_val(vif->wilc,
1307 							     wids[i].id,
1308 							     wids[i].val,
1309 							     wids[i].size);
1310 		}
1311 	} else if (mode == WILC_SET_CFG) {
1312 		for (i = 0; i < count; i++) {
1313 			if (!wilc_wlan_cfg_set(vif, !i,
1314 					       wids[i].id,
1315 					       wids[i].val,
1316 					       wids[i].size,
1317 					       (i == count - 1),
1318 					       drv)) {
1319 				ret = -ETIMEDOUT;
1320 				break;
1321 			}
1322 		}
1323 	}
1324 
1325 	return ret;
1326 }
1327 
1328 static int init_chip(struct net_device *dev)
1329 {
1330 	u32 chipid;
1331 	u32 reg;
1332 	int ret = 0;
1333 	struct wilc_vif *vif = netdev_priv(dev);
1334 	struct wilc *wilc = vif->wilc;
1335 
1336 	acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
1337 
1338 	chipid = wilc_get_chipid(wilc, true);
1339 
1340 	if ((chipid & 0xfff) != 0xa0) {
1341 		ret = wilc->hif_func->hif_read_reg(wilc,
1342 						   WILC_CORTUS_RESET_MUX_SEL,
1343 						   &reg);
1344 		if (ret) {
1345 			netdev_err(dev, "fail read reg 0x1118\n");
1346 			goto release;
1347 		}
1348 		reg |= BIT(0);
1349 		ret = wilc->hif_func->hif_write_reg(wilc,
1350 						    WILC_CORTUS_RESET_MUX_SEL,
1351 						    reg);
1352 		if (ret) {
1353 			netdev_err(dev, "fail write reg 0x1118\n");
1354 			goto release;
1355 		}
1356 		ret = wilc->hif_func->hif_write_reg(wilc,
1357 						    WILC_CORTUS_BOOT_REGISTER,
1358 						    WILC_CORTUS_BOOT_FROM_IRAM);
1359 		if (ret) {
1360 			netdev_err(dev, "fail write reg 0xc0000\n");
1361 			goto release;
1362 		}
1363 	}
1364 
1365 release:
1366 	release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1367 
1368 	return ret;
1369 }
1370 
1371 u32 wilc_get_chipid(struct wilc *wilc, bool update)
1372 {
1373 	static u32 chipid;
1374 	u32 tempchipid = 0;
1375 	u32 rfrevid = 0;
1376 
1377 	if (chipid == 0 || update) {
1378 		wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &tempchipid);
1379 		wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID,
1380 					     &rfrevid);
1381 		if (!is_wilc1000(tempchipid)) {
1382 			chipid = 0;
1383 			return chipid;
1384 		}
1385 		if (tempchipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */
1386 			if (rfrevid != 0x1)
1387 				tempchipid = WILC_1000_BASE_ID_2A_REV1;
1388 		} else if (tempchipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */
1389 			if (rfrevid == 0x4)
1390 				tempchipid = WILC_1000_BASE_ID_2B_REV1;
1391 			else if (rfrevid != 0x3)
1392 				tempchipid = WILC_1000_BASE_ID_2B_REV2;
1393 		}
1394 
1395 		chipid = tempchipid;
1396 	}
1397 	return chipid;
1398 }
1399 
1400 int wilc_wlan_init(struct net_device *dev)
1401 {
1402 	int ret = 0;
1403 	struct wilc_vif *vif = netdev_priv(dev);
1404 	struct wilc *wilc;
1405 
1406 	wilc = vif->wilc;
1407 
1408 	wilc->quit = 0;
1409 
1410 	if (wilc->hif_func->hif_init(wilc, false)) {
1411 		ret = -EIO;
1412 		goto fail;
1413 	}
1414 
1415 	if (!wilc->tx_buffer)
1416 		wilc->tx_buffer = kmalloc(WILC_TX_BUFF_SIZE, GFP_KERNEL);
1417 
1418 	if (!wilc->tx_buffer) {
1419 		ret = -ENOBUFS;
1420 		goto fail;
1421 	}
1422 
1423 	if (!wilc->rx_buffer)
1424 		wilc->rx_buffer = kmalloc(WILC_RX_BUFF_SIZE, GFP_KERNEL);
1425 
1426 	if (!wilc->rx_buffer) {
1427 		ret = -ENOBUFS;
1428 		goto fail;
1429 	}
1430 
1431 	if (init_chip(dev)) {
1432 		ret = -EIO;
1433 		goto fail;
1434 	}
1435 
1436 	return 0;
1437 
1438 fail:
1439 
1440 	kfree(wilc->rx_buffer);
1441 	wilc->rx_buffer = NULL;
1442 	kfree(wilc->tx_buffer);
1443 	wilc->tx_buffer = NULL;
1444 
1445 	return ret;
1446 }
1447