16b9d76478b17208fc2567cf1e7e5bc7f9320afa
[cascardo/linux.git] / drivers / staging / ks7010 / ks7010_sdio.c
1 /*
2  *   Driver for KeyStream, KS7010 based SDIO cards.
3  *
4  *   Copyright (C) 2006-2008 KeyStream Corp.
5  *   Copyright (C) 2009 Renesas Technology Corp.
6  *   Copyright (C) 2016 Sang Engineering, Wolfram Sang
7  *
8  *   This program is free software; you can redistribute it and/or modify
9  *   it under the terms of the GNU General Public License version 2 as
10  *   published by the Free Software Foundation.
11  */
12
13 #include <linux/firmware.h>
14 #include <linux/mmc/card.h>
15 #include <linux/mmc/sdio_func.h>
16 #include <linux/workqueue.h>
17 #include <asm/atomic.h>
18
19 #include "ks_wlan.h"
20 #include "ks_wlan_ioctl.h"
21 #include "ks_hostif.h"
22 #include "ks7010_sdio.h"
23
24 #define KS7010_FUNC_NUM 1
25 #define KS7010_IO_BLOCK_SIZE 512
26 #define KS7010_MAX_CLOCK 25000000
27
28 static int reg_net = 0;
29
30 static const struct sdio_device_id ks7010_sdio_ids[] = {
31         {SDIO_DEVICE(SDIO_VENDOR_ID_KS_CODE_A, SDIO_DEVICE_ID_KS_7010)},
32         {SDIO_DEVICE(SDIO_VENDOR_ID_KS_CODE_B, SDIO_DEVICE_ID_KS_7010)},
33         { /* all zero */ }
34 };
35 MODULE_DEVICE_TABLE(sdio, ks7010_sdio_ids);
36
37 /* macro */
38
39 #define inc_txqhead(priv) \
40         ( priv->tx_dev.qhead = (priv->tx_dev.qhead + 1) % TX_DEVICE_BUFF_SIZE )
41 #define inc_txqtail(priv) \
42         ( priv->tx_dev.qtail = (priv->tx_dev.qtail + 1) % TX_DEVICE_BUFF_SIZE )
43 #define cnt_txqbody(priv) \
44         (((priv->tx_dev.qtail + TX_DEVICE_BUFF_SIZE) - (priv->tx_dev.qhead)) % TX_DEVICE_BUFF_SIZE )
45
46 #define inc_rxqhead(priv) \
47         ( priv->rx_dev.qhead = (priv->rx_dev.qhead + 1) % RX_DEVICE_BUFF_SIZE )
48 #define inc_rxqtail(priv) \
49         ( priv->rx_dev.qtail = (priv->rx_dev.qtail + 1) % RX_DEVICE_BUFF_SIZE )
50 #define cnt_rxqbody(priv) \
51         (((priv->rx_dev.qtail + RX_DEVICE_BUFF_SIZE) - (priv->rx_dev.qhead)) % RX_DEVICE_BUFF_SIZE )
52
53 static int ks7010_sdio_read(struct ks_wlan_private *priv, unsigned int address,
54                             unsigned char *buffer, int length)
55 {
56         struct ks_sdio_card *card;
57         int rc;
58
59         card = priv->ks_wlan_hw.sdio_card;
60
61         if (length == 1)        /* CMD52 */
62                 *buffer = sdio_readb(card->func, address, &rc);
63         else    /* CMD53 multi-block transfer */
64                 rc = sdio_memcpy_fromio(card->func, buffer, address, length);
65
66         if (rc != 0)
67                 DPRINTK(1, "sdio error=%d size=%d\n", rc, length);
68
69         return rc;
70 }
71
72 static int ks7010_sdio_write(struct ks_wlan_private *priv, unsigned int address,
73                              unsigned char *buffer, int length)
74 {
75         struct ks_sdio_card *card;
76         int rc;
77
78         card = priv->ks_wlan_hw.sdio_card;
79
80         if (length == 1)        /* CMD52 */
81                 sdio_writeb(card->func, *buffer, (unsigned int)address, &rc);
82         else    /* CMD53 */
83                 rc = sdio_memcpy_toio(card->func, (unsigned int)address, buffer,
84                                       length);
85
86         if (rc != 0)
87                 DPRINTK(1, "sdio error=%d size=%d\n", rc, length);
88
89         return rc;
90 }
91
92 void ks_wlan_hw_sleep_doze_request(struct ks_wlan_private *priv)
93 {
94         unsigned char rw_data;
95         int retval;
96
97         DPRINTK(4, "\n");
98
99         /* clear request */
100         atomic_set(&priv->sleepstatus.doze_request, 0);
101
102         if (atomic_read(&priv->sleepstatus.status) == 0) {
103                 rw_data = GCR_B_DOZE;
104                 retval =
105                     ks7010_sdio_write(priv, GCR_B, &rw_data, sizeof(rw_data));
106                 if (retval) {
107                         DPRINTK(1, " error : GCR_B=%02X\n", rw_data);
108                         goto out;
109                 }
110                 DPRINTK(4, "PMG SET!! : GCR_B=%02X\n", rw_data);
111                 DPRINTK(3, "sleep_mode=SLP_SLEEP\n");
112                 atomic_set(&priv->sleepstatus.status, 1);
113                 priv->last_doze = jiffies;
114         } else {
115                 DPRINTK(1, "sleep_mode=%d\n", priv->sleep_mode);
116         }
117
118  out:
119         priv->sleep_mode = atomic_read(&priv->sleepstatus.status);
120         return;
121 }
122
123 void ks_wlan_hw_sleep_wakeup_request(struct ks_wlan_private *priv)
124 {
125         unsigned char rw_data;
126         int retval;
127
128         DPRINTK(4, "\n");
129
130         /* clear request */
131         atomic_set(&priv->sleepstatus.wakeup_request, 0);
132
133         if (atomic_read(&priv->sleepstatus.status) == 1) {
134                 rw_data = WAKEUP_REQ;
135                 retval =
136                     ks7010_sdio_write(priv, WAKEUP, &rw_data, sizeof(rw_data));
137                 if (retval) {
138                         DPRINTK(1, " error : WAKEUP=%02X\n", rw_data);
139                         goto out;
140                 }
141                 DPRINTK(4, "wake up : WAKEUP=%02X\n", rw_data);
142                 atomic_set(&priv->sleepstatus.status, 0);
143                 priv->last_wakeup = jiffies;
144                 ++priv->wakeup_count;
145         } else {
146                 DPRINTK(1, "sleep_mode=%d\n", priv->sleep_mode);
147         }
148
149  out:
150         priv->sleep_mode = atomic_read(&priv->sleepstatus.status);
151         return;
152 }
153
154 void ks_wlan_hw_wakeup_request(struct ks_wlan_private *priv)
155 {
156         unsigned char rw_data;
157         int retval;
158
159         DPRINTK(4, "\n");
160         if (atomic_read(&priv->psstatus.status) == PS_SNOOZE) {
161                 rw_data = WAKEUP_REQ;
162                 retval =
163                     ks7010_sdio_write(priv, WAKEUP, &rw_data, sizeof(rw_data));
164                 if (retval) {
165                         DPRINTK(1, " error : WAKEUP=%02X\n", rw_data);
166                 }
167                 DPRINTK(4, "wake up : WAKEUP=%02X\n", rw_data);
168                 priv->last_wakeup = jiffies;
169                 ++priv->wakeup_count;
170         } else {
171                 DPRINTK(1, "psstatus=%d\n",
172                         atomic_read(&priv->psstatus.status));
173         }
174 }
175
176 int _ks_wlan_hw_power_save(struct ks_wlan_private *priv)
177 {
178         int rc = 0;
179         unsigned char rw_data;
180         int retval;
181
182         if (priv->reg.powermgt == POWMGT_ACTIVE_MODE)
183                 return rc;
184
185         if (priv->reg.operation_mode == MODE_INFRASTRUCTURE &&
186             (priv->connect_status & CONNECT_STATUS_MASK) == CONNECT_STATUS) {
187
188                 //DPRINTK(1,"psstatus.status=%d\n",atomic_read(&priv->psstatus.status));
189                 if (priv->dev_state == DEVICE_STATE_SLEEP) {
190                         switch (atomic_read(&priv->psstatus.status)) {
191                         case PS_SNOOZE: /* 4 */
192                                 break;
193                         default:
194                                 DPRINTK(5, "\npsstatus.status=%d\npsstatus.confirm_wait=%d\npsstatus.snooze_guard=%d\ncnt_txqbody=%d\n",
195                                         atomic_read(&priv->psstatus.status),
196                                         atomic_read(&priv->psstatus.confirm_wait),
197                                         atomic_read(&priv->psstatus.snooze_guard),
198                                         cnt_txqbody(priv));
199
200                                 if (!atomic_read(&priv->psstatus.confirm_wait)
201                                     && !atomic_read(&priv->psstatus.snooze_guard)
202                                     && !cnt_txqbody(priv)) {
203                                         retval =
204                                             ks7010_sdio_read(priv, INT_PENDING,
205                                                              &rw_data,
206                                                              sizeof(rw_data));
207                                         if (retval) {
208                                                 DPRINTK(1,
209                                                         " error : INT_PENDING=%02X\n",
210                                                         rw_data);
211                                                 queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
212                                                                    &priv->ks_wlan_hw.rw_wq, 1);
213                                                 break;
214                                         }
215                                         if (!rw_data) {
216                                                 rw_data = GCR_B_DOZE;
217                                                 retval =
218                                                     ks7010_sdio_write(priv,
219                                                                       GCR_B,
220                                                                       &rw_data,
221                                                                       sizeof(rw_data));
222                                                 if (retval) {
223                                                         DPRINTK(1,
224                                                                 " error : GCR_B=%02X\n",
225                                                                 rw_data);
226                                                         queue_delayed_work
227                                                             (priv->ks_wlan_hw.ks7010sdio_wq,
228                                                              &priv->ks_wlan_hw.rw_wq, 1);
229                                                         break;
230                                                 }
231                                                 DPRINTK(4,
232                                                         "PMG SET!! : GCR_B=%02X\n",
233                                                         rw_data);
234                                                 atomic_set(&priv->psstatus.
235                                                            status, PS_SNOOZE);
236                                                 DPRINTK(3,
237                                                         "psstatus.status=PS_SNOOZE\n");
238                                         } else {
239                                                 queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
240                                                                    &priv->ks_wlan_hw.rw_wq, 1);
241                                         }
242                                 } else {
243                                         queue_delayed_work(priv->ks_wlan_hw.
244                                                            ks7010sdio_wq,
245                                                            &priv->ks_wlan_hw.rw_wq,
246                                                            0);
247                                 }
248                                 break;
249                         }
250                 }
251
252         }
253
254         return rc;
255 }
256
257 int ks_wlan_hw_power_save(struct ks_wlan_private *priv)
258 {
259         queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
260                            &priv->ks_wlan_hw.rw_wq, 1);
261         return 0;
262 }
263
264 static int enqueue_txdev(struct ks_wlan_private *priv, unsigned char *p,
265                          unsigned long size,
266                          void (*complete_handler) (void *arg1, void *arg2),
267                          void *arg1, void *arg2)
268 {
269         struct tx_device_buffer *sp;
270
271         if (priv->dev_state < DEVICE_STATE_BOOT) {
272                 kfree(p);
273                 if (complete_handler != NULL)
274                         (*complete_handler) (arg1, arg2);
275                 return 1;
276         }
277
278         if ((TX_DEVICE_BUFF_SIZE - 1) <= cnt_txqbody(priv)) {
279                 /* in case of buffer overflow */
280                 DPRINTK(1, "tx buffer overflow\n");
281                 kfree(p);
282                 if (complete_handler != NULL)
283                         (*complete_handler) (arg1, arg2);
284                 return 1;
285         }
286
287         sp = &priv->tx_dev.tx_dev_buff[priv->tx_dev.qtail];
288         sp->sendp = p;
289         sp->size = size;
290         sp->complete_handler = complete_handler;
291         sp->arg1 = arg1;
292         sp->arg2 = arg2;
293         inc_txqtail(priv);
294
295         return 0;
296 }
297
298 /* write data */
299 static int write_to_device(struct ks_wlan_private *priv, unsigned char *buffer,
300                            unsigned long size)
301 {
302         int rc, retval;
303         unsigned char rw_data;
304         struct hostif_hdr *hdr;
305         hdr = (struct hostif_hdr *)buffer;
306         rc = 0;
307
308         DPRINTK(4, "size=%d\n", hdr->size);
309         if (hdr->event < HIF_DATA_REQ || HIF_REQ_MAX < hdr->event) {
310                 DPRINTK(1, "unknown event=%04X\n", hdr->event);
311                 return 0;
312         }
313
314         retval = ks7010_sdio_write(priv, DATA_WINDOW, buffer, size);
315         if (retval) {
316                 DPRINTK(1, " write error : retval=%d\n", retval);
317                 return -4;
318         }
319
320         rw_data = WRITE_STATUS_BUSY;
321         retval =
322             ks7010_sdio_write(priv, WRITE_STATUS, &rw_data, sizeof(rw_data));
323         if (retval) {
324                 DPRINTK(1, " error : WRITE_STATUS=%02X\n", rw_data);
325                 return -3;
326         }
327
328         return 0;
329 }
330
331 static void tx_device_task(void *dev)
332 {
333         struct ks_wlan_private *priv = (struct ks_wlan_private *)dev;
334         struct tx_device_buffer *sp;
335         int rc = 0;
336
337         DPRINTK(4, "\n");
338         if (cnt_txqbody(priv) > 0
339             && atomic_read(&priv->psstatus.status) != PS_SNOOZE) {
340                 sp = &priv->tx_dev.tx_dev_buff[priv->tx_dev.qhead];
341                 if (priv->dev_state >= DEVICE_STATE_BOOT) {
342                         rc = write_to_device(priv, sp->sendp, sp->size);
343                         if (rc) {
344                                 DPRINTK(1, "write_to_device error !!(%d)\n",
345                                         rc);
346                                 queue_delayed_work(priv->ks_wlan_hw.
347                                                    ks7010sdio_wq,
348                                                    &priv->ks_wlan_hw.rw_wq, 1);
349                                 return;
350                         }
351
352                 }
353                 kfree(sp->sendp);       /* allocated memory free */
354                 if (sp->complete_handler != NULL)       /* TX Complete */
355                         (*sp->complete_handler) (sp->arg1, sp->arg2);
356                 inc_txqhead(priv);
357
358                 if (cnt_txqbody(priv) > 0) {
359                         queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
360                                            &priv->ks_wlan_hw.rw_wq, 0);
361                 }
362         }
363         return;
364 }
365
366 int ks_wlan_hw_tx(struct ks_wlan_private *priv, void *p, unsigned long size,
367                   void (*complete_handler) (void *arg1, void *arg2),
368                   void *arg1, void *arg2)
369 {
370         int result = 0;
371         struct hostif_hdr *hdr;
372         hdr = (struct hostif_hdr *)p;
373
374         if (hdr->event < HIF_DATA_REQ || HIF_REQ_MAX < hdr->event) {
375                 DPRINTK(1, "unknown event=%04X\n", hdr->event);
376                 return 0;
377         }
378
379         /* add event to hostt buffer */
380         priv->hostt.buff[priv->hostt.qtail] = hdr->event;
381         priv->hostt.qtail = (priv->hostt.qtail + 1) % SME_EVENT_BUFF_SIZE;
382
383         DPRINTK(4, "event=%04X\n", hdr->event);
384         spin_lock(&priv->tx_dev.tx_dev_lock);
385         result = enqueue_txdev(priv, p, size, complete_handler, arg1, arg2);
386         spin_unlock(&priv->tx_dev.tx_dev_lock);
387
388         if (cnt_txqbody(priv) > 0) {
389                 queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
390                                    &priv->ks_wlan_hw.rw_wq, 0);
391         }
392         return result;
393 }
394
395 static void rx_event_task(unsigned long dev)
396 {
397         struct ks_wlan_private *priv = (struct ks_wlan_private *)dev;
398         struct rx_device_buffer *rp;
399
400         DPRINTK(4, "\n");
401
402         if (cnt_rxqbody(priv) > 0 && priv->dev_state >= DEVICE_STATE_BOOT) {
403                 rp = &priv->rx_dev.rx_dev_buff[priv->rx_dev.qhead];
404                 hostif_receive(priv, rp->data, rp->size);
405                 inc_rxqhead(priv);
406
407                 if (cnt_rxqbody(priv) > 0) {
408                         tasklet_schedule(&priv->ks_wlan_hw.rx_bh_task);
409                 }
410         }
411
412         return;
413 }
414
415 static void ks_wlan_hw_rx(void *dev, uint16_t size)
416 {
417         struct ks_wlan_private *priv = (struct ks_wlan_private *)dev;
418         int retval;
419         struct rx_device_buffer *rx_buffer;
420         struct hostif_hdr *hdr;
421         unsigned char read_status;
422         unsigned short event = 0;
423
424         DPRINTK(4, "\n");
425
426         /* receive data */
427         if (cnt_rxqbody(priv) >= (RX_DEVICE_BUFF_SIZE - 1)) {
428                 /* in case of buffer overflow */
429                 DPRINTK(1, "rx buffer overflow \n");
430                 goto error_out;
431         }
432         rx_buffer = &priv->rx_dev.rx_dev_buff[priv->rx_dev.qtail];
433
434         retval =
435             ks7010_sdio_read(priv, DATA_WINDOW, &rx_buffer->data[0],
436                              hif_align_size(size));
437         if (retval) {
438                 goto error_out;
439         }
440
441         /* length check */
442         if (size > 2046 || size == 0) {
443 #ifdef KS_WLAN_DEBUG
444                 if (KS_WLAN_DEBUG > 5)
445                         print_hex_dump_bytes("INVALID DATA dump: ",
446                                              DUMP_PREFIX_OFFSET,
447                                              rx_buffer->data, 32);
448 #endif
449                 /* rx_status update */
450                 read_status = READ_STATUS_IDLE;
451                 retval =
452                     ks7010_sdio_write(priv, READ_STATUS, &read_status,
453                                       sizeof(read_status));
454                 if (retval) {
455                         DPRINTK(1, " error : READ_STATUS=%02X\n", read_status);
456                 }
457                 goto error_out;
458         }
459
460         hdr = (struct hostif_hdr *)&rx_buffer->data[0];
461         rx_buffer->size = le16_to_cpu(hdr->size) + sizeof(hdr->size);
462         event = hdr->event;
463         inc_rxqtail(priv);
464
465         /* read status update */
466         read_status = READ_STATUS_IDLE;
467         retval =
468             ks7010_sdio_write(priv, READ_STATUS, &read_status,
469                               sizeof(read_status));
470         if (retval) {
471                 DPRINTK(1, " error : READ_STATUS=%02X\n", read_status);
472         }
473         DPRINTK(4, "READ_STATUS=%02X\n", read_status);
474
475         if (atomic_read(&priv->psstatus.confirm_wait)) {
476                 if (IS_HIF_CONF(event)) {
477                         DPRINTK(4, "IS_HIF_CONF true !!\n");
478                         atomic_dec(&priv->psstatus.confirm_wait);
479                 }
480         }
481
482         /* rx_event_task((void *)priv); */
483         tasklet_schedule(&priv->ks_wlan_hw.rx_bh_task);
484
485  error_out:
486         return;
487 }
488
489 static void ks7010_rw_function(struct work_struct *work)
490 {
491         struct hw_info_t *hw;
492         struct ks_wlan_private *priv;
493         unsigned char rw_data;
494         int retval;
495
496         hw = container_of(work, struct hw_info_t, rw_wq.work);
497         priv = container_of(hw, struct ks_wlan_private, ks_wlan_hw);
498
499         DPRINTK(4, "\n");
500
501         /* wiat after DOZE */
502         if (time_after(priv->last_doze + ((30 * HZ) / 1000), jiffies)) {
503                 DPRINTK(4, "wait after DOZE \n");
504                 queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
505                                    &priv->ks_wlan_hw.rw_wq, 1);
506                 return;
507         }
508
509         /* wiat after WAKEUP */
510         while (time_after(priv->last_wakeup + ((30 * HZ) / 1000), jiffies)) {
511                 DPRINTK(4, "wait after WAKEUP \n");
512 /*              queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,&priv->ks_wlan_hw.rw_wq,
513                 (priv->last_wakeup + ((30*HZ)/1000) - jiffies));*/
514                 printk("wake: %lu %lu\n", priv->last_wakeup + (30 * HZ) / 1000,
515                        jiffies);
516                 msleep(30);
517         }
518
519         sdio_claim_host(priv->ks_wlan_hw.sdio_card->func);
520
521         /* power save wakeup */
522         if (atomic_read(&priv->psstatus.status) == PS_SNOOZE) {
523                 if (cnt_txqbody(priv) > 0) {
524                         ks_wlan_hw_wakeup_request(priv);
525                         queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
526                                            &priv->ks_wlan_hw.rw_wq, 1);
527                 }
528                 goto err_out;
529         }
530
531         /* sleep mode doze */
532         if (atomic_read(&priv->sleepstatus.doze_request) == 1) {
533                 ks_wlan_hw_sleep_doze_request(priv);
534                 goto err_out;
535         }
536         /* sleep mode wakeup */
537         if (atomic_read(&priv->sleepstatus.wakeup_request) == 1) {
538                 ks_wlan_hw_sleep_wakeup_request(priv);
539                 goto err_out;
540         }
541
542         /* read (WriteStatus/ReadDataSize FN1:00_0014) */
543         retval =
544             ks7010_sdio_read(priv, WSTATUS_RSIZE, &rw_data, sizeof(rw_data));
545         if (retval) {
546                 DPRINTK(1, " error : WSTATUS_RSIZE=%02X psstatus=%d\n", rw_data,
547                         atomic_read(&priv->psstatus.status));
548                 goto err_out;
549         }
550         DPRINTK(4, "WSTATUS_RSIZE=%02X\n", rw_data);
551
552         if (rw_data & RSIZE_MASK) {     /* Read schedule */
553                 ks_wlan_hw_rx((void *)priv,
554                               (uint16_t) (((rw_data & RSIZE_MASK) << 4)));
555         }
556         if ((rw_data & WSTATUS_MASK)) {
557                 tx_device_task((void *)priv);
558         }
559         _ks_wlan_hw_power_save(priv);
560
561  err_out:
562         sdio_release_host(priv->ks_wlan_hw.sdio_card->func);
563
564         return;
565 }
566
567 static void ks_sdio_interrupt(struct sdio_func *func)
568 {
569         int retval;
570         struct ks_sdio_card *card;
571         struct ks_wlan_private *priv;
572         unsigned char status, rsize, rw_data;
573
574         card = sdio_get_drvdata(func);
575         priv = card->priv;
576         DPRINTK(4, "\n");
577
578         if (priv->dev_state >= DEVICE_STATE_BOOT) {
579                 retval =
580                     ks7010_sdio_read(priv, INT_PENDING, &status,
581                                      sizeof(status));
582                 if (retval) {
583                         DPRINTK(1, "read INT_PENDING Failed!!(%d)\n", retval);
584                         goto intr_out;
585                 }
586                 DPRINTK(4, "INT_PENDING=%02X\n", rw_data);
587
588                 /* schedule task for interrupt status */
589                 /* bit7 -> Write General Communication B register */
590                 /* read (General Communication B register) */
591                 /* bit5 -> Write Status Idle */
592                 /* bit2 -> Read Status Busy  */
593                 if (status & INT_GCR_B
594                     || atomic_read(&priv->psstatus.status) == PS_SNOOZE) {
595                         retval =
596                             ks7010_sdio_read(priv, GCR_B, &rw_data,
597                                              sizeof(rw_data));
598                         if (retval) {
599                                 DPRINTK(1, " error : GCR_B=%02X\n", rw_data);
600                                 goto intr_out;
601                         }
602                         /* DPRINTK(1, "GCR_B=%02X\n", rw_data); */
603                         if (rw_data == GCR_B_ACTIVE) {
604                                 if (atomic_read(&priv->psstatus.status) ==
605                                     PS_SNOOZE) {
606                                         atomic_set(&priv->psstatus.status,
607                                                    PS_WAKEUP);
608                                         priv->wakeup_count = 0;
609                                 }
610                                 complete(&priv->psstatus.wakeup_wait);
611                         }
612
613                 }
614
615                 do {
616                         /* read (WriteStatus/ReadDataSize FN1:00_0014) */
617                         retval =
618                             ks7010_sdio_read(priv, WSTATUS_RSIZE, &rw_data,
619                                              sizeof(rw_data));
620                         if (retval) {
621                                 DPRINTK(1, " error : WSTATUS_RSIZE=%02X\n",
622                                         rw_data);
623                                 goto intr_out;
624                         }
625                         DPRINTK(4, "WSTATUS_RSIZE=%02X\n", rw_data);
626                         rsize = rw_data & RSIZE_MASK;
627                         if (rsize) {    /* Read schedule */
628                                 ks_wlan_hw_rx((void *)priv,
629                                               (uint16_t) (((rsize) << 4)));
630                         }
631                         if (rw_data & WSTATUS_MASK) {
632 #if 0
633                                 if (status & INT_WRITE_STATUS
634                                     && !cnt_txqbody(priv)) {
635                                         /* dummy write for interrupt clear */
636                                         rw_data = 0;
637                                         retval =
638                                             ks7010_sdio_write(priv, DATA_WINDOW,
639                                                               &rw_data,
640                                                               sizeof(rw_data));
641                                         if (retval) {
642                                                 DPRINTK(1,
643                                                         "write DATA_WINDOW Failed!!(%d)\n",
644                                                         retval);
645                                         }
646                                         status &= ~INT_WRITE_STATUS;
647                                 } else {
648 #endif
649                                         if (atomic_read(&priv->psstatus.status) == PS_SNOOZE) {
650                                                 if (cnt_txqbody(priv)) {
651                                                         ks_wlan_hw_wakeup_request(priv);
652                                                         queue_delayed_work
653                                                             (priv->ks_wlan_hw.
654                                                              ks7010sdio_wq,
655                                                              &priv->ks_wlan_hw.
656                                                              rw_wq, 1);
657                                                         return;
658                                                 }
659                                         } else {
660                                                 tx_device_task((void *)priv);
661                                         }
662 #if 0
663                                 }
664 #endif
665                         }
666                 } while (rsize);
667         }
668
669  intr_out:
670         queue_delayed_work(priv->ks_wlan_hw.ks7010sdio_wq,
671                            &priv->ks_wlan_hw.rw_wq, 0);
672         return;
673 }
674
675 static int trx_device_init(struct ks_wlan_private *priv)
676 {
677         /* initialize values (tx) */
678         priv->tx_dev.qtail = priv->tx_dev.qhead = 0;
679
680         /* initialize values (rx) */
681         priv->rx_dev.qtail = priv->rx_dev.qhead = 0;
682
683         /* initialize spinLock (tx,rx) */
684         spin_lock_init(&priv->tx_dev.tx_dev_lock);
685         spin_lock_init(&priv->rx_dev.rx_dev_lock);
686
687         tasklet_init(&priv->ks_wlan_hw.rx_bh_task, rx_event_task,
688                      (unsigned long)priv);
689
690         return 0;
691 }
692
693 static void trx_device_exit(struct ks_wlan_private *priv)
694 {
695         struct tx_device_buffer *sp;
696
697         /* tx buffer clear */
698         while (cnt_txqbody(priv) > 0) {
699                 sp = &priv->tx_dev.tx_dev_buff[priv->tx_dev.qhead];
700                 kfree(sp->sendp);       /* allocated memory free */
701                 if (sp->complete_handler != NULL)       /* TX Complete */
702                         (*sp->complete_handler) (sp->arg1, sp->arg2);
703                 inc_txqhead(priv);
704         }
705
706         tasklet_kill(&priv->ks_wlan_hw.rx_bh_task);
707
708         return;
709 }
710
711 static int ks7010_sdio_update_index(struct ks_wlan_private *priv, u32 index)
712 {
713         int rc = 0;
714         int retval;
715         unsigned char *data_buf;
716         data_buf = NULL;
717
718         data_buf = kmalloc(sizeof(u32), GFP_KERNEL);
719         if (!data_buf) {
720                 rc = 1;
721                 goto error_out;
722         }
723
724         memcpy(data_buf, &index, sizeof(index));
725         retval = ks7010_sdio_write(priv, WRITE_INDEX, data_buf, sizeof(index));
726         if (retval) {
727                 rc = 2;
728                 goto error_out;
729         }
730
731         retval = ks7010_sdio_write(priv, READ_INDEX, data_buf, sizeof(index));
732         if (retval) {
733                 rc = 3;
734                 goto error_out;
735         }
736  error_out:
737         if (data_buf)
738                 kfree(data_buf);
739         return rc;
740 }
741
742 #define ROM_BUFF_SIZE (64*1024)
743 static int ks7010_sdio_data_compare(struct ks_wlan_private *priv, u32 address,
744                                     unsigned char *data, unsigned int size)
745 {
746         int rc = 0;
747         int retval;
748         unsigned char *read_buf;
749         read_buf = NULL;
750         read_buf = kmalloc(ROM_BUFF_SIZE, GFP_KERNEL);
751         if (!read_buf) {
752                 rc = 1;
753                 goto error_out;
754         }
755         retval = ks7010_sdio_read(priv, address, read_buf, size);
756         if (retval) {
757                 rc = 2;
758                 goto error_out;
759         }
760         retval = memcmp(data, read_buf, size);
761
762         if (retval) {
763                 DPRINTK(0, "data compare error (%d) \n", retval);
764                 rc = 3;
765                 goto error_out;
766         }
767  error_out:
768         if (read_buf)
769                 kfree(read_buf);
770         return rc;
771 }
772
773 static int ks7010_upload_firmware(struct ks_wlan_private *priv,
774                                   struct ks_sdio_card *card)
775 {
776         unsigned int size, offset, n = 0;
777         unsigned char *rom_buf;
778         unsigned char rw_data = 0;
779         int retval, rc = 0;
780         int length;
781         const struct firmware *fw_entry = NULL;
782
783         rom_buf = NULL;
784
785         /* buffer allocate */
786         rom_buf = kmalloc(ROM_BUFF_SIZE, GFP_KERNEL);
787         if (!rom_buf) {
788                 rc = 3;
789                 goto error_out0;
790         }
791
792         sdio_claim_host(card->func);
793
794         /* Firmware running ? */
795         retval = ks7010_sdio_read(priv, GCR_A, &rw_data, sizeof(rw_data));
796         if (rw_data == GCR_A_RUN) {
797                 DPRINTK(0, "MAC firmware running ...\n");
798                 rc = 0;
799                 goto error_out0;
800         }
801
802         retval = request_firmware(&fw_entry, ROM_FILE, &priv->ks_wlan_hw.sdio_card->func->dev);
803         if (retval)
804                 return retval;
805
806         length = fw_entry->size;
807
808         /* Load Program */
809         n = 0;
810         do {
811                 if (length >= ROM_BUFF_SIZE) {
812                         size = ROM_BUFF_SIZE;
813                         length = length - ROM_BUFF_SIZE;
814                 } else {
815                         size = length;
816                         length = 0;
817                 }
818                 DPRINTK(4, "size = %d\n", size);
819                 if (size == 0)
820                         break;
821                 memcpy(rom_buf, fw_entry->data + n, size);
822                 /* Update write index */
823                 offset = n;
824                 retval =
825                     ks7010_sdio_update_index(priv,
826                                              KS7010_IRAM_ADDRESS + offset);
827                 if (retval) {
828                         rc = 6;
829                         goto error_out1;
830                 }
831
832                 /* Write data */
833                 retval = ks7010_sdio_write(priv, DATA_WINDOW, rom_buf, size);
834                 if (retval) {
835                         rc = 8;
836                         goto error_out1;
837                 }
838
839                 /* compare */
840                 retval =
841                     ks7010_sdio_data_compare(priv, DATA_WINDOW, rom_buf, size);
842                 if (retval) {
843                         rc = 9;
844                         goto error_out1;
845                 }
846                 n += size;
847
848         } while (size);
849
850         /* Remap request */
851         rw_data = GCR_A_REMAP;
852         retval = ks7010_sdio_write(priv, GCR_A, &rw_data, sizeof(rw_data));
853         if (retval) {
854                 rc = 11;
855                 goto error_out1;
856         }
857         DPRINTK(4, " REMAP Request : GCR_A=%02X\n", rw_data);
858
859         /* Firmware running check */
860         for (n = 0; n < 50; ++n) {
861                 mdelay(10);     /* wait_ms(10); */
862                 retval =
863                     ks7010_sdio_read(priv, GCR_A, &rw_data, sizeof(rw_data));
864                 if (retval) {
865                         rc = 11;
866                         goto error_out1;
867                 }
868                 if (rw_data == GCR_A_RUN)
869                         break;
870         }
871         DPRINTK(4, "firmware wakeup (%d)!!!!\n", n);
872         if ((50) <= n) {
873                 DPRINTK(1, "firmware can't start\n");
874                 rc = 12;
875                 goto error_out1;
876         }
877
878         rc = 0;
879
880  error_out1:
881         release_firmware(fw_entry);
882  error_out0:
883         sdio_release_host(card->func);
884         if (rom_buf)
885                 kfree(rom_buf);
886         return rc;
887 }
888
889 static void ks7010_card_init(struct ks_wlan_private *priv)
890 {
891         DPRINTK(5, "\ncard_init_task()\n");
892
893         /* init_waitqueue_head(&priv->confirm_wait); */
894         init_completion(&priv->confirm_wait);
895
896         DPRINTK(5, "init_completion()\n");
897
898         /* get mac address & firmware version */
899         hostif_sme_enqueue(priv, SME_START);
900
901         DPRINTK(5, "hostif_sme_enqueu()\n");
902
903         if (!wait_for_completion_interruptible_timeout
904             (&priv->confirm_wait, 5 * HZ)) {
905                 DPRINTK(1, "wait time out!! SME_START\n");
906         }
907
908         if (priv->mac_address_valid && priv->version_size) {
909                 priv->dev_state = DEVICE_STATE_PREINIT;
910         }
911
912         hostif_sme_enqueue(priv, SME_GET_EEPROM_CKSUM);
913
914         /* load initial wireless parameter */
915         hostif_sme_enqueue(priv, SME_STOP_REQUEST);
916
917         hostif_sme_enqueue(priv, SME_RTS_THRESHOLD_REQUEST);
918         hostif_sme_enqueue(priv, SME_FRAGMENTATION_THRESHOLD_REQUEST);
919
920         hostif_sme_enqueue(priv, SME_WEP_INDEX_REQUEST);
921         hostif_sme_enqueue(priv, SME_WEP_KEY1_REQUEST);
922         hostif_sme_enqueue(priv, SME_WEP_KEY2_REQUEST);
923         hostif_sme_enqueue(priv, SME_WEP_KEY3_REQUEST);
924         hostif_sme_enqueue(priv, SME_WEP_KEY4_REQUEST);
925
926         hostif_sme_enqueue(priv, SME_WEP_FLAG_REQUEST);
927         hostif_sme_enqueue(priv, SME_RSN_ENABLED_REQUEST);
928         hostif_sme_enqueue(priv, SME_MODE_SET_REQUEST);
929         hostif_sme_enqueue(priv, SME_START_REQUEST);
930
931         if (!wait_for_completion_interruptible_timeout
932             (&priv->confirm_wait, 5 * HZ)) {
933                 DPRINTK(1, "wait time out!! wireless parameter set\n");
934         }
935
936         if (priv->dev_state >= DEVICE_STATE_PREINIT) {
937                 DPRINTK(1, "DEVICE READY!!\n");
938                 priv->dev_state = DEVICE_STATE_READY;
939                 reg_net = register_netdev(priv->net_dev);
940                 DPRINTK(3, "register_netdev=%d\n", reg_net);
941         } else {
942                 DPRINTK(1, "dev_state=%d\n", priv->dev_state);
943         }
944 }
945
946 static void ks7010_init_defaults(struct ks_wlan_private *priv)
947 {
948         priv->reg.tx_rate = TX_RATE_AUTO;
949         priv->reg.preamble = LONG_PREAMBLE;
950         priv->reg.powermgt = POWMGT_ACTIVE_MODE;
951         priv->reg.scan_type = ACTIVE_SCAN;
952         priv->reg.beacon_lost_count = 20;
953         priv->reg.rts = 2347UL;
954         priv->reg.fragment = 2346UL;
955         priv->reg.phy_type = D_11BG_COMPATIBLE_MODE;
956         priv->reg.cts_mode = CTS_MODE_FALSE;
957         priv->reg.rate_set.body[11] = TX_RATE_54M;
958         priv->reg.rate_set.body[10] = TX_RATE_48M;
959         priv->reg.rate_set.body[9] = TX_RATE_36M;
960         priv->reg.rate_set.body[8] = TX_RATE_18M;
961         priv->reg.rate_set.body[7] = TX_RATE_9M;
962         priv->reg.rate_set.body[6] = TX_RATE_24M | BASIC_RATE;
963         priv->reg.rate_set.body[5] = TX_RATE_12M | BASIC_RATE;
964         priv->reg.rate_set.body[4] = TX_RATE_6M | BASIC_RATE;
965         priv->reg.rate_set.body[3] = TX_RATE_11M | BASIC_RATE;
966         priv->reg.rate_set.body[2] = TX_RATE_5M | BASIC_RATE;
967         priv->reg.rate_set.body[1] = TX_RATE_2M | BASIC_RATE;
968         priv->reg.rate_set.body[0] = TX_RATE_1M | BASIC_RATE;
969         priv->reg.tx_rate = TX_RATE_FULL_AUTO;
970         priv->reg.rate_set.size = 12;
971 }
972
973 static int ks7010_sdio_probe(struct sdio_func *func,
974                              const struct sdio_device_id *device)
975 {
976         struct ks_wlan_private *priv;
977         struct ks_sdio_card *card;
978         struct net_device *netdev;
979         unsigned char rw_data;
980         int ret;
981
982         DPRINTK(5, "ks7010_sdio_probe()\n");
983
984         priv = NULL;
985         netdev = NULL;
986
987         /* initilize ks_sdio_card */
988         card = kzalloc(sizeof(struct ks_sdio_card), GFP_KERNEL);
989         if (!card)
990                 return -ENOMEM;
991
992         card->func = func;
993         spin_lock_init(&card->lock);
994
995         /*** Initialize  SDIO ***/
996         sdio_claim_host(func);
997
998         /* bus setting  */
999         /* Issue config request to override clock rate */
1000
1001         /* function blocksize set */
1002         ret = sdio_set_block_size(func, KS7010_IO_BLOCK_SIZE);
1003         DPRINTK(5, "multi_block=%d sdio_set_block_size()=%d %d\n",
1004                 func->card->cccr.multi_block, func->cur_blksize, ret);
1005
1006         /* Allocate the slot current */
1007
1008         /* function enable */
1009         ret = sdio_enable_func(func);
1010         DPRINTK(5, "sdio_enable_func() %d\n", ret);
1011         if (ret)
1012                 goto error_free_card;
1013
1014         /* interrupt disable */
1015         sdio_writeb(func, 0, INT_ENABLE, &ret);
1016         if (ret)
1017                 goto error_free_card;
1018         sdio_writeb(func, 0xff, INT_PENDING, &ret);
1019         if (ret)
1020                 goto error_disable_func;
1021
1022         /* setup interrupt handler */
1023         ret = sdio_claim_irq(func, ks_sdio_interrupt);
1024         if (ret)
1025                 goto error_disable_func;
1026
1027         sdio_release_host(func);
1028
1029         sdio_set_drvdata(func, card);
1030
1031         DPRINTK(5, "class = 0x%X, vendor = 0x%X, "
1032                 "device = 0x%X\n", func->class, func->vendor, func->device);
1033
1034         /* private memory allocate */
1035         netdev = alloc_etherdev(sizeof(*priv));
1036         if (netdev == NULL) {
1037                 printk(KERN_ERR "ks7010 : Unable to alloc new net device\n");
1038                 goto error_release_irq;
1039         }
1040         if (dev_alloc_name(netdev, netdev->name) < 0) {
1041                 printk(KERN_ERR "ks7010 :  Couldn't get name!\n");
1042                 goto error_free_netdev;
1043         }
1044
1045         priv = netdev_priv(netdev);
1046
1047         card->priv = priv;
1048         SET_NETDEV_DEV(netdev, &card->func->dev);       /* for create sysfs symlinks */
1049
1050         /* private memory initialize */
1051         priv->ks_wlan_hw.sdio_card = card;
1052         init_completion(&priv->ks_wlan_hw.ks7010_sdio_wait);
1053         priv->ks_wlan_hw.read_buf = NULL;
1054         priv->ks_wlan_hw.read_buf = kmalloc(RX_DATA_SIZE, GFP_KERNEL);
1055         if (!priv->ks_wlan_hw.read_buf) {
1056                 goto error_free_netdev;
1057         }
1058         priv->dev_state = DEVICE_STATE_PREBOOT;
1059         priv->net_dev = netdev;
1060         priv->firmware_version[0] = '\0';
1061         priv->version_size = 0;
1062         priv->last_doze = jiffies;      /* set current jiffies */
1063         priv->last_wakeup = jiffies;
1064         memset(&priv->nstats, 0, sizeof(priv->nstats));
1065         memset(&priv->wstats, 0, sizeof(priv->wstats));
1066
1067         /* sleep mode */
1068         atomic_set(&priv->sleepstatus.doze_request, 0);
1069         atomic_set(&priv->sleepstatus.wakeup_request, 0);
1070         atomic_set(&priv->sleepstatus.wakeup_request, 0);
1071
1072         trx_device_init(priv);
1073         hostif_init(priv);
1074         ks_wlan_net_start(netdev);
1075
1076         ks7010_init_defaults(priv);
1077
1078         /* Upload firmware */
1079         ret = ks7010_upload_firmware(priv, card);       /* firmware load */
1080         if (ret) {
1081                 printk(KERN_ERR
1082                        "ks7010: firmware load failed !! retern code = %d\n",
1083                        ret);
1084                 goto error_free_read_buf;
1085         }
1086
1087         /* interrupt setting */
1088         /* clear Interrupt status write (ARMtoSD_InterruptPending FN1:00_0024) */
1089         rw_data = 0xff;
1090         sdio_claim_host(func);
1091         ret = ks7010_sdio_write(priv, INT_PENDING, &rw_data, sizeof(rw_data));
1092         sdio_release_host(func);
1093         if (ret) {
1094                 DPRINTK(1, " error : INT_PENDING=%02X\n", rw_data);
1095         }
1096         DPRINTK(4, " clear Interrupt : INT_PENDING=%02X\n", rw_data);
1097
1098         /* enable ks7010sdio interrupt (INT_GCR_B|INT_READ_STATUS|INT_WRITE_STATUS) */
1099         rw_data = (INT_GCR_B | INT_READ_STATUS | INT_WRITE_STATUS);
1100         sdio_claim_host(func);
1101         ret = ks7010_sdio_write(priv, INT_ENABLE, &rw_data, sizeof(rw_data));
1102         sdio_release_host(func);
1103         if (ret) {
1104                 DPRINTK(1, " error : INT_ENABLE=%02X\n", rw_data);
1105         }
1106         DPRINTK(4, " enable Interrupt : INT_ENABLE=%02X\n", rw_data);
1107         priv->dev_state = DEVICE_STATE_BOOT;
1108
1109         priv->ks_wlan_hw.ks7010sdio_wq = create_workqueue("ks7010sdio_wq");
1110         if (!priv->ks_wlan_hw.ks7010sdio_wq) {
1111                 DPRINTK(1, "create_workqueue failed !!\n");
1112                 goto error_free_read_buf;
1113         }
1114
1115         INIT_DELAYED_WORK(&priv->ks_wlan_hw.rw_wq, ks7010_rw_function);
1116         ks7010_card_init(priv);
1117
1118         return 0;
1119
1120  error_free_read_buf:
1121         kfree(priv->ks_wlan_hw.read_buf);
1122         priv->ks_wlan_hw.read_buf = NULL;
1123  error_free_netdev:
1124         free_netdev(priv->net_dev);
1125         card->priv = NULL;
1126  error_release_irq:
1127         sdio_claim_host(func);
1128         sdio_release_irq(func);
1129  error_disable_func:
1130         sdio_disable_func(func);
1131  error_free_card:
1132         sdio_release_host(func);
1133         sdio_set_drvdata(func, NULL);
1134         kfree(card);
1135
1136         return -ENODEV;
1137 }
1138
1139 static void ks7010_sdio_remove(struct sdio_func *func)
1140 {
1141         int ret;
1142         struct ks_sdio_card *card;
1143         struct ks_wlan_private *priv;
1144         struct net_device *netdev;
1145         DPRINTK(1, "ks7010_sdio_remove()\n");
1146
1147         card = sdio_get_drvdata(func);
1148
1149         if (card == NULL)
1150                 return;
1151
1152         DPRINTK(1, "priv = card->priv\n");
1153         priv = card->priv;
1154         netdev = priv->net_dev;
1155         if (priv) {
1156                 ks_wlan_net_stop(netdev);
1157                 DPRINTK(1, "ks_wlan_net_stop\n");
1158
1159                 /* interrupt disable */
1160                 sdio_claim_host(func);
1161                 sdio_writeb(func, 0, INT_ENABLE, &ret);
1162                 sdio_writeb(func, 0xff, INT_PENDING, &ret);
1163                 sdio_release_host(func);
1164                 DPRINTK(1, "interrupt disable\n");
1165
1166                 /* send stop request to MAC */
1167                 {
1168                         struct hostif_stop_request_t *pp;
1169                         pp = (struct hostif_stop_request_t *)
1170                             kzalloc(hif_align_size(sizeof(*pp)), GFP_KERNEL);
1171                         if (pp == NULL) {
1172                                 DPRINTK(3, "allocate memory failed..\n");
1173                                 return; /* to do goto ni suru */
1174                         }
1175                         pp->header.size =
1176                             cpu_to_le16((uint16_t)
1177                                         (sizeof(*pp) -
1178                                          sizeof(pp->header.size)));
1179                         pp->header.event = cpu_to_le16((uint16_t) HIF_STOP_REQ);
1180
1181                         sdio_claim_host(func);
1182                         write_to_device(priv, (unsigned char *)pp,
1183                                         hif_align_size(sizeof(*pp)));
1184                         sdio_release_host(func);
1185                         kfree(pp);
1186                 }
1187                 DPRINTK(1, "STOP Req\n");
1188
1189                 if (priv->ks_wlan_hw.ks7010sdio_wq) {
1190                         flush_workqueue(priv->ks_wlan_hw.ks7010sdio_wq);
1191                         destroy_workqueue(priv->ks_wlan_hw.ks7010sdio_wq);
1192                 }
1193                 DPRINTK(1,
1194                         "destroy_workqueue(priv->ks_wlan_hw.ks7010sdio_wq);\n");
1195
1196                 hostif_exit(priv);
1197                 DPRINTK(1, "hostif_exit\n");
1198
1199                 if (!reg_net)
1200                         unregister_netdev(netdev);
1201                 DPRINTK(1, "unregister_netdev\n");
1202
1203                 trx_device_exit(priv);
1204                 if (priv->ks_wlan_hw.read_buf) {
1205                         kfree(priv->ks_wlan_hw.read_buf);
1206                 }
1207                 free_netdev(priv->net_dev);
1208                 card->priv = NULL;
1209         }
1210
1211         sdio_claim_host(func);
1212         sdio_release_irq(func);
1213         DPRINTK(1, "sdio_release_irq()\n");
1214         sdio_disable_func(func);
1215         DPRINTK(1, "sdio_disable_func()\n");
1216         sdio_release_host(func);
1217
1218         sdio_set_drvdata(func, NULL);
1219
1220         kfree(card);
1221         DPRINTK(1, "kfree()\n");
1222
1223         DPRINTK(5, " Bye !!\n");
1224         return;
1225 }
1226
1227 static struct sdio_driver ks7010_sdio_driver = {
1228         .name = "ks7010_sdio",
1229         .id_table = ks7010_sdio_ids,
1230         .probe = ks7010_sdio_probe,
1231         .remove = ks7010_sdio_remove,
1232 };
1233
1234 module_driver(ks7010_sdio_driver, sdio_register_driver, sdio_unregister_driver);
1235 MODULE_AUTHOR("Sang Engineering, Qi-Hardware, KeyStream");
1236 MODULE_DESCRIPTION("Driver for KeyStream KS7010 based SDIO cards");
1237 MODULE_LICENSE("GPL v2");
1238 MODULE_FIRMWARE(ROM_FILE);