2 * This file is part of wl1271
4 * Copyright (C) 2008-2010 Nokia Corporation
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 #include <linux/module.h>
23 #include <linux/platform_device.h>
25 #include <linux/err.h>
27 #include <linux/wl12xx.h>
29 #include "../wlcore/wlcore.h"
30 #include "../wlcore/debug.h"
31 #include "../wlcore/io.h"
32 #include "../wlcore/acx.h"
33 #include "../wlcore/tx.h"
34 #include "../wlcore/rx.h"
35 #include "../wlcore/io.h"
36 #include "../wlcore/boot.h"
42 #define WL12XX_TX_HW_BLOCK_SPARE_DEFAULT 1
43 #define WL12XX_TX_HW_BLOCK_GEM_SPARE 2
44 #define WL12XX_TX_HW_BLOCK_SIZE 252
46 static const u8 wl12xx_rate_to_idx_2ghz
[] = {
47 /* MCS rates are used only with 11n */
48 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI */
49 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7 */
50 6, /* WL12XX_CONF_HW_RXTX_RATE_MCS6 */
51 5, /* WL12XX_CONF_HW_RXTX_RATE_MCS5 */
52 4, /* WL12XX_CONF_HW_RXTX_RATE_MCS4 */
53 3, /* WL12XX_CONF_HW_RXTX_RATE_MCS3 */
54 2, /* WL12XX_CONF_HW_RXTX_RATE_MCS2 */
55 1, /* WL12XX_CONF_HW_RXTX_RATE_MCS1 */
56 0, /* WL12XX_CONF_HW_RXTX_RATE_MCS0 */
58 11, /* WL12XX_CONF_HW_RXTX_RATE_54 */
59 10, /* WL12XX_CONF_HW_RXTX_RATE_48 */
60 9, /* WL12XX_CONF_HW_RXTX_RATE_36 */
61 8, /* WL12XX_CONF_HW_RXTX_RATE_24 */
63 /* TI-specific rate */
64 CONF_HW_RXTX_RATE_UNSUPPORTED
, /* WL12XX_CONF_HW_RXTX_RATE_22 */
66 7, /* WL12XX_CONF_HW_RXTX_RATE_18 */
67 6, /* WL12XX_CONF_HW_RXTX_RATE_12 */
68 3, /* WL12XX_CONF_HW_RXTX_RATE_11 */
69 5, /* WL12XX_CONF_HW_RXTX_RATE_9 */
70 4, /* WL12XX_CONF_HW_RXTX_RATE_6 */
71 2, /* WL12XX_CONF_HW_RXTX_RATE_5_5 */
72 1, /* WL12XX_CONF_HW_RXTX_RATE_2 */
73 0 /* WL12XX_CONF_HW_RXTX_RATE_1 */
76 static const u8 wl12xx_rate_to_idx_5ghz
[] = {
77 /* MCS rates are used only with 11n */
78 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI */
79 7, /* WL12XX_CONF_HW_RXTX_RATE_MCS7 */
80 6, /* WL12XX_CONF_HW_RXTX_RATE_MCS6 */
81 5, /* WL12XX_CONF_HW_RXTX_RATE_MCS5 */
82 4, /* WL12XX_CONF_HW_RXTX_RATE_MCS4 */
83 3, /* WL12XX_CONF_HW_RXTX_RATE_MCS3 */
84 2, /* WL12XX_CONF_HW_RXTX_RATE_MCS2 */
85 1, /* WL12XX_CONF_HW_RXTX_RATE_MCS1 */
86 0, /* WL12XX_CONF_HW_RXTX_RATE_MCS0 */
88 7, /* WL12XX_CONF_HW_RXTX_RATE_54 */
89 6, /* WL12XX_CONF_HW_RXTX_RATE_48 */
90 5, /* WL12XX_CONF_HW_RXTX_RATE_36 */
91 4, /* WL12XX_CONF_HW_RXTX_RATE_24 */
93 /* TI-specific rate */
94 CONF_HW_RXTX_RATE_UNSUPPORTED
, /* WL12XX_CONF_HW_RXTX_RATE_22 */
96 3, /* WL12XX_CONF_HW_RXTX_RATE_18 */
97 2, /* WL12XX_CONF_HW_RXTX_RATE_12 */
98 CONF_HW_RXTX_RATE_UNSUPPORTED
, /* WL12XX_CONF_HW_RXTX_RATE_11 */
99 1, /* WL12XX_CONF_HW_RXTX_RATE_9 */
100 0, /* WL12XX_CONF_HW_RXTX_RATE_6 */
101 CONF_HW_RXTX_RATE_UNSUPPORTED
, /* WL12XX_CONF_HW_RXTX_RATE_5_5 */
102 CONF_HW_RXTX_RATE_UNSUPPORTED
, /* WL12XX_CONF_HW_RXTX_RATE_2 */
103 CONF_HW_RXTX_RATE_UNSUPPORTED
/* WL12XX_CONF_HW_RXTX_RATE_1 */
106 static const u8
*wl12xx_band_rate_to_idx
[] = {
107 [IEEE80211_BAND_2GHZ
] = wl12xx_rate_to_idx_2ghz
,
108 [IEEE80211_BAND_5GHZ
] = wl12xx_rate_to_idx_5ghz
111 enum wl12xx_hw_rates
{
112 WL12XX_CONF_HW_RXTX_RATE_MCS7_SGI
= 0,
113 WL12XX_CONF_HW_RXTX_RATE_MCS7
,
114 WL12XX_CONF_HW_RXTX_RATE_MCS6
,
115 WL12XX_CONF_HW_RXTX_RATE_MCS5
,
116 WL12XX_CONF_HW_RXTX_RATE_MCS4
,
117 WL12XX_CONF_HW_RXTX_RATE_MCS3
,
118 WL12XX_CONF_HW_RXTX_RATE_MCS2
,
119 WL12XX_CONF_HW_RXTX_RATE_MCS1
,
120 WL12XX_CONF_HW_RXTX_RATE_MCS0
,
121 WL12XX_CONF_HW_RXTX_RATE_54
,
122 WL12XX_CONF_HW_RXTX_RATE_48
,
123 WL12XX_CONF_HW_RXTX_RATE_36
,
124 WL12XX_CONF_HW_RXTX_RATE_24
,
125 WL12XX_CONF_HW_RXTX_RATE_22
,
126 WL12XX_CONF_HW_RXTX_RATE_18
,
127 WL12XX_CONF_HW_RXTX_RATE_12
,
128 WL12XX_CONF_HW_RXTX_RATE_11
,
129 WL12XX_CONF_HW_RXTX_RATE_9
,
130 WL12XX_CONF_HW_RXTX_RATE_6
,
131 WL12XX_CONF_HW_RXTX_RATE_5_5
,
132 WL12XX_CONF_HW_RXTX_RATE_2
,
133 WL12XX_CONF_HW_RXTX_RATE_1
,
134 WL12XX_CONF_HW_RXTX_RATE_MAX
,
137 static struct wlcore_partition_set wl12xx_ptable
[PART_TABLE_LEN
] = {
144 .start
= REGISTERS_BASE
,
157 [PART_BOOT
] = { /* in wl12xx we can use a mix of work and down
164 .start
= REGISTERS_BASE
,
183 .start
= REGISTERS_BASE
,
216 static const int wl12xx_rtable
[REG_TABLE_LEN
] = {
217 [REG_ECPU_CONTROL
] = WL12XX_REG_ECPU_CONTROL
,
218 [REG_INTERRUPT_NO_CLEAR
] = WL12XX_REG_INTERRUPT_NO_CLEAR
,
219 [REG_INTERRUPT_ACK
] = WL12XX_REG_INTERRUPT_ACK
,
220 [REG_COMMAND_MAILBOX_PTR
] = WL12XX_REG_COMMAND_MAILBOX_PTR
,
221 [REG_EVENT_MAILBOX_PTR
] = WL12XX_REG_EVENT_MAILBOX_PTR
,
222 [REG_INTERRUPT_TRIG
] = WL12XX_REG_INTERRUPT_TRIG
,
223 [REG_INTERRUPT_MASK
] = WL12XX_REG_INTERRUPT_MASK
,
224 [REG_PC_ON_RECOVERY
] = WL12XX_SCR_PAD4
,
225 [REG_CHIP_ID_B
] = WL12XX_CHIP_ID_B
,
226 [REG_CMD_MBOX_ADDRESS
] = WL12XX_CMD_MBOX_ADDRESS
,
228 /* data access memory addresses, used with partition translation */
229 [REG_SLV_MEM_DATA
] = WL1271_SLV_MEM_DATA
,
230 [REG_SLV_REG_DATA
] = WL1271_SLV_REG_DATA
,
232 /* raw data access memory addresses */
233 [REG_RAW_FW_STATUS_ADDR
] = FW_STATUS_ADDR
,
236 /* TODO: maybe move to a new header file? */
237 #define WL127X_FW_NAME_MULTI "ti-connectivity/wl127x-fw-4-mr.bin"
238 #define WL127X_FW_NAME_SINGLE "ti-connectivity/wl127x-fw-4-sr.bin"
239 #define WL127X_PLT_FW_NAME "ti-connectivity/wl127x-fw-4-plt.bin"
241 #define WL128X_FW_NAME_MULTI "ti-connectivity/wl128x-fw-4-mr.bin"
242 #define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin"
243 #define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin"
245 static void wl127x_prepare_read(struct wl1271
*wl
, u32 rx_desc
, u32 len
)
247 if (wl
->chip
.id
!= CHIP_ID_1283_PG20
) {
248 struct wl1271_acx_mem_map
*wl_mem_map
= wl
->target_mem_map
;
249 struct wl1271_rx_mem_pool_addr rx_mem_addr
;
252 * Choose the block we want to read
253 * For aggregated packets, only the first memory block
254 * should be retrieved. The FW takes care of the rest.
256 u32 mem_block
= rx_desc
& RX_MEM_BLOCK_MASK
;
258 rx_mem_addr
.addr
= (mem_block
<< 8) +
259 le32_to_cpu(wl_mem_map
->packet_memory_pool_start
);
261 rx_mem_addr
.addr_extra
= rx_mem_addr
.addr
+ 4;
263 wl1271_write(wl
, WL1271_SLV_REG_DATA
,
264 &rx_mem_addr
, sizeof(rx_mem_addr
), false);
268 static int wl12xx_identify_chip(struct wl1271
*wl
)
272 switch (wl
->chip
.id
) {
273 case CHIP_ID_1271_PG10
:
274 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
277 /* clear the alignment quirk, since we don't support it */
278 wl
->quirks
&= ~WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN
;
280 wl
->quirks
|= WLCORE_QUIRK_LEGACY_NVS
;
281 wl
->sr_fw_name
= WL127X_FW_NAME_SINGLE
;
282 wl
->mr_fw_name
= WL127X_FW_NAME_MULTI
;
284 /* read data preparation is only needed by wl127x */
285 wl
->ops
->prepare_read
= wl127x_prepare_read
;
289 case CHIP_ID_1271_PG20
:
290 wl1271_debug(DEBUG_BOOT
, "chip id 0x%x (1271 PG20)",
293 /* clear the alignment quirk, since we don't support it */
294 wl
->quirks
&= ~WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN
;
296 wl
->quirks
|= WLCORE_QUIRK_LEGACY_NVS
;
297 wl
->plt_fw_name
= WL127X_PLT_FW_NAME
;
298 wl
->sr_fw_name
= WL127X_FW_NAME_SINGLE
;
299 wl
->mr_fw_name
= WL127X_FW_NAME_MULTI
;
301 /* read data preparation is only needed by wl127x */
302 wl
->ops
->prepare_read
= wl127x_prepare_read
;
306 case CHIP_ID_1283_PG20
:
307 wl1271_debug(DEBUG_BOOT
, "chip id 0x%x (1283 PG20)",
309 wl
->plt_fw_name
= WL128X_PLT_FW_NAME
;
310 wl
->sr_fw_name
= WL128X_FW_NAME_SINGLE
;
311 wl
->mr_fw_name
= WL128X_FW_NAME_MULTI
;
313 case CHIP_ID_1283_PG10
:
315 wl1271_warning("unsupported chip id: 0x%x", wl
->chip
.id
);
324 static void wl12xx_top_reg_write(struct wl1271
*wl
, int addr
, u16 val
)
326 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
327 addr
= (addr
>> 1) + 0x30000;
328 wl1271_write32(wl
, WL12XX_OCP_POR_CTR
, addr
);
330 /* write value to OCP_POR_WDATA */
331 wl1271_write32(wl
, WL12XX_OCP_DATA_WRITE
, val
);
333 /* write 1 to OCP_CMD */
334 wl1271_write32(wl
, WL12XX_OCP_CMD
, OCP_CMD_WRITE
);
337 static u16
wl12xx_top_reg_read(struct wl1271
*wl
, int addr
)
340 int timeout
= OCP_CMD_LOOP
;
342 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
343 addr
= (addr
>> 1) + 0x30000;
344 wl1271_write32(wl
, WL12XX_OCP_POR_CTR
, addr
);
346 /* write 2 to OCP_CMD */
347 wl1271_write32(wl
, WL12XX_OCP_CMD
, OCP_CMD_READ
);
349 /* poll for data ready */
351 val
= wl1271_read32(wl
, WL12XX_OCP_DATA_READ
);
352 } while (!(val
& OCP_READY_MASK
) && --timeout
);
355 wl1271_warning("Top register access timed out.");
359 /* check data status and return if OK */
360 if ((val
& OCP_STATUS_MASK
) == OCP_STATUS_OK
)
363 wl1271_warning("Top register access returned error.");
368 static int wl128x_switch_tcxo_to_fref(struct wl1271
*wl
)
372 /* Mask bits [2] & [8:4] in the sys_clk_cfg register */
373 spare_reg
= wl12xx_top_reg_read(wl
, WL_SPARE_REG
);
374 if (spare_reg
== 0xFFFF)
376 spare_reg
|= (BIT(3) | BIT(5) | BIT(6));
377 wl12xx_top_reg_write(wl
, WL_SPARE_REG
, spare_reg
);
379 /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */
380 wl12xx_top_reg_write(wl
, SYS_CLK_CFG_REG
,
381 WL_CLK_REQ_TYPE_PG2
| MCS_PLL_CLK_SEL_FREF
);
383 /* Delay execution for 15msec, to let the HW settle */
389 static bool wl128x_is_tcxo_valid(struct wl1271
*wl
)
393 tcxo_detection
= wl12xx_top_reg_read(wl
, TCXO_CLK_DETECT_REG
);
394 if (tcxo_detection
& TCXO_DET_FAILED
)
400 static bool wl128x_is_fref_valid(struct wl1271
*wl
)
404 fref_detection
= wl12xx_top_reg_read(wl
, FREF_CLK_DETECT_REG
);
405 if (fref_detection
& FREF_CLK_DETECT_FAIL
)
411 static int wl128x_manually_configure_mcs_pll(struct wl1271
*wl
)
413 wl12xx_top_reg_write(wl
, MCS_PLL_M_REG
, MCS_PLL_M_REG_VAL
);
414 wl12xx_top_reg_write(wl
, MCS_PLL_N_REG
, MCS_PLL_N_REG_VAL
);
415 wl12xx_top_reg_write(wl
, MCS_PLL_CONFIG_REG
, MCS_PLL_CONFIG_REG_VAL
);
420 static int wl128x_configure_mcs_pll(struct wl1271
*wl
, int clk
)
426 /* Mask bits [3:1] in the sys_clk_cfg register */
427 spare_reg
= wl12xx_top_reg_read(wl
, WL_SPARE_REG
);
428 if (spare_reg
== 0xFFFF)
431 wl12xx_top_reg_write(wl
, WL_SPARE_REG
, spare_reg
);
433 /* Handle special cases of the TCXO clock */
434 if (wl
->tcxo_clock
== WL12XX_TCXOCLOCK_16_8
||
435 wl
->tcxo_clock
== WL12XX_TCXOCLOCK_33_6
)
436 return wl128x_manually_configure_mcs_pll(wl
);
438 /* Set the input frequency according to the selected clock source */
439 input_freq
= (clk
& 1) + 1;
441 pll_config
= wl12xx_top_reg_read(wl
, MCS_PLL_CONFIG_REG
);
442 if (pll_config
== 0xFFFF)
444 pll_config
|= (input_freq
<< MCS_SEL_IN_FREQ_SHIFT
);
445 pll_config
|= MCS_PLL_ENABLE_HP
;
446 wl12xx_top_reg_write(wl
, MCS_PLL_CONFIG_REG
, pll_config
);
452 * WL128x has two clocks input - TCXO and FREF.
453 * TCXO is the main clock of the device, while FREF is used to sync
454 * between the GPS and the cellular modem.
455 * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used
456 * as the WLAN/BT main clock.
458 static int wl128x_boot_clk(struct wl1271
*wl
, int *selected_clock
)
462 /* For XTAL-only modes, FREF will be used after switching from TCXO */
463 if (wl
->ref_clock
== WL12XX_REFCLOCK_26_XTAL
||
464 wl
->ref_clock
== WL12XX_REFCLOCK_38_XTAL
) {
465 if (!wl128x_switch_tcxo_to_fref(wl
))
470 /* Query the HW, to determine which clock source we should use */
471 sys_clk_cfg
= wl12xx_top_reg_read(wl
, SYS_CLK_CFG_REG
);
472 if (sys_clk_cfg
== 0xFFFF)
474 if (sys_clk_cfg
& PRCM_CM_EN_MUX_WLAN_FREF
)
477 /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */
478 if (wl
->tcxo_clock
== WL12XX_TCXOCLOCK_16_368
||
479 wl
->tcxo_clock
== WL12XX_TCXOCLOCK_32_736
) {
480 if (!wl128x_switch_tcxo_to_fref(wl
))
485 /* TCXO clock is selected */
486 if (!wl128x_is_tcxo_valid(wl
))
488 *selected_clock
= wl
->tcxo_clock
;
492 /* FREF clock is selected */
493 if (!wl128x_is_fref_valid(wl
))
495 *selected_clock
= wl
->ref_clock
;
498 return wl128x_configure_mcs_pll(wl
, *selected_clock
);
501 static int wl127x_boot_clk(struct wl1271
*wl
)
506 if (WL127X_PG_GET_MAJOR(wl
->hw_pg_ver
) < 3)
507 wl
->quirks
|= WLCORE_QUIRK_END_OF_TRANSACTION
;
509 if (wl
->ref_clock
== CONF_REF_CLK_19_2_E
||
510 wl
->ref_clock
== CONF_REF_CLK_38_4_E
||
511 wl
->ref_clock
== CONF_REF_CLK_38_4_M_XTAL
)
512 /* ref clk: 19.2/38.4/38.4-XTAL */
514 else if (wl
->ref_clock
== CONF_REF_CLK_26_E
||
515 wl
->ref_clock
== CONF_REF_CLK_52_E
)
521 if (wl
->ref_clock
!= CONF_REF_CLK_19_2_E
) {
523 /* Set clock type (open drain) */
524 val
= wl12xx_top_reg_read(wl
, OCP_REG_CLK_TYPE
);
525 val
&= FREF_CLK_TYPE_BITS
;
526 wl12xx_top_reg_write(wl
, OCP_REG_CLK_TYPE
, val
);
528 /* Set clock pull mode (no pull) */
529 val
= wl12xx_top_reg_read(wl
, OCP_REG_CLK_PULL
);
531 wl12xx_top_reg_write(wl
, OCP_REG_CLK_PULL
, val
);
534 /* Set clock polarity */
535 val
= wl12xx_top_reg_read(wl
, OCP_REG_CLK_POLARITY
);
536 val
&= FREF_CLK_POLARITY_BITS
;
537 val
|= CLK_REQ_OUTN_SEL
;
538 wl12xx_top_reg_write(wl
, OCP_REG_CLK_POLARITY
, val
);
541 wl1271_write32(wl
, WL12XX_PLL_PARAMETERS
, clk
);
543 pause
= wl1271_read32(wl
, WL12XX_PLL_PARAMETERS
);
545 wl1271_debug(DEBUG_BOOT
, "pause1 0x%x", pause
);
547 pause
&= ~(WU_COUNTER_PAUSE_VAL
);
548 pause
|= WU_COUNTER_PAUSE_VAL
;
549 wl1271_write32(wl
, WL12XX_WU_COUNTER_PAUSE
, pause
);
554 static int wl1271_boot_soft_reset(struct wl1271
*wl
)
556 unsigned long timeout
;
559 /* perform soft reset */
560 wl1271_write32(wl
, WL12XX_SLV_SOFT_RESET
, ACX_SLV_SOFT_RESET_BIT
);
562 /* SOFT_RESET is self clearing */
563 timeout
= jiffies
+ usecs_to_jiffies(SOFT_RESET_MAX_TIME
);
565 boot_data
= wl1271_read32(wl
, WL12XX_SLV_SOFT_RESET
);
566 wl1271_debug(DEBUG_BOOT
, "soft reset bootdata 0x%x", boot_data
);
567 if ((boot_data
& ACX_SLV_SOFT_RESET_BIT
) == 0)
570 if (time_after(jiffies
, timeout
)) {
571 /* 1.2 check pWhalBus->uSelfClearTime if the
572 * timeout was reached */
573 wl1271_error("soft reset timeout");
577 udelay(SOFT_RESET_STALL_TIME
);
581 wl1271_write32(wl
, WL12XX_ENABLE
, 0x0);
583 /* disable auto calibration on start*/
584 wl1271_write32(wl
, WL12XX_SPARE_A2
, 0xffff);
589 static int wl12xx_pre_boot(struct wl1271
*wl
)
593 int selected_clock
= -1;
595 if (wl
->chip
.id
== CHIP_ID_1283_PG20
) {
596 ret
= wl128x_boot_clk(wl
, &selected_clock
);
600 ret
= wl127x_boot_clk(wl
);
605 /* Continue the ELP wake up sequence */
606 wl1271_write32(wl
, WL12XX_WELP_ARM_COMMAND
, WELP_ARM_COMMAND_VAL
);
609 wlcore_set_partition(wl
, &wl
->ptable
[PART_DRPW
]);
611 /* Read-modify-write DRPW_SCRATCH_START register (see next state)
612 to be used by DRPw FW. The RTRIM value will be added by the FW
613 before taking DRPw out of reset */
615 clk
= wl1271_read32(wl
, WL12XX_DRPW_SCRATCH_START
);
617 wl1271_debug(DEBUG_BOOT
, "clk2 0x%x", clk
);
619 if (wl
->chip
.id
== CHIP_ID_1283_PG20
)
620 clk
|= ((selected_clock
& 0x3) << 1) << 4;
622 clk
|= (wl
->ref_clock
<< 1) << 4;
624 wl1271_write32(wl
, WL12XX_DRPW_SCRATCH_START
, clk
);
626 wlcore_set_partition(wl
, &wl
->ptable
[PART_WORK
]);
628 /* Disable interrupts */
629 wlcore_write_reg(wl
, REG_INTERRUPT_MASK
, WL1271_ACX_INTR_ALL
);
631 ret
= wl1271_boot_soft_reset(wl
);
639 static void wl12xx_pre_upload(struct wl1271
*wl
)
643 /* write firmware's last address (ie. it's length) to
644 * ACX_EEPROMLESS_IND_REG */
645 wl1271_debug(DEBUG_BOOT
, "ACX_EEPROMLESS_IND_REG");
647 wl1271_write32(wl
, WL12XX_EEPROMLESS_IND
, WL12XX_EEPROMLESS_IND
);
649 tmp
= wlcore_read_reg(wl
, REG_CHIP_ID_B
);
651 wl1271_debug(DEBUG_BOOT
, "chip id 0x%x", tmp
);
653 /* 6. read the EEPROM parameters */
654 tmp
= wl1271_read32(wl
, WL12XX_SCR_PAD2
);
656 /* WL1271: The reference driver skips steps 7 to 10 (jumps directly
659 if (wl
->chip
.id
== CHIP_ID_1283_PG20
)
660 wl12xx_top_reg_write(wl
, SDIO_IO_DS
, HCI_IO_DS_6MA
);
663 static void wl12xx_enable_interrupts(struct wl1271
*wl
)
667 polarity
= wl12xx_top_reg_read(wl
, OCP_REG_POLARITY
);
669 /* We use HIGH polarity, so unset the LOW bit */
670 polarity
&= ~POLARITY_LOW
;
671 wl12xx_top_reg_write(wl
, OCP_REG_POLARITY
, polarity
);
673 wlcore_write_reg(wl
, REG_INTERRUPT_MASK
, WL1271_ACX_ALL_EVENTS_VECTOR
);
675 wlcore_enable_interrupts(wl
);
676 wlcore_write_reg(wl
, REG_INTERRUPT_MASK
,
677 WL1271_ACX_INTR_ALL
& ~(WL1271_INTR_MASK
));
679 wl1271_write32(wl
, WL12XX_HI_CFG
, HI_CFG_DEF_VAL
);
682 static int wl12xx_boot(struct wl1271
*wl
)
686 ret
= wl12xx_pre_boot(wl
);
690 ret
= wlcore_boot_upload_nvs(wl
);
694 wl12xx_pre_upload(wl
);
696 ret
= wlcore_boot_upload_firmware(wl
);
700 ret
= wlcore_boot_run_firmware(wl
);
704 wl12xx_enable_interrupts(wl
);
710 static void wl12xx_trigger_cmd(struct wl1271
*wl
)
712 wlcore_write_reg(wl
, REG_INTERRUPT_TRIG
, WL12XX_INTR_TRIG_CMD
);
715 static void wl12xx_ack_event(struct wl1271
*wl
)
717 wlcore_write_reg(wl
, REG_INTERRUPT_TRIG
, WL12XX_INTR_TRIG_EVENT_ACK
);
720 static u32
wl12xx_calc_tx_blocks(struct wl1271
*wl
, u32 len
, u32 spare_blks
)
722 u32 blk_size
= WL12XX_TX_HW_BLOCK_SIZE
;
723 u32 align_len
= wlcore_calc_packet_alignment(wl
, len
);
725 return (align_len
+ blk_size
- 1) / blk_size
+ spare_blks
;
729 wl12xx_set_tx_desc_blocks(struct wl1271
*wl
, struct wl1271_tx_hw_descr
*desc
,
730 u32 blks
, u32 spare_blks
)
732 if (wl
->chip
.id
== CHIP_ID_1283_PG20
) {
733 desc
->wl128x_mem
.total_mem_blocks
= blks
;
735 desc
->wl127x_mem
.extra_blocks
= spare_blks
;
736 desc
->wl127x_mem
.total_mem_blocks
= blks
;
741 wl12xx_set_tx_desc_data_len(struct wl1271
*wl
, struct wl1271_tx_hw_descr
*desc
,
744 u32 aligned_len
= wlcore_calc_packet_alignment(wl
, skb
->len
);
746 if (wl
->chip
.id
== CHIP_ID_1283_PG20
) {
747 desc
->wl128x_mem
.extra_bytes
= aligned_len
- skb
->len
;
748 desc
->length
= cpu_to_le16(aligned_len
>> 2);
750 wl1271_debug(DEBUG_TX
,
751 "tx_fill_hdr: hlid: %d len: %d life: %d mem: %d extra: %d",
753 le16_to_cpu(desc
->length
),
754 le16_to_cpu(desc
->life_time
),
755 desc
->wl128x_mem
.total_mem_blocks
,
756 desc
->wl128x_mem
.extra_bytes
);
758 /* calculate number of padding bytes */
759 int pad
= aligned_len
- skb
->len
;
761 cpu_to_le16(pad
<< TX_HW_ATTR_OFST_LAST_WORD_PAD
);
763 /* Store the aligned length in terms of words */
764 desc
->length
= cpu_to_le16(aligned_len
>> 2);
766 wl1271_debug(DEBUG_TX
,
767 "tx_fill_hdr: pad: %d hlid: %d len: %d life: %d mem: %d",
769 le16_to_cpu(desc
->length
),
770 le16_to_cpu(desc
->life_time
),
771 desc
->wl127x_mem
.total_mem_blocks
);
775 static enum wl_rx_buf_align
776 wl12xx_get_rx_buf_align(struct wl1271
*wl
, u32 rx_desc
)
778 if (rx_desc
& RX_BUF_UNALIGNED_PAYLOAD
)
779 return WLCORE_RX_BUF_UNALIGNED
;
781 return WLCORE_RX_BUF_ALIGNED
;
784 static u32
wl12xx_get_rx_packet_len(struct wl1271
*wl
, void *rx_data
,
787 struct wl1271_rx_descriptor
*desc
= rx_data
;
790 if (data_len
< sizeof(*desc
) ||
791 data_len
< sizeof(*desc
) + desc
->pad_len
)
794 return data_len
- sizeof(*desc
) - desc
->pad_len
;
797 static void wl12xx_tx_delayed_compl(struct wl1271
*wl
)
799 if (wl
->fw_status
->tx_results_counter
== (wl
->tx_results_count
& 0xff))
802 wl1271_tx_complete(wl
);
805 static int wl12xx_hw_init(struct wl1271
*wl
)
809 if (wl
->chip
.id
== CHIP_ID_1283_PG20
) {
810 u32 host_cfg_bitmap
= HOST_IF_CFG_RX_FIFO_ENABLE
;
812 ret
= wl128x_cmd_general_parms(wl
);
815 ret
= wl128x_cmd_radio_parms(wl
);
819 if (wl
->quirks
& WLCORE_QUIRK_TX_BLOCKSIZE_ALIGN
)
820 /* Enable SDIO padding */
821 host_cfg_bitmap
|= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK
;
823 /* Must be before wl1271_acx_init_mem_config() */
824 ret
= wl1271_acx_host_if_cfg_bitmap(wl
, host_cfg_bitmap
);
828 ret
= wl1271_cmd_general_parms(wl
);
831 ret
= wl1271_cmd_radio_parms(wl
);
834 ret
= wl1271_cmd_ext_radio_parms(wl
);
842 static bool wl12xx_mac_in_fuse(struct wl1271
*wl
)
844 bool supported
= false;
847 if (wl
->chip
.id
== CHIP_ID_1283_PG20
) {
848 major
= WL128X_PG_GET_MAJOR(wl
->hw_pg_ver
);
849 minor
= WL128X_PG_GET_MINOR(wl
->hw_pg_ver
);
851 /* in wl128x we have the MAC address if the PG is >= (2, 1) */
852 if (major
> 2 || (major
== 2 && minor
>= 1))
855 major
= WL127X_PG_GET_MAJOR(wl
->hw_pg_ver
);
856 minor
= WL127X_PG_GET_MINOR(wl
->hw_pg_ver
);
858 /* in wl127x we have the MAC address if the PG is >= (3, 1) */
859 if (major
== 3 && minor
>= 1)
863 wl1271_debug(DEBUG_PROBE
,
864 "PG Ver major = %d minor = %d, MAC %s present",
865 major
, minor
, supported
? "is" : "is not");
870 static void wl12xx_get_fuse_mac(struct wl1271
*wl
)
874 wlcore_set_partition(wl
, &wl
->ptable
[PART_DRPW
]);
876 mac1
= wl1271_read32(wl
, WL12XX_REG_FUSE_BD_ADDR_1
);
877 mac2
= wl1271_read32(wl
, WL12XX_REG_FUSE_BD_ADDR_2
);
879 /* these are the two parts of the BD_ADDR */
880 wl
->fuse_oui_addr
= ((mac2
& 0xffff) << 8) +
881 ((mac1
& 0xff000000) >> 24);
882 wl
->fuse_nic_addr
= mac1
& 0xffffff;
884 wlcore_set_partition(wl
, &wl
->ptable
[PART_DOWN
]);
887 static s8
wl12xx_get_pg_ver(struct wl1271
*wl
)
891 if (wl
->chip
.id
== CHIP_ID_1283_PG20
)
892 die_info
= wl12xx_top_reg_read(wl
, WL128X_REG_FUSE_DATA_2_1
);
894 die_info
= wl12xx_top_reg_read(wl
, WL127X_REG_FUSE_DATA_2_1
);
896 return (s8
) (die_info
& PG_VER_MASK
) >> PG_VER_OFFSET
;
899 static void wl12xx_get_mac(struct wl1271
*wl
)
901 if (wl12xx_mac_in_fuse(wl
))
902 wl12xx_get_fuse_mac(wl
);
905 static struct wlcore_ops wl12xx_ops
= {
906 .identify_chip
= wl12xx_identify_chip
,
908 .trigger_cmd
= wl12xx_trigger_cmd
,
909 .ack_event
= wl12xx_ack_event
,
910 .calc_tx_blocks
= wl12xx_calc_tx_blocks
,
911 .set_tx_desc_blocks
= wl12xx_set_tx_desc_blocks
,
912 .set_tx_desc_data_len
= wl12xx_set_tx_desc_data_len
,
913 .get_rx_buf_align
= wl12xx_get_rx_buf_align
,
914 .get_rx_packet_len
= wl12xx_get_rx_packet_len
,
915 .tx_immediate_compl
= NULL
,
916 .tx_delayed_compl
= wl12xx_tx_delayed_compl
,
917 .hw_init
= wl12xx_hw_init
,
918 .get_pg_ver
= wl12xx_get_pg_ver
,
919 .get_mac
= wl12xx_get_mac
,
925 static int __devinit
wl12xx_probe(struct platform_device
*pdev
)
928 struct ieee80211_hw
*hw
;
929 struct wl12xx_priv
*priv
;
931 hw
= wlcore_alloc_hw(sizeof(*priv
));
933 wl1271_error("can't allocate hw");
938 wl
->ops
= &wl12xx_ops
;
939 wl
->ptable
= wl12xx_ptable
;
940 wl
->rtable
= wl12xx_rtable
;
941 wl
->num_tx_desc
= 16;
942 wl
->normal_tx_spare
= WL12XX_TX_HW_BLOCK_SPARE_DEFAULT
;
943 wl
->gem_tx_spare
= WL12XX_TX_HW_BLOCK_GEM_SPARE
;
944 wl
->band_rate_to_idx
= wl12xx_band_rate_to_idx
;
945 wl
->hw_tx_rate_tbl_size
= WL12XX_CONF_HW_RXTX_RATE_MAX
;
946 wl
->hw_min_ht_rate
= WL12XX_CONF_HW_RXTX_RATE_MCS0
;
948 return wlcore_probe(wl
, pdev
);
951 static const struct platform_device_id wl12xx_id_table
[] __devinitconst
= {
953 { } /* Terminating Entry */
955 MODULE_DEVICE_TABLE(platform
, wl12xx_id_table
);
957 static struct platform_driver wl12xx_driver
= {
958 .probe
= wl12xx_probe
,
959 .remove
= __devexit_p(wlcore_remove
),
960 .id_table
= wl12xx_id_table
,
962 .name
= "wl12xx_driver",
963 .owner
= THIS_MODULE
,
967 static int __init
wl12xx_init(void)
969 return platform_driver_register(&wl12xx_driver
);
971 module_init(wl12xx_init
);
973 static void __exit
wl12xx_exit(void)
975 platform_driver_unregister(&wl12xx_driver
);
977 module_exit(wl12xx_exit
);
979 MODULE_LICENSE("GPL v2");
980 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
981 MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE
);
982 MODULE_FIRMWARE(WL127X_FW_NAME_MULTI
);
983 MODULE_FIRMWARE(WL127X_PLT_FW_NAME
);
984 MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE
);
985 MODULE_FIRMWARE(WL128X_FW_NAME_MULTI
);
986 MODULE_FIRMWARE(WL128X_PLT_FW_NAME
);