Loading...
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#define WAKE_UP_TRIAL_RETRY 10000
14
15static void wilc_wlan_txq_remove(struct wilc *wilc, u8 q_num,
16 struct txq_entry_t *tqe)
17{
18 list_del(&tqe->list);
19 wilc->txq_entries -= 1;
20 wilc->txq[q_num].count--;
21}
22
23static struct txq_entry_t *
24wilc_wlan_txq_remove_from_head(struct wilc *wilc, u8 q_num)
25{
26 struct txq_entry_t *tqe = NULL;
27 unsigned long flags;
28
29 spin_lock_irqsave(&wilc->txq_spinlock, flags);
30
31 if (!list_empty(&wilc->txq[q_num].txq_head.list)) {
32 tqe = list_first_entry(&wilc->txq[q_num].txq_head.list,
33 struct txq_entry_t, list);
34 list_del(&tqe->list);
35 wilc->txq_entries -= 1;
36 wilc->txq[q_num].count--;
37 }
38 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
39 return tqe;
40}
41
42static void wilc_wlan_txq_add_to_tail(struct net_device *dev, u8 q_num,
43 struct txq_entry_t *tqe)
44{
45 unsigned long flags;
46 struct wilc_vif *vif = netdev_priv(dev);
47 struct wilc *wilc = vif->wilc;
48
49 spin_lock_irqsave(&wilc->txq_spinlock, flags);
50
51 list_add_tail(&tqe->list, &wilc->txq[q_num].txq_head.list);
52 wilc->txq_entries += 1;
53 wilc->txq[q_num].count++;
54
55 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
56
57 complete(&wilc->txq_event);
58}
59
60static void wilc_wlan_txq_add_to_head(struct wilc_vif *vif, u8 q_num,
61 struct txq_entry_t *tqe)
62{
63 unsigned long flags;
64 struct wilc *wilc = vif->wilc;
65
66 mutex_lock(&wilc->txq_add_to_head_cs);
67
68 spin_lock_irqsave(&wilc->txq_spinlock, flags);
69
70 list_add(&tqe->list, &wilc->txq[q_num].txq_head.list);
71 wilc->txq_entries += 1;
72 wilc->txq[q_num].count++;
73
74 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
75 mutex_unlock(&wilc->txq_add_to_head_cs);
76 complete(&wilc->txq_event);
77}
78
79#define NOT_TCP_ACK (-1)
80
81static inline void add_tcp_session(struct wilc_vif *vif, u32 src_prt,
82 u32 dst_prt, u32 seq)
83{
84 struct tcp_ack_filter *f = &vif->ack_filter;
85
86 if (f->tcp_session < 2 * MAX_TCP_SESSION) {
87 f->ack_session_info[f->tcp_session].seq_num = seq;
88 f->ack_session_info[f->tcp_session].bigger_ack_num = 0;
89 f->ack_session_info[f->tcp_session].src_port = src_prt;
90 f->ack_session_info[f->tcp_session].dst_port = dst_prt;
91 f->tcp_session++;
92 }
93}
94
95static inline void update_tcp_session(struct wilc_vif *vif, u32 index, u32 ack)
96{
97 struct tcp_ack_filter *f = &vif->ack_filter;
98
99 if (index < 2 * MAX_TCP_SESSION &&
100 ack > f->ack_session_info[index].bigger_ack_num)
101 f->ack_session_info[index].bigger_ack_num = ack;
102}
103
104static inline void add_tcp_pending_ack(struct wilc_vif *vif, u32 ack,
105 u32 session_index,
106 struct txq_entry_t *txqe)
107{
108 struct tcp_ack_filter *f = &vif->ack_filter;
109 u32 i = f->pending_base + f->pending_acks_idx;
110
111 if (i < MAX_PENDING_ACKS) {
112 f->pending_acks[i].ack_num = ack;
113 f->pending_acks[i].txqe = txqe;
114 f->pending_acks[i].session_index = session_index;
115 txqe->ack_idx = i;
116 f->pending_acks_idx++;
117 }
118}
119
120static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe)
121{
122 void *buffer = tqe->buffer;
123 const struct ethhdr *eth_hdr_ptr = buffer;
124 int i;
125 unsigned long flags;
126 struct wilc_vif *vif = netdev_priv(dev);
127 struct wilc *wilc = vif->wilc;
128 struct tcp_ack_filter *f = &vif->ack_filter;
129 const struct iphdr *ip_hdr_ptr;
130 const struct tcphdr *tcp_hdr_ptr;
131 u32 ihl, total_length, data_offset;
132
133 spin_lock_irqsave(&wilc->txq_spinlock, flags);
134
135 if (eth_hdr_ptr->h_proto != htons(ETH_P_IP))
136 goto out;
137
138 ip_hdr_ptr = buffer + ETH_HLEN;
139
140 if (ip_hdr_ptr->protocol != IPPROTO_TCP)
141 goto out;
142
143 ihl = ip_hdr_ptr->ihl << 2;
144 tcp_hdr_ptr = buffer + ETH_HLEN + ihl;
145 total_length = ntohs(ip_hdr_ptr->tot_len);
146
147 data_offset = tcp_hdr_ptr->doff << 2;
148 if (total_length == (ihl + data_offset)) {
149 u32 seq_no, ack_no;
150
151 seq_no = ntohl(tcp_hdr_ptr->seq);
152 ack_no = ntohl(tcp_hdr_ptr->ack_seq);
153 for (i = 0; i < f->tcp_session; i++) {
154 u32 j = f->ack_session_info[i].seq_num;
155
156 if (i < 2 * MAX_TCP_SESSION &&
157 j == seq_no) {
158 update_tcp_session(vif, i, ack_no);
159 break;
160 }
161 }
162 if (i == f->tcp_session)
163 add_tcp_session(vif, 0, 0, seq_no);
164
165 add_tcp_pending_ack(vif, ack_no, i, tqe);
166 }
167
168out:
169 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
170}
171
172static void wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
173{
174 struct wilc_vif *vif = netdev_priv(dev);
175 struct wilc *wilc = vif->wilc;
176 struct tcp_ack_filter *f = &vif->ack_filter;
177 u32 i = 0;
178 u32 dropped = 0;
179 unsigned long flags;
180
181 spin_lock_irqsave(&wilc->txq_spinlock, flags);
182 for (i = f->pending_base;
183 i < (f->pending_base + f->pending_acks_idx); i++) {
184 u32 index;
185 u32 bigger_ack_num;
186
187 if (i >= MAX_PENDING_ACKS)
188 break;
189
190 index = f->pending_acks[i].session_index;
191
192 if (index >= 2 * MAX_TCP_SESSION)
193 break;
194
195 bigger_ack_num = f->ack_session_info[index].bigger_ack_num;
196
197 if (f->pending_acks[i].ack_num < bigger_ack_num) {
198 struct txq_entry_t *tqe;
199
200 tqe = f->pending_acks[i].txqe;
201 if (tqe) {
202 wilc_wlan_txq_remove(wilc, tqe->q_num, tqe);
203 tqe->status = 1;
204 if (tqe->tx_complete_func)
205 tqe->tx_complete_func(tqe->priv,
206 tqe->status);
207 kfree(tqe);
208 dropped++;
209 }
210 }
211 }
212 f->pending_acks_idx = 0;
213 f->tcp_session = 0;
214
215 if (f->pending_base == 0)
216 f->pending_base = MAX_TCP_SESSION;
217 else
218 f->pending_base = 0;
219
220 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
221
222 while (dropped > 0) {
223 wait_for_completion_timeout(&wilc->txq_event,
224 msecs_to_jiffies(1));
225 dropped--;
226 }
227}
228
229void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value)
230{
231 vif->ack_filter.enabled = value;
232}
233
234static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
235 u32 buffer_size)
236{
237 struct txq_entry_t *tqe;
238 struct wilc *wilc = vif->wilc;
239
240 netdev_dbg(vif->ndev, "Adding config packet ...\n");
241 if (wilc->quit) {
242 netdev_dbg(vif->ndev, "Return due to clear function\n");
243 complete(&wilc->cfg_event);
244 return 0;
245 }
246
247 tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
248 if (!tqe) {
249 complete(&wilc->cfg_event);
250 return 0;
251 }
252
253 tqe->type = WILC_CFG_PKT;
254 tqe->buffer = buffer;
255 tqe->buffer_size = buffer_size;
256 tqe->tx_complete_func = NULL;
257 tqe->priv = NULL;
258 tqe->q_num = AC_VO_Q;
259 tqe->ack_idx = NOT_TCP_ACK;
260 tqe->vif = vif;
261
262 wilc_wlan_txq_add_to_head(vif, AC_VO_Q, tqe);
263
264 return 1;
265}
266
267static bool is_ac_q_limit(struct wilc *wl, u8 q_num)
268{
269 u8 factors[NQUEUES] = {1, 1, 1, 1};
270 u16 i;
271 unsigned long flags;
272 struct wilc_tx_queue_status *q = &wl->tx_q_limit;
273 u8 end_index;
274 u8 q_limit;
275 bool ret = false;
276
277 spin_lock_irqsave(&wl->txq_spinlock, flags);
278 if (!q->initialized) {
279 for (i = 0; i < AC_BUFFER_SIZE; i++)
280 q->buffer[i] = i % NQUEUES;
281
282 for (i = 0; i < NQUEUES; i++) {
283 q->cnt[i] = AC_BUFFER_SIZE * factors[i] / NQUEUES;
284 q->sum += q->cnt[i];
285 }
286 q->end_index = AC_BUFFER_SIZE - 1;
287 q->initialized = 1;
288 }
289
290 end_index = q->end_index;
291 q->cnt[q->buffer[end_index]] -= factors[q->buffer[end_index]];
292 q->cnt[q_num] += factors[q_num];
293 q->sum += (factors[q_num] - factors[q->buffer[end_index]]);
294
295 q->buffer[end_index] = q_num;
296 if (end_index > 0)
297 q->end_index--;
298 else
299 q->end_index = AC_BUFFER_SIZE - 1;
300
301 if (!q->sum)
302 q_limit = 1;
303 else
304 q_limit = (q->cnt[q_num] * FLOW_CONTROL_UPPER_THRESHOLD / q->sum) + 1;
305
306 if (wl->txq[q_num].count <= q_limit)
307 ret = true;
308
309 spin_unlock_irqrestore(&wl->txq_spinlock, flags);
310
311 return ret;
312}
313
314static inline u8 ac_classify(struct wilc *wilc, struct sk_buff *skb)
315{
316 u8 q_num = AC_BE_Q;
317 u8 dscp;
318
319 switch (skb->protocol) {
320 case htons(ETH_P_IP):
321 dscp = ipv4_get_dsfield(ip_hdr(skb)) & 0xfc;
322 break;
323 case htons(ETH_P_IPV6):
324 dscp = ipv6_get_dsfield(ipv6_hdr(skb)) & 0xfc;
325 break;
326 default:
327 return q_num;
328 }
329
330 switch (dscp) {
331 case 0x08:
332 case 0x20:
333 case 0x40:
334 q_num = AC_BK_Q;
335 break;
336 case 0x80:
337 case 0xA0:
338 case 0x28:
339 q_num = AC_VI_Q;
340 break;
341 case 0xC0:
342 case 0xD0:
343 case 0xE0:
344 case 0x88:
345 case 0xB8:
346 q_num = AC_VO_Q;
347 break;
348 }
349
350 return q_num;
351}
352
353static inline int ac_balance(struct wilc *wl, u8 *ratio)
354{
355 u8 i, max_count = 0;
356
357 if (!ratio)
358 return -EINVAL;
359
360 for (i = 0; i < NQUEUES; i++)
361 if (wl->txq[i].fw.count > max_count)
362 max_count = wl->txq[i].fw.count;
363
364 for (i = 0; i < NQUEUES; i++)
365 ratio[i] = max_count - wl->txq[i].fw.count;
366
367 return 0;
368}
369
370static inline void ac_update_fw_ac_pkt_info(struct wilc *wl, u32 reg)
371{
372 wl->txq[AC_BK_Q].fw.count = FIELD_GET(BK_AC_COUNT_FIELD, reg);
373 wl->txq[AC_BE_Q].fw.count = FIELD_GET(BE_AC_COUNT_FIELD, reg);
374 wl->txq[AC_VI_Q].fw.count = FIELD_GET(VI_AC_COUNT_FIELD, reg);
375 wl->txq[AC_VO_Q].fw.count = FIELD_GET(VO_AC_COUNT_FIELD, reg);
376
377 wl->txq[AC_BK_Q].fw.acm = FIELD_GET(BK_AC_ACM_STAT_FIELD, reg);
378 wl->txq[AC_BE_Q].fw.acm = FIELD_GET(BE_AC_ACM_STAT_FIELD, reg);
379 wl->txq[AC_VI_Q].fw.acm = FIELD_GET(VI_AC_ACM_STAT_FIELD, reg);
380 wl->txq[AC_VO_Q].fw.acm = FIELD_GET(VO_AC_ACM_STAT_FIELD, reg);
381}
382
383static inline u8 ac_change(struct wilc *wilc, u8 *ac)
384{
385 do {
386 if (wilc->txq[*ac].fw.acm == 0)
387 return 0;
388 (*ac)++;
389 } while (*ac < NQUEUES);
390
391 return 1;
392}
393
394int wilc_wlan_txq_add_net_pkt(struct net_device *dev,
395 struct tx_complete_data *tx_data, u8 *buffer,
396 u32 buffer_size,
397 void (*tx_complete_fn)(void *, int))
398{
399 struct txq_entry_t *tqe;
400 struct wilc_vif *vif = netdev_priv(dev);
401 struct wilc *wilc;
402 u8 q_num;
403
404 wilc = vif->wilc;
405
406 if (wilc->quit) {
407 tx_complete_fn(tx_data, 0);
408 return 0;
409 }
410
411 if (!wilc->initialized) {
412 tx_complete_fn(tx_data, 0);
413 return 0;
414 }
415
416 tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
417
418 if (!tqe) {
419 tx_complete_fn(tx_data, 0);
420 return 0;
421 }
422 tqe->type = WILC_NET_PKT;
423 tqe->buffer = buffer;
424 tqe->buffer_size = buffer_size;
425 tqe->tx_complete_func = tx_complete_fn;
426 tqe->priv = tx_data;
427 tqe->vif = vif;
428
429 q_num = ac_classify(wilc, tx_data->skb);
430 tqe->q_num = q_num;
431 if (ac_change(wilc, &q_num)) {
432 tx_complete_fn(tx_data, 0);
433 kfree(tqe);
434 return 0;
435 }
436
437 if (is_ac_q_limit(wilc, q_num)) {
438 tqe->ack_idx = NOT_TCP_ACK;
439 if (vif->ack_filter.enabled)
440 tcp_process(dev, tqe);
441 wilc_wlan_txq_add_to_tail(dev, q_num, tqe);
442 } else {
443 tx_complete_fn(tx_data, 0);
444 kfree(tqe);
445 }
446
447 return wilc->txq_entries;
448}
449
450int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
451 u32 buffer_size,
452 void (*tx_complete_fn)(void *, int))
453{
454 struct txq_entry_t *tqe;
455 struct wilc_vif *vif = netdev_priv(dev);
456 struct wilc *wilc;
457
458 wilc = vif->wilc;
459
460 if (wilc->quit) {
461 tx_complete_fn(priv, 0);
462 return 0;
463 }
464
465 if (!wilc->initialized) {
466 tx_complete_fn(priv, 0);
467 return 0;
468 }
469 tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
470
471 if (!tqe) {
472 tx_complete_fn(priv, 0);
473 return 0;
474 }
475 tqe->type = WILC_MGMT_PKT;
476 tqe->buffer = buffer;
477 tqe->buffer_size = buffer_size;
478 tqe->tx_complete_func = tx_complete_fn;
479 tqe->priv = priv;
480 tqe->q_num = AC_BE_Q;
481 tqe->ack_idx = NOT_TCP_ACK;
482 tqe->vif = vif;
483 wilc_wlan_txq_add_to_tail(dev, AC_VO_Q, tqe);
484 return 1;
485}
486
487static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc, u8 q_num)
488{
489 struct txq_entry_t *tqe = NULL;
490 unsigned long flags;
491
492 spin_lock_irqsave(&wilc->txq_spinlock, flags);
493
494 if (!list_empty(&wilc->txq[q_num].txq_head.list))
495 tqe = list_first_entry(&wilc->txq[q_num].txq_head.list,
496 struct txq_entry_t, list);
497
498 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
499
500 return tqe;
501}
502
503static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc,
504 struct txq_entry_t *tqe,
505 u8 q_num)
506{
507 unsigned long flags;
508
509 spin_lock_irqsave(&wilc->txq_spinlock, flags);
510
511 if (!list_is_last(&tqe->list, &wilc->txq[q_num].txq_head.list))
512 tqe = list_next_entry(tqe, list);
513 else
514 tqe = NULL;
515 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
516
517 return tqe;
518}
519
520static void wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe)
521{
522 if (wilc->quit)
523 return;
524
525 mutex_lock(&wilc->rxq_cs);
526 list_add_tail(&rqe->list, &wilc->rxq_head.list);
527 mutex_unlock(&wilc->rxq_cs);
528}
529
530static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
531{
532 struct rxq_entry_t *rqe = NULL;
533
534 mutex_lock(&wilc->rxq_cs);
535 if (!list_empty(&wilc->rxq_head.list)) {
536 rqe = list_first_entry(&wilc->rxq_head.list, struct rxq_entry_t,
537 list);
538 list_del(&rqe->list);
539 }
540 mutex_unlock(&wilc->rxq_cs);
541 return rqe;
542}
543
544static int chip_allow_sleep_wilc1000(struct wilc *wilc)
545{
546 u32 reg = 0;
547 const struct wilc_hif_func *hif_func = wilc->hif_func;
548 u32 wakeup_reg, wakeup_bit;
549 u32 to_host_from_fw_reg, to_host_from_fw_bit;
550 u32 from_host_to_fw_reg, from_host_to_fw_bit;
551 u32 trials = 100;
552 int ret;
553
554 if (wilc->io_type == WILC_HIF_SDIO) {
555 wakeup_reg = WILC_SDIO_WAKEUP_REG;
556 wakeup_bit = WILC_SDIO_WAKEUP_BIT;
557 from_host_to_fw_reg = WILC_SDIO_HOST_TO_FW_REG;
558 from_host_to_fw_bit = WILC_SDIO_HOST_TO_FW_BIT;
559 to_host_from_fw_reg = WILC_SDIO_FW_TO_HOST_REG;
560 to_host_from_fw_bit = WILC_SDIO_FW_TO_HOST_BIT;
561 } else {
562 wakeup_reg = WILC_SPI_WAKEUP_REG;
563 wakeup_bit = WILC_SPI_WAKEUP_BIT;
564 from_host_to_fw_reg = WILC_SPI_HOST_TO_FW_REG;
565 from_host_to_fw_bit = WILC_SPI_HOST_TO_FW_BIT;
566 to_host_from_fw_reg = WILC_SPI_FW_TO_HOST_REG;
567 to_host_from_fw_bit = WILC_SPI_FW_TO_HOST_BIT;
568 }
569
570 while (--trials) {
571 ret = hif_func->hif_read_reg(wilc, to_host_from_fw_reg, ®);
572 if (ret)
573 return ret;
574 if ((reg & to_host_from_fw_bit) == 0)
575 break;
576 }
577 if (!trials)
578 pr_warn("FW not responding\n");
579
580 /* Clear bit 1 */
581 ret = hif_func->hif_read_reg(wilc, wakeup_reg, ®);
582 if (ret)
583 return ret;
584 if (reg & wakeup_bit) {
585 reg &= ~wakeup_bit;
586 ret = hif_func->hif_write_reg(wilc, wakeup_reg, reg);
587 if (ret)
588 return ret;
589 }
590
591 ret = hif_func->hif_read_reg(wilc, from_host_to_fw_reg, ®);
592 if (ret)
593 return ret;
594 if (reg & from_host_to_fw_bit) {
595 reg &= ~from_host_to_fw_bit;
596 ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg, reg);
597 if (ret)
598 return ret;
599 }
600
601 return 0;
602}
603
604static int chip_allow_sleep_wilc3000(struct wilc *wilc)
605{
606 u32 reg = 0;
607 int ret;
608 const struct wilc_hif_func *hif_func = wilc->hif_func;
609
610 if (wilc->io_type == WILC_HIF_SDIO) {
611 ret = hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, ®);
612 if (ret)
613 return ret;
614 ret = hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
615 reg & ~WILC_SDIO_WAKEUP_BIT);
616 if (ret)
617 return ret;
618 } else {
619 ret = hif_func->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, ®);
620 if (ret)
621 return ret;
622 ret = hif_func->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
623 reg & ~WILC_SPI_WAKEUP_BIT);
624 if (ret)
625 return ret;
626 }
627 return 0;
628}
629
630static int chip_allow_sleep(struct wilc *wilc)
631{
632 if (is_wilc1000(wilc->chipid))
633 return chip_allow_sleep_wilc1000(wilc);
634 else
635 return chip_allow_sleep_wilc3000(wilc);
636}
637
638static int chip_wakeup_wilc1000(struct wilc *wilc)
639{
640 u32 ret = 0;
641 u32 clk_status_val = 0, trials = 0;
642 u32 wakeup_reg, wakeup_bit;
643 u32 clk_status_reg, clk_status_bit;
644 u32 from_host_to_fw_reg, from_host_to_fw_bit;
645 const struct wilc_hif_func *hif_func = wilc->hif_func;
646
647 if (wilc->io_type == WILC_HIF_SDIO) {
648 wakeup_reg = WILC_SDIO_WAKEUP_REG;
649 wakeup_bit = WILC_SDIO_WAKEUP_BIT;
650 clk_status_reg = WILC1000_SDIO_CLK_STATUS_REG;
651 clk_status_bit = WILC1000_SDIO_CLK_STATUS_BIT;
652 from_host_to_fw_reg = WILC_SDIO_HOST_TO_FW_REG;
653 from_host_to_fw_bit = WILC_SDIO_HOST_TO_FW_BIT;
654 } else {
655 wakeup_reg = WILC_SPI_WAKEUP_REG;
656 wakeup_bit = WILC_SPI_WAKEUP_BIT;
657 clk_status_reg = WILC1000_SPI_CLK_STATUS_REG;
658 clk_status_bit = WILC1000_SPI_CLK_STATUS_BIT;
659 from_host_to_fw_reg = WILC_SPI_HOST_TO_FW_REG;
660 from_host_to_fw_bit = WILC_SPI_HOST_TO_FW_BIT;
661 }
662
663 /* indicate host wakeup */
664 ret = hif_func->hif_write_reg(wilc, from_host_to_fw_reg,
665 from_host_to_fw_bit);
666 if (ret)
667 return ret;
668
669 /* Set wake-up bit */
670 ret = hif_func->hif_write_reg(wilc, wakeup_reg,
671 wakeup_bit);
672 if (ret)
673 return ret;
674
675 while (trials < WAKE_UP_TRIAL_RETRY) {
676 ret = hif_func->hif_read_reg(wilc, clk_status_reg,
677 &clk_status_val);
678 if (ret) {
679 pr_err("Bus error %d %x\n", ret, clk_status_val);
680 return ret;
681 }
682 if (clk_status_val & clk_status_bit)
683 break;
684
685 trials++;
686 }
687 if (trials >= WAKE_UP_TRIAL_RETRY) {
688 pr_err("Failed to wake-up the chip\n");
689 return -ETIMEDOUT;
690 }
691 /* Sometimes spi fail to read clock regs after reading
692 * writing clockless registers
693 */
694 if (wilc->io_type == WILC_HIF_SPI)
695 wilc->hif_func->hif_reset(wilc);
696
697 return 0;
698}
699
700static int chip_wakeup_wilc3000(struct wilc *wilc)
701{
702 u32 wakeup_reg_val, clk_status_reg_val, trials = 0;
703 u32 wakeup_reg, wakeup_bit;
704 u32 clk_status_reg, clk_status_bit;
705 int wake_seq_trials = 5;
706 const struct wilc_hif_func *hif_func = wilc->hif_func;
707
708 if (wilc->io_type == WILC_HIF_SDIO) {
709 wakeup_reg = WILC_SDIO_WAKEUP_REG;
710 wakeup_bit = WILC_SDIO_WAKEUP_BIT;
711 clk_status_reg = WILC3000_SDIO_CLK_STATUS_REG;
712 clk_status_bit = WILC3000_SDIO_CLK_STATUS_BIT;
713 } else {
714 wakeup_reg = WILC_SPI_WAKEUP_REG;
715 wakeup_bit = WILC_SPI_WAKEUP_BIT;
716 clk_status_reg = WILC3000_SPI_CLK_STATUS_REG;
717 clk_status_bit = WILC3000_SPI_CLK_STATUS_BIT;
718 }
719
720 hif_func->hif_read_reg(wilc, wakeup_reg, &wakeup_reg_val);
721 do {
722 hif_func->hif_write_reg(wilc, wakeup_reg, wakeup_reg_val |
723 wakeup_bit);
724 /* Check the clock status */
725 hif_func->hif_read_reg(wilc, clk_status_reg,
726 &clk_status_reg_val);
727
728 /* In case of clocks off, wait 1ms, and check it again.
729 * if still off, wait for another 1ms, for a total wait of 3ms.
730 * If still off, redo the wake up sequence
731 */
732 while ((clk_status_reg_val & clk_status_bit) == 0 &&
733 (++trials % 4) != 0) {
734 /* Wait for the chip to stabilize*/
735 usleep_range(1000, 1100);
736
737 /* Make sure chip is awake. This is an extra step that
738 * can be removed later to avoid the bus access
739 * overhead
740 */
741 hif_func->hif_read_reg(wilc, clk_status_reg,
742 &clk_status_reg_val);
743 }
744 /* in case of failure, Reset the wakeup bit to introduce a new
745 * edge on the next loop
746 */
747 if ((clk_status_reg_val & clk_status_bit) == 0) {
748 hif_func->hif_write_reg(wilc, wakeup_reg,
749 wakeup_reg_val & (~wakeup_bit));
750 /* added wait before wakeup sequence retry */
751 usleep_range(200, 300);
752 }
753 } while ((clk_status_reg_val & clk_status_bit) == 0 && wake_seq_trials-- > 0);
754 if (!wake_seq_trials)
755 dev_err(wilc->dev, "clocks still OFF. Wake up failed\n");
756
757 return 0;
758}
759
760static int chip_wakeup(struct wilc *wilc)
761{
762 if (is_wilc1000(wilc->chipid))
763 return chip_wakeup_wilc1000(wilc);
764 else
765 return chip_wakeup_wilc3000(wilc);
766}
767
768static inline int acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
769{
770 int ret = 0;
771
772 mutex_lock(&wilc->hif_cs);
773 if (acquire == WILC_BUS_ACQUIRE_AND_WAKEUP && wilc->power_save_mode) {
774 ret = chip_wakeup(wilc);
775 if (ret)
776 mutex_unlock(&wilc->hif_cs);
777 }
778
779 return ret;
780}
781
782static inline int release_bus(struct wilc *wilc, enum bus_release release)
783{
784 int ret = 0;
785
786 if (release == WILC_BUS_RELEASE_ALLOW_SLEEP && wilc->power_save_mode)
787 ret = chip_allow_sleep(wilc);
788 mutex_unlock(&wilc->hif_cs);
789
790 return ret;
791}
792
793int host_wakeup_notify(struct wilc *wilc)
794{
795 int ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
796
797 if (ret)
798 return ret;
799
800 wilc->hif_func->hif_write_reg(wilc, is_wilc1000(wilc->chipid) ?
801 WILC1000_CORTUS_INTERRUPT_2 :
802 WILC3000_CORTUS_INTERRUPT_2, 1);
803 return release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
804}
805EXPORT_SYMBOL_GPL(host_wakeup_notify);
806
807int host_sleep_notify(struct wilc *wilc)
808{
809 int ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
810
811 if (ret)
812 return ret;
813
814 wilc->hif_func->hif_write_reg(wilc, is_wilc1000(wilc->chipid) ?
815 WILC1000_CORTUS_INTERRUPT_1 :
816 WILC3000_CORTUS_INTERRUPT_1, 1);
817 return release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
818}
819EXPORT_SYMBOL_GPL(host_sleep_notify);
820
821int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
822{
823 int i, entries = 0;
824 u8 k, ac;
825 u32 sum;
826 u32 reg;
827 u8 ac_desired_ratio[NQUEUES] = {0, 0, 0, 0};
828 u8 ac_preserve_ratio[NQUEUES] = {1, 1, 1, 1};
829 u8 *num_pkts_to_add;
830 u8 vmm_entries_ac[WILC_VMM_TBL_SIZE];
831 u32 offset = 0;
832 bool max_size_over = 0, ac_exist = 0;
833 int vmm_sz = 0;
834 struct txq_entry_t *tqe_q[NQUEUES];
835 int ret = 0;
836 int counter;
837 int timeout;
838 u32 *vmm_table = wilc->vmm_table;
839 u8 ac_pkt_num_to_chip[NQUEUES] = {0, 0, 0, 0};
840 const struct wilc_hif_func *func;
841 int srcu_idx;
842 u8 *txb = wilc->tx_buffer;
843 struct wilc_vif *vif;
844 int rv;
845
846 if (wilc->quit)
847 goto out_update_cnt;
848
849 if (ac_balance(wilc, ac_desired_ratio))
850 return -EINVAL;
851
852 mutex_lock(&wilc->txq_add_to_head_cs);
853
854 srcu_idx = srcu_read_lock(&wilc->srcu);
855 wilc_for_each_vif(wilc, vif)
856 wilc_wlan_txq_filter_dup_tcp_ack(vif->ndev);
857 srcu_read_unlock(&wilc->srcu, srcu_idx);
858
859 for (ac = 0; ac < NQUEUES; ac++)
860 tqe_q[ac] = wilc_wlan_txq_get_first(wilc, ac);
861
862 i = 0;
863 sum = 0;
864 max_size_over = 0;
865 num_pkts_to_add = ac_desired_ratio;
866 do {
867 ac_exist = 0;
868 for (ac = 0; (ac < NQUEUES) && (!max_size_over); ac++) {
869 if (!tqe_q[ac])
870 continue;
871
872 ac_exist = 1;
873 for (k = 0; (k < num_pkts_to_add[ac]) &&
874 (!max_size_over) && tqe_q[ac]; k++) {
875 if (i >= (WILC_VMM_TBL_SIZE - 1)) {
876 max_size_over = 1;
877 break;
878 }
879
880 if (tqe_q[ac]->type == WILC_CFG_PKT)
881 vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
882 else if (tqe_q[ac]->type == WILC_NET_PKT)
883 vmm_sz = ETH_ETHERNET_HDR_OFFSET;
884 else
885 vmm_sz = HOST_HDR_OFFSET;
886
887 vmm_sz += tqe_q[ac]->buffer_size;
888 vmm_sz = ALIGN(vmm_sz, 4);
889
890 if ((sum + vmm_sz) > WILC_TX_BUFF_SIZE) {
891 max_size_over = 1;
892 break;
893 }
894 vmm_table[i] = vmm_sz / 4;
895 if (tqe_q[ac]->type == WILC_CFG_PKT)
896 vmm_table[i] |= BIT(10);
897
898 cpu_to_le32s(&vmm_table[i]);
899 vmm_entries_ac[i] = ac;
900
901 i++;
902 sum += vmm_sz;
903 tqe_q[ac] = wilc_wlan_txq_get_next(wilc,
904 tqe_q[ac],
905 ac);
906 }
907 }
908 num_pkts_to_add = ac_preserve_ratio;
909 } while (!max_size_over && ac_exist);
910
911 if (i == 0)
912 goto out_unlock;
913 vmm_table[i] = 0x0;
914
915 ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
916 if (ret)
917 goto out_unlock;
918
919 counter = 0;
920 func = wilc->hif_func;
921 do {
922 ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, ®);
923 if (ret)
924 break;
925
926 if ((reg & 0x1) == 0) {
927 ac_update_fw_ac_pkt_info(wilc, reg);
928 break;
929 }
930
931 counter++;
932 if (counter > 200) {
933 counter = 0;
934 ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0);
935 break;
936 }
937 } while (!wilc->quit);
938
939 if (ret)
940 goto out_release_bus;
941
942 timeout = 200;
943 do {
944 ret = func->hif_block_tx(wilc,
945 WILC_VMM_TBL_RX_SHADOW_BASE,
946 (u8 *)vmm_table,
947 ((i + 1) * 4));
948 if (ret)
949 break;
950
951 if (is_wilc1000(wilc->chipid)) {
952 ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
953 if (ret)
954 break;
955
956 do {
957 ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, ®);
958 if (ret)
959 break;
960 if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) {
961 entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
962 break;
963 }
964 } while (--timeout);
965 } else {
966 ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0);
967 if (ret)
968 break;
969
970 /* interrupt firmware */
971 ret = func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_BASE, 1);
972 if (ret)
973 break;
974
975 do {
976 ret = func->hif_read_reg(wilc, WILC_CORTUS_INTERRUPT_BASE, ®);
977 if (ret)
978 break;
979 if (reg == 0) {
980 /* Get the entries */
981 ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, ®);
982 if (ret)
983 break;
984
985 entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
986 break;
987 }
988 } while (--timeout);
989 }
990 if (timeout <= 0) {
991 ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
992 break;
993 }
994
995 if (ret)
996 break;
997
998 if (entries == 0) {
999 ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, ®);
1000 if (ret)
1001 break;
1002 reg &= ~BIT(0);
1003 ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg);
1004 }
1005 } while (0);
1006
1007 if (ret)
1008 goto out_release_bus;
1009
1010 if (entries == 0) {
1011 /*
1012 * No VMM space available in firmware so retry to transmit
1013 * the packet from tx queue.
1014 */
1015 ret = WILC_VMM_ENTRY_FULL_RETRY;
1016 goto out_release_bus;
1017 }
1018
1019 ret = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1020 if (ret)
1021 goto out_unlock;
1022
1023 offset = 0;
1024 i = 0;
1025 do {
1026 struct txq_entry_t *tqe;
1027 u32 header, buffer_offset;
1028 char *bssid;
1029 u8 mgmt_ptk = 0;
1030
1031 if (vmm_table[i] == 0 || vmm_entries_ac[i] >= NQUEUES)
1032 break;
1033
1034 tqe = wilc_wlan_txq_remove_from_head(wilc, vmm_entries_ac[i]);
1035 if (!tqe)
1036 break;
1037
1038 ac_pkt_num_to_chip[vmm_entries_ac[i]]++;
1039 vif = tqe->vif;
1040
1041 le32_to_cpus(&vmm_table[i]);
1042 vmm_sz = FIELD_GET(WILC_VMM_BUFFER_SIZE, vmm_table[i]);
1043 vmm_sz *= 4;
1044
1045 if (tqe->type == WILC_MGMT_PKT)
1046 mgmt_ptk = 1;
1047
1048 header = (FIELD_PREP(WILC_VMM_HDR_TYPE, tqe->type) |
1049 FIELD_PREP(WILC_VMM_HDR_MGMT_FIELD, mgmt_ptk) |
1050 FIELD_PREP(WILC_VMM_HDR_PKT_SIZE, tqe->buffer_size) |
1051 FIELD_PREP(WILC_VMM_HDR_BUFF_SIZE, vmm_sz));
1052
1053 cpu_to_le32s(&header);
1054 memcpy(&txb[offset], &header, 4);
1055 if (tqe->type == WILC_CFG_PKT) {
1056 buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
1057 } else if (tqe->type == WILC_NET_PKT) {
1058 int prio = tqe->q_num;
1059
1060 bssid = tqe->vif->bssid;
1061 buffer_offset = ETH_ETHERNET_HDR_OFFSET;
1062 memcpy(&txb[offset + 4], &prio, sizeof(prio));
1063 memcpy(&txb[offset + 8], bssid, 6);
1064 } else {
1065 buffer_offset = HOST_HDR_OFFSET;
1066 }
1067
1068 memcpy(&txb[offset + buffer_offset],
1069 tqe->buffer, tqe->buffer_size);
1070 offset += vmm_sz;
1071 i++;
1072 tqe->status = 1;
1073 if (tqe->tx_complete_func)
1074 tqe->tx_complete_func(tqe->priv, tqe->status);
1075 if (tqe->ack_idx != NOT_TCP_ACK &&
1076 tqe->ack_idx < MAX_PENDING_ACKS)
1077 vif->ack_filter.pending_acks[tqe->ack_idx].txqe = NULL;
1078 kfree(tqe);
1079 } while (--entries);
1080 for (i = 0; i < NQUEUES; i++)
1081 wilc->txq[i].fw.count += ac_pkt_num_to_chip[i];
1082
1083 ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
1084 if (ret)
1085 goto out_unlock;
1086
1087 ret = func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
1088 if (ret)
1089 goto out_release_bus;
1090
1091 ret = func->hif_block_tx_ext(wilc, 0, txb, offset);
1092
1093out_release_bus:
1094 rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1095 if (!ret && rv)
1096 ret = rv;
1097
1098out_unlock:
1099 mutex_unlock(&wilc->txq_add_to_head_cs);
1100
1101out_update_cnt:
1102 *txq_count = wilc->txq_entries;
1103 return ret;
1104}
1105
1106static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size)
1107{
1108 int offset = 0;
1109 u32 header;
1110 u32 pkt_len, pkt_offset, tp_len;
1111 int is_cfg_packet;
1112 u8 *buff_ptr;
1113
1114 do {
1115 buff_ptr = buffer + offset;
1116 header = get_unaligned_le32(buff_ptr);
1117
1118 is_cfg_packet = FIELD_GET(WILC_PKT_HDR_CONFIG_FIELD, header);
1119 pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
1120 tp_len = FIELD_GET(WILC_PKT_HDR_TOTAL_LEN_FIELD, header);
1121 pkt_len = FIELD_GET(WILC_PKT_HDR_LEN_FIELD, header);
1122
1123 if (pkt_len == 0 || tp_len == 0)
1124 break;
1125
1126 if (pkt_offset & IS_MANAGMEMENT) {
1127 buff_ptr += HOST_HDR_OFFSET;
1128 wilc_wfi_mgmt_rx(wilc, buff_ptr, pkt_len,
1129 pkt_offset & IS_MGMT_AUTH_PKT);
1130 } else {
1131 if (!is_cfg_packet) {
1132 wilc_frmw_to_host(wilc, buff_ptr, pkt_len,
1133 pkt_offset);
1134 } else {
1135 struct wilc_cfg_rsp rsp;
1136
1137 buff_ptr += pkt_offset;
1138
1139 wilc_wlan_cfg_indicate_rx(wilc, buff_ptr,
1140 pkt_len,
1141 &rsp);
1142 if (rsp.type == WILC_CFG_RSP) {
1143 if (wilc->cfg_seq_no == rsp.seq_no)
1144 complete(&wilc->cfg_event);
1145 } else if (rsp.type == WILC_CFG_RSP_STATUS) {
1146 wilc_mac_indicate(wilc);
1147 }
1148 }
1149 }
1150 offset += tp_len;
1151 } while (offset < size);
1152}
1153
1154static void wilc_wlan_handle_rxq(struct wilc *wilc)
1155{
1156 int size;
1157 u8 *buffer;
1158 struct rxq_entry_t *rqe;
1159
1160 while (!wilc->quit) {
1161 rqe = wilc_wlan_rxq_remove(wilc);
1162 if (!rqe)
1163 break;
1164
1165 buffer = rqe->buffer;
1166 size = rqe->buffer_size;
1167 wilc_wlan_handle_rx_buff(wilc, buffer, size);
1168
1169 kfree(rqe);
1170 }
1171 if (wilc->quit)
1172 complete(&wilc->cfg_event);
1173}
1174
1175static void wilc_unknown_isr_ext(struct wilc *wilc)
1176{
1177 wilc->hif_func->hif_clear_int_ext(wilc, 0);
1178}
1179
1180static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
1181{
1182 u32 offset = wilc->rx_buffer_offset;
1183 u8 *buffer = NULL;
1184 u32 size;
1185 u32 retries = 0;
1186 int ret = 0;
1187 struct rxq_entry_t *rqe;
1188
1189 size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, int_status) << 2;
1190
1191 while (!size && retries < 10) {
1192 wilc->hif_func->hif_read_size(wilc, &size);
1193 size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, size) << 2;
1194 retries++;
1195 }
1196
1197 if (size <= 0)
1198 return;
1199
1200 if (WILC_RX_BUFF_SIZE - offset < size)
1201 offset = 0;
1202
1203 buffer = &wilc->rx_buffer[offset];
1204
1205 wilc->hif_func->hif_clear_int_ext(wilc, DATA_INT_CLR | ENABLE_RX_VMM);
1206 ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size);
1207 if (ret)
1208 return;
1209
1210 offset += size;
1211 wilc->rx_buffer_offset = offset;
1212 rqe = kmalloc(sizeof(*rqe), GFP_KERNEL);
1213 if (!rqe)
1214 return;
1215
1216 rqe->buffer = buffer;
1217 rqe->buffer_size = size;
1218 wilc_wlan_rxq_add(wilc, rqe);
1219 wilc_wlan_handle_rxq(wilc);
1220}
1221
1222void wilc_handle_isr(struct wilc *wilc)
1223{
1224 u32 int_status;
1225 int ret;
1226
1227 ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
1228 if (ret) {
1229 dev_err_ratelimited(wilc->dev, "Cannot acquire bus\n");
1230 return;
1231 }
1232
1233 wilc->hif_func->hif_read_int(wilc, &int_status);
1234
1235 if (int_status & DATA_INT_EXT)
1236 wilc_wlan_handle_isr_ext(wilc, int_status);
1237
1238 if (!(int_status & (ALL_INT_EXT)))
1239 wilc_unknown_isr_ext(wilc);
1240
1241 ret = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1242 if (ret)
1243 dev_err_ratelimited(wilc->dev, "Cannot release bus\n");
1244}
1245EXPORT_SYMBOL_GPL(wilc_handle_isr);
1246
1247int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
1248 u32 buffer_size)
1249{
1250 u32 offset;
1251 u32 addr, size, size2, blksz;
1252 u8 *dma_buffer;
1253 int ret = 0;
1254 u32 reg = 0;
1255 int rv;
1256
1257 blksz = BIT(12);
1258
1259 dma_buffer = kmalloc(blksz, GFP_KERNEL);
1260 if (!dma_buffer)
1261 return -EIO;
1262
1263 offset = 0;
1264 pr_debug("%s: Downloading firmware size = %d\n", __func__, buffer_size);
1265
1266 ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
1267 if (ret)
1268 return ret;
1269
1270 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
1271 reg &= ~BIT(10);
1272 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1273 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
1274 if (reg & BIT(10))
1275 pr_err("%s: Failed to reset\n", __func__);
1276
1277 ret = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1278 if (ret)
1279 goto fail;
1280
1281 do {
1282 addr = get_unaligned_le32(&buffer[offset]);
1283 size = get_unaligned_le32(&buffer[offset + 4]);
1284 ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
1285 if (ret)
1286 goto fail;
1287
1288 offset += 8;
1289 while (((int)size) && (offset < buffer_size)) {
1290 if (size <= blksz)
1291 size2 = size;
1292 else
1293 size2 = blksz;
1294
1295 memcpy(dma_buffer, &buffer[offset], size2);
1296 ret = wilc->hif_func->hif_block_tx(wilc, addr,
1297 dma_buffer, size2);
1298 if (ret)
1299 break;
1300
1301 addr += size2;
1302 offset += size2;
1303 size -= size2;
1304 }
1305 rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1306 if (!ret && rv)
1307 ret = rv;
1308
1309 if (ret) {
1310 pr_err("%s Bus error\n", __func__);
1311 goto fail;
1312 }
1313 pr_debug("%s Offset = %d\n", __func__, offset);
1314 } while (offset < buffer_size);
1315
1316fail:
1317
1318 kfree(dma_buffer);
1319
1320 return ret;
1321}
1322
1323int wilc_wlan_start(struct wilc *wilc)
1324{
1325 u32 reg = 0;
1326 int ret, rv;
1327 u32 chipid;
1328
1329 if (wilc->io_type == WILC_HIF_SDIO) {
1330 reg = 0;
1331 reg |= BIT(3);
1332 } else if (wilc->io_type == WILC_HIF_SPI) {
1333 reg = 1;
1334 }
1335 ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
1336 if (ret)
1337 return ret;
1338
1339 ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
1340 if (ret)
1341 goto release;
1342
1343 reg = 0;
1344 if (wilc->io_type == WILC_HIF_SDIO && wilc->dev_irq_num)
1345 reg |= WILC_HAVE_SDIO_IRQ_GPIO;
1346
1347 if (is_wilc3000(wilc->chipid))
1348 reg |= WILC_HAVE_SLEEP_CLK_SRC_RTC;
1349
1350 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
1351 if (ret)
1352 goto release;
1353
1354 wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT);
1355
1356 ret = wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
1357 if (ret)
1358 goto release;
1359
1360 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
1361 if ((reg & BIT(10)) == BIT(10)) {
1362 reg &= ~BIT(10);
1363 wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1364 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
1365 }
1366
1367 reg |= BIT(10);
1368 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1369 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
1370
1371release:
1372 rv = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1373 return ret ? ret : rv;
1374}
1375
1376int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
1377{
1378 u32 reg = 0;
1379 int ret, rv;
1380
1381 ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
1382 if (ret)
1383 return ret;
1384
1385 ret = wilc->hif_func->hif_read_reg(wilc, GLOBAL_MODE_CONTROL, ®);
1386 if (ret)
1387 goto release;
1388
1389 reg &= ~WILC_GLOBAL_MODE_ENABLE_WIFI;
1390 ret = wilc->hif_func->hif_write_reg(wilc, GLOBAL_MODE_CONTROL, reg);
1391 if (ret)
1392 goto release;
1393
1394 ret = wilc->hif_func->hif_read_reg(wilc, PWR_SEQ_MISC_CTRL, ®);
1395 if (ret)
1396 goto release;
1397
1398 reg &= ~WILC_PWR_SEQ_ENABLE_WIFI_SLEEP;
1399 ret = wilc->hif_func->hif_write_reg(wilc, PWR_SEQ_MISC_CTRL, reg);
1400 if (ret)
1401 goto release;
1402
1403 ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, ®);
1404 if (ret) {
1405 netdev_err(vif->ndev, "Error while reading reg\n");
1406 goto release;
1407 }
1408
1409 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0,
1410 (reg | WILC_ABORT_REQ_BIT));
1411 if (ret) {
1412 netdev_err(vif->ndev, "Error while writing reg\n");
1413 goto release;
1414 }
1415
1416 ret = 0;
1417release:
1418 /* host comm is disabled - we can't issue sleep command anymore: */
1419 rv = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1420
1421 return ret ? ret : rv;
1422}
1423
1424void wilc_wlan_cleanup(struct net_device *dev)
1425{
1426 struct txq_entry_t *tqe;
1427 struct rxq_entry_t *rqe;
1428 u8 ac;
1429 struct wilc_vif *vif = netdev_priv(dev);
1430 struct wilc *wilc = vif->wilc;
1431
1432 wilc->quit = 1;
1433 for (ac = 0; ac < NQUEUES; ac++) {
1434 while ((tqe = wilc_wlan_txq_remove_from_head(wilc, ac))) {
1435 if (tqe->tx_complete_func)
1436 tqe->tx_complete_func(tqe->priv, 0);
1437 kfree(tqe);
1438 }
1439 }
1440
1441 while ((rqe = wilc_wlan_rxq_remove(wilc)))
1442 kfree(rqe);
1443
1444 kfree(wilc->vmm_table);
1445 wilc->vmm_table = NULL;
1446 kfree(wilc->rx_buffer);
1447 wilc->rx_buffer = NULL;
1448 kfree(wilc->tx_buffer);
1449 wilc->tx_buffer = NULL;
1450 wilc->hif_func->hif_deinit(wilc);
1451}
1452
1453static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type,
1454 u32 drv_handler)
1455{
1456 struct wilc *wilc = vif->wilc;
1457 struct wilc_cfg_frame *cfg = &wilc->cfg_frame;
1458 int t_len = wilc->cfg_frame_offset + sizeof(struct wilc_cfg_cmd_hdr);
1459
1460 if (type == WILC_CFG_SET)
1461 cfg->hdr.cmd_type = 'W';
1462 else
1463 cfg->hdr.cmd_type = 'Q';
1464
1465 cfg->hdr.seq_no = wilc->cfg_seq_no % 256;
1466 cfg->hdr.total_len = cpu_to_le16(t_len);
1467 cfg->hdr.driver_handler = cpu_to_le32(drv_handler);
1468 wilc->cfg_seq_no = cfg->hdr.seq_no;
1469
1470 if (!wilc_wlan_txq_add_cfg_pkt(vif, (u8 *)&cfg->hdr, t_len))
1471 return -1;
1472
1473 return 0;
1474}
1475
1476int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
1477 u32 buffer_size, int commit, u32 drv_handler)
1478{
1479 u32 offset;
1480 int ret_size;
1481 struct wilc *wilc = vif->wilc;
1482
1483 mutex_lock(&wilc->cfg_cmd_lock);
1484
1485 if (start)
1486 wilc->cfg_frame_offset = 0;
1487
1488 offset = wilc->cfg_frame_offset;
1489 ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset,
1490 wid, buffer, buffer_size);
1491 offset += ret_size;
1492 wilc->cfg_frame_offset = offset;
1493
1494 if (!commit) {
1495 mutex_unlock(&wilc->cfg_cmd_lock);
1496 return ret_size;
1497 }
1498
1499 netdev_dbg(vif->ndev, "%s: seqno[%d]\n", __func__, wilc->cfg_seq_no);
1500
1501 if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler))
1502 ret_size = 0;
1503
1504 if (!wait_for_completion_timeout(&wilc->cfg_event,
1505 WILC_CFG_PKTS_TIMEOUT)) {
1506 netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
1507 ret_size = 0;
1508 }
1509
1510 wilc->cfg_frame_offset = 0;
1511 wilc->cfg_seq_no += 1;
1512 mutex_unlock(&wilc->cfg_cmd_lock);
1513
1514 return ret_size;
1515}
1516
1517int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit,
1518 u32 drv_handler)
1519{
1520 u32 offset;
1521 int ret_size;
1522 struct wilc *wilc = vif->wilc;
1523
1524 mutex_lock(&wilc->cfg_cmd_lock);
1525
1526 if (start)
1527 wilc->cfg_frame_offset = 0;
1528
1529 offset = wilc->cfg_frame_offset;
1530 ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset, wid);
1531 offset += ret_size;
1532 wilc->cfg_frame_offset = offset;
1533
1534 if (!commit) {
1535 mutex_unlock(&wilc->cfg_cmd_lock);
1536 return ret_size;
1537 }
1538
1539 if (wilc_wlan_cfg_commit(vif, WILC_CFG_QUERY, drv_handler))
1540 ret_size = 0;
1541
1542 if (!wait_for_completion_timeout(&wilc->cfg_event,
1543 WILC_CFG_PKTS_TIMEOUT)) {
1544 netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
1545 ret_size = 0;
1546 }
1547 wilc->cfg_frame_offset = 0;
1548 wilc->cfg_seq_no += 1;
1549 mutex_unlock(&wilc->cfg_cmd_lock);
1550
1551 return ret_size;
1552}
1553
1554int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
1555 u32 count)
1556{
1557 int i;
1558 int ret = 0;
1559 u32 drv = wilc_get_vif_idx(vif);
1560
1561 if (mode == WILC_GET_CFG) {
1562 for (i = 0; i < count; i++) {
1563 if (!wilc_wlan_cfg_get(vif, !i,
1564 wids[i].id,
1565 (i == count - 1),
1566 drv)) {
1567 ret = -ETIMEDOUT;
1568 break;
1569 }
1570 }
1571 for (i = 0; i < count; i++) {
1572 wids[i].size = wilc_wlan_cfg_get_val(vif->wilc,
1573 wids[i].id,
1574 wids[i].val,
1575 wids[i].size);
1576 }
1577 } else if (mode == WILC_SET_CFG) {
1578 for (i = 0; i < count; i++) {
1579 if (!wilc_wlan_cfg_set(vif, !i,
1580 wids[i].id,
1581 wids[i].val,
1582 wids[i].size,
1583 (i == count - 1),
1584 drv)) {
1585 ret = -ETIMEDOUT;
1586 break;
1587 }
1588 }
1589 }
1590
1591 return ret;
1592}
1593
1594int wilc_get_chipid(struct wilc *wilc)
1595{
1596 u32 chipid = 0;
1597 u32 rfrevid = 0;
1598
1599 if (wilc->chipid == 0) {
1600 wilc->hif_func->hif_read_reg(wilc, WILC3000_CHIP_ID, &chipid);
1601 if (!is_wilc3000(chipid)) {
1602 wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
1603 wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID,
1604 &rfrevid);
1605
1606 if (!is_wilc1000(chipid)) {
1607 wilc->chipid = 0;
1608 return -EINVAL;
1609 }
1610 if (chipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */
1611 if (rfrevid != 0x1)
1612 chipid = WILC_1000_BASE_ID_2A_REV1;
1613 } else if (chipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */
1614 if (rfrevid == 0x4)
1615 chipid = WILC_1000_BASE_ID_2B_REV1;
1616 else if (rfrevid != 0x3)
1617 chipid = WILC_1000_BASE_ID_2B_REV2;
1618 }
1619 }
1620
1621 wilc->chipid = chipid;
1622 }
1623
1624 return 0;
1625}
1626EXPORT_SYMBOL_GPL(wilc_get_chipid);
1627
1628static int init_chip(struct net_device *dev)
1629{
1630 u32 reg;
1631 int ret, rv;
1632 struct wilc_vif *vif = netdev_priv(dev);
1633 struct wilc *wilc = vif->wilc;
1634
1635 ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
1636 if (ret)
1637 return ret;
1638
1639 ret = wilc_get_chipid(wilc);
1640 if (ret)
1641 goto release;
1642
1643 if ((wilc->chipid & 0xfff) != 0xa0) {
1644 ret = wilc->hif_func->hif_read_reg(wilc,
1645 WILC_CORTUS_RESET_MUX_SEL,
1646 ®);
1647 if (ret) {
1648 netdev_err(dev, "fail read reg 0x1118\n");
1649 goto release;
1650 }
1651 reg |= BIT(0);
1652 ret = wilc->hif_func->hif_write_reg(wilc,
1653 WILC_CORTUS_RESET_MUX_SEL,
1654 reg);
1655 if (ret) {
1656 netdev_err(dev, "fail write reg 0x1118\n");
1657 goto release;
1658 }
1659 ret = wilc->hif_func->hif_write_reg(wilc,
1660 WILC_CORTUS_BOOT_REGISTER,
1661 WILC_CORTUS_BOOT_FROM_IRAM);
1662 if (ret) {
1663 netdev_err(dev, "fail write reg 0xc0000\n");
1664 goto release;
1665 }
1666 }
1667
1668 if (is_wilc3000(wilc->chipid)) {
1669 ret = wilc->hif_func->hif_read_reg(wilc, WILC3000_BOOTROM_STATUS, ®);
1670 if (ret) {
1671 netdev_err(dev, "failed to read WILC3000 BootROM status register\n");
1672 goto release;
1673 }
1674
1675 ret = wilc->hif_func->hif_write_reg(wilc, WILC3000_CORTUS_BOOT_REGISTER_2,
1676 WILC_CORTUS_BOOT_FROM_IRAM);
1677 if (ret) {
1678 netdev_err(dev, "failed to write WILC3000 Boot register\n");
1679 goto release;
1680 }
1681 }
1682
1683release:
1684 rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
1685
1686 return ret ? ret : rv;
1687}
1688
1689int wilc_load_mac_from_nv(struct wilc *wl)
1690{
1691 int ret, rv;
1692 unsigned int i;
1693
1694 ret = acquire_bus(wl, WILC_BUS_ACQUIRE_AND_WAKEUP);
1695 if (ret)
1696 return ret;
1697
1698 for (i = 0; i < WILC_NVMEM_MAX_NUM_BANK; i++) {
1699 int bank_offset = get_bank_offset_from_bank_index(i);
1700 u32 reg1, reg2;
1701 u8 invalid;
1702 u8 used;
1703
1704 ret = wl->hif_func->hif_read_reg(wl,
1705 WILC_NVMEM_BANK_BASE + bank_offset,
1706 ®1);
1707 if (ret) {
1708 pr_err("Can not read address %d lower part", i);
1709 break;
1710 }
1711 ret = wl->hif_func->hif_read_reg(wl,
1712 WILC_NVMEM_BANK_BASE + bank_offset + 4,
1713 ®2);
1714 if (ret) {
1715 pr_err("Can not read address %d upper part", i);
1716 break;
1717 }
1718
1719 used = FIELD_GET(WILC_NVMEM_IS_BANK_USED, reg1);
1720 invalid = FIELD_GET(WILC_NVMEM_IS_BANK_INVALID, reg1);
1721 if (!used || invalid)
1722 continue;
1723
1724 wl->nv_mac_address[0] = FIELD_GET(GENMASK(23, 16), reg1);
1725 wl->nv_mac_address[1] = FIELD_GET(GENMASK(15, 8), reg1);
1726 wl->nv_mac_address[2] = FIELD_GET(GENMASK(7, 0), reg1);
1727 wl->nv_mac_address[3] = FIELD_GET(GENMASK(31, 24), reg2);
1728 wl->nv_mac_address[4] = FIELD_GET(GENMASK(23, 16), reg2);
1729 wl->nv_mac_address[5] = FIELD_GET(GENMASK(15, 8), reg2);
1730
1731 ret = 0;
1732 break;
1733 }
1734
1735 rv = release_bus(wl, WILC_BUS_RELEASE_ALLOW_SLEEP);
1736 return ret ? ret : rv;
1737}
1738EXPORT_SYMBOL_GPL(wilc_load_mac_from_nv);
1739
1740int wilc_wlan_init(struct net_device *dev)
1741{
1742 int ret = 0, rv;
1743 struct wilc_vif *vif = netdev_priv(dev);
1744 struct wilc *wilc;
1745
1746 wilc = vif->wilc;
1747
1748 wilc->quit = 0;
1749
1750 if (!wilc->hif_func->hif_is_init(wilc)) {
1751 ret = acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
1752 if (ret)
1753 return ret;
1754
1755 ret = wilc->hif_func->hif_init(wilc, false);
1756 if (!ret)
1757 ret = wilc_get_chipid(wilc);
1758 rv = release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1759 if (!ret && rv)
1760 ret = rv;
1761 if (ret)
1762 goto fail;
1763
1764 if (!is_wilc1000(wilc->chipid) && !is_wilc3000(wilc->chipid)) {
1765 netdev_err(dev, "Unsupported chipid: %x\n", wilc->chipid);
1766 ret = -EINVAL;
1767 goto fail;
1768 }
1769
1770 netdev_dbg(dev, "chipid (%08x)\n", wilc->chipid);
1771 }
1772
1773 if (!wilc->vmm_table)
1774 wilc->vmm_table = kcalloc(WILC_VMM_TBL_SIZE, sizeof(u32), GFP_KERNEL);
1775
1776 if (!wilc->vmm_table) {
1777 ret = -ENOBUFS;
1778 goto fail;
1779 }
1780
1781 if (!wilc->tx_buffer)
1782 wilc->tx_buffer = kmalloc(WILC_TX_BUFF_SIZE, GFP_KERNEL);
1783
1784 if (!wilc->tx_buffer) {
1785 ret = -ENOBUFS;
1786 goto fail;
1787 }
1788
1789 if (!wilc->rx_buffer)
1790 wilc->rx_buffer = kmalloc(WILC_RX_BUFF_SIZE, GFP_KERNEL);
1791
1792 if (!wilc->rx_buffer) {
1793 ret = -ENOBUFS;
1794 goto fail;
1795 }
1796
1797 if (init_chip(dev)) {
1798 ret = -EIO;
1799 goto fail;
1800 }
1801
1802 return 0;
1803
1804fail:
1805 kfree(wilc->vmm_table);
1806 wilc->vmm_table = NULL;
1807 kfree(wilc->rx_buffer);
1808 wilc->rx_buffer = NULL;
1809 kfree(wilc->tx_buffer);
1810 wilc->tx_buffer = NULL;
1811
1812 return ret;
1813}
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 "cfg80211.h"
10#include "wlan_cfg.h"
11
12static inline bool is_wilc1000(u32 id)
13{
14 return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID;
15}
16
17static inline void acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
18{
19 mutex_lock(&wilc->hif_cs);
20 if (acquire == WILC_BUS_ACQUIRE_AND_WAKEUP)
21 chip_wakeup(wilc);
22}
23
24static inline void release_bus(struct wilc *wilc, enum bus_release release)
25{
26 if (release == WILC_BUS_RELEASE_ALLOW_SLEEP)
27 chip_allow_sleep(wilc);
28 mutex_unlock(&wilc->hif_cs);
29}
30
31static void wilc_wlan_txq_remove(struct wilc *wilc, struct txq_entry_t *tqe)
32{
33 list_del(&tqe->list);
34 wilc->txq_entries -= 1;
35}
36
37static struct txq_entry_t *
38wilc_wlan_txq_remove_from_head(struct net_device *dev)
39{
40 struct txq_entry_t *tqe = NULL;
41 unsigned long flags;
42 struct wilc_vif *vif = netdev_priv(dev);
43 struct wilc *wilc = vif->wilc;
44
45 spin_lock_irqsave(&wilc->txq_spinlock, flags);
46
47 if (!list_empty(&wilc->txq_head.list)) {
48 tqe = list_first_entry(&wilc->txq_head.list, struct txq_entry_t,
49 list);
50 list_del(&tqe->list);
51 wilc->txq_entries -= 1;
52 }
53 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
54 return tqe;
55}
56
57static void wilc_wlan_txq_add_to_tail(struct net_device *dev,
58 struct txq_entry_t *tqe)
59{
60 unsigned long flags;
61 struct wilc_vif *vif = netdev_priv(dev);
62 struct wilc *wilc = vif->wilc;
63
64 spin_lock_irqsave(&wilc->txq_spinlock, flags);
65
66 list_add_tail(&tqe->list, &wilc->txq_head.list);
67 wilc->txq_entries += 1;
68
69 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
70
71 complete(&wilc->txq_event);
72}
73
74static void wilc_wlan_txq_add_to_head(struct wilc_vif *vif,
75 struct txq_entry_t *tqe)
76{
77 unsigned long flags;
78 struct wilc *wilc = vif->wilc;
79
80 mutex_lock(&wilc->txq_add_to_head_cs);
81
82 spin_lock_irqsave(&wilc->txq_spinlock, flags);
83
84 list_add(&tqe->list, &wilc->txq_head.list);
85 wilc->txq_entries += 1;
86
87 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
88 mutex_unlock(&wilc->txq_add_to_head_cs);
89 complete(&wilc->txq_event);
90}
91
92#define NOT_TCP_ACK (-1)
93
94static inline void add_tcp_session(struct wilc_vif *vif, u32 src_prt,
95 u32 dst_prt, u32 seq)
96{
97 struct tcp_ack_filter *f = &vif->ack_filter;
98
99 if (f->tcp_session < 2 * MAX_TCP_SESSION) {
100 f->ack_session_info[f->tcp_session].seq_num = seq;
101 f->ack_session_info[f->tcp_session].bigger_ack_num = 0;
102 f->ack_session_info[f->tcp_session].src_port = src_prt;
103 f->ack_session_info[f->tcp_session].dst_port = dst_prt;
104 f->tcp_session++;
105 }
106}
107
108static inline void update_tcp_session(struct wilc_vif *vif, u32 index, u32 ack)
109{
110 struct tcp_ack_filter *f = &vif->ack_filter;
111
112 if (index < 2 * MAX_TCP_SESSION &&
113 ack > f->ack_session_info[index].bigger_ack_num)
114 f->ack_session_info[index].bigger_ack_num = ack;
115}
116
117static inline void add_tcp_pending_ack(struct wilc_vif *vif, u32 ack,
118 u32 session_index,
119 struct txq_entry_t *txqe)
120{
121 struct tcp_ack_filter *f = &vif->ack_filter;
122 u32 i = f->pending_base + f->pending_acks_idx;
123
124 if (i < MAX_PENDING_ACKS) {
125 f->pending_acks[i].ack_num = ack;
126 f->pending_acks[i].txqe = txqe;
127 f->pending_acks[i].session_index = session_index;
128 txqe->ack_idx = i;
129 f->pending_acks_idx++;
130 }
131}
132
133static inline void tcp_process(struct net_device *dev, struct txq_entry_t *tqe)
134{
135 void *buffer = tqe->buffer;
136 const struct ethhdr *eth_hdr_ptr = buffer;
137 int i;
138 unsigned long flags;
139 struct wilc_vif *vif = netdev_priv(dev);
140 struct wilc *wilc = vif->wilc;
141 struct tcp_ack_filter *f = &vif->ack_filter;
142 const struct iphdr *ip_hdr_ptr;
143 const struct tcphdr *tcp_hdr_ptr;
144 u32 ihl, total_length, data_offset;
145
146 spin_lock_irqsave(&wilc->txq_spinlock, flags);
147
148 if (eth_hdr_ptr->h_proto != htons(ETH_P_IP))
149 goto out;
150
151 ip_hdr_ptr = buffer + ETH_HLEN;
152
153 if (ip_hdr_ptr->protocol != IPPROTO_TCP)
154 goto out;
155
156 ihl = ip_hdr_ptr->ihl << 2;
157 tcp_hdr_ptr = buffer + ETH_HLEN + ihl;
158 total_length = ntohs(ip_hdr_ptr->tot_len);
159
160 data_offset = tcp_hdr_ptr->doff << 2;
161 if (total_length == (ihl + data_offset)) {
162 u32 seq_no, ack_no;
163
164 seq_no = ntohl(tcp_hdr_ptr->seq);
165 ack_no = ntohl(tcp_hdr_ptr->ack_seq);
166 for (i = 0; i < f->tcp_session; i++) {
167 u32 j = f->ack_session_info[i].seq_num;
168
169 if (i < 2 * MAX_TCP_SESSION &&
170 j == seq_no) {
171 update_tcp_session(vif, i, ack_no);
172 break;
173 }
174 }
175 if (i == f->tcp_session)
176 add_tcp_session(vif, 0, 0, seq_no);
177
178 add_tcp_pending_ack(vif, ack_no, i, tqe);
179 }
180
181out:
182 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
183}
184
185static void wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
186{
187 struct wilc_vif *vif = netdev_priv(dev);
188 struct wilc *wilc = vif->wilc;
189 struct tcp_ack_filter *f = &vif->ack_filter;
190 u32 i = 0;
191 u32 dropped = 0;
192 unsigned long flags;
193
194 spin_lock_irqsave(&wilc->txq_spinlock, flags);
195 for (i = f->pending_base;
196 i < (f->pending_base + f->pending_acks_idx); i++) {
197 u32 index;
198 u32 bigger_ack_num;
199
200 if (i >= MAX_PENDING_ACKS)
201 break;
202
203 index = f->pending_acks[i].session_index;
204
205 if (index >= 2 * MAX_TCP_SESSION)
206 break;
207
208 bigger_ack_num = f->ack_session_info[index].bigger_ack_num;
209
210 if (f->pending_acks[i].ack_num < bigger_ack_num) {
211 struct txq_entry_t *tqe;
212
213 tqe = f->pending_acks[i].txqe;
214 if (tqe) {
215 wilc_wlan_txq_remove(wilc, tqe);
216 tqe->status = 1;
217 if (tqe->tx_complete_func)
218 tqe->tx_complete_func(tqe->priv,
219 tqe->status);
220 kfree(tqe);
221 dropped++;
222 }
223 }
224 }
225 f->pending_acks_idx = 0;
226 f->tcp_session = 0;
227
228 if (f->pending_base == 0)
229 f->pending_base = MAX_TCP_SESSION;
230 else
231 f->pending_base = 0;
232
233 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
234
235 while (dropped > 0) {
236 wait_for_completion_timeout(&wilc->txq_event,
237 msecs_to_jiffies(1));
238 dropped--;
239 }
240}
241
242void wilc_enable_tcp_ack_filter(struct wilc_vif *vif, bool value)
243{
244 vif->ack_filter.enabled = value;
245}
246
247static int wilc_wlan_txq_add_cfg_pkt(struct wilc_vif *vif, u8 *buffer,
248 u32 buffer_size)
249{
250 struct txq_entry_t *tqe;
251 struct wilc *wilc = vif->wilc;
252
253 netdev_dbg(vif->ndev, "Adding config packet ...\n");
254 if (wilc->quit) {
255 netdev_dbg(vif->ndev, "Return due to clear function\n");
256 complete(&wilc->cfg_event);
257 return 0;
258 }
259
260 tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
261 if (!tqe)
262 return 0;
263
264 tqe->type = WILC_CFG_PKT;
265 tqe->buffer = buffer;
266 tqe->buffer_size = buffer_size;
267 tqe->tx_complete_func = NULL;
268 tqe->priv = NULL;
269 tqe->ack_idx = NOT_TCP_ACK;
270 tqe->vif = vif;
271
272 wilc_wlan_txq_add_to_head(vif, tqe);
273
274 return 1;
275}
276
277int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
278 u32 buffer_size,
279 void (*tx_complete_fn)(void *, int))
280{
281 struct txq_entry_t *tqe;
282 struct wilc_vif *vif = netdev_priv(dev);
283 struct wilc *wilc;
284
285 wilc = vif->wilc;
286
287 if (wilc->quit)
288 return 0;
289
290 tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
291
292 if (!tqe)
293 return 0;
294 tqe->type = WILC_NET_PKT;
295 tqe->buffer = buffer;
296 tqe->buffer_size = buffer_size;
297 tqe->tx_complete_func = tx_complete_fn;
298 tqe->priv = priv;
299 tqe->vif = vif;
300
301 tqe->ack_idx = NOT_TCP_ACK;
302 if (vif->ack_filter.enabled)
303 tcp_process(dev, tqe);
304 wilc_wlan_txq_add_to_tail(dev, tqe);
305 return wilc->txq_entries;
306}
307
308int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
309 u32 buffer_size,
310 void (*tx_complete_fn)(void *, int))
311{
312 struct txq_entry_t *tqe;
313 struct wilc_vif *vif = netdev_priv(dev);
314 struct wilc *wilc;
315
316 wilc = vif->wilc;
317
318 if (wilc->quit)
319 return 0;
320
321 tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
322
323 if (!tqe)
324 return 0;
325 tqe->type = WILC_MGMT_PKT;
326 tqe->buffer = buffer;
327 tqe->buffer_size = buffer_size;
328 tqe->tx_complete_func = tx_complete_fn;
329 tqe->priv = priv;
330 tqe->ack_idx = NOT_TCP_ACK;
331 tqe->vif = vif;
332 wilc_wlan_txq_add_to_tail(dev, tqe);
333 return 1;
334}
335
336static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc)
337{
338 struct txq_entry_t *tqe = NULL;
339 unsigned long flags;
340
341 spin_lock_irqsave(&wilc->txq_spinlock, flags);
342
343 if (!list_empty(&wilc->txq_head.list))
344 tqe = list_first_entry(&wilc->txq_head.list, struct txq_entry_t,
345 list);
346
347 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
348
349 return tqe;
350}
351
352static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc,
353 struct txq_entry_t *tqe)
354{
355 unsigned long flags;
356
357 spin_lock_irqsave(&wilc->txq_spinlock, flags);
358
359 if (!list_is_last(&tqe->list, &wilc->txq_head.list))
360 tqe = list_next_entry(tqe, list);
361 else
362 tqe = NULL;
363 spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
364
365 return tqe;
366}
367
368static void wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe)
369{
370 if (wilc->quit)
371 return;
372
373 mutex_lock(&wilc->rxq_cs);
374 list_add_tail(&rqe->list, &wilc->rxq_head.list);
375 mutex_unlock(&wilc->rxq_cs);
376}
377
378static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
379{
380 struct rxq_entry_t *rqe = NULL;
381
382 mutex_lock(&wilc->rxq_cs);
383 if (!list_empty(&wilc->rxq_head.list)) {
384 rqe = list_first_entry(&wilc->rxq_head.list, struct rxq_entry_t,
385 list);
386 list_del(&rqe->list);
387 }
388 mutex_unlock(&wilc->rxq_cs);
389 return rqe;
390}
391
392void chip_allow_sleep(struct wilc *wilc)
393{
394 u32 reg = 0;
395
396 wilc->hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, ®);
397
398 wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
399 reg & ~WILC_SDIO_WAKEUP_BIT);
400 wilc->hif_func->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG, 0);
401}
402EXPORT_SYMBOL_GPL(chip_allow_sleep);
403
404void chip_wakeup(struct wilc *wilc)
405{
406 u32 reg, clk_status_reg;
407 const struct wilc_hif_func *h = wilc->hif_func;
408
409 if (wilc->io_type == WILC_HIF_SPI) {
410 do {
411 h->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, ®);
412 h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
413 reg | WILC_SPI_WAKEUP_BIT);
414 h->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
415 reg & ~WILC_SPI_WAKEUP_BIT);
416
417 do {
418 usleep_range(2000, 2500);
419 wilc_get_chipid(wilc, true);
420 } while (wilc_get_chipid(wilc, true) == 0);
421 } while (wilc_get_chipid(wilc, true) == 0);
422 } else if (wilc->io_type == WILC_HIF_SDIO) {
423 h->hif_write_reg(wilc, WILC_SDIO_HOST_TO_FW_REG,
424 WILC_SDIO_HOST_TO_FW_BIT);
425 usleep_range(200, 400);
426 h->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, ®);
427 do {
428 h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
429 reg | WILC_SDIO_WAKEUP_BIT);
430 h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
431 &clk_status_reg);
432
433 while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
434 usleep_range(2000, 2500);
435
436 h->hif_read_reg(wilc, WILC_SDIO_CLK_STATUS_REG,
437 &clk_status_reg);
438 }
439 if (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT)) {
440 h->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
441 reg & ~WILC_SDIO_WAKEUP_BIT);
442 }
443 } while (!(clk_status_reg & WILC_SDIO_CLK_STATUS_BIT));
444 }
445
446 if (wilc->chip_ps_state == WILC_CHIP_SLEEPING_MANUAL) {
447 if (wilc_get_chipid(wilc, false) < WILC_1000_BASE_ID_2B) {
448 u32 val32;
449
450 h->hif_read_reg(wilc, WILC_REG_4_TO_1_RX, &val32);
451 val32 |= BIT(6);
452 h->hif_write_reg(wilc, WILC_REG_4_TO_1_RX, val32);
453
454 h->hif_read_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, &val32);
455 val32 |= BIT(6);
456 h->hif_write_reg(wilc, WILC_REG_4_TO_1_TX_BANK0, val32);
457 }
458 }
459 wilc->chip_ps_state = WILC_CHIP_WAKEDUP;
460}
461EXPORT_SYMBOL_GPL(chip_wakeup);
462
463void host_wakeup_notify(struct wilc *wilc)
464{
465 acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
466 wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_2, 1);
467 release_bus(wilc, WILC_BUS_RELEASE_ONLY);
468}
469EXPORT_SYMBOL_GPL(host_wakeup_notify);
470
471void host_sleep_notify(struct wilc *wilc)
472{
473 acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
474 wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_1, 1);
475 release_bus(wilc, WILC_BUS_RELEASE_ONLY);
476}
477EXPORT_SYMBOL_GPL(host_sleep_notify);
478
479int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
480{
481 int i, entries = 0;
482 u32 sum;
483 u32 reg;
484 u32 offset = 0;
485 int vmm_sz = 0;
486 struct txq_entry_t *tqe;
487 int ret = 0;
488 int counter;
489 int timeout;
490 u32 vmm_table[WILC_VMM_TBL_SIZE];
491 const struct wilc_hif_func *func;
492 u8 *txb = wilc->tx_buffer;
493 struct net_device *dev;
494 struct wilc_vif *vif;
495
496 if (wilc->quit)
497 goto out_update_cnt;
498
499 mutex_lock(&wilc->txq_add_to_head_cs);
500 tqe = wilc_wlan_txq_get_first(wilc);
501 if (!tqe)
502 goto out_unlock;
503 dev = tqe->vif->ndev;
504 wilc_wlan_txq_filter_dup_tcp_ack(dev);
505 i = 0;
506 sum = 0;
507 while (tqe && (i < (WILC_VMM_TBL_SIZE - 1))) {
508 if (tqe->type == WILC_CFG_PKT)
509 vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
510 else if (tqe->type == WILC_NET_PKT)
511 vmm_sz = ETH_ETHERNET_HDR_OFFSET;
512 else
513 vmm_sz = HOST_HDR_OFFSET;
514
515 vmm_sz += tqe->buffer_size;
516 vmm_sz = ALIGN(vmm_sz, 4);
517
518 if ((sum + vmm_sz) > WILC_TX_BUFF_SIZE)
519 break;
520
521 vmm_table[i] = vmm_sz / 4;
522 if (tqe->type == WILC_CFG_PKT)
523 vmm_table[i] |= BIT(10);
524 cpu_to_le32s(&vmm_table[i]);
525
526 i++;
527 sum += vmm_sz;
528 tqe = wilc_wlan_txq_get_next(wilc, tqe);
529 }
530
531 if (i == 0)
532 goto out_unlock;
533 vmm_table[i] = 0x0;
534
535 acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
536 counter = 0;
537 func = wilc->hif_func;
538 do {
539 ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, ®);
540 if (ret)
541 break;
542
543 if ((reg & 0x1) == 0)
544 break;
545
546 counter++;
547 if (counter > 200) {
548 counter = 0;
549 ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0);
550 break;
551 }
552 } while (!wilc->quit);
553
554 if (ret)
555 goto out_release_bus;
556
557 timeout = 200;
558 do {
559 ret = func->hif_block_tx(wilc,
560 WILC_VMM_TBL_RX_SHADOW_BASE,
561 (u8 *)vmm_table,
562 ((i + 1) * 4));
563 if (ret)
564 break;
565
566 ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
567 if (ret)
568 break;
569
570 do {
571 ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, ®);
572 if (ret)
573 break;
574 if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) {
575 entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
576 break;
577 }
578 } while (--timeout);
579 if (timeout <= 0) {
580 ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
581 break;
582 }
583
584 if (ret)
585 break;
586
587 if (entries == 0) {
588 ret = func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, ®);
589 if (ret)
590 break;
591 reg &= ~BIT(0);
592 ret = func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg);
593 }
594 } while (0);
595
596 if (ret)
597 goto out_release_bus;
598
599 if (entries == 0) {
600 /*
601 * No VMM space available in firmware so retry to transmit
602 * the packet from tx queue.
603 */
604 ret = WILC_VMM_ENTRY_FULL_RETRY;
605 goto out_release_bus;
606 }
607
608 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
609
610 offset = 0;
611 i = 0;
612 do {
613 u32 header, buffer_offset;
614 char *bssid;
615 u8 mgmt_ptk = 0;
616
617 tqe = wilc_wlan_txq_remove_from_head(dev);
618 if (!tqe)
619 break;
620
621 vif = tqe->vif;
622 if (vmm_table[i] == 0)
623 break;
624
625 le32_to_cpus(&vmm_table[i]);
626 vmm_sz = FIELD_GET(WILC_VMM_BUFFER_SIZE, vmm_table[i]);
627 vmm_sz *= 4;
628
629 if (tqe->type == WILC_MGMT_PKT)
630 mgmt_ptk = 1;
631
632 header = (FIELD_PREP(WILC_VMM_HDR_TYPE, tqe->type) |
633 FIELD_PREP(WILC_VMM_HDR_MGMT_FIELD, mgmt_ptk) |
634 FIELD_PREP(WILC_VMM_HDR_PKT_SIZE, tqe->buffer_size) |
635 FIELD_PREP(WILC_VMM_HDR_BUFF_SIZE, vmm_sz));
636
637 cpu_to_le32s(&header);
638 memcpy(&txb[offset], &header, 4);
639 if (tqe->type == WILC_CFG_PKT) {
640 buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
641 } else if (tqe->type == WILC_NET_PKT) {
642 bssid = tqe->vif->bssid;
643 buffer_offset = ETH_ETHERNET_HDR_OFFSET;
644 memcpy(&txb[offset + 8], bssid, 6);
645 } else {
646 buffer_offset = HOST_HDR_OFFSET;
647 }
648
649 memcpy(&txb[offset + buffer_offset],
650 tqe->buffer, tqe->buffer_size);
651 offset += vmm_sz;
652 i++;
653 tqe->status = 1;
654 if (tqe->tx_complete_func)
655 tqe->tx_complete_func(tqe->priv, tqe->status);
656 if (tqe->ack_idx != NOT_TCP_ACK &&
657 tqe->ack_idx < MAX_PENDING_ACKS)
658 vif->ack_filter.pending_acks[tqe->ack_idx].txqe = NULL;
659 kfree(tqe);
660 } while (--entries);
661
662 acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
663
664 ret = func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
665 if (ret)
666 goto out_release_bus;
667
668 ret = func->hif_block_tx_ext(wilc, 0, txb, offset);
669
670out_release_bus:
671 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
672
673out_unlock:
674 mutex_unlock(&wilc->txq_add_to_head_cs);
675
676out_update_cnt:
677 *txq_count = wilc->txq_entries;
678 return ret;
679}
680
681static void wilc_wlan_handle_rx_buff(struct wilc *wilc, u8 *buffer, int size)
682{
683 int offset = 0;
684 u32 header;
685 u32 pkt_len, pkt_offset, tp_len;
686 int is_cfg_packet;
687 u8 *buff_ptr;
688
689 do {
690 buff_ptr = buffer + offset;
691 header = get_unaligned_le32(buff_ptr);
692
693 is_cfg_packet = FIELD_GET(WILC_PKT_HDR_CONFIG_FIELD, header);
694 pkt_offset = FIELD_GET(WILC_PKT_HDR_OFFSET_FIELD, header);
695 tp_len = FIELD_GET(WILC_PKT_HDR_TOTAL_LEN_FIELD, header);
696 pkt_len = FIELD_GET(WILC_PKT_HDR_LEN_FIELD, header);
697
698 if (pkt_len == 0 || tp_len == 0)
699 break;
700
701 if (pkt_offset & IS_MANAGMEMENT) {
702 buff_ptr += HOST_HDR_OFFSET;
703 wilc_wfi_mgmt_rx(wilc, buff_ptr, pkt_len);
704 } else {
705 if (!is_cfg_packet) {
706 wilc_frmw_to_host(wilc, buff_ptr, pkt_len,
707 pkt_offset);
708 } else {
709 struct wilc_cfg_rsp rsp;
710
711 buff_ptr += pkt_offset;
712
713 wilc_wlan_cfg_indicate_rx(wilc, buff_ptr,
714 pkt_len,
715 &rsp);
716 if (rsp.type == WILC_CFG_RSP) {
717 if (wilc->cfg_seq_no == rsp.seq_no)
718 complete(&wilc->cfg_event);
719 } else if (rsp.type == WILC_CFG_RSP_STATUS) {
720 wilc_mac_indicate(wilc);
721 }
722 }
723 }
724 offset += tp_len;
725 } while (offset < size);
726}
727
728static void wilc_wlan_handle_rxq(struct wilc *wilc)
729{
730 int size;
731 u8 *buffer;
732 struct rxq_entry_t *rqe;
733
734 while (!wilc->quit) {
735 rqe = wilc_wlan_rxq_remove(wilc);
736 if (!rqe)
737 break;
738
739 buffer = rqe->buffer;
740 size = rqe->buffer_size;
741 wilc_wlan_handle_rx_buff(wilc, buffer, size);
742
743 kfree(rqe);
744 }
745 if (wilc->quit)
746 complete(&wilc->cfg_event);
747}
748
749static void wilc_unknown_isr_ext(struct wilc *wilc)
750{
751 wilc->hif_func->hif_clear_int_ext(wilc, 0);
752}
753
754static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
755{
756 u32 offset = wilc->rx_buffer_offset;
757 u8 *buffer = NULL;
758 u32 size;
759 u32 retries = 0;
760 int ret = 0;
761 struct rxq_entry_t *rqe;
762
763 size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, int_status) << 2;
764
765 while (!size && retries < 10) {
766 wilc->hif_func->hif_read_size(wilc, &size);
767 size = FIELD_GET(WILC_INTERRUPT_DATA_SIZE, size) << 2;
768 retries++;
769 }
770
771 if (size <= 0)
772 return;
773
774 if (WILC_RX_BUFF_SIZE - offset < size)
775 offset = 0;
776
777 buffer = &wilc->rx_buffer[offset];
778
779 wilc->hif_func->hif_clear_int_ext(wilc, DATA_INT_CLR | ENABLE_RX_VMM);
780 ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size);
781 if (ret)
782 return;
783
784 offset += size;
785 wilc->rx_buffer_offset = offset;
786 rqe = kmalloc(sizeof(*rqe), GFP_KERNEL);
787 if (!rqe)
788 return;
789
790 rqe->buffer = buffer;
791 rqe->buffer_size = size;
792 wilc_wlan_rxq_add(wilc, rqe);
793 wilc_wlan_handle_rxq(wilc);
794}
795
796void wilc_handle_isr(struct wilc *wilc)
797{
798 u32 int_status;
799
800 acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
801 wilc->hif_func->hif_read_int(wilc, &int_status);
802
803 if (int_status & DATA_INT_EXT)
804 wilc_wlan_handle_isr_ext(wilc, int_status);
805
806 if (!(int_status & (ALL_INT_EXT)))
807 wilc_unknown_isr_ext(wilc);
808
809 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
810}
811EXPORT_SYMBOL_GPL(wilc_handle_isr);
812
813int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
814 u32 buffer_size)
815{
816 u32 offset;
817 u32 addr, size, size2, blksz;
818 u8 *dma_buffer;
819 int ret = 0;
820
821 blksz = BIT(12);
822
823 dma_buffer = kmalloc(blksz, GFP_KERNEL);
824 if (!dma_buffer)
825 return -EIO;
826
827 offset = 0;
828 do {
829 addr = get_unaligned_le32(&buffer[offset]);
830 size = get_unaligned_le32(&buffer[offset + 4]);
831 acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
832 offset += 8;
833 while (((int)size) && (offset < buffer_size)) {
834 if (size <= blksz)
835 size2 = size;
836 else
837 size2 = blksz;
838
839 memcpy(dma_buffer, &buffer[offset], size2);
840 ret = wilc->hif_func->hif_block_tx(wilc, addr,
841 dma_buffer, size2);
842 if (ret)
843 break;
844
845 addr += size2;
846 offset += size2;
847 size -= size2;
848 }
849 release_bus(wilc, WILC_BUS_RELEASE_ONLY);
850
851 if (ret)
852 goto fail;
853 } while (offset < buffer_size);
854
855fail:
856
857 kfree(dma_buffer);
858
859 return ret;
860}
861
862int wilc_wlan_start(struct wilc *wilc)
863{
864 u32 reg = 0;
865 int ret;
866 u32 chipid;
867
868 if (wilc->io_type == WILC_HIF_SDIO) {
869 reg = 0;
870 reg |= BIT(3);
871 } else if (wilc->io_type == WILC_HIF_SPI) {
872 reg = 1;
873 }
874 acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
875 ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
876 if (ret) {
877 release_bus(wilc, WILC_BUS_RELEASE_ONLY);
878 return ret;
879 }
880 reg = 0;
881 if (wilc->io_type == WILC_HIF_SDIO && wilc->dev_irq_num)
882 reg |= WILC_HAVE_SDIO_IRQ_GPIO;
883
884 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
885 if (ret) {
886 release_bus(wilc, WILC_BUS_RELEASE_ONLY);
887 return ret;
888 }
889
890 wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT);
891
892 ret = wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
893 if (ret) {
894 release_bus(wilc, WILC_BUS_RELEASE_ONLY);
895 return ret;
896 }
897
898 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
899 if ((reg & BIT(10)) == BIT(10)) {
900 reg &= ~BIT(10);
901 wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
902 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
903 }
904
905 reg |= BIT(10);
906 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
907 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, ®);
908 release_bus(wilc, WILC_BUS_RELEASE_ONLY);
909
910 return ret;
911}
912
913int wilc_wlan_stop(struct wilc *wilc, struct wilc_vif *vif)
914{
915 u32 reg = 0;
916 int ret;
917
918 acquire_bus(wilc, WILC_BUS_ACQUIRE_AND_WAKEUP);
919
920 ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, ®);
921 if (ret) {
922 netdev_err(vif->ndev, "Error while reading reg\n");
923 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
924 return ret;
925 }
926
927 ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0,
928 (reg | WILC_ABORT_REQ_BIT));
929 if (ret) {
930 netdev_err(vif->ndev, "Error while writing reg\n");
931 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
932 return ret;
933 }
934
935 ret = wilc->hif_func->hif_read_reg(wilc, WILC_FW_HOST_COMM, ®);
936 if (ret) {
937 netdev_err(vif->ndev, "Error while reading reg\n");
938 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
939 return ret;
940 }
941 reg = BIT(0);
942
943 ret = wilc->hif_func->hif_write_reg(wilc, WILC_FW_HOST_COMM, reg);
944 if (ret) {
945 netdev_err(vif->ndev, "Error while writing reg\n");
946 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
947 return ret;
948 }
949
950 release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
951
952 return 0;
953}
954
955void wilc_wlan_cleanup(struct net_device *dev)
956{
957 struct txq_entry_t *tqe;
958 struct rxq_entry_t *rqe;
959 struct wilc_vif *vif = netdev_priv(dev);
960 struct wilc *wilc = vif->wilc;
961
962 wilc->quit = 1;
963 while ((tqe = wilc_wlan_txq_remove_from_head(dev))) {
964 if (tqe->tx_complete_func)
965 tqe->tx_complete_func(tqe->priv, 0);
966 kfree(tqe);
967 }
968
969 while ((rqe = wilc_wlan_rxq_remove(wilc)))
970 kfree(rqe);
971
972 kfree(wilc->rx_buffer);
973 wilc->rx_buffer = NULL;
974 kfree(wilc->tx_buffer);
975 wilc->tx_buffer = NULL;
976 wilc->hif_func->hif_deinit(NULL);
977}
978
979static int wilc_wlan_cfg_commit(struct wilc_vif *vif, int type,
980 u32 drv_handler)
981{
982 struct wilc *wilc = vif->wilc;
983 struct wilc_cfg_frame *cfg = &wilc->cfg_frame;
984 int t_len = wilc->cfg_frame_offset + sizeof(struct wilc_cfg_cmd_hdr);
985
986 if (type == WILC_CFG_SET)
987 cfg->hdr.cmd_type = 'W';
988 else
989 cfg->hdr.cmd_type = 'Q';
990
991 cfg->hdr.seq_no = wilc->cfg_seq_no % 256;
992 cfg->hdr.total_len = cpu_to_le16(t_len);
993 cfg->hdr.driver_handler = cpu_to_le32(drv_handler);
994 wilc->cfg_seq_no = cfg->hdr.seq_no;
995
996 if (!wilc_wlan_txq_add_cfg_pkt(vif, (u8 *)&cfg->hdr, t_len))
997 return -1;
998
999 return 0;
1000}
1001
1002int wilc_wlan_cfg_set(struct wilc_vif *vif, int start, u16 wid, u8 *buffer,
1003 u32 buffer_size, int commit, u32 drv_handler)
1004{
1005 u32 offset;
1006 int ret_size;
1007 struct wilc *wilc = vif->wilc;
1008
1009 mutex_lock(&wilc->cfg_cmd_lock);
1010
1011 if (start)
1012 wilc->cfg_frame_offset = 0;
1013
1014 offset = wilc->cfg_frame_offset;
1015 ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset,
1016 wid, buffer, buffer_size);
1017 offset += ret_size;
1018 wilc->cfg_frame_offset = offset;
1019
1020 if (!commit) {
1021 mutex_unlock(&wilc->cfg_cmd_lock);
1022 return ret_size;
1023 }
1024
1025 netdev_dbg(vif->ndev, "%s: seqno[%d]\n", __func__, wilc->cfg_seq_no);
1026
1027 if (wilc_wlan_cfg_commit(vif, WILC_CFG_SET, drv_handler))
1028 ret_size = 0;
1029
1030 if (!wait_for_completion_timeout(&wilc->cfg_event,
1031 WILC_CFG_PKTS_TIMEOUT)) {
1032 netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
1033 ret_size = 0;
1034 }
1035
1036 wilc->cfg_frame_offset = 0;
1037 wilc->cfg_seq_no += 1;
1038 mutex_unlock(&wilc->cfg_cmd_lock);
1039
1040 return ret_size;
1041}
1042
1043int wilc_wlan_cfg_get(struct wilc_vif *vif, int start, u16 wid, int commit,
1044 u32 drv_handler)
1045{
1046 u32 offset;
1047 int ret_size;
1048 struct wilc *wilc = vif->wilc;
1049
1050 mutex_lock(&wilc->cfg_cmd_lock);
1051
1052 if (start)
1053 wilc->cfg_frame_offset = 0;
1054
1055 offset = wilc->cfg_frame_offset;
1056 ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset, wid);
1057 offset += ret_size;
1058 wilc->cfg_frame_offset = offset;
1059
1060 if (!commit) {
1061 mutex_unlock(&wilc->cfg_cmd_lock);
1062 return ret_size;
1063 }
1064
1065 if (wilc_wlan_cfg_commit(vif, WILC_CFG_QUERY, drv_handler))
1066 ret_size = 0;
1067
1068 if (!wait_for_completion_timeout(&wilc->cfg_event,
1069 WILC_CFG_PKTS_TIMEOUT)) {
1070 netdev_dbg(vif->ndev, "%s: Timed Out\n", __func__);
1071 ret_size = 0;
1072 }
1073 wilc->cfg_frame_offset = 0;
1074 wilc->cfg_seq_no += 1;
1075 mutex_unlock(&wilc->cfg_cmd_lock);
1076
1077 return ret_size;
1078}
1079
1080int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
1081 u32 count)
1082{
1083 int i;
1084 int ret = 0;
1085 u32 drv = wilc_get_vif_idx(vif);
1086
1087 if (mode == WILC_GET_CFG) {
1088 for (i = 0; i < count; i++) {
1089 if (!wilc_wlan_cfg_get(vif, !i,
1090 wids[i].id,
1091 (i == count - 1),
1092 drv)) {
1093 ret = -ETIMEDOUT;
1094 break;
1095 }
1096 }
1097 for (i = 0; i < count; i++) {
1098 wids[i].size = wilc_wlan_cfg_get_val(vif->wilc,
1099 wids[i].id,
1100 wids[i].val,
1101 wids[i].size);
1102 }
1103 } else if (mode == WILC_SET_CFG) {
1104 for (i = 0; i < count; i++) {
1105 if (!wilc_wlan_cfg_set(vif, !i,
1106 wids[i].id,
1107 wids[i].val,
1108 wids[i].size,
1109 (i == count - 1),
1110 drv)) {
1111 ret = -ETIMEDOUT;
1112 break;
1113 }
1114 }
1115 }
1116
1117 return ret;
1118}
1119
1120static int init_chip(struct net_device *dev)
1121{
1122 u32 chipid;
1123 u32 reg;
1124 int ret = 0;
1125 struct wilc_vif *vif = netdev_priv(dev);
1126 struct wilc *wilc = vif->wilc;
1127
1128 acquire_bus(wilc, WILC_BUS_ACQUIRE_ONLY);
1129
1130 chipid = wilc_get_chipid(wilc, true);
1131
1132 if ((chipid & 0xfff) != 0xa0) {
1133 ret = wilc->hif_func->hif_read_reg(wilc,
1134 WILC_CORTUS_RESET_MUX_SEL,
1135 ®);
1136 if (ret) {
1137 netdev_err(dev, "fail read reg 0x1118\n");
1138 goto release;
1139 }
1140 reg |= BIT(0);
1141 ret = wilc->hif_func->hif_write_reg(wilc,
1142 WILC_CORTUS_RESET_MUX_SEL,
1143 reg);
1144 if (ret) {
1145 netdev_err(dev, "fail write reg 0x1118\n");
1146 goto release;
1147 }
1148 ret = wilc->hif_func->hif_write_reg(wilc,
1149 WILC_CORTUS_BOOT_REGISTER,
1150 WILC_CORTUS_BOOT_FROM_IRAM);
1151 if (ret) {
1152 netdev_err(dev, "fail write reg 0xc0000\n");
1153 goto release;
1154 }
1155 }
1156
1157release:
1158 release_bus(wilc, WILC_BUS_RELEASE_ONLY);
1159
1160 return ret;
1161}
1162
1163u32 wilc_get_chipid(struct wilc *wilc, bool update)
1164{
1165 static u32 chipid;
1166 u32 tempchipid = 0;
1167 u32 rfrevid = 0;
1168
1169 if (chipid == 0 || update) {
1170 wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &tempchipid);
1171 wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID,
1172 &rfrevid);
1173 if (!is_wilc1000(tempchipid)) {
1174 chipid = 0;
1175 return chipid;
1176 }
1177 if (tempchipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */
1178 if (rfrevid != 0x1)
1179 tempchipid = WILC_1000_BASE_ID_2A_REV1;
1180 } else if (tempchipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */
1181 if (rfrevid == 0x4)
1182 tempchipid = WILC_1000_BASE_ID_2B_REV1;
1183 else if (rfrevid != 0x3)
1184 tempchipid = WILC_1000_BASE_ID_2B_REV2;
1185 }
1186
1187 chipid = tempchipid;
1188 }
1189 return chipid;
1190}
1191
1192int wilc_wlan_init(struct net_device *dev)
1193{
1194 int ret = 0;
1195 struct wilc_vif *vif = netdev_priv(dev);
1196 struct wilc *wilc;
1197
1198 wilc = vif->wilc;
1199
1200 wilc->quit = 0;
1201
1202 if (wilc->hif_func->hif_init(wilc, false)) {
1203 ret = -EIO;
1204 goto fail;
1205 }
1206
1207 if (!wilc->tx_buffer)
1208 wilc->tx_buffer = kmalloc(WILC_TX_BUFF_SIZE, GFP_KERNEL);
1209
1210 if (!wilc->tx_buffer) {
1211 ret = -ENOBUFS;
1212 goto fail;
1213 }
1214
1215 if (!wilc->rx_buffer)
1216 wilc->rx_buffer = kmalloc(WILC_RX_BUFF_SIZE, GFP_KERNEL);
1217
1218 if (!wilc->rx_buffer) {
1219 ret = -ENOBUFS;
1220 goto fail;
1221 }
1222
1223 if (init_chip(dev)) {
1224 ret = -EIO;
1225 goto fail;
1226 }
1227
1228 return 0;
1229
1230fail:
1231
1232 kfree(wilc->rx_buffer);
1233 wilc->rx_buffer = NULL;
1234 kfree(wilc->tx_buffer);
1235 wilc->tx_buffer = NULL;
1236
1237 return ret;
1238}