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