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