]> Git Repo - linux.git/blob - drivers/net/wireless/microchip/wilc1000/wlan.c
KVM: x86: fix CPUID entries returned by KVM_GET_CPUID2 ioctl
[linux.git] / drivers / net / wireless / microchip / wilc1000 / wlan.c
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 }
This page took 0.121397 seconds and 4 git commands to generate.