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