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