2 * This file is part of wl12xx
4 * Copyright (C) 2008-2009 Nokia Corporation
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 #include <linux/kernel.h>
25 #include <linux/module.h>
38 static struct wl12xx_partition_set wl1251_part_table
[PART_TABLE_LEN
] = {
45 .start
= REGISTERS_BASE
,
46 .size
= REGISTERS_DOWN_SIZE
56 .start
= REGISTERS_BASE
,
57 .size
= REGISTERS_WORK_SIZE
61 /* WL1251 doesn't use the DRPW partition, so we don't set it here */
64 static enum wl12xx_acx_int_reg wl1251_acx_reg_table
[ACX_REG_TABLE_LEN
] = {
65 [ACX_REG_INTERRUPT_TRIG
] = (REGISTERS_BASE
+ 0x0474),
66 [ACX_REG_INTERRUPT_TRIG_H
] = (REGISTERS_BASE
+ 0x0478),
67 [ACX_REG_INTERRUPT_MASK
] = (REGISTERS_BASE
+ 0x0494),
68 [ACX_REG_HINT_MASK_SET
] = (REGISTERS_BASE
+ 0x0498),
69 [ACX_REG_HINT_MASK_CLR
] = (REGISTERS_BASE
+ 0x049C),
70 [ACX_REG_INTERRUPT_NO_CLEAR
] = (REGISTERS_BASE
+ 0x04B0),
71 [ACX_REG_INTERRUPT_CLEAR
] = (REGISTERS_BASE
+ 0x04A4),
72 [ACX_REG_INTERRUPT_ACK
] = (REGISTERS_BASE
+ 0x04A8),
73 [ACX_REG_SLV_SOFT_RESET
] = (REGISTERS_BASE
+ 0x0000),
74 [ACX_REG_EE_START
] = (REGISTERS_BASE
+ 0x080C),
75 [ACX_REG_ECPU_CONTROL
] = (REGISTERS_BASE
+ 0x0804)
78 static int wl1251_upload_firmware(struct wl12xx
*wl
)
80 struct wl12xx_partition_set
*p_table
= wl
->chip
.p_table
;
81 int addr
, chunk_num
, partition_limit
;
85 /* whal_FwCtrl_LoadFwImageSm() */
87 wl12xx_debug(DEBUG_BOOT
, "chip id before fw upload: 0x%x",
88 wl12xx_reg_read32(wl
, CHIP_ID_B
));
90 /* 10.0 check firmware length and set partition */
91 fw_data_len
= (wl
->fw
[4] << 24) | (wl
->fw
[5] << 16) |
92 (wl
->fw
[6] << 8) | (wl
->fw
[7]);
94 wl12xx_debug(DEBUG_BOOT
, "fw_data_len %zu chunk_size %d", fw_data_len
,
97 if ((fw_data_len
% 4) != 0) {
98 wl12xx_error("firmware length not multiple of four");
102 wl12xx_set_partition(wl
,
103 p_table
[PART_DOWN
].mem
.start
,
104 p_table
[PART_DOWN
].mem
.size
,
105 p_table
[PART_DOWN
].reg
.start
,
106 p_table
[PART_DOWN
].reg
.size
);
108 /* 10.1 set partition limit and chunk num */
110 partition_limit
= p_table
[PART_DOWN
].mem
.size
;
112 while (chunk_num
< fw_data_len
/ CHUNK_SIZE
) {
113 /* 10.2 update partition, if needed */
114 addr
= p_table
[PART_DOWN
].mem
.start
+
115 (chunk_num
+ 2) * CHUNK_SIZE
;
116 if (addr
> partition_limit
) {
117 addr
= p_table
[PART_DOWN
].mem
.start
+
118 chunk_num
* CHUNK_SIZE
;
119 partition_limit
= chunk_num
* CHUNK_SIZE
+
120 p_table
[PART_DOWN
].mem
.size
;
121 wl12xx_set_partition(wl
,
123 p_table
[PART_DOWN
].mem
.size
,
124 p_table
[PART_DOWN
].reg
.start
,
125 p_table
[PART_DOWN
].reg
.size
);
128 /* 10.3 upload the chunk */
129 addr
= p_table
[PART_DOWN
].mem
.start
+ chunk_num
* CHUNK_SIZE
;
130 p
= wl
->fw
+ FW_HDR_SIZE
+ chunk_num
* CHUNK_SIZE
;
131 wl12xx_debug(DEBUG_BOOT
, "uploading fw chunk 0x%p to 0x%x",
133 wl12xx_spi_mem_write(wl
, addr
, p
, CHUNK_SIZE
);
138 /* 10.4 upload the last chunk */
139 addr
= p_table
[PART_DOWN
].mem
.start
+ chunk_num
* CHUNK_SIZE
;
140 p
= wl
->fw
+ FW_HDR_SIZE
+ chunk_num
* CHUNK_SIZE
;
141 wl12xx_debug(DEBUG_BOOT
, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
142 fw_data_len
% CHUNK_SIZE
, p
, addr
);
143 wl12xx_spi_mem_write(wl
, addr
, p
, fw_data_len
% CHUNK_SIZE
);
148 static int wl1251_upload_nvs(struct wl12xx
*wl
)
150 size_t nvs_len
, nvs_bytes_written
, burst_len
;
161 nvs_len
= wl
->nvs_len
;
162 nvs_start
= wl
->fw_len
;
165 * Layout before the actual NVS tables:
166 * 1 byte : burst length.
167 * 2 bytes: destination address.
168 * n bytes: data to burst copy.
170 * This is ended by a 0 length, then the NVS tables.
174 burst_len
= nvs_ptr
[0];
175 dest_addr
= (nvs_ptr
[1] & 0xfe) | ((u32
)(nvs_ptr
[2] << 8));
177 /* We move our pointer to the data */
180 for (i
= 0; i
< burst_len
; i
++) {
181 val
= (nvs_ptr
[0] | (nvs_ptr
[1] << 8)
182 | (nvs_ptr
[2] << 16) | (nvs_ptr
[3] << 24));
184 wl12xx_debug(DEBUG_BOOT
,
185 "nvs burst write 0x%x: 0x%x",
187 wl12xx_mem_write32(wl
, dest_addr
, val
);
195 * We've reached the first zero length, the first NVS table
196 * is 7 bytes further.
199 nvs_len
-= nvs_ptr
- nvs
;
200 nvs_len
= ALIGN(nvs_len
, 4);
202 /* Now we must set the partition correctly */
203 wl12xx_set_partition(wl
, nvs_start
,
204 wl
->chip
.p_table
[PART_DOWN
].mem
.size
,
205 wl
->chip
.p_table
[PART_DOWN
].reg
.start
,
206 wl
->chip
.p_table
[PART_DOWN
].reg
.size
);
208 /* And finally we upload the NVS tables */
209 nvs_bytes_written
= 0;
210 while (nvs_bytes_written
< nvs_len
) {
211 val
= (nvs_ptr
[0] | (nvs_ptr
[1] << 8)
212 | (nvs_ptr
[2] << 16) | (nvs_ptr
[3] << 24));
214 val
= cpu_to_le32(val
);
216 wl12xx_debug(DEBUG_BOOT
,
217 "nvs write table 0x%x: 0x%x",
219 wl12xx_mem_write32(wl
, nvs_start
, val
);
222 nvs_bytes_written
+= 4;
229 static int wl1251_boot(struct wl12xx
*wl
)
231 int ret
= 0, minor_minor_e2_ver
;
234 ret
= wl12xx_boot_soft_reset(wl
);
238 /* 2. start processing NVS file */
239 ret
= wl
->chip
.op_upload_nvs(wl
);
243 /* write firmware's last address (ie. it's length) to
244 * ACX_EEPROMLESS_IND_REG */
245 wl12xx_reg_write32(wl
, ACX_EEPROMLESS_IND_REG
, wl
->fw_len
);
247 /* 6. read the EEPROM parameters */
248 tmp
= wl12xx_reg_read32(wl
, SCR_PAD2
);
250 /* 7. read bootdata */
251 wl
->boot_attr
.radio_type
= (tmp
& 0x0000FF00) >> 8;
252 wl
->boot_attr
.major
= (tmp
& 0x00FF0000) >> 16;
253 tmp
= wl12xx_reg_read32(wl
, SCR_PAD3
);
255 /* 8. check bootdata and call restart sequence */
256 wl
->boot_attr
.minor
= (tmp
& 0x00FF0000) >> 16;
257 minor_minor_e2_ver
= (tmp
& 0xFF000000) >> 24;
259 wl12xx_debug(DEBUG_BOOT
, "radioType 0x%x majorE2Ver 0x%x "
260 "minorE2Ver 0x%x minor_minor_e2_ver 0x%x",
261 wl
->boot_attr
.radio_type
, wl
->boot_attr
.major
,
262 wl
->boot_attr
.minor
, minor_minor_e2_ver
);
264 ret
= wl12xx_boot_init_seq(wl
);
268 /* 9. NVS processing done */
269 boot_data
= wl12xx_reg_read32(wl
, ACX_REG_ECPU_CONTROL
);
271 wl12xx_debug(DEBUG_BOOT
, "halt boot_data 0x%x", boot_data
);
273 /* 10. check that ECPU_CONTROL_HALT bits are set in
274 * pWhalBus->uBootData and start uploading firmware
276 if ((boot_data
& ECPU_CONTROL_HALT
) == 0) {
277 wl12xx_error("boot failed, ECPU_CONTROL_HALT not set");
282 ret
= wl
->chip
.op_upload_fw(wl
);
286 /* 10.5 start firmware */
287 ret
= wl12xx_boot_run_firmware(wl
);
291 /* Get and save the firmware version */
292 wl12xx_acx_fw_version(wl
, wl
->chip
.fw_ver
, sizeof(wl
->chip
.fw_ver
));
298 static int wl1251_mem_cfg(struct wl12xx
*wl
)
300 struct wl1251_acx_config_memory mem_conf
;
303 wl12xx_debug(DEBUG_ACX
, "wl1251 mem cfg");
306 mem_conf
.mem_config
.num_stations
= cpu_to_le16(DEFAULT_NUM_STATIONS
);
307 mem_conf
.mem_config
.rx_mem_block_num
= 35;
308 mem_conf
.mem_config
.tx_min_mem_block_num
= 64;
309 mem_conf
.mem_config
.num_tx_queues
= MAX_TX_QUEUES
;
310 mem_conf
.mem_config
.host_if_options
= HOSTIF_PKT_RING
;
311 mem_conf
.mem_config
.num_ssid_profiles
= 1;
312 mem_conf
.mem_config
.debug_buffer_size
=
313 cpu_to_le16(TRACE_BUFFER_MAX_SIZE
);
315 /* RX queue config */
316 mem_conf
.rx_queue_config
.dma_address
= 0;
317 mem_conf
.rx_queue_config
.num_descs
= ACX_RX_DESC_DEF
;
318 mem_conf
.rx_queue_config
.priority
= DEFAULT_RXQ_PRIORITY
;
319 mem_conf
.rx_queue_config
.type
= DEFAULT_RXQ_TYPE
;
321 /* TX queue config */
322 for (i
= 0; i
< MAX_TX_QUEUES
; i
++) {
323 mem_conf
.tx_queue_config
[i
].num_descs
= ACX_TX_DESC_DEF
;
324 mem_conf
.tx_queue_config
[i
].attributes
= i
;
327 mem_conf
.header
.id
= ACX_MEM_CFG
;
328 mem_conf
.header
.len
= sizeof(struct wl1251_acx_config_memory
) -
329 sizeof(struct acx_header
);
330 mem_conf
.header
.len
-=
331 (MAX_TX_QUEUE_CONFIGS
- mem_conf
.mem_config
.num_tx_queues
) *
332 sizeof(struct wl1251_acx_tx_queue_config
);
334 ret
= wl12xx_cmd_configure(wl
, &mem_conf
,
335 sizeof(struct wl1251_acx_config_memory
));
337 wl12xx_warning("wl1251 mem config failed: %d", ret
);
342 static int wl1251_hw_init_mem_config(struct wl12xx
*wl
)
346 ret
= wl1251_mem_cfg(wl
);
350 wl
->target_mem_map
= kzalloc(sizeof(struct wl1251_acx_mem_map
),
352 if (!wl
->target_mem_map
) {
353 wl12xx_error("couldn't allocate target memory map");
357 /* we now ask for the firmware built memory map */
358 ret
= wl12xx_acx_mem_map(wl
, wl
->target_mem_map
,
359 sizeof(struct wl1251_acx_mem_map
));
361 wl12xx_error("couldn't retrieve firmware memory map");
362 kfree(wl
->target_mem_map
);
363 wl
->target_mem_map
= NULL
;
370 static void wl1251_set_ecpu_ctrl(struct wl12xx
*wl
, u32 flag
)
374 /* 10.5.0 run the firmware (I) */
375 cpu_ctrl
= wl12xx_reg_read32(wl
, ACX_REG_ECPU_CONTROL
);
377 /* 10.5.1 run the firmware (II) */
379 wl12xx_reg_write32(wl
, ACX_REG_ECPU_CONTROL
, cpu_ctrl
);
382 static void wl1251_target_enable_interrupts(struct wl12xx
*wl
)
384 /* Enable target's interrupts */
385 wl
->intr_mask
= WL1251_ACX_INTR_RX0_DATA
|
386 WL1251_ACX_INTR_RX1_DATA
|
387 WL1251_ACX_INTR_TX_RESULT
|
388 WL1251_ACX_INTR_EVENT_A
|
389 WL1251_ACX_INTR_EVENT_B
|
390 WL1251_ACX_INTR_INIT_COMPLETE
;
391 wl12xx_boot_target_enable_interrupts(wl
);
394 static void wl1251_irq_work(struct work_struct
*work
)
398 container_of(work
, struct wl12xx
, irq_work
);
400 mutex_lock(&wl
->mutex
);
402 wl12xx_debug(DEBUG_IRQ
, "IRQ work");
404 if (wl
->state
== WL12XX_STATE_OFF
)
407 wl12xx_ps_elp_wakeup(wl
);
409 wl12xx_reg_write32(wl
, ACX_REG_INTERRUPT_MASK
, WL1251_ACX_INTR_ALL
);
411 intr
= wl12xx_reg_read32(wl
, ACX_REG_INTERRUPT_CLEAR
);
412 wl12xx_debug(DEBUG_IRQ
, "intr: 0x%x", intr
);
415 wl12xx_spi_mem_read(wl
, wl
->data_path
->rx_control_addr
,
416 &wl
->rx_counter
, sizeof(u32
));
418 /* We handle a frmware bug here */
419 switch ((wl
->rx_counter
- wl
->rx_handled
) & 0xf) {
421 wl12xx_debug(DEBUG_IRQ
, "RX: FW and host in sync");
422 intr
&= ~WL1251_ACX_INTR_RX0_DATA
;
423 intr
&= ~WL1251_ACX_INTR_RX1_DATA
;
426 wl12xx_debug(DEBUG_IRQ
, "RX: FW +1");
427 intr
|= WL1251_ACX_INTR_RX0_DATA
;
428 intr
&= ~WL1251_ACX_INTR_RX1_DATA
;
431 wl12xx_debug(DEBUG_IRQ
, "RX: FW +2");
432 intr
|= WL1251_ACX_INTR_RX0_DATA
;
433 intr
|= WL1251_ACX_INTR_RX1_DATA
;
436 wl12xx_warning("RX: FW and host out of sync: %d",
437 wl
->rx_counter
- wl
->rx_handled
);
441 wl
->rx_handled
= wl
->rx_counter
;
444 wl12xx_debug(DEBUG_IRQ
, "RX counter: %d", wl
->rx_counter
);
447 intr
&= wl
->intr_mask
;
450 wl12xx_debug(DEBUG_IRQ
, "INTR is 0");
451 wl12xx_reg_write32(wl
, ACX_REG_INTERRUPT_MASK
,
457 if (intr
& WL1251_ACX_INTR_RX0_DATA
) {
458 wl12xx_debug(DEBUG_IRQ
, "WL1251_ACX_INTR_RX0_DATA");
462 if (intr
& WL1251_ACX_INTR_RX1_DATA
) {
463 wl12xx_debug(DEBUG_IRQ
, "WL1251_ACX_INTR_RX1_DATA");
467 if (intr
& WL1251_ACX_INTR_TX_RESULT
) {
468 wl12xx_debug(DEBUG_IRQ
, "WL1251_ACX_INTR_TX_RESULT");
469 wl12xx_tx_complete(wl
);
472 if (intr
& (WL1251_ACX_INTR_EVENT_A
| WL1251_ACX_INTR_EVENT_B
)) {
473 wl12xx_debug(DEBUG_IRQ
, "WL1251_ACX_INTR_EVENT (0x%x)", intr
);
474 if (intr
& WL1251_ACX_INTR_EVENT_A
)
475 wl12xx_event_handle(wl
, 0);
477 wl12xx_event_handle(wl
, 1);
480 if (intr
& WL1251_ACX_INTR_INIT_COMPLETE
)
481 wl12xx_debug(DEBUG_IRQ
, "WL1251_ACX_INTR_INIT_COMPLETE");
483 wl12xx_reg_write32(wl
, ACX_REG_INTERRUPT_MASK
, ~(wl
->intr_mask
));
486 wl12xx_ps_elp_sleep(wl
);
488 mutex_unlock(&wl
->mutex
);
491 static int wl1251_hw_init_txq_fill(u8 qid
,
492 struct acx_tx_queue_qos_config
*config
,
499 config
->high_threshold
=
500 (QOS_TX_HIGH_BE_DEF
* num_blocks
) / 100;
501 config
->low_threshold
=
502 (QOS_TX_LOW_BE_DEF
* num_blocks
) / 100;
505 config
->high_threshold
=
506 (QOS_TX_HIGH_BK_DEF
* num_blocks
) / 100;
507 config
->low_threshold
=
508 (QOS_TX_LOW_BK_DEF
* num_blocks
) / 100;
511 config
->high_threshold
=
512 (QOS_TX_HIGH_VI_DEF
* num_blocks
) / 100;
513 config
->low_threshold
=
514 (QOS_TX_LOW_VI_DEF
* num_blocks
) / 100;
517 config
->high_threshold
=
518 (QOS_TX_HIGH_VO_DEF
* num_blocks
) / 100;
519 config
->low_threshold
=
520 (QOS_TX_LOW_VO_DEF
* num_blocks
) / 100;
523 wl12xx_error("Invalid TX queue id: %d", qid
);
530 static int wl1251_hw_init_tx_queue_config(struct wl12xx
*wl
)
532 struct acx_tx_queue_qos_config config
;
533 struct wl1251_acx_mem_map
*wl_mem_map
= wl
->target_mem_map
;
536 wl12xx_debug(DEBUG_ACX
, "acx tx queue config");
538 config
.header
.id
= ACX_TX_QUEUE_CFG
;
539 config
.header
.len
= sizeof(struct acx_tx_queue_qos_config
) -
540 sizeof(struct acx_header
);
542 for (i
= 0; i
< MAX_NUM_OF_AC
; i
++) {
543 ret
= wl1251_hw_init_txq_fill(i
, &config
,
544 wl_mem_map
->num_tx_mem_blocks
);
548 ret
= wl12xx_cmd_configure(wl
, &config
, sizeof(config
));
556 static int wl1251_hw_init_data_path_config(struct wl12xx
*wl
)
560 /* asking for the data path parameters */
561 wl
->data_path
= kzalloc(sizeof(struct acx_data_path_params_resp
),
563 if (!wl
->data_path
) {
564 wl12xx_error("Couldnt allocate data path parameters");
568 ret
= wl12xx_acx_data_path_params(wl
, wl
->data_path
);
570 kfree(wl
->data_path
);
571 wl
->data_path
= NULL
;
578 static int wl1251_hw_init(struct wl12xx
*wl
)
580 struct wl1251_acx_mem_map
*wl_mem_map
;
583 ret
= wl12xx_hw_init_hwenc_config(wl
);
587 /* Template settings */
588 ret
= wl12xx_hw_init_templates_config(wl
);
592 /* Default memory configuration */
593 ret
= wl1251_hw_init_mem_config(wl
);
597 /* Default data path configuration */
598 ret
= wl1251_hw_init_data_path_config(wl
);
600 goto out_free_memmap
;
603 ret
= wl12xx_hw_init_rx_config(wl
,
604 RX_CFG_PROMISCUOUS
| RX_CFG_TSF
,
605 RX_FILTER_OPTION_DEF
);
606 /* RX_CONFIG_OPTION_ANY_DST_ANY_BSS,
607 RX_FILTER_OPTION_FILTER_ALL); */
609 goto out_free_data_path
;
611 /* TX queues config */
612 ret
= wl1251_hw_init_tx_queue_config(wl
);
614 goto out_free_data_path
;
616 /* PHY layer config */
617 ret
= wl12xx_hw_init_phy_config(wl
);
619 goto out_free_data_path
;
621 /* Beacon filtering */
622 ret
= wl12xx_hw_init_beacon_filter(wl
);
624 goto out_free_data_path
;
626 /* Bluetooth WLAN coexistence */
627 ret
= wl12xx_hw_init_pta(wl
);
629 goto out_free_data_path
;
631 /* Energy detection */
632 ret
= wl12xx_hw_init_energy_detection(wl
);
634 goto out_free_data_path
;
636 /* Beacons and boradcast settings */
637 ret
= wl12xx_hw_init_beacon_broadcast(wl
);
639 goto out_free_data_path
;
641 /* Enable data path */
642 ret
= wl12xx_cmd_data_path(wl
, wl
->channel
, 1);
644 goto out_free_data_path
;
646 /* Default power state */
647 ret
= wl12xx_hw_init_power_auth(wl
);
649 goto out_free_data_path
;
651 wl_mem_map
= wl
->target_mem_map
;
652 wl12xx_info("%d tx blocks at 0x%x, %d rx blocks at 0x%x",
653 wl_mem_map
->num_tx_mem_blocks
,
654 wl
->data_path
->tx_control_addr
,
655 wl_mem_map
->num_rx_mem_blocks
,
656 wl
->data_path
->rx_control_addr
);
661 kfree(wl
->data_path
);
664 kfree(wl
->target_mem_map
);
669 static int wl1251_plt_init(struct wl12xx
*wl
)
673 ret
= wl1251_hw_init_mem_config(wl
);
677 ret
= wl12xx_cmd_data_path(wl
, wl
->channel
, 1);
684 void wl1251_setup(struct wl12xx
*wl
)
686 /* FIXME: Is it better to use strncpy here or is this ok? */
687 wl
->chip
.fw_filename
= WL1251_FW_NAME
;
688 wl
->chip
.nvs_filename
= WL1251_NVS_NAME
;
690 /* Now we know what chip we're using, so adjust the power on sleep
691 * time accordingly */
692 wl
->chip
.power_on_sleep
= WL1251_POWER_ON_SLEEP
;
694 wl
->chip
.intr_cmd_complete
= WL1251_ACX_INTR_CMD_COMPLETE
;
695 wl
->chip
.intr_init_complete
= WL1251_ACX_INTR_INIT_COMPLETE
;
697 wl
->chip
.op_upload_nvs
= wl1251_upload_nvs
;
698 wl
->chip
.op_upload_fw
= wl1251_upload_firmware
;
699 wl
->chip
.op_boot
= wl1251_boot
;
700 wl
->chip
.op_set_ecpu_ctrl
= wl1251_set_ecpu_ctrl
;
701 wl
->chip
.op_target_enable_interrupts
= wl1251_target_enable_interrupts
;
702 wl
->chip
.op_hw_init
= wl1251_hw_init
;
703 wl
->chip
.op_plt_init
= wl1251_plt_init
;
705 wl
->chip
.p_table
= wl1251_part_table
;
706 wl
->chip
.acx_reg_table
= wl1251_acx_reg_table
;
708 INIT_WORK(&wl
->irq_work
, wl1251_irq_work
);