2 * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
3 * drivers/misc/iwmc3200top/main.c
5 * Copyright (C) 2009 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version
9 * 2 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/kernel.h>
30 #include <linux/debugfs.h>
31 #include <linux/mmc/sdio_ids.h>
32 #include <linux/mmc/sdio_func.h>
33 #include <linux/mmc/sdio.h>
35 #include "iwmc3200top.h"
41 #define DRIVER_DESCRIPTION "Intel(R) IWMC 3200 Top Driver"
42 #define DRIVER_COPYRIGHT "Copyright (c) 2008 Intel Corporation."
44 #define IWMCT_VERSION "0.1.62"
46 #ifdef REPOSITORY_LABEL
47 #define RL REPOSITORY_LABEL
52 #ifdef CONFIG_IWMC3200TOP_DEBUG
58 #define DRIVER_VERSION IWMCT_VERSION "-" __stringify(RL) VD
60 MODULE_DESCRIPTION(DRIVER_DESCRIPTION
);
61 MODULE_VERSION(DRIVER_VERSION
);
62 MODULE_LICENSE("GPL");
63 MODULE_AUTHOR(DRIVER_COPYRIGHT
);
66 /* FIXME: These can be found in sdio_ids.h in newer kernels */
67 #ifndef SDIO_INTEL_VENDOR_ID
68 #define SDIO_INTEL_VENDOR_ID 0x0089
70 #ifndef SDIO_DEVICE_ID_INTEL_IWMC3200TOP
71 #define SDIO_DEVICE_ID_INTEL_IWMC3200TOP 0x1404
75 * This workers main task is to wait for OP_OPR_ALIVE
76 * from TOP FW until ALIVE_MSG_TIMOUT timeout is elapsed.
77 * When OP_OPR_ALIVE received it will issue
78 * a call to "bus_rescan_devices".
80 static void iwmct_rescan_worker(struct work_struct
*ws
)
82 struct iwmct_priv
*priv
;
85 priv
= container_of(ws
, struct iwmct_priv
, bus_rescan_worker
);
87 LOG_INFO(priv
, FW_MSG
, "Calling bus_rescan\n");
89 ret
= bus_rescan_devices(priv
->func
->dev
.bus
);
91 LOG_INFO(priv
, FW_DOWNLOAD
, "bus_rescan_devices FAILED!!!\n");
94 static void op_top_message(struct iwmct_priv
*priv
, struct top_msg
*msg
)
96 switch (msg
->hdr
.opcode
) {
98 LOG_INFO(priv
, FW_MSG
, "Got ALIVE from device, wake rescan\n");
99 queue_work(priv
->bus_rescan_wq
, &priv
->bus_rescan_worker
);
102 LOG_INFO(priv
, FW_MSG
, "Received msg opcode 0x%X\n",
109 static void handle_top_message(struct iwmct_priv
*priv
, u8
*buf
, int len
)
113 msg
= (struct top_msg
*)buf
;
115 if (msg
->hdr
.type
!= COMM_TYPE_D2H
) {
116 LOG_ERROR(priv
, FW_MSG
,
117 "Message from TOP with invalid message type 0x%X\n",
122 if (len
< sizeof(msg
->hdr
)) {
123 LOG_ERROR(priv
, FW_MSG
,
124 "Message from TOP is too short for message header "
125 "received %d bytes, expected at least %zd bytes\n",
126 len
, sizeof(msg
->hdr
));
130 if (len
< le16_to_cpu(msg
->hdr
.length
) + sizeof(msg
->hdr
)) {
131 LOG_ERROR(priv
, FW_MSG
,
132 "Message length (%d bytes) is shorter than "
133 "in header (%d bytes)\n",
134 len
, le16_to_cpu(msg
->hdr
.length
));
138 switch (msg
->hdr
.category
) {
139 case COMM_CATEGORY_OPERATIONAL
:
140 op_top_message(priv
, (struct top_msg
*)buf
);
143 case COMM_CATEGORY_DEBUG
:
144 case COMM_CATEGORY_TESTABILITY
:
145 case COMM_CATEGORY_DIAGNOSTICS
:
146 iwmct_log_top_message(priv
, buf
, len
);
150 LOG_ERROR(priv
, FW_MSG
,
151 "Message from TOP with unknown category 0x%X\n",
157 int iwmct_send_hcmd(struct iwmct_priv
*priv
, u8
*cmd
, u16 len
)
162 LOG_INFOEX(priv
, FW_MSG
, "Sending hcmd:\n");
164 /* add padding to 256 for IWMC */
165 ((struct top_msg
*)cmd
)->hdr
.flags
|= CMD_FLAG_PADDING_256
;
167 LOG_HEXDUMP(FW_MSG
, cmd
, len
);
169 if (len
> FW_HCMD_BLOCK_SIZE
) {
170 LOG_ERROR(priv
, FW_MSG
, "size %d exceeded hcmd max size %d\n",
171 len
, FW_HCMD_BLOCK_SIZE
);
175 buf
= kzalloc(FW_HCMD_BLOCK_SIZE
, GFP_KERNEL
);
177 LOG_ERROR(priv
, FW_MSG
, "kzalloc error, buf size %d\n",
182 memcpy(buf
, cmd
, len
);
184 sdio_claim_host(priv
->func
);
185 ret
= sdio_memcpy_toio(priv
->func
, IWMC_SDIO_DATA_ADDR
, buf
,
187 sdio_release_host(priv
->func
);
193 int iwmct_tx(struct iwmct_priv
*priv
, unsigned int addr
,
194 void *src
, int count
)
198 sdio_claim_host(priv
->func
);
199 ret
= sdio_memcpy_toio(priv
->func
, addr
, src
, count
);
200 sdio_release_host(priv
->func
);
205 static void iwmct_irq_read_worker(struct work_struct
*ws
)
207 struct iwmct_priv
*priv
;
208 struct iwmct_work_struct
*read_req
;
215 priv
= container_of(ws
, struct iwmct_priv
, isr_worker
);
217 LOG_INFO(priv
, IRQ
, "enter iwmct_irq_read_worker %p\n", ws
);
219 /* --------------------- Handshake with device -------------------- */
220 sdio_claim_host(priv
->func
);
222 /* all list manipulations have to be protected by
223 * sdio_claim_host/sdio_release_host */
224 if (list_empty(&priv
->read_req_list
)) {
225 LOG_ERROR(priv
, IRQ
, "read_req_list empty in read worker\n");
229 read_req
= list_entry(priv
->read_req_list
.next
,
230 struct iwmct_work_struct
, list
);
232 list_del(&read_req
->list
);
233 iosize
= read_req
->iosize
;
236 buf
= kzalloc(iosize
, GFP_KERNEL
);
238 LOG_ERROR(priv
, IRQ
, "kzalloc error, buf size %d\n", iosize
);
242 LOG_INFO(priv
, IRQ
, "iosize=%d, buf=%p, func=%d\n",
243 iosize
, buf
, priv
->func
->num
);
245 /* read from device */
246 ret
= sdio_memcpy_fromio(priv
->func
, buf
, IWMC_SDIO_DATA_ADDR
, iosize
);
248 LOG_ERROR(priv
, IRQ
, "error %d reading buffer\n", ret
);
252 LOG_HEXDUMP(IRQ
, (u8
*)buf
, iosize
);
254 barker
= le32_to_cpu(buf
[0]);
256 /* Verify whether it's a barker and if not - treat as regular Rx */
257 if (barker
== IWMC_BARKER_ACK
||
258 (barker
& BARKER_DNLOAD_BARKER_MSK
) == IWMC_BARKER_REBOOT
) {
260 /* Valid Barker is equal on first 4 dwords */
261 is_barker
= (buf
[1] == buf
[0]) &&
262 (buf
[2] == buf
[0]) &&
266 LOG_WARNING(priv
, IRQ
,
267 "Potentially inconsistent barker "
268 "%08X_%08X_%08X_%08X\n",
269 le32_to_cpu(buf
[0]), le32_to_cpu(buf
[1]),
270 le32_to_cpu(buf
[2]), le32_to_cpu(buf
[3]));
276 /* Handle Top CommHub message */
278 sdio_release_host(priv
->func
);
279 handle_top_message(priv
, (u8
*)buf
, iosize
);
281 } else if (barker
== IWMC_BARKER_ACK
) { /* Handle barkers */
282 if (atomic_read(&priv
->dev_sync
) == 0) {
284 "ACK barker arrived out-of-sync\n");
288 /* Continuing to FW download (after Sync is completed)*/
289 atomic_set(&priv
->dev_sync
, 0);
290 LOG_INFO(priv
, IRQ
, "ACK barker arrived "
291 "- starting FW download\n");
292 } else { /* REBOOT barker */
293 LOG_INFO(priv
, IRQ
, "Recieved reboot barker: %x\n", barker
);
294 priv
->barker
= barker
;
296 if (barker
& BARKER_DNLOAD_SYNC_MSK
) {
297 /* Send the same barker back */
298 ret
= sdio_memcpy_toio(priv
->func
, IWMC_SDIO_DATA_ADDR
,
302 "error %d echoing barker\n", ret
);
305 LOG_INFO(priv
, IRQ
, "Echoing barker to device\n");
306 atomic_set(&priv
->dev_sync
, 1);
310 /* Continuing to FW download (without Sync) */
311 LOG_INFO(priv
, IRQ
, "No sync requested "
312 "- starting FW download\n");
315 sdio_release_host(priv
->func
);
318 LOG_INFO(priv
, IRQ
, "barker download request 0x%x is:\n", priv
->barker
);
319 LOG_INFO(priv
, IRQ
, "******* Top FW %s requested ********\n",
320 (priv
->barker
& BARKER_DNLOAD_TOP_MSK
) ? "was" : "not");
321 LOG_INFO(priv
, IRQ
, "******* GPS FW %s requested ********\n",
322 (priv
->barker
& BARKER_DNLOAD_GPS_MSK
) ? "was" : "not");
323 LOG_INFO(priv
, IRQ
, "******* BT FW %s requested ********\n",
324 (priv
->barker
& BARKER_DNLOAD_BT_MSK
) ? "was" : "not");
326 if (priv
->dbg
.fw_download
)
329 LOG_ERROR(priv
, IRQ
, "FW download not allowed\n");
334 sdio_release_host(priv
->func
);
337 LOG_INFO(priv
, IRQ
, "exit iwmct_irq_read_worker\n");
340 static void iwmct_irq(struct sdio_func
*func
)
342 struct iwmct_priv
*priv
;
345 int addr
= IWMC_SDIO_INTR_GET_SIZE_ADDR
;
346 struct iwmct_work_struct
*read_req
;
348 priv
= sdio_get_drvdata(func
);
350 LOG_INFO(priv
, IRQ
, "enter iwmct_irq\n");
352 /* read the function's status register */
353 val
= sdio_readb(func
, IWMC_SDIO_INTR_STATUS_ADDR
, &ret
);
355 LOG_INFO(priv
, IRQ
, "iir value = %d, ret=%d\n", val
, ret
);
358 LOG_ERROR(priv
, IRQ
, "iir = 0, exiting ISR\n");
359 goto exit_clear_intr
;
364 * read 2 bytes of the transaction size
365 * IMPORTANT: sdio transaction size has to be read before clearing
368 val
= sdio_readb(priv
->func
, addr
++, &ret
);
370 val
= sdio_readb(priv
->func
, addr
++, &ret
);
373 LOG_INFO(priv
, IRQ
, "READ size %d\n", iosize
);
376 LOG_ERROR(priv
, IRQ
, "READ size %d, exiting ISR\n", iosize
);
377 goto exit_clear_intr
;
380 /* allocate a work structure to pass iosize to the worker */
381 read_req
= kzalloc(sizeof(struct iwmct_work_struct
), GFP_KERNEL
);
383 LOG_ERROR(priv
, IRQ
, "failed to allocate read_req, exit ISR\n");
384 goto exit_clear_intr
;
387 INIT_LIST_HEAD(&read_req
->list
);
388 read_req
->iosize
= iosize
;
390 list_add_tail(&priv
->read_req_list
, &read_req
->list
);
392 /* clear the function's interrupt request bit (write 1 to clear) */
393 sdio_writeb(func
, 1, IWMC_SDIO_INTR_CLEAR_ADDR
, &ret
);
395 queue_work(priv
->wq
, &priv
->isr_worker
);
397 LOG_INFO(priv
, IRQ
, "exit iwmct_irq\n");
402 /* clear the function's interrupt request bit (write 1 to clear) */
403 sdio_writeb(func
, 1, IWMC_SDIO_INTR_CLEAR_ADDR
, &ret
);
408 module_param(blocks
, int, 0604);
409 MODULE_PARM_DESC(blocks
, "max_blocks_to_send");
412 module_param(dump
, bool, 0604);
413 MODULE_PARM_DESC(dump
, "dump_hex_content");
416 module_param(jump
, bool, 0604);
418 static int direct
= 1;
419 module_param(direct
, bool, 0604);
421 static int checksum
= 1;
422 module_param(checksum
, bool, 0604);
424 static int fw_download
= 1;
425 module_param(fw_download
, bool, 0604);
427 static int block_size
= IWMC_SDIO_BLK_SIZE
;
428 module_param(block_size
, int, 0404);
430 static int download_trans_blks
= IWMC_DEFAULT_TR_BLK
;
431 module_param(download_trans_blks
, int, 0604);
433 static int rubbish_barker
;
434 module_param(rubbish_barker
, bool, 0604);
436 #ifdef CONFIG_IWMC3200TOP_DEBUG
437 static int log_level
[LOG_SRC_MAX
];
438 static unsigned int log_level_argc
;
439 module_param_array(log_level
, int, &log_level_argc
, 0604);
440 MODULE_PARM_DESC(log_level
, "log_level");
442 static int log_level_fw
[FW_LOG_SRC_MAX
];
443 static unsigned int log_level_fw_argc
;
444 module_param_array(log_level_fw
, int, &log_level_fw_argc
, 0604);
445 MODULE_PARM_DESC(log_level_fw
, "log_level_fw");
448 void iwmct_dbg_init_params(struct iwmct_priv
*priv
)
450 #ifdef CONFIG_IWMC3200TOP_DEBUG
453 for (i
= 0; i
< log_level_argc
; i
++) {
454 dev_notice(&priv
->func
->dev
, "log_level[%d]=0x%X\n",
456 iwmct_log_set_filter((log_level
[i
] >> 8) & 0xFF,
457 log_level
[i
] & 0xFF);
459 for (i
= 0; i
< log_level_fw_argc
; i
++) {
460 dev_notice(&priv
->func
->dev
, "log_level_fw[%d]=0x%X\n",
462 iwmct_log_set_fw_filter((log_level_fw
[i
] >> 8) & 0xFF,
463 log_level_fw
[i
] & 0xFF);
467 priv
->dbg
.blocks
= blocks
;
468 LOG_INFO(priv
, INIT
, "blocks=%d\n", blocks
);
469 priv
->dbg
.dump
= (bool)dump
;
470 LOG_INFO(priv
, INIT
, "dump=%d\n", dump
);
471 priv
->dbg
.jump
= (bool)jump
;
472 LOG_INFO(priv
, INIT
, "jump=%d\n", jump
);
473 priv
->dbg
.direct
= (bool)direct
;
474 LOG_INFO(priv
, INIT
, "direct=%d\n", direct
);
475 priv
->dbg
.checksum
= (bool)checksum
;
476 LOG_INFO(priv
, INIT
, "checksum=%d\n", checksum
);
477 priv
->dbg
.fw_download
= (bool)fw_download
;
478 LOG_INFO(priv
, INIT
, "fw_download=%d\n", fw_download
);
479 priv
->dbg
.block_size
= block_size
;
480 LOG_INFO(priv
, INIT
, "block_size=%d\n", block_size
);
481 priv
->dbg
.download_trans_blks
= download_trans_blks
;
482 LOG_INFO(priv
, INIT
, "download_trans_blks=%d\n", download_trans_blks
);
485 /*****************************************************************************
489 *****************************************************************************/
490 static ssize_t
show_iwmct_fw_version(struct device
*d
,
491 struct device_attribute
*attr
, char *buf
)
493 struct iwmct_priv
*priv
= dev_get_drvdata(d
);
494 return sprintf(buf
, "%s\n", priv
->dbg
.label_fw
);
496 static DEVICE_ATTR(cc_label_fw
, S_IRUGO
, show_iwmct_fw_version
, NULL
);
498 #ifdef CONFIG_IWMC3200TOP_DEBUG
499 static DEVICE_ATTR(log_level
, S_IWUSR
| S_IRUGO
,
500 show_iwmct_log_level
, store_iwmct_log_level
);
501 static DEVICE_ATTR(log_level_fw
, S_IWUSR
| S_IRUGO
,
502 show_iwmct_log_level_fw
, store_iwmct_log_level_fw
);
505 static struct attribute
*iwmct_sysfs_entries
[] = {
506 &dev_attr_cc_label_fw
.attr
,
507 #ifdef CONFIG_IWMC3200TOP_DEBUG
508 &dev_attr_log_level
.attr
,
509 &dev_attr_log_level_fw
.attr
,
514 static struct attribute_group iwmct_attribute_group
= {
515 .name
= NULL
, /* put in device directory */
516 .attrs
= iwmct_sysfs_entries
,
520 static int iwmct_probe(struct sdio_func
*func
,
521 const struct sdio_device_id
*id
)
523 struct iwmct_priv
*priv
;
526 int addr
= IWMC_SDIO_INTR_ENABLE_ADDR
;
528 dev_dbg(&func
->dev
, "enter iwmct_probe\n");
530 dev_dbg(&func
->dev
, "IRQ polling period id %u msecs, HZ is %d\n",
531 jiffies_to_msecs(2147483647), HZ
);
533 priv
= kzalloc(sizeof(struct iwmct_priv
), GFP_KERNEL
);
535 dev_err(&func
->dev
, "kzalloc error\n");
539 sdio_set_drvdata(func
, priv
);
542 /* create drivers work queue */
543 priv
->wq
= create_workqueue(DRV_NAME
"_wq");
544 priv
->bus_rescan_wq
= create_workqueue(DRV_NAME
"_rescan_wq");
545 INIT_WORK(&priv
->bus_rescan_worker
, iwmct_rescan_worker
);
546 INIT_WORK(&priv
->isr_worker
, iwmct_irq_read_worker
);
548 init_waitqueue_head(&priv
->wait_q
);
550 sdio_claim_host(func
);
551 /* FIXME: Remove after it is fixed in the Boot ROM upgrade */
552 func
->enable_timeout
= 10;
554 /* In our HW, setting the block size also wakes up the boot rom. */
555 ret
= sdio_set_block_size(func
, priv
->dbg
.block_size
);
557 LOG_ERROR(priv
, INIT
,
558 "sdio_set_block_size() failure: %d\n", ret
);
559 goto error_sdio_enable
;
562 ret
= sdio_enable_func(func
);
564 LOG_ERROR(priv
, INIT
, "sdio_enable_func() failure: %d\n", ret
);
565 goto error_sdio_enable
;
568 /* init reset and dev_sync states */
569 atomic_set(&priv
->reset
, 0);
570 atomic_set(&priv
->dev_sync
, 0);
572 /* init read req queue */
573 INIT_LIST_HEAD(&priv
->read_req_list
);
575 /* process configurable parameters */
576 iwmct_dbg_init_params(priv
);
577 ret
= sysfs_create_group(&func
->dev
.kobj
, &iwmct_attribute_group
);
579 LOG_ERROR(priv
, INIT
, "Failed to register attributes and "
580 "initialize module_params\n");
581 goto error_dev_attrs
;
584 iwmct_dbgfs_register(priv
, DRV_NAME
);
586 if (!priv
->dbg
.direct
&& priv
->dbg
.download_trans_blks
> 8) {
588 "Reducing transaction to 8 blocks = 2K (from %d)\n",
589 priv
->dbg
.download_trans_blks
);
590 priv
->dbg
.download_trans_blks
= 8;
592 priv
->trans_len
= priv
->dbg
.download_trans_blks
* priv
->dbg
.block_size
;
593 LOG_INFO(priv
, INIT
, "Transaction length = %d\n", priv
->trans_len
);
595 ret
= sdio_claim_irq(func
, iwmct_irq
);
597 LOG_ERROR(priv
, INIT
, "sdio_claim_irq() failure: %d\n", ret
);
598 goto error_claim_irq
;
602 /* Enable function's interrupt */
603 sdio_writeb(priv
->func
, val
, addr
, &ret
);
605 LOG_ERROR(priv
, INIT
, "Failure writing to "
606 "Interrupt Enable Register (%d): %d\n", addr
, ret
);
607 goto error_enable_int
;
610 sdio_release_host(func
);
612 LOG_INFO(priv
, INIT
, "exit iwmct_probe\n");
617 sdio_release_irq(func
);
619 sdio_disable_func(func
);
621 iwmct_dbgfs_unregister(priv
->dbgfs
);
622 sysfs_remove_group(&func
->dev
.kobj
, &iwmct_attribute_group
);
624 sdio_release_host(func
);
628 static void iwmct_remove(struct sdio_func
*func
)
630 struct iwmct_work_struct
*read_req
;
631 struct iwmct_priv
*priv
= sdio_get_drvdata(func
);
633 priv
= sdio_get_drvdata(func
);
635 LOG_INFO(priv
, INIT
, "enter\n");
637 sdio_claim_host(func
);
638 sdio_release_irq(func
);
639 sdio_release_host(func
);
641 /* Safely destroy osc workqueue */
642 destroy_workqueue(priv
->bus_rescan_wq
);
643 destroy_workqueue(priv
->wq
);
645 sdio_claim_host(func
);
646 sdio_disable_func(func
);
647 sysfs_remove_group(&func
->dev
.kobj
, &iwmct_attribute_group
);
648 iwmct_dbgfs_unregister(priv
->dbgfs
);
649 sdio_release_host(func
);
651 /* free read requests */
652 while (!list_empty(&priv
->read_req_list
)) {
653 read_req
= list_entry(priv
->read_req_list
.next
,
654 struct iwmct_work_struct
, list
);
656 list_del(&read_req
->list
);
664 static const struct sdio_device_id iwmct_ids
[] = {
665 { SDIO_DEVICE(SDIO_INTEL_VENDOR_ID
, SDIO_DEVICE_ID_INTEL_IWMC3200TOP
)},
666 { /* end: all zeroes */ },
669 MODULE_DEVICE_TABLE(sdio
, iwmct_ids
);
671 static struct sdio_driver iwmct_driver
= {
672 .probe
= iwmct_probe
,
673 .remove
= iwmct_remove
,
675 .id_table
= iwmct_ids
,
678 static int __init
iwmct_init(void)
682 /* Default log filter settings */
683 iwmct_log_set_filter(LOG_SRC_ALL
, LOG_SEV_FILTER_RUNTIME
);
684 iwmct_log_set_filter(LOG_SRC_FW_MSG
, LOG_SEV_FILTER_ALL
);
685 iwmct_log_set_fw_filter(LOG_SRC_ALL
, FW_LOG_SEV_FILTER_RUNTIME
);
687 rc
= sdio_register_driver(&iwmct_driver
);
692 static void __exit
iwmct_exit(void)
694 sdio_unregister_driver(&iwmct_driver
);
697 module_init(iwmct_init
);
698 module_exit(iwmct_exit
);