]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/wilc1000/wilc_wlan.c
ipc/msg.c: use freezable blocking call
[karo-tx-linux.git] / drivers / staging / wilc1000 / wilc_wlan.c
1 #include "wilc_wlan_if.h"
2 #include "wilc_wlan.h"
3 #include "wilc_wfi_netdevice.h"
4 #include "wilc_wlan_cfg.h"
5
6 #ifdef WILC_OPTIMIZE_SLEEP_INT
7 static inline void chip_allow_sleep(struct wilc *wilc);
8 #endif
9 static inline void chip_wakeup(struct wilc *wilc);
10 static u32 dbgflag = N_INIT | N_ERR | N_INTR | N_TXQ | N_RXQ;
11
12 /* FIXME: replace with dev_debug() */
13 static void wilc_debug(u32 flag, char *fmt, ...)
14 {
15         char buf[256];
16         va_list args;
17
18         if (flag & dbgflag) {
19                 va_start(args, fmt);
20                 vsprintf(buf, fmt, args);
21                 va_end(args);
22
23                 wilc_dbg(buf);
24         }
25 }
26
27 static CHIP_PS_STATE_T chip_ps_state = CHIP_WAKEDUP;
28
29 static inline void acquire_bus(struct wilc *wilc, BUS_ACQUIRE_T acquire)
30 {
31         mutex_lock(&wilc->hif_cs);
32         #ifndef WILC_OPTIMIZE_SLEEP_INT
33         if (chip_ps_state != CHIP_WAKEDUP)
34         #endif
35         {
36                 if (acquire == ACQUIRE_AND_WAKEUP)
37                         chip_wakeup(wilc);
38         }
39 }
40
41 static inline void release_bus(struct wilc *wilc, BUS_RELEASE_T release)
42 {
43         #ifdef WILC_OPTIMIZE_SLEEP_INT
44         if (release == RELEASE_ALLOW_SLEEP)
45                 chip_allow_sleep(wilc);
46         #endif
47         mutex_unlock(&wilc->hif_cs);
48 }
49
50 #ifdef TCP_ACK_FILTER
51 static void wilc_wlan_txq_remove(struct txq_entry_t *tqe)
52 {
53
54         if (tqe == wilc->txq_head) {
55                 wilc->txq_head = tqe->next;
56                 if (wilc->txq_head)
57                         wilc->txq_head->prev = NULL;
58         } else if (tqe == wilc->txq_tail) {
59                 wilc->txq_tail = (tqe->prev);
60                 if (wilc->txq_tail)
61                         wilc->txq_tail->next = NULL;
62         } else {
63                 tqe->prev->next = tqe->next;
64                 tqe->next->prev = tqe->prev;
65         }
66         wilc->txq_entries -= 1;
67 }
68 #endif
69
70 static struct txq_entry_t *
71 wilc_wlan_txq_remove_from_head(struct net_device *dev)
72 {
73         struct txq_entry_t *tqe;
74         unsigned long flags;
75         struct wilc_vif *vif;
76         struct wilc *wilc;
77
78         vif = netdev_priv(dev);
79         wilc = vif->wilc;
80
81         spin_lock_irqsave(&wilc->txq_spinlock, flags);
82         if (wilc->txq_head) {
83                 tqe = wilc->txq_head;
84                 wilc->txq_head = tqe->next;
85                 if (wilc->txq_head)
86                         wilc->txq_head->prev = NULL;
87
88                 wilc->txq_entries -= 1;
89         } else {
90                 tqe = NULL;
91         }
92         spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
93         return tqe;
94 }
95
96 static void wilc_wlan_txq_add_to_tail(struct net_device *dev,
97                                       struct txq_entry_t *tqe)
98 {
99         unsigned long flags;
100         struct wilc_vif *vif;
101         struct wilc *wilc;
102
103         vif = netdev_priv(dev);
104         wilc = vif->wilc;
105
106         spin_lock_irqsave(&wilc->txq_spinlock, flags);
107
108         if (!wilc->txq_head) {
109                 tqe->next = NULL;
110                 tqe->prev = NULL;
111                 wilc->txq_head = tqe;
112                 wilc->txq_tail = tqe;
113         } else {
114                 tqe->next = NULL;
115                 tqe->prev = wilc->txq_tail;
116                 wilc->txq_tail->next = tqe;
117                 wilc->txq_tail = tqe;
118         }
119         wilc->txq_entries += 1;
120         PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", wilc->txq_entries);
121
122         spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
123
124         PRINT_D(TX_DBG, "Wake the txq_handling\n");
125
126         up(&wilc->txq_event);
127 }
128
129 static int wilc_wlan_txq_add_to_head(struct wilc *wilc, struct txq_entry_t *tqe)
130 {
131         unsigned long flags;
132         if (wilc_lock_timeout(wilc, &wilc->txq_add_to_head_cs,
133                                     CFG_PKTS_TIMEOUT))
134                 return -1;
135
136         spin_lock_irqsave(&wilc->txq_spinlock, flags);
137
138         if (!wilc->txq_head) {
139                 tqe->next = NULL;
140                 tqe->prev = NULL;
141                 wilc->txq_head = tqe;
142                 wilc->txq_tail = tqe;
143         } else {
144                 tqe->next = wilc->txq_head;
145                 tqe->prev = NULL;
146                 wilc->txq_head->prev = tqe;
147                 wilc->txq_head = tqe;
148         }
149         wilc->txq_entries += 1;
150         PRINT_D(TX_DBG, "Number of entries in TxQ = %d\n", wilc->txq_entries);
151
152         spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
153         up(&wilc->txq_add_to_head_cs);
154         up(&wilc->txq_event);
155         PRINT_D(TX_DBG, "Wake up the txq_handler\n");
156
157         return 0;
158 }
159
160 #ifdef  TCP_ACK_FILTER
161 struct ack_session_info;
162 struct ack_session_info {
163         u32 seq_num;
164         u32 bigger_ack_num;
165         u16 src_port;
166         u16 dst_port;
167         u16 status;
168 };
169
170 struct pending_acks_info {
171         u32 ack_num;
172         u32 session_index;
173         struct txq_entry_t  *txqe;
174 };
175
176
177 #define NOT_TCP_ACK                     (-1)
178
179 #define MAX_TCP_SESSION         25
180 #define MAX_PENDING_ACKS                256
181 static struct ack_session_info ack_session_info[2 * MAX_TCP_SESSION];
182 static struct pending_acks_info pending_acks_info[MAX_PENDING_ACKS];
183
184 static u32 pending_base;
185 static u32 tcp_session;
186 static u32 pending_acks;
187
188 static inline int init_tcp_tracking(void)
189 {
190         return 0;
191 }
192
193 static inline int add_tcp_session(u32 src_prt, u32 dst_prt, u32 seq)
194 {
195         ack_session_info[tcp_session].seq_num = seq;
196         ack_session_info[tcp_session].bigger_ack_num = 0;
197         ack_session_info[tcp_session].src_port = src_prt;
198         ack_session_info[tcp_session].dst_port = dst_prt;
199         tcp_session++;
200
201         PRINT_D(TCP_ENH, "TCP Session %d to Ack %d\n", tcp_session, seq);
202         return 0;
203 }
204
205 static inline int update_tcp_session(u32 index, u32 ack)
206 {
207         if (ack > ack_session_info[index].bigger_ack_num)
208                 ack_session_info[index].bigger_ack_num = ack;
209         return 0;
210 }
211
212 static inline int add_tcp_pending_ack(u32 ack, u32 session_index,
213                                       struct txq_entry_t *txqe)
214 {
215         if (pending_acks < MAX_PENDING_ACKS) {
216                 pending_acks_info[pending_base + pending_acks].ack_num = ack;
217                 pending_acks_info[pending_base + pending_acks].txqe = txqe;
218                 pending_acks_info[pending_base + pending_acks].session_index = session_index;
219                 txqe->tcp_pending_ack_idx = pending_base + pending_acks;
220                 pending_acks++;
221         }
222         return 0;
223 }
224 static inline int remove_TCP_related(struct wilc *wilc)
225 {
226         unsigned long flags;
227
228         spin_lock_irqsave(&wilc->txq_spinlock, flags);
229
230         spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
231         return 0;
232 }
233
234 static inline int tcp_process(struct net_device *dev, struct txq_entry_t *tqe)
235 {
236         int ret;
237         u8 *eth_hdr_ptr;
238         u8 *buffer = tqe->buffer;
239         unsigned short h_proto;
240         int i;
241         unsigned long flags;
242         struct wilc_vif *vif;
243         struct wilc *wilc;
244
245         vif = netdev_priv(dev);
246         wilc = vif->wilc;
247
248
249         eth_hdr_ptr = &buffer[0];
250         h_proto = ntohs(*((unsigned short *)&eth_hdr_ptr[12]));
251         if (h_proto == 0x0800) {
252                 u8 *ip_hdr_ptr;
253                 u8 protocol;
254
255                 ip_hdr_ptr = &buffer[ETHERNET_HDR_LEN];
256                 protocol = ip_hdr_ptr[9];
257
258                 if (protocol == 0x06) {
259                         u8 *tcp_hdr_ptr;
260                         u32 IHL, total_length, data_offset;
261
262                         tcp_hdr_ptr = &ip_hdr_ptr[IP_HDR_LEN];
263                         IHL = (ip_hdr_ptr[0] & 0xf) << 2;
264                         total_length = ((u32)ip_hdr_ptr[2] << 8) +
265                                         (u32)ip_hdr_ptr[3];
266                         data_offset = ((u32)tcp_hdr_ptr[12] & 0xf0) >> 2;
267                         if (total_length == (IHL + data_offset)) {
268                                 u32 seq_no, ack_no;
269
270                                 seq_no = ((u32)tcp_hdr_ptr[4] << 24) +
271                                          ((u32)tcp_hdr_ptr[5] << 16) +
272                                          ((u32)tcp_hdr_ptr[6] << 8) +
273                                          (u32)tcp_hdr_ptr[7];
274
275                                 ack_no = ((u32)tcp_hdr_ptr[8] << 24) +
276                                          ((u32)tcp_hdr_ptr[9] << 16) +
277                                          ((u32)tcp_hdr_ptr[10] << 8) +
278                                          (u32)tcp_hdr_ptr[11];
279
280                                 for (i = 0; i < tcp_session; i++) {
281                                         if (ack_session_info[i].seq_num == seq_no) {
282                                                 update_tcp_session(i, ack_no);
283                                                 break;
284                                         }
285                                 }
286                                 if (i == tcp_session)
287                                         add_tcp_session(0, 0, seq_no);
288
289                                 add_tcp_pending_ack(ack_no, i, tqe);
290                         }
291
292                 } else {
293                         ret = 0;
294                 }
295         } else {
296                 ret = 0;
297         }
298         spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
299         return ret;
300 }
301
302 static int wilc_wlan_txq_filter_dup_tcp_ack(struct net_device *dev)
303 {
304         struct wilc_vif *vif;
305         struct wilc *wilc;
306         u32 i = 0;
307         u32 dropped = 0;
308
309         vif = netdev_priv(dev);
310         wilc = vif->wilc;
311
312         spin_lock_irqsave(&wilc->txq_spinlock, wilc->txq_spinlock_flags);
313         for (i = pending_base; i < (pending_base + pending_acks); i++) {
314                 if (pending_acks_info[i].ack_num < ack_session_info[pending_acks_info[i].session_index].bigger_ack_num) {
315                         struct txq_entry_t *tqe;
316
317                         PRINT_D(TCP_ENH, "DROP ACK: %u\n",
318                                 pending_acks_info[i].ack_num);
319                         tqe = pending_acks_info[i].txqe;
320                         if (tqe) {
321                                 wilc_wlan_txq_remove(tqe);
322                                 tqe->status = 1;
323                                 if (tqe->tx_complete_func)
324                                         tqe->tx_complete_func(tqe->priv,
325                                                               tqe->status);
326                                 kfree(tqe);
327                                 dropped++;
328                         }
329                 }
330         }
331         pending_acks = 0;
332         tcp_session = 0;
333
334         if (pending_base == 0)
335                 pending_base = MAX_TCP_SESSION;
336         else
337                 pending_base = 0;
338
339         spin_unlock_irqrestore(&wilc->txq_spinlock, wilc->txq_spinlock_flags);
340
341         while (dropped > 0) {
342                 wilc_lock_timeout(wilc, &wilc->txq_event, 1);
343                 dropped--;
344         }
345
346         return 1;
347 }
348 #endif
349
350 static bool enabled = false;
351
352 void wilc_enable_tcp_ack_filter(bool value)
353 {
354         enabled = value;
355 }
356
357 #ifdef TCP_ACK_FILTER
358 static bool is_tcp_ack_filter_enabled(void)
359 {
360         return enabled;
361 }
362 #endif
363
364 static int wilc_wlan_txq_add_cfg_pkt(struct wilc *wilc, u8 *buffer, u32 buffer_size)
365 {
366         struct txq_entry_t *tqe;
367
368         PRINT_D(TX_DBG, "Adding config packet ...\n");
369         if (wilc->quit) {
370                 PRINT_D(TX_DBG, "Return due to clear function\n");
371                 up(&wilc->cfg_event);
372                 return 0;
373         }
374
375         tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
376         if (!tqe) {
377                 PRINT_ER("Failed to allocate memory\n");
378                 return 0;
379         }
380
381         tqe->type = WILC_CFG_PKT;
382         tqe->buffer = buffer;
383         tqe->buffer_size = buffer_size;
384         tqe->tx_complete_func = NULL;
385         tqe->priv = NULL;
386 #ifdef TCP_ACK_FILTER
387         tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
388 #endif
389         PRINT_D(TX_DBG, "Adding the config packet at the Queue tail\n");
390
391         if (wilc_wlan_txq_add_to_head(wilc, tqe))
392                 return 0;
393         return 1;
394 }
395
396 int wilc_wlan_txq_add_net_pkt(struct net_device *dev, void *priv, u8 *buffer,
397                               u32 buffer_size, wilc_tx_complete_func_t func)
398 {
399         struct txq_entry_t *tqe;
400         struct wilc_vif *vif = netdev_priv(dev);
401         struct wilc *wilc;
402
403         wilc = vif->wilc;
404
405         if (wilc->quit)
406                 return 0;
407
408         tqe = kmalloc(sizeof(*tqe), GFP_ATOMIC);
409
410         if (!tqe)
411                 return 0;
412         tqe->type = WILC_NET_PKT;
413         tqe->buffer = buffer;
414         tqe->buffer_size = buffer_size;
415         tqe->tx_complete_func = func;
416         tqe->priv = priv;
417
418         PRINT_D(TX_DBG, "Adding mgmt packet at the Queue tail\n");
419 #ifdef TCP_ACK_FILTER
420         tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
421         if (is_tcp_ack_filter_enabled())
422                 tcp_process(dev, tqe);
423 #endif
424         wilc_wlan_txq_add_to_tail(dev, tqe);
425         return wilc->txq_entries;
426 }
427
428 int wilc_wlan_txq_add_mgmt_pkt(struct net_device *dev, void *priv, u8 *buffer,
429                                u32 buffer_size, wilc_tx_complete_func_t func)
430 {
431         struct txq_entry_t *tqe;
432         struct wilc_vif *vif = netdev_priv(dev);
433         struct wilc *wilc;
434
435         wilc = vif->wilc;
436
437         if (wilc->quit)
438                 return 0;
439
440         tqe = kmalloc(sizeof(*tqe), GFP_KERNEL);
441
442         if (!tqe)
443                 return 0;
444         tqe->type = WILC_MGMT_PKT;
445         tqe->buffer = buffer;
446         tqe->buffer_size = buffer_size;
447         tqe->tx_complete_func = func;
448         tqe->priv = priv;
449 #ifdef TCP_ACK_FILTER
450         tqe->tcp_pending_ack_idx = NOT_TCP_ACK;
451 #endif
452         PRINT_D(TX_DBG, "Adding Network packet at the Queue tail\n");
453         wilc_wlan_txq_add_to_tail(dev, tqe);
454         return 1;
455 }
456
457 static struct txq_entry_t *wilc_wlan_txq_get_first(struct wilc *wilc)
458 {
459         struct txq_entry_t *tqe;
460         unsigned long flags;
461
462         spin_lock_irqsave(&wilc->txq_spinlock, flags);
463
464         tqe = wilc->txq_head;
465
466         spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
467
468         return tqe;
469 }
470
471 static struct txq_entry_t *wilc_wlan_txq_get_next(struct wilc *wilc,
472                                                   struct txq_entry_t *tqe)
473 {
474         unsigned long flags;
475
476         spin_lock_irqsave(&wilc->txq_spinlock, flags);
477
478         tqe = tqe->next;
479         spin_unlock_irqrestore(&wilc->txq_spinlock, flags);
480
481         return tqe;
482 }
483
484 static int wilc_wlan_rxq_add(struct wilc *wilc, struct rxq_entry_t *rqe)
485 {
486
487         if (wilc->quit)
488                 return 0;
489
490         mutex_lock(&wilc->rxq_cs);
491         if (!wilc->rxq_head) {
492                 PRINT_D(RX_DBG, "Add to Queue head\n");
493                 rqe->next = NULL;
494                 wilc->rxq_head = rqe;
495                 wilc->rxq_tail = rqe;
496         } else {
497                 PRINT_D(RX_DBG, "Add to Queue tail\n");
498                 wilc->rxq_tail->next = rqe;
499                 rqe->next = NULL;
500                 wilc->rxq_tail = rqe;
501         }
502         wilc->rxq_entries += 1;
503         PRINT_D(RX_DBG, "Number of queue entries: %d\n", wilc->rxq_entries);
504         mutex_unlock(&wilc->rxq_cs);
505         return wilc->rxq_entries;
506 }
507
508 static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
509 {
510
511         PRINT_D(RX_DBG, "Getting rxQ element\n");
512         if (wilc->rxq_head) {
513                 struct rxq_entry_t *rqe;
514
515                 mutex_lock(&wilc->rxq_cs);
516                 rqe = wilc->rxq_head;
517                 wilc->rxq_head = wilc->rxq_head->next;
518                 wilc->rxq_entries -= 1;
519                 PRINT_D(RX_DBG, "RXQ entries decreased\n");
520                 mutex_unlock(&wilc->rxq_cs);
521                 return rqe;
522         }
523         PRINT_D(RX_DBG, "Nothing to get from Q\n");
524         return NULL;
525 }
526
527 #ifdef WILC_OPTIMIZE_SLEEP_INT
528
529 static inline void chip_allow_sleep(struct wilc *wilc)
530 {
531         u32 reg = 0;
532
533         wilc->hif_func->hif_read_reg(wilc, 0xf0, &reg);
534
535         wilc->hif_func->hif_write_reg(wilc, 0xf0, reg & ~BIT(0));
536 }
537
538 static inline void chip_wakeup(struct wilc *wilc)
539 {
540         u32 reg, clk_status_reg, trials = 0;
541         u32 sleep_time;
542
543         if ((wilc->io_type & 0x1) == HIF_SPI) {
544                 do {
545                         wilc->hif_func->hif_read_reg(wilc, 1, &reg);
546                         wilc->hif_func->hif_write_reg(wilc, 1, reg | BIT(1));
547                         wilc->hif_func->hif_write_reg(wilc, 1, reg & ~BIT(1));
548
549                         do {
550                                 usleep_range(2 * 1000, 2 * 1000);
551                                 if ((wilc_get_chipid(wilc, true) == 0))
552                                         wilc_debug(N_ERR, "Couldn't read chip id. Wake up failed\n");
553
554                         } while ((wilc_get_chipid(wilc, true) == 0) && ((++trials % 3) == 0));
555
556                 } while (wilc_get_chipid(wilc, true) == 0);
557         } else if ((wilc->io_type & 0x1) == HIF_SDIO)    {
558                 wilc->hif_func->hif_read_reg(wilc, 0xf0, &reg);
559                 do {
560                         wilc->hif_func->hif_write_reg(wilc, 0xf0,
561                                                       reg | BIT(0));
562                         wilc->hif_func->hif_read_reg(wilc, 0xf1,
563                                                      &clk_status_reg);
564
565                         while (((clk_status_reg & 0x1) == 0) && (((++trials) % 3) == 0)) {
566                                 usleep_range(2 * 1000, 2 * 1000);
567
568                                 wilc->hif_func->hif_read_reg(wilc, 0xf1,
569                                                              &clk_status_reg);
570
571                                 if ((clk_status_reg & 0x1) == 0)
572                                         wilc_debug(N_ERR, "clocks still OFF. Wake up failed\n");
573                         }
574                         if ((clk_status_reg & 0x1) == 0) {
575                                 wilc->hif_func->hif_write_reg(wilc, 0xf0,
576                                                               reg & (~BIT(0)));
577                         }
578                 } while ((clk_status_reg & 0x1) == 0);
579         }
580
581         if (chip_ps_state == CHIP_SLEEPING_MANUAL) {
582                 wilc->hif_func->hif_read_reg(wilc, 0x1C0C, &reg);
583                 reg &= ~BIT(0);
584                 wilc->hif_func->hif_write_reg(wilc, 0x1C0C, reg);
585
586                 if (wilc_get_chipid(wilc, false) >= 0x1002b0) {
587                         u32 val32;
588
589                         wilc->hif_func->hif_read_reg(wilc, 0x1e1c, &val32);
590                         val32 |= BIT(6);
591                         wilc->hif_func->hif_write_reg(wilc, 0x1e1c, val32);
592
593                         wilc->hif_func->hif_read_reg(wilc, 0x1e9c, &val32);
594                         val32 |= BIT(6);
595                         wilc->hif_func->hif_write_reg(wilc, 0x1e9c, val32);
596                 }
597         }
598         chip_ps_state = CHIP_WAKEDUP;
599 }
600 #else
601 static inline void chip_wakeup(struct wilc *wilc)
602 {
603         u32 reg, trials = 0;
604
605         do {
606                 if ((wilc->io_type & 0x1) == HIF_SPI) {
607                         wilc->hif_func->hif_read_reg(wilc, 1, &reg);
608                         wilc->hif_func->hif_write_reg(wilc, 1, reg & ~BIT(1));
609                         wilc->hif_func->hif_write_reg(wilc, 1, reg | BIT(1));
610                         wilc->hif_func->hif_write_reg(wilc, 1, reg  & ~BIT(1));
611                 } else if ((wilc->io_type & 0x1) == HIF_SDIO)    {
612                         wilc->hif_func->hif_read_reg(wilc, 0xf0, &reg);
613                         wilc->hif_func->hif_write_reg(wilc, 0xf0,
614                                                       reg & ~BIT(0));
615                         wilc->hif_func->hif_write_reg(wilc, 0xf0,
616                                                       reg | BIT(0));
617                         wilc->hif_func->hif_write_reg(wilc, 0xf0,
618                                                       reg  & ~BIT(0));
619                 }
620
621                 do {
622                         mdelay(3);
623
624                         if ((wilc_get_chipid(wilc, true) == 0))
625                                 wilc_debug(N_ERR, "Couldn't read chip id. Wake up failed\n");
626
627                 } while ((wilc_get_chipid(wilc, true) == 0) && ((++trials % 3) == 0));
628
629         } while (wilc_get_chipid(wilc, true) == 0);
630
631         if (chip_ps_state == CHIP_SLEEPING_MANUAL) {
632                 wilc->hif_func->hif_read_reg(wilc, 0x1C0C, &reg);
633                 reg &= ~BIT(0);
634                 wilc->hif_func->hif_write_reg(wilc, 0x1C0C, reg);
635
636                 if (wilc_get_chipid(wilc, false) >= 0x1002b0) {
637                         u32 val32;
638
639                         wilc->hif_func->hif_read_reg(wilc, 0x1e1c, &val32);
640                         val32 |= BIT(6);
641                         wilc->hif_func->hif_write_reg(wilc, 0x1e1c, val32);
642
643                         wilc->hif_func->hif_read_reg(wilc, 0x1e9c, &val32);
644                         val32 |= BIT(6);
645                         wilc->hif_func->hif_write_reg(wilc, 0x1e9c, val32);
646                 }
647         }
648         chip_ps_state = CHIP_WAKEDUP;
649 }
650 #endif
651 void wilc_chip_sleep_manually(struct wilc *wilc)
652 {
653         if (chip_ps_state != CHIP_WAKEDUP)
654                 return;
655         acquire_bus(wilc, ACQUIRE_ONLY);
656
657 #ifdef WILC_OPTIMIZE_SLEEP_INT
658         chip_allow_sleep(wilc);
659 #endif
660         wilc->hif_func->hif_write_reg(wilc, 0x10a8, 1);
661
662         chip_ps_state = CHIP_SLEEPING_MANUAL;
663         release_bus(wilc, RELEASE_ONLY);
664 }
665
666 int wilc_wlan_handle_txq(struct net_device *dev, u32 *txq_count)
667 {
668         int i, entries = 0;
669         u32 sum;
670         u32 reg;
671         u8 *txb;
672         u32 offset = 0;
673         int vmm_sz = 0;
674         struct txq_entry_t *tqe;
675         int ret = 0;
676         int counter;
677         int timeout;
678         u32 vmm_table[WILC_VMM_TBL_SIZE];
679         struct wilc_vif *vif;
680         struct wilc *wilc;
681
682         vif = netdev_priv(dev);
683         wilc = vif->wilc;
684
685         txb = wilc->tx_buffer;
686         wilc->txq_exit = 0;
687         do {
688                 if (wilc->quit)
689                         break;
690
691                 wilc_lock_timeout(wilc, &wilc->txq_add_to_head_cs,
692                                         CFG_PKTS_TIMEOUT);
693 #ifdef  TCP_ACK_FILTER
694                 wilc_wlan_txq_filter_dup_tcp_ack(dev);
695 #endif
696                 PRINT_D(TX_DBG, "Getting the head of the TxQ\n");
697                 tqe = wilc_wlan_txq_get_first(wilc);
698                 i = 0;
699                 sum = 0;
700                 do {
701                         if (tqe && (i < (WILC_VMM_TBL_SIZE - 1))) {
702                                 if (tqe->type == WILC_CFG_PKT)
703                                         vmm_sz = ETH_CONFIG_PKT_HDR_OFFSET;
704
705                                 else if (tqe->type == WILC_NET_PKT)
706                                         vmm_sz = ETH_ETHERNET_HDR_OFFSET;
707
708                                 else
709                                         vmm_sz = HOST_HDR_OFFSET;
710
711                                 vmm_sz += tqe->buffer_size;
712                                 PRINT_D(TX_DBG, "VMM Size before alignment = %d\n", vmm_sz);
713                                 if (vmm_sz & 0x3)
714                                         vmm_sz = (vmm_sz + 4) & ~0x3;
715
716                                 if ((sum + vmm_sz) > LINUX_TX_SIZE)
717                                         break;
718
719                                 PRINT_D(TX_DBG, "VMM Size AFTER alignment = %d\n", vmm_sz);
720                                 vmm_table[i] = vmm_sz / 4;
721                                 PRINT_D(TX_DBG, "VMMTable entry size = %d\n",
722                                         vmm_table[i]);
723
724                                 if (tqe->type == WILC_CFG_PKT) {
725                                         vmm_table[i] |= BIT(10);
726                                         PRINT_D(TX_DBG, "VMMTable entry changed for CFG packet = %d\n", vmm_table[i]);
727                                 }
728                                 vmm_table[i] = cpu_to_le32(vmm_table[i]);
729
730                                 i++;
731                                 sum += vmm_sz;
732                                 PRINT_D(TX_DBG, "sum = %d\n", sum);
733                                 tqe = wilc_wlan_txq_get_next(wilc, tqe);
734                         } else {
735                                 break;
736                         }
737                 } while (1);
738
739                 if (i == 0) {
740                         PRINT_D(TX_DBG, "Nothing in TX-Q\n");
741                         break;
742                 } else {
743                         PRINT_D(TX_DBG, "Mark the last entry in VMM table - number of previous entries = %d\n", i);
744                         vmm_table[i] = 0x0;
745                 }
746                 acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
747                 counter = 0;
748                 do {
749                         ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_TX_CTRL,
750                                                        &reg);
751                         if (!ret) {
752                                 wilc_debug(N_ERR, "[wilc txq]: fail can't read reg vmm_tbl_entry..\n");
753                                 break;
754                         }
755
756                         if ((reg & 0x1) == 0) {
757                                 PRINT_D(TX_DBG, "Writing VMM table ... with Size = %d\n", ((i + 1) * 4));
758                                 break;
759                         } else {
760                                 counter++;
761                                 if (counter > 200) {
762                                         counter = 0;
763                                         PRINT_D(TX_DBG, "Looping in tx ctrl , forcce quit\n");
764                                         ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, 0);
765                                         break;
766                                 }
767                                 PRINT_WRN(GENERIC_DBG, "[wilc txq]: warn, vmm table not clear yet, wait...\n");
768                                 release_bus(wilc, RELEASE_ALLOW_SLEEP);
769                                 usleep_range(3000, 3000);
770                                 acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
771                         }
772                 } while (!wilc->quit);
773
774                 if (!ret)
775                         goto _end_;
776
777                 timeout = 200;
778                 do {
779                         ret = wilc->hif_func->hif_block_tx(wilc, WILC_VMM_TBL_RX_SHADOW_BASE, (u8 *)vmm_table, ((i + 1) * 4));
780                         if (!ret) {
781                                 wilc_debug(N_ERR, "ERR block TX of VMM table.\n");
782                                 break;
783                         }
784
785                         ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_VMM_CTL,
786                                                         0x2);
787                         if (!ret) {
788                                 wilc_debug(N_ERR, "[wilc txq]: fail can't write reg host_vmm_ctl..\n");
789                                 break;
790                         }
791
792                         do {
793                                 ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
794                                 if (!ret) {
795                                         wilc_debug(N_ERR, "[wilc txq]: fail can't read reg host_vmm_ctl..\n");
796                                         break;
797                                 }
798                                 if ((reg >> 2) & 0x1) {
799                                         entries = ((reg >> 3) & 0x3f);
800                                         break;
801                                 } else {
802                                         release_bus(wilc, RELEASE_ALLOW_SLEEP);
803                                         usleep_range(3000, 3000);
804                                         acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
805                                         PRINT_WRN(GENERIC_DBG, "Can't get VMM entery - reg = %2x\n", reg);
806                                 }
807                         } while (--timeout);
808                         if (timeout <= 0) {
809                                 ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
810                                 break;
811                         }
812
813                         if (!ret)
814                                 break;
815
816                         if (entries == 0) {
817                                 PRINT_WRN(GENERIC_DBG, "[wilc txq]: no more buffer in the chip (reg: %08x), retry later [[ %d, %x ]]\n", reg, i, vmm_table[i - 1]);
818
819                                 ret = wilc->hif_func->hif_read_reg(wilc, WILC_HOST_TX_CTRL, &reg);
820                                 if (!ret) {
821                                         wilc_debug(N_ERR, "[wilc txq]: fail can't read reg WILC_HOST_TX_CTRL..\n");
822                                         break;
823                                 }
824                                 reg &= ~BIT(0);
825                                 ret = wilc->hif_func->hif_write_reg(wilc, WILC_HOST_TX_CTRL, reg);
826                                 if (!ret) {
827                                         wilc_debug(N_ERR, "[wilc txq]: fail can't write reg WILC_HOST_TX_CTRL..\n");
828                                         break;
829                                 }
830                                 break;
831                         } else {
832                                 break;
833                         }
834                 } while (1);
835
836                 if (!ret)
837                         goto _end_;
838
839                 if (entries == 0) {
840                         ret = WILC_TX_ERR_NO_BUF;
841                         goto _end_;
842                 }
843
844                 release_bus(wilc, RELEASE_ALLOW_SLEEP);
845
846                 offset = 0;
847                 i = 0;
848                 do {
849                         tqe = wilc_wlan_txq_remove_from_head(dev);
850                         if (tqe && (vmm_table[i] != 0)) {
851                                 u32 header, buffer_offset;
852
853                                 vmm_table[i] = cpu_to_le32(vmm_table[i]);
854                                 vmm_sz = (vmm_table[i] & 0x3ff);
855                                 vmm_sz *= 4;
856                                 header = (tqe->type << 31) |
857                                          (tqe->buffer_size << 15) |
858                                          vmm_sz;
859                                 if (tqe->type == WILC_MGMT_PKT)
860                                         header |= BIT(30);
861                                 else
862                                         header &= ~BIT(30);
863
864                                 header = cpu_to_le32(header);
865                                 memcpy(&txb[offset], &header, 4);
866                                 if (tqe->type == WILC_CFG_PKT) {
867                                         buffer_offset = ETH_CONFIG_PKT_HDR_OFFSET;
868                                 } else if (tqe->type == WILC_NET_PKT) {
869                                         char *bssid = ((struct tx_complete_data *)(tqe->priv))->pBssid;
870
871                                         buffer_offset = ETH_ETHERNET_HDR_OFFSET;
872                                         memcpy(&txb[offset + 4], bssid, 6);
873                                 } else {
874                                         buffer_offset = HOST_HDR_OFFSET;
875                                 }
876
877                                 memcpy(&txb[offset + buffer_offset],
878                                        tqe->buffer, tqe->buffer_size);
879                                 offset += vmm_sz;
880                                 i++;
881                                 tqe->status = 1;
882                                 if (tqe->tx_complete_func)
883                                         tqe->tx_complete_func(tqe->priv,
884                                                               tqe->status);
885                                 #ifdef TCP_ACK_FILTER
886                                 if (tqe->tcp_pending_ack_idx != NOT_TCP_ACK)
887                                         pending_acks_info[tqe->tcp_pending_ack_idx].txqe = NULL;
888                                 #endif
889                                 kfree(tqe);
890                         } else {
891                                 break;
892                         }
893                 } while (--entries);
894
895                 acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
896
897                 ret = wilc->hif_func->hif_clear_int_ext(wilc, ENABLE_TX_VMM);
898                 if (!ret) {
899                         wilc_debug(N_ERR, "[wilc txq]: fail can't start tx VMM ...\n");
900                         goto _end_;
901                 }
902
903                 ret = wilc->hif_func->hif_block_tx_ext(wilc, 0, txb, offset);
904                 if (!ret) {
905                         wilc_debug(N_ERR, "[wilc txq]: fail can't block tx ext...\n");
906                         goto _end_;
907                 }
908
909 _end_:
910
911                 release_bus(wilc, RELEASE_ALLOW_SLEEP);
912                 if (ret != 1)
913                         break;
914         } while (0);
915         up(&wilc->txq_add_to_head_cs);
916
917         wilc->txq_exit = 1;
918         PRINT_D(TX_DBG, "THREAD: Exiting txq\n");
919         *txq_count = wilc->txq_entries;
920         return ret;
921 }
922
923 static void wilc_wlan_handle_rxq(struct wilc *wilc)
924 {
925         int offset = 0, size, has_packet = 0;
926         u8 *buffer;
927         struct rxq_entry_t *rqe;
928
929         wilc->rxq_exit = 0;
930
931         do {
932                 if (wilc->quit) {
933                         PRINT_D(RX_DBG, "exit 1st do-while due to Clean_UP function\n");
934                         up(&wilc->cfg_event);
935                         break;
936                 }
937                 rqe = wilc_wlan_rxq_remove(wilc);
938                 if (!rqe) {
939                         PRINT_D(RX_DBG, "nothing in the queue - exit 1st do-while\n");
940                         break;
941                 }
942                 buffer = rqe->buffer;
943                 size = rqe->buffer_size;
944                 PRINT_D(RX_DBG, "rxQ entery Size = %d - Address = %p\n",
945                         size, buffer);
946                 offset = 0;
947
948                 do {
949                         u32 header;
950                         u32 pkt_len, pkt_offset, tp_len;
951                         int is_cfg_packet;
952
953                         PRINT_D(RX_DBG, "In the 2nd do-while\n");
954                         memcpy(&header, &buffer[offset], 4);
955                         header = cpu_to_le32(header);
956                         PRINT_D(RX_DBG, "Header = %04x - Offset = %d\n",
957                                 header, offset);
958
959                         is_cfg_packet = (header >> 31) & 0x1;
960                         pkt_offset = (header >> 22) & 0x1ff;
961                         tp_len = (header >> 11) & 0x7ff;
962                         pkt_len = header & 0x7ff;
963
964                         if (pkt_len == 0 || tp_len == 0) {
965                                 wilc_debug(N_RXQ, "[wilc rxq]: data corrupt, packet len or tp_len is 0 [%d][%d]\n", pkt_len, tp_len);
966                                 break;
967                         }
968
969                         #define IS_MANAGMEMENT                          0x100
970                         #define IS_MANAGMEMENT_CALLBACK                 0x080
971                         #define IS_MGMT_STATUS_SUCCES                   0x040
972
973                         if (pkt_offset & IS_MANAGMEMENT) {
974                                 pkt_offset &= ~(IS_MANAGMEMENT |
975                                                 IS_MANAGMEMENT_CALLBACK |
976                                                 IS_MGMT_STATUS_SUCCES);
977
978                                 WILC_WFI_mgmt_rx(wilc, &buffer[offset + HOST_HDR_OFFSET], pkt_len);
979                         } else {
980                                 if (!is_cfg_packet) {
981                                         if (pkt_len > 0) {
982                                                 wilc_frmw_to_linux(wilc,
983                                                               &buffer[offset],
984                                                               pkt_len,
985                                                               pkt_offset);
986                                                 has_packet = 1;
987                                         }
988                                 } else {
989                                         struct wilc_cfg_rsp rsp;
990
991                                         wilc_wlan_cfg_indicate_rx(wilc, &buffer[pkt_offset + offset], pkt_len, &rsp);
992                                         if (rsp.type == WILC_CFG_RSP) {
993                                                 PRINT_D(RX_DBG, "wilc->cfg_seq_no = %d - rsp.seq_no = %d\n", wilc->cfg_seq_no, rsp.seq_no);
994                                                 if (wilc->cfg_seq_no == rsp.seq_no)
995                                                         up(&wilc->cfg_event);
996                                         } else if (rsp.type == WILC_CFG_RSP_STATUS) {
997                                                 wilc_mac_indicate(wilc, WILC_MAC_INDICATE_STATUS);
998
999                                         } else if (rsp.type == WILC_CFG_RSP_SCAN) {
1000                                                 wilc_mac_indicate(wilc, WILC_MAC_INDICATE_SCAN);
1001                                         }
1002                                 }
1003                         }
1004                         offset += tp_len;
1005                         if (offset >= size)
1006                                 break;
1007                 } while (1);
1008                 kfree(rqe);
1009
1010                 if (has_packet)
1011                         wilc_rx_complete(wilc);
1012
1013         } while (1);
1014
1015         wilc->rxq_exit = 1;
1016         PRINT_D(RX_DBG, "THREAD: Exiting RX thread\n");
1017 }
1018
1019 static void wilc_unknown_isr_ext(struct wilc *wilc)
1020 {
1021         wilc->hif_func->hif_clear_int_ext(wilc, 0);
1022 }
1023
1024 static void wilc_pllupdate_isr_ext(struct wilc *wilc, u32 int_stats)
1025 {
1026         int trials = 10;
1027
1028         wilc->hif_func->hif_clear_int_ext(wilc, PLL_INT_CLR);
1029
1030         if (wilc->io_type == HIF_SDIO)
1031                 mdelay(WILC_PLL_TO_SDIO);
1032         else
1033                 mdelay(WILC_PLL_TO_SPI);
1034
1035         while (!(ISWILC1000(wilc_get_chipid(wilc, true)) && --trials)) {
1036                 PRINT_D(TX_DBG, "PLL update retrying\n");
1037                 mdelay(1);
1038         }
1039 }
1040
1041 static void wilc_sleeptimer_isr_ext(struct wilc *wilc, u32 int_stats1)
1042 {
1043         wilc->hif_func->hif_clear_int_ext(wilc, SLEEP_INT_CLR);
1044 #ifndef WILC_OPTIMIZE_SLEEP_INT
1045         chip_ps_state = CHIP_SLEEPING_AUTO;
1046 #endif
1047 }
1048
1049 static void wilc_wlan_handle_isr_ext(struct wilc *wilc, u32 int_status)
1050 {
1051         u32 offset = wilc->rx_buffer_offset;
1052         u8 *buffer = NULL;
1053         u32 size;
1054         u32 retries = 0;
1055         int ret = 0;
1056         struct rxq_entry_t *rqe;
1057
1058         size = ((int_status & 0x7fff) << 2);
1059
1060         while (!size && retries < 10) {
1061                 u32 time = 0;
1062
1063                 wilc_debug(N_ERR, "RX Size equal zero ... Trying to read it again for %d time\n", time++);
1064                 wilc->hif_func->hif_read_size(wilc, &size);
1065                 size = ((size & 0x7fff) << 2);
1066                 retries++;
1067         }
1068
1069         if (size > 0) {
1070                 if (LINUX_RX_SIZE - offset < size)
1071                         offset = 0;
1072
1073                 if (wilc->rx_buffer) {
1074                         buffer = &wilc->rx_buffer[offset];
1075                 } else {
1076                         wilc_debug(N_ERR, "[wilc isr]: fail Rx Buffer is NULL...drop the packets (%d)\n", size);
1077                         goto _end_;
1078                 }
1079
1080                 wilc->hif_func->hif_clear_int_ext(wilc,
1081                                               DATA_INT_CLR | ENABLE_RX_VMM);
1082                 ret = wilc->hif_func->hif_block_rx_ext(wilc, 0, buffer, size);
1083
1084                 if (!ret) {
1085                         wilc_debug(N_ERR, "[wilc isr]: fail block rx...\n");
1086                         goto _end_;
1087                 }
1088 _end_:
1089                 if (ret) {
1090                         offset += size;
1091                         wilc->rx_buffer_offset = offset;
1092                         rqe = kmalloc(sizeof(*rqe), GFP_KERNEL);
1093                         if (rqe) {
1094                                 rqe->buffer = buffer;
1095                                 rqe->buffer_size = size;
1096                                 PRINT_D(RX_DBG, "rxq entery Size= %d - Address = %p\n", rqe->buffer_size, rqe->buffer);
1097                                 wilc_wlan_rxq_add(wilc, rqe);
1098                         }
1099                 }
1100         }
1101         wilc_wlan_handle_rxq(wilc);
1102 }
1103
1104 void wilc_handle_isr(struct wilc *wilc)
1105 {
1106         u32 int_status;
1107
1108         acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
1109         wilc->hif_func->hif_read_int(wilc, &int_status);
1110
1111         if (int_status & PLL_INT_EXT)
1112                 wilc_pllupdate_isr_ext(wilc, int_status);
1113
1114         if (int_status & DATA_INT_EXT) {
1115                 wilc_wlan_handle_isr_ext(wilc, int_status);
1116         #ifndef WILC_OPTIMIZE_SLEEP_INT
1117                 chip_ps_state = CHIP_WAKEDUP;
1118         #endif
1119         }
1120         if (int_status & SLEEP_INT_EXT)
1121                 wilc_sleeptimer_isr_ext(wilc, int_status);
1122
1123         if (!(int_status & (ALL_INT_EXT))) {
1124                 wilc_unknown_isr_ext(wilc);
1125         }
1126         release_bus(wilc, RELEASE_ALLOW_SLEEP);
1127 }
1128 EXPORT_SYMBOL_GPL(wilc_handle_isr);
1129
1130 int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer, u32 buffer_size)
1131 {
1132         u32 offset;
1133         u32 addr, size, size2, blksz;
1134         u8 *dma_buffer;
1135         int ret = 0;
1136
1137         blksz = BIT(12);
1138
1139         dma_buffer = kmalloc(blksz, GFP_KERNEL);
1140         if (!dma_buffer) {
1141                 ret = -EIO;
1142                 PRINT_ER("Can't allocate buffer for firmware download IO error\n ");
1143                 goto _fail_1;
1144         }
1145
1146         PRINT_D(INIT_DBG, "Downloading firmware size = %d ...\n", buffer_size);
1147
1148         offset = 0;
1149         do {
1150                 memcpy(&addr, &buffer[offset], 4);
1151                 memcpy(&size, &buffer[offset + 4], 4);
1152                 addr = cpu_to_le32(addr);
1153                 size = cpu_to_le32(size);
1154                 acquire_bus(wilc, ACQUIRE_ONLY);
1155                 offset += 8;
1156                 while (((int)size) && (offset < buffer_size)) {
1157                         if (size <= blksz)
1158                                 size2 = size;
1159                         else
1160                                 size2 = blksz;
1161
1162                         memcpy(dma_buffer, &buffer[offset], size2);
1163                         ret = wilc->hif_func->hif_block_tx(wilc, addr, dma_buffer,
1164                                                        size2);
1165                         if (!ret)
1166                                 break;
1167
1168                         addr += size2;
1169                         offset += size2;
1170                         size -= size2;
1171                 }
1172                 release_bus(wilc, RELEASE_ONLY);
1173
1174                 if (!ret) {
1175                         ret = -EIO;
1176                         PRINT_ER("Can't download firmware IO error\n ");
1177                         goto _fail_;
1178                 }
1179                 PRINT_D(INIT_DBG, "Offset = %d\n", offset);
1180         } while (offset < buffer_size);
1181
1182 _fail_:
1183
1184         kfree(dma_buffer);
1185
1186 _fail_1:
1187
1188         return (ret < 0) ? ret : 0;
1189 }
1190
1191 int wilc_wlan_start(struct wilc *wilc)
1192 {
1193         u32 reg = 0;
1194         int ret;
1195         u32 chipid;
1196
1197         if (wilc->io_type == HIF_SDIO) {
1198                 reg = 0;
1199                 reg |= BIT(3);
1200         } else if (wilc->io_type == HIF_SPI) {
1201                 reg = 1;
1202         }
1203         acquire_bus(wilc, ACQUIRE_ONLY);
1204         ret = wilc->hif_func->hif_write_reg(wilc, WILC_VMM_CORE_CFG, reg);
1205         if (!ret) {
1206                 wilc_debug(N_ERR, "[wilc start]: fail write reg vmm_core_cfg...\n");
1207                 release_bus(wilc, RELEASE_ONLY);
1208                 ret = -EIO;
1209                 return ret;
1210         }
1211         reg = 0;
1212         if (wilc->io_type == HIF_SDIO && wilc->dev_irq_num)
1213                 reg |= WILC_HAVE_SDIO_IRQ_GPIO;
1214
1215 #ifdef WILC_DISABLE_PMU
1216 #else
1217         reg |= WILC_HAVE_USE_PMU;
1218 #endif
1219
1220 #ifdef WILC_SLEEP_CLK_SRC_XO
1221         reg |= WILC_HAVE_SLEEP_CLK_SRC_XO;
1222 #elif defined WILC_SLEEP_CLK_SRC_RTC
1223         reg |= WILC_HAVE_SLEEP_CLK_SRC_RTC;
1224 #endif
1225
1226 #ifdef WILC_EXT_PA_INV_TX_RX
1227         reg |= WILC_HAVE_EXT_PA_INV_TX_RX;
1228 #endif
1229
1230         reg |= WILC_HAVE_LEGACY_RF_SETTINGS;
1231 #ifdef XTAL_24
1232         reg |= WILC_HAVE_XTAL_24;
1233 #endif
1234 #ifdef DISABLE_WILC_UART
1235         reg |= WILC_HAVE_DISABLE_WILC_UART;
1236 #endif
1237
1238         ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
1239         if (!ret) {
1240                 wilc_debug(N_ERR, "[wilc start]: fail write WILC_GP_REG_1 ...\n");
1241                 release_bus(wilc, RELEASE_ONLY);
1242                 ret = -EIO;
1243                 return ret;
1244         }
1245
1246         wilc->hif_func->hif_sync_ext(wilc, NUM_INT_EXT);
1247
1248         ret = wilc->hif_func->hif_read_reg(wilc, 0x1000, &chipid);
1249         if (!ret) {
1250                 wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1000 ...\n");
1251                 release_bus(wilc, RELEASE_ONLY);
1252                 ret = -EIO;
1253                 return ret;
1254         }
1255
1256         wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1257         if ((reg & BIT(10)) == BIT(10)) {
1258                 reg &= ~BIT(10);
1259                 wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1260                 wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1261         }
1262
1263         reg |= BIT(10);
1264         ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1265         wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1266         release_bus(wilc, RELEASE_ONLY);
1267
1268         return (ret < 0) ? ret : 0;
1269 }
1270
1271 void wilc_wlan_global_reset(struct wilc *wilc)
1272 {
1273         acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
1274         wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, 0x0);
1275         release_bus(wilc, RELEASE_ONLY);
1276 }
1277 int wilc_wlan_stop(struct wilc *wilc)
1278 {
1279         u32 reg = 0;
1280         int ret;
1281         u8 timeout = 10;
1282         acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
1283
1284         ret = wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1285         if (!ret) {
1286                 PRINT_ER("Error while reading reg\n");
1287                 release_bus(wilc, RELEASE_ALLOW_SLEEP);
1288                 return ret;
1289         }
1290
1291         reg &= ~BIT(10);
1292         ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1293         if (!ret) {
1294                 PRINT_ER("Error while writing reg\n");
1295                 release_bus(wilc, RELEASE_ALLOW_SLEEP);
1296                 return ret;
1297         }
1298
1299         do {
1300                 ret = wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0, &reg);
1301                 if (!ret) {
1302                         PRINT_ER("Error while reading reg\n");
1303                         release_bus(wilc, RELEASE_ALLOW_SLEEP);
1304                         return ret;
1305                 }
1306                 PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n",
1307                         reg, timeout);
1308
1309                 if ((reg & BIT(10))) {
1310                         PRINT_D(GENERIC_DBG, "Bit 10 not reset : Retry %d\n",
1311                                 timeout);
1312                         reg &= ~BIT(10);
1313                         ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0,
1314                                                         reg);
1315                         timeout--;
1316                 } else {
1317                         PRINT_D(GENERIC_DBG, "Bit 10 reset after : Retry %d\n",
1318                                 timeout);
1319                         ret = wilc->hif_func->hif_read_reg(wilc, WILC_GLB_RESET_0,
1320                                                        &reg);
1321                         if (!ret) {
1322                                 PRINT_ER("Error while reading reg\n");
1323                                 release_bus(wilc, RELEASE_ALLOW_SLEEP);
1324                                 return ret;
1325                         }
1326                         PRINT_D(GENERIC_DBG, "Read RESET Reg %x : Retry%d\n",
1327                                 reg, timeout);
1328                         break;
1329                 }
1330
1331         } while (timeout);
1332         reg = (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(8) | BIT(9) | BIT(26) |
1333                BIT(29) | BIT(30) | BIT(31));
1334
1335         wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1336         reg = (u32)~BIT(10);
1337
1338         ret = wilc->hif_func->hif_write_reg(wilc, WILC_GLB_RESET_0, reg);
1339
1340         release_bus(wilc, RELEASE_ALLOW_SLEEP);
1341
1342         return ret;
1343 }
1344
1345 void wilc_wlan_cleanup(struct net_device *dev)
1346 {
1347         struct txq_entry_t *tqe;
1348         struct rxq_entry_t *rqe;
1349         u32 reg = 0;
1350         int ret;
1351         struct wilc_vif *vif;
1352         struct wilc *wilc;
1353
1354         vif = netdev_priv(dev);
1355         wilc = vif->wilc;
1356
1357         wilc->quit = 1;
1358         do {
1359                 tqe = wilc_wlan_txq_remove_from_head(dev);
1360                 if (!tqe)
1361                         break;
1362                 if (tqe->tx_complete_func)
1363                         tqe->tx_complete_func(tqe->priv, 0);
1364                 kfree(tqe);
1365         } while (1);
1366
1367         do {
1368                 rqe = wilc_wlan_rxq_remove(wilc);
1369                 if (!rqe)
1370                         break;
1371                 kfree(rqe);
1372         } while (1);
1373
1374         kfree(wilc->rx_buffer);
1375         wilc->rx_buffer = NULL;
1376         kfree(wilc->tx_buffer);
1377         wilc->tx_buffer = NULL;
1378
1379         acquire_bus(wilc, ACQUIRE_AND_WAKEUP);
1380
1381         ret = wilc->hif_func->hif_read_reg(wilc, WILC_GP_REG_0, &reg);
1382         if (!ret) {
1383                 PRINT_ER("Error while reading reg\n");
1384                 release_bus(wilc, RELEASE_ALLOW_SLEEP);
1385         }
1386         PRINT_ER("Writing ABORT reg\n");
1387         ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_0,
1388                                         (reg | ABORT_INT));
1389         if (!ret) {
1390                 PRINT_ER("Error while writing reg\n");
1391                 release_bus(wilc, RELEASE_ALLOW_SLEEP);
1392         }
1393         release_bus(wilc, RELEASE_ALLOW_SLEEP);
1394         wilc->hif_func->hif_deinit(NULL);
1395 }
1396
1397 static int wilc_wlan_cfg_commit(struct wilc *wilc, int type, u32 drv_handler)
1398 {
1399         struct wilc_cfg_frame *cfg = &wilc->cfg_frame;
1400         int total_len = wilc->cfg_frame_offset + 4 + DRIVER_HANDLER_SIZE;
1401         int seq_no = wilc->cfg_seq_no % 256;
1402         int driver_handler = (u32)drv_handler;
1403
1404         if (type == WILC_CFG_SET)
1405                 cfg->wid_header[0] = 'W';
1406         else
1407                 cfg->wid_header[0] = 'Q';
1408         cfg->wid_header[1] = seq_no;
1409         cfg->wid_header[2] = (u8)total_len;
1410         cfg->wid_header[3] = (u8)(total_len >> 8);
1411         cfg->wid_header[4] = (u8)driver_handler;
1412         cfg->wid_header[5] = (u8)(driver_handler >> 8);
1413         cfg->wid_header[6] = (u8)(driver_handler >> 16);
1414         cfg->wid_header[7] = (u8)(driver_handler >> 24);
1415         wilc->cfg_seq_no = seq_no;
1416
1417         if (!wilc_wlan_txq_add_cfg_pkt(wilc, &cfg->wid_header[0], total_len))
1418                 return -1;
1419
1420         return 0;
1421 }
1422
1423 int wilc_wlan_cfg_set(struct wilc *wilc, int start, u32 wid, u8 *buffer,
1424                       u32 buffer_size, int commit, u32 drv_handler)
1425 {
1426         u32 offset;
1427         int ret_size;
1428
1429         if (wilc->cfg_frame_in_use)
1430                 return 0;
1431
1432         if (start)
1433                 wilc->cfg_frame_offset = 0;
1434
1435         offset = wilc->cfg_frame_offset;
1436         ret_size = wilc_wlan_cfg_set_wid(wilc->cfg_frame.frame, offset,
1437                                          (u16)wid, buffer, buffer_size);
1438         offset += ret_size;
1439         wilc->cfg_frame_offset = offset;
1440
1441         if (commit) {
1442                 PRINT_D(TX_DBG, "[WILC]PACKET Commit with sequence number %d\n",
1443                         wilc->cfg_seq_no);
1444                 PRINT_D(RX_DBG, "Processing cfg_set()\n");
1445                 wilc->cfg_frame_in_use = 1;
1446
1447                 if (wilc_wlan_cfg_commit(wilc, WILC_CFG_SET, drv_handler))
1448                         ret_size = 0;
1449
1450                 if (wilc_lock_timeout(wilc, &wilc->cfg_event,
1451                                             CFG_PKTS_TIMEOUT)) {
1452                         PRINT_D(TX_DBG, "Set Timed Out\n");
1453                         ret_size = 0;
1454                 }
1455                 wilc->cfg_frame_in_use = 0;
1456                 wilc->cfg_frame_offset = 0;
1457                 wilc->cfg_seq_no += 1;
1458         }
1459
1460         return ret_size;
1461 }
1462
1463 int wilc_wlan_cfg_get(struct wilc *wilc, int start, u32 wid, int commit,
1464                       u32 drv_handler)
1465 {
1466         u32 offset;
1467         int ret_size;
1468
1469         if (wilc->cfg_frame_in_use)
1470                 return 0;
1471
1472         if (start)
1473                 wilc->cfg_frame_offset = 0;
1474
1475         offset = wilc->cfg_frame_offset;
1476         ret_size = wilc_wlan_cfg_get_wid(wilc->cfg_frame.frame, offset,
1477                                          (u16)wid);
1478         offset += ret_size;
1479         wilc->cfg_frame_offset = offset;
1480
1481         if (commit) {
1482                 wilc->cfg_frame_in_use = 1;
1483
1484                 if (wilc_wlan_cfg_commit(wilc, WILC_CFG_QUERY, drv_handler))
1485                         ret_size = 0;
1486
1487                 if (wilc_lock_timeout(wilc, &wilc->cfg_event,
1488                                             CFG_PKTS_TIMEOUT)) {
1489                         PRINT_D(TX_DBG, "Get Timed Out\n");
1490                         ret_size = 0;
1491                 }
1492                 PRINT_D(GENERIC_DBG, "[WILC]Get Response received\n");
1493                 wilc->cfg_frame_in_use = 0;
1494                 wilc->cfg_frame_offset = 0;
1495                 wilc->cfg_seq_no += 1;
1496         }
1497
1498         return ret_size;
1499 }
1500
1501 int wilc_wlan_cfg_get_val(u32 wid, u8 *buffer, u32 buffer_size)
1502 {
1503         int ret;
1504
1505         ret = wilc_wlan_cfg_get_wid_value((u16)wid, buffer, buffer_size);
1506
1507         return ret;
1508 }
1509
1510 static u32 init_chip(struct net_device *dev)
1511 {
1512         u32 chipid;
1513         u32 reg, ret = 0;
1514         struct wilc_vif *vif;
1515         struct wilc *wilc;
1516
1517         vif = netdev_priv(dev);
1518         wilc = vif->wilc;
1519
1520         acquire_bus(wilc, ACQUIRE_ONLY);
1521
1522         chipid = wilc_get_chipid(wilc, true);
1523
1524         if ((chipid & 0xfff) != 0xa0) {
1525                 ret = wilc->hif_func->hif_read_reg(wilc, 0x1118, &reg);
1526                 if (!ret) {
1527                         wilc_debug(N_ERR, "[wilc start]: fail read reg 0x1118 ...\n");
1528                         return ret;
1529                 }
1530                 reg |= BIT(0);
1531                 ret = wilc->hif_func->hif_write_reg(wilc, 0x1118, reg);
1532                 if (!ret) {
1533                         wilc_debug(N_ERR, "[wilc start]: fail write reg 0x1118 ...\n");
1534                         return ret;
1535                 }
1536                 ret = wilc->hif_func->hif_write_reg(wilc, 0xc0000, 0x71);
1537                 if (!ret) {
1538                         wilc_debug(N_ERR, "[wilc start]: fail write reg 0xc0000 ...\n");
1539                         return ret;
1540                 }
1541         }
1542
1543         release_bus(wilc, RELEASE_ONLY);
1544
1545         return ret;
1546 }
1547
1548 u32 wilc_get_chipid(struct wilc *wilc, u8 update)
1549 {
1550         static u32 chipid;
1551         u32 tempchipid = 0;
1552         u32 rfrevid;
1553
1554         if (chipid == 0 || update != 0) {
1555                 wilc->hif_func->hif_read_reg(wilc, 0x1000, &tempchipid);
1556                 wilc->hif_func->hif_read_reg(wilc, 0x13f4, &rfrevid);
1557                 if (!ISWILC1000(tempchipid)) {
1558                         chipid = 0;
1559                         goto _fail_;
1560                 }
1561                 if (tempchipid == 0x1002a0) {
1562                         if (rfrevid == 0x1) {
1563                         } else {
1564                                 tempchipid = 0x1002a1;
1565                         }
1566                 } else if (tempchipid == 0x1002b0) {
1567                         if (rfrevid == 3) {
1568                         } else if (rfrevid == 4) {
1569                                 tempchipid = 0x1002b1;
1570                         } else {
1571                                 tempchipid = 0x1002b2;
1572                         }
1573                 }
1574
1575                 chipid = tempchipid;
1576         }
1577 _fail_:
1578         return chipid;
1579 }
1580
1581 int wilc_wlan_init(struct net_device *dev)
1582 {
1583         int ret = 0;
1584         struct wilc_vif *vif = netdev_priv(dev);
1585         struct wilc *wilc;
1586
1587         wilc = vif->wilc;
1588
1589         PRINT_D(INIT_DBG, "Initializing WILC_Wlan ...\n");
1590
1591         if (!wilc->hif_func->hif_init(wilc)) {
1592                 ret = -EIO;
1593                 goto _fail_;
1594         }
1595
1596         if (!wilc_wlan_cfg_init(wilc_debug)) {
1597                 ret = -ENOBUFS;
1598                 goto _fail_;
1599         }
1600
1601         if (!wilc->tx_buffer)
1602                 wilc->tx_buffer = kmalloc(LINUX_TX_SIZE, GFP_KERNEL);
1603         PRINT_D(TX_DBG, "wilc->tx_buffer = %p\n", wilc->tx_buffer);
1604
1605         if (!wilc->tx_buffer) {
1606                 ret = -ENOBUFS;
1607                 PRINT_ER("Can't allocate Tx Buffer");
1608                 goto _fail_;
1609         }
1610
1611         if (!wilc->rx_buffer)
1612                 wilc->rx_buffer = kmalloc(LINUX_RX_SIZE, GFP_KERNEL);
1613         PRINT_D(TX_DBG, "wilc->rx_buffer =%p\n", wilc->rx_buffer);
1614         if (!wilc->rx_buffer) {
1615                 ret = -ENOBUFS;
1616                 PRINT_ER("Can't allocate Rx Buffer");
1617                 goto _fail_;
1618         }
1619
1620         if (!init_chip(dev)) {
1621                 ret = -EIO;
1622                 goto _fail_;
1623         }
1624 #ifdef  TCP_ACK_FILTER
1625         init_tcp_tracking();
1626 #endif
1627
1628         return 1;
1629
1630 _fail_:
1631
1632         kfree(wilc->rx_buffer);
1633         wilc->rx_buffer = NULL;
1634         kfree(wilc->tx_buffer);
1635         wilc->tx_buffer = NULL;
1636
1637         return ret;
1638 }
1639
1640 u16 wilc_set_machw_change_vir_if(struct net_device *dev, bool value)
1641 {
1642         u16 ret;
1643         u32 reg;
1644         struct wilc_vif *vif;
1645         struct wilc *wilc;
1646
1647         vif = netdev_priv(dev);
1648         wilc = vif->wilc;
1649
1650         mutex_lock(&wilc->hif_cs);
1651         ret = wilc->hif_func->hif_read_reg(wilc, WILC_CHANGING_VIR_IF,
1652                                                &reg);
1653         if (!ret)
1654                 PRINT_ER("Error while Reading reg WILC_CHANGING_VIR_IF\n");
1655
1656         if (value)
1657                 reg |= BIT(31);
1658         else
1659                 reg &= ~BIT(31);
1660
1661         ret = wilc->hif_func->hif_write_reg(wilc, WILC_CHANGING_VIR_IF,
1662                                                 reg);
1663
1664         if (!ret)
1665                 PRINT_ER("Error while writing reg WILC_CHANGING_VIR_IF\n");
1666
1667         mutex_unlock(&wilc->hif_cs);
1668
1669         return ret;
1670 }