]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/net/wireless/ti/wl12xx/main.c
wlcore/wl12xx: add hw op for calculating hw block count per packet
[mirror_ubuntu-bionic-kernel.git] / drivers / net / wireless / ti / wl12xx / main.c
1 /*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2008-2010 Nokia Corporation
5 *
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.
9 *
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.
14 *
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
18 * 02110-1301 USA
19 *
20 */
21
22 #include <linux/module.h>
23 #include <linux/platform_device.h>
24
25 #include <linux/err.h>
26
27 #include <linux/wl12xx.h>
28
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/boot.h"
35
36 #include "reg.h"
37
38 #define WL12XX_TX_HW_BLOCK_SPARE_DEFAULT 1
39 #define WL12XX_TX_HW_BLOCK_GEM_SPARE 2
40 #define WL12XX_TX_HW_BLOCK_SIZE 252
41
42
43 static struct wlcore_partition_set wl12xx_ptable[PART_TABLE_LEN] = {
44 [PART_DOWN] = {
45 .mem = {
46 .start = 0x00000000,
47 .size = 0x000177c0
48 },
49 .reg = {
50 .start = REGISTERS_BASE,
51 .size = 0x00008800
52 },
53 .mem2 = {
54 .start = 0x00000000,
55 .size = 0x00000000
56 },
57 .mem3 = {
58 .start = 0x00000000,
59 .size = 0x00000000
60 },
61 },
62
63 [PART_BOOT] = { /* in wl12xx we can use a mix of work and down
64 * partition here */
65 .mem = {
66 .start = 0x00040000,
67 .size = 0x00014fc0
68 },
69 .reg = {
70 .start = REGISTERS_BASE,
71 .size = 0x00008800
72 },
73 .mem2 = {
74 .start = 0x00000000,
75 .size = 0x00000000
76 },
77 .mem3 = {
78 .start = 0x00000000,
79 .size = 0x00000000
80 },
81 },
82
83 [PART_WORK] = {
84 .mem = {
85 .start = 0x00040000,
86 .size = 0x00014fc0
87 },
88 .reg = {
89 .start = REGISTERS_BASE,
90 .size = 0x0000a000
91 },
92 .mem2 = {
93 .start = 0x003004f8,
94 .size = 0x00000004
95 },
96 .mem3 = {
97 .start = 0x00040404,
98 .size = 0x00000000
99 },
100 },
101
102 [PART_DRPW] = {
103 .mem = {
104 .start = 0x00040000,
105 .size = 0x00014fc0
106 },
107 .reg = {
108 .start = DRPW_BASE,
109 .size = 0x00006000
110 },
111 .mem2 = {
112 .start = 0x00000000,
113 .size = 0x00000000
114 },
115 .mem3 = {
116 .start = 0x00000000,
117 .size = 0x00000000
118 }
119 }
120 };
121
122 static const int wl12xx_rtable[REG_TABLE_LEN] = {
123 [REG_ECPU_CONTROL] = WL12XX_REG_ECPU_CONTROL,
124 [REG_INTERRUPT_NO_CLEAR] = WL12XX_REG_INTERRUPT_NO_CLEAR,
125 [REG_INTERRUPT_ACK] = WL12XX_REG_INTERRUPT_ACK,
126 [REG_COMMAND_MAILBOX_PTR] = WL12XX_REG_COMMAND_MAILBOX_PTR,
127 [REG_EVENT_MAILBOX_PTR] = WL12XX_REG_EVENT_MAILBOX_PTR,
128 [REG_INTERRUPT_TRIG] = WL12XX_REG_INTERRUPT_TRIG,
129 [REG_INTERRUPT_MASK] = WL12XX_REG_INTERRUPT_MASK,
130 [REG_PC_ON_RECOVERY] = WL12XX_SCR_PAD4,
131 [REG_CHIP_ID_B] = WL12XX_CHIP_ID_B,
132 [REG_CMD_MBOX_ADDRESS] = WL12XX_CMD_MBOX_ADDRESS,
133
134 /* data access memory addresses, used with partition translation */
135 [REG_SLV_MEM_DATA] = WL1271_SLV_MEM_DATA,
136 [REG_SLV_REG_DATA] = WL1271_SLV_REG_DATA,
137
138 /* raw data access memory addresses */
139 [REG_RAW_FW_STATUS_ADDR] = FW_STATUS_ADDR,
140 };
141
142 /* TODO: maybe move to a new header file? */
143 #define WL127X_FW_NAME_MULTI "ti-connectivity/wl127x-fw-4-mr.bin"
144 #define WL127X_FW_NAME_SINGLE "ti-connectivity/wl127x-fw-4-sr.bin"
145 #define WL127X_PLT_FW_NAME "ti-connectivity/wl127x-fw-4-plt.bin"
146
147 #define WL128X_FW_NAME_MULTI "ti-connectivity/wl128x-fw-4-mr.bin"
148 #define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin"
149 #define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin"
150
151 static int wl12xx_identify_chip(struct wl1271 *wl)
152 {
153 int ret = 0;
154
155 switch (wl->chip.id) {
156 case CHIP_ID_1271_PG10:
157 wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
158 wl->chip.id);
159
160 wl->quirks |= WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT |
161 WLCORE_QUIRK_LEGACY_NVS;
162 wl->plt_fw_name = WL127X_PLT_FW_NAME;
163 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
164 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
165 break;
166
167 case CHIP_ID_1271_PG20:
168 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
169 wl->chip.id);
170
171 wl->quirks |= WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT |
172 WLCORE_QUIRK_LEGACY_NVS;
173 wl->plt_fw_name = WL127X_PLT_FW_NAME;
174 wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
175 wl->mr_fw_name = WL127X_FW_NAME_MULTI;
176 break;
177
178 case CHIP_ID_1283_PG20:
179 wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
180 wl->chip.id);
181 wl->plt_fw_name = WL128X_PLT_FW_NAME;
182 wl->sr_fw_name = WL128X_FW_NAME_SINGLE;
183 wl->mr_fw_name = WL128X_FW_NAME_MULTI;
184 break;
185 case CHIP_ID_1283_PG10:
186 default:
187 wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
188 ret = -ENODEV;
189 goto out;
190 }
191
192 out:
193 return ret;
194 }
195
196 static void wl12xx_top_reg_write(struct wl1271 *wl, int addr, u16 val)
197 {
198 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
199 addr = (addr >> 1) + 0x30000;
200 wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr);
201
202 /* write value to OCP_POR_WDATA */
203 wl1271_write32(wl, WL12XX_OCP_DATA_WRITE, val);
204
205 /* write 1 to OCP_CMD */
206 wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_WRITE);
207 }
208
209 static u16 wl12xx_top_reg_read(struct wl1271 *wl, int addr)
210 {
211 u32 val;
212 int timeout = OCP_CMD_LOOP;
213
214 /* write address >> 1 + 0x30000 to OCP_POR_CTR */
215 addr = (addr >> 1) + 0x30000;
216 wl1271_write32(wl, WL12XX_OCP_POR_CTR, addr);
217
218 /* write 2 to OCP_CMD */
219 wl1271_write32(wl, WL12XX_OCP_CMD, OCP_CMD_READ);
220
221 /* poll for data ready */
222 do {
223 val = wl1271_read32(wl, WL12XX_OCP_DATA_READ);
224 } while (!(val & OCP_READY_MASK) && --timeout);
225
226 if (!timeout) {
227 wl1271_warning("Top register access timed out.");
228 return 0xffff;
229 }
230
231 /* check data status and return if OK */
232 if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)
233 return val & 0xffff;
234 else {
235 wl1271_warning("Top register access returned error.");
236 return 0xffff;
237 }
238 }
239
240 static int wl128x_switch_tcxo_to_fref(struct wl1271 *wl)
241 {
242 u16 spare_reg;
243
244 /* Mask bits [2] & [8:4] in the sys_clk_cfg register */
245 spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG);
246 if (spare_reg == 0xFFFF)
247 return -EFAULT;
248 spare_reg |= (BIT(3) | BIT(5) | BIT(6));
249 wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
250
251 /* Enable FREF_CLK_REQ & mux MCS and coex PLLs to FREF */
252 wl12xx_top_reg_write(wl, SYS_CLK_CFG_REG,
253 WL_CLK_REQ_TYPE_PG2 | MCS_PLL_CLK_SEL_FREF);
254
255 /* Delay execution for 15msec, to let the HW settle */
256 mdelay(15);
257
258 return 0;
259 }
260
261 static bool wl128x_is_tcxo_valid(struct wl1271 *wl)
262 {
263 u16 tcxo_detection;
264
265 tcxo_detection = wl12xx_top_reg_read(wl, TCXO_CLK_DETECT_REG);
266 if (tcxo_detection & TCXO_DET_FAILED)
267 return false;
268
269 return true;
270 }
271
272 static bool wl128x_is_fref_valid(struct wl1271 *wl)
273 {
274 u16 fref_detection;
275
276 fref_detection = wl12xx_top_reg_read(wl, FREF_CLK_DETECT_REG);
277 if (fref_detection & FREF_CLK_DETECT_FAIL)
278 return false;
279
280 return true;
281 }
282
283 static int wl128x_manually_configure_mcs_pll(struct wl1271 *wl)
284 {
285 wl12xx_top_reg_write(wl, MCS_PLL_M_REG, MCS_PLL_M_REG_VAL);
286 wl12xx_top_reg_write(wl, MCS_PLL_N_REG, MCS_PLL_N_REG_VAL);
287 wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, MCS_PLL_CONFIG_REG_VAL);
288
289 return 0;
290 }
291
292 static int wl128x_configure_mcs_pll(struct wl1271 *wl, int clk)
293 {
294 u16 spare_reg;
295 u16 pll_config;
296 u8 input_freq;
297
298 /* Mask bits [3:1] in the sys_clk_cfg register */
299 spare_reg = wl12xx_top_reg_read(wl, WL_SPARE_REG);
300 if (spare_reg == 0xFFFF)
301 return -EFAULT;
302 spare_reg |= BIT(2);
303 wl12xx_top_reg_write(wl, WL_SPARE_REG, spare_reg);
304
305 /* Handle special cases of the TCXO clock */
306 if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_8 ||
307 wl->tcxo_clock == WL12XX_TCXOCLOCK_33_6)
308 return wl128x_manually_configure_mcs_pll(wl);
309
310 /* Set the input frequency according to the selected clock source */
311 input_freq = (clk & 1) + 1;
312
313 pll_config = wl12xx_top_reg_read(wl, MCS_PLL_CONFIG_REG);
314 if (pll_config == 0xFFFF)
315 return -EFAULT;
316 pll_config |= (input_freq << MCS_SEL_IN_FREQ_SHIFT);
317 pll_config |= MCS_PLL_ENABLE_HP;
318 wl12xx_top_reg_write(wl, MCS_PLL_CONFIG_REG, pll_config);
319
320 return 0;
321 }
322
323 /*
324 * WL128x has two clocks input - TCXO and FREF.
325 * TCXO is the main clock of the device, while FREF is used to sync
326 * between the GPS and the cellular modem.
327 * In cases where TCXO is 32.736MHz or 16.368MHz, the FREF will be used
328 * as the WLAN/BT main clock.
329 */
330 static int wl128x_boot_clk(struct wl1271 *wl, int *selected_clock)
331 {
332 u16 sys_clk_cfg;
333
334 /* For XTAL-only modes, FREF will be used after switching from TCXO */
335 if (wl->ref_clock == WL12XX_REFCLOCK_26_XTAL ||
336 wl->ref_clock == WL12XX_REFCLOCK_38_XTAL) {
337 if (!wl128x_switch_tcxo_to_fref(wl))
338 return -EINVAL;
339 goto fref_clk;
340 }
341
342 /* Query the HW, to determine which clock source we should use */
343 sys_clk_cfg = wl12xx_top_reg_read(wl, SYS_CLK_CFG_REG);
344 if (sys_clk_cfg == 0xFFFF)
345 return -EINVAL;
346 if (sys_clk_cfg & PRCM_CM_EN_MUX_WLAN_FREF)
347 goto fref_clk;
348
349 /* If TCXO is either 32.736MHz or 16.368MHz, switch to FREF */
350 if (wl->tcxo_clock == WL12XX_TCXOCLOCK_16_368 ||
351 wl->tcxo_clock == WL12XX_TCXOCLOCK_32_736) {
352 if (!wl128x_switch_tcxo_to_fref(wl))
353 return -EINVAL;
354 goto fref_clk;
355 }
356
357 /* TCXO clock is selected */
358 if (!wl128x_is_tcxo_valid(wl))
359 return -EINVAL;
360 *selected_clock = wl->tcxo_clock;
361 goto config_mcs_pll;
362
363 fref_clk:
364 /* FREF clock is selected */
365 if (!wl128x_is_fref_valid(wl))
366 return -EINVAL;
367 *selected_clock = wl->ref_clock;
368
369 config_mcs_pll:
370 return wl128x_configure_mcs_pll(wl, *selected_clock);
371 }
372
373 static int wl127x_boot_clk(struct wl1271 *wl)
374 {
375 u32 pause;
376 u32 clk;
377
378 if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
379 wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
380
381 if (wl->ref_clock == CONF_REF_CLK_19_2_E ||
382 wl->ref_clock == CONF_REF_CLK_38_4_E ||
383 wl->ref_clock == CONF_REF_CLK_38_4_M_XTAL)
384 /* ref clk: 19.2/38.4/38.4-XTAL */
385 clk = 0x3;
386 else if (wl->ref_clock == CONF_REF_CLK_26_E ||
387 wl->ref_clock == CONF_REF_CLK_52_E)
388 /* ref clk: 26/52 */
389 clk = 0x5;
390 else
391 return -EINVAL;
392
393 if (wl->ref_clock != CONF_REF_CLK_19_2_E) {
394 u16 val;
395 /* Set clock type (open drain) */
396 val = wl12xx_top_reg_read(wl, OCP_REG_CLK_TYPE);
397 val &= FREF_CLK_TYPE_BITS;
398 wl12xx_top_reg_write(wl, OCP_REG_CLK_TYPE, val);
399
400 /* Set clock pull mode (no pull) */
401 val = wl12xx_top_reg_read(wl, OCP_REG_CLK_PULL);
402 val |= NO_PULL;
403 wl12xx_top_reg_write(wl, OCP_REG_CLK_PULL, val);
404 } else {
405 u16 val;
406 /* Set clock polarity */
407 val = wl12xx_top_reg_read(wl, OCP_REG_CLK_POLARITY);
408 val &= FREF_CLK_POLARITY_BITS;
409 val |= CLK_REQ_OUTN_SEL;
410 wl12xx_top_reg_write(wl, OCP_REG_CLK_POLARITY, val);
411 }
412
413 wl1271_write32(wl, WL12XX_PLL_PARAMETERS, clk);
414
415 pause = wl1271_read32(wl, WL12XX_PLL_PARAMETERS);
416
417 wl1271_debug(DEBUG_BOOT, "pause1 0x%x", pause);
418
419 pause &= ~(WU_COUNTER_PAUSE_VAL);
420 pause |= WU_COUNTER_PAUSE_VAL;
421 wl1271_write32(wl, WL12XX_WU_COUNTER_PAUSE, pause);
422
423 return 0;
424 }
425
426 static int wl1271_boot_soft_reset(struct wl1271 *wl)
427 {
428 unsigned long timeout;
429 u32 boot_data;
430
431 /* perform soft reset */
432 wl1271_write32(wl, WL12XX_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
433
434 /* SOFT_RESET is self clearing */
435 timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
436 while (1) {
437 boot_data = wl1271_read32(wl, WL12XX_SLV_SOFT_RESET);
438 wl1271_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
439 if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
440 break;
441
442 if (time_after(jiffies, timeout)) {
443 /* 1.2 check pWhalBus->uSelfClearTime if the
444 * timeout was reached */
445 wl1271_error("soft reset timeout");
446 return -1;
447 }
448
449 udelay(SOFT_RESET_STALL_TIME);
450 }
451
452 /* disable Rx/Tx */
453 wl1271_write32(wl, WL12XX_ENABLE, 0x0);
454
455 /* disable auto calibration on start*/
456 wl1271_write32(wl, WL12XX_SPARE_A2, 0xffff);
457
458 return 0;
459 }
460
461 static int wl12xx_pre_boot(struct wl1271 *wl)
462 {
463 int ret = 0;
464 u32 clk;
465 int selected_clock = -1;
466
467 if (wl->chip.id == CHIP_ID_1283_PG20) {
468 ret = wl128x_boot_clk(wl, &selected_clock);
469 if (ret < 0)
470 goto out;
471 } else {
472 ret = wl127x_boot_clk(wl);
473 if (ret < 0)
474 goto out;
475 }
476
477 /* Continue the ELP wake up sequence */
478 wl1271_write32(wl, WL12XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
479 udelay(500);
480
481 wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
482
483 /* Read-modify-write DRPW_SCRATCH_START register (see next state)
484 to be used by DRPw FW. The RTRIM value will be added by the FW
485 before taking DRPw out of reset */
486
487 clk = wl1271_read32(wl, WL12XX_DRPW_SCRATCH_START);
488
489 wl1271_debug(DEBUG_BOOT, "clk2 0x%x", clk);
490
491 if (wl->chip.id == CHIP_ID_1283_PG20)
492 clk |= ((selected_clock & 0x3) << 1) << 4;
493 else
494 clk |= (wl->ref_clock << 1) << 4;
495
496 wl1271_write32(wl, WL12XX_DRPW_SCRATCH_START, clk);
497
498 wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
499
500 /* Disable interrupts */
501 wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
502
503 ret = wl1271_boot_soft_reset(wl);
504 if (ret < 0)
505 goto out;
506
507 out:
508 return ret;
509 }
510
511 static void wl12xx_pre_upload(struct wl1271 *wl)
512 {
513 u32 tmp;
514
515 /* write firmware's last address (ie. it's length) to
516 * ACX_EEPROMLESS_IND_REG */
517 wl1271_debug(DEBUG_BOOT, "ACX_EEPROMLESS_IND_REG");
518
519 wl1271_write32(wl, WL12XX_EEPROMLESS_IND, WL12XX_EEPROMLESS_IND);
520
521 tmp = wlcore_read_reg(wl, REG_CHIP_ID_B);
522
523 wl1271_debug(DEBUG_BOOT, "chip id 0x%x", tmp);
524
525 /* 6. read the EEPROM parameters */
526 tmp = wl1271_read32(wl, WL12XX_SCR_PAD2);
527
528 /* WL1271: The reference driver skips steps 7 to 10 (jumps directly
529 * to upload_fw) */
530
531 if (wl->chip.id == CHIP_ID_1283_PG20)
532 wl12xx_top_reg_write(wl, SDIO_IO_DS, HCI_IO_DS_6MA);
533 }
534
535 static void wl12xx_enable_interrupts(struct wl1271 *wl)
536 {
537 u32 polarity;
538
539 polarity = wl12xx_top_reg_read(wl, OCP_REG_POLARITY);
540
541 /* We use HIGH polarity, so unset the LOW bit */
542 polarity &= ~POLARITY_LOW;
543 wl12xx_top_reg_write(wl, OCP_REG_POLARITY, polarity);
544
545 wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_ALL_EVENTS_VECTOR);
546
547 wlcore_enable_interrupts(wl);
548 wlcore_write_reg(wl, REG_INTERRUPT_MASK,
549 WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));
550
551 wl1271_write32(wl, WL12XX_HI_CFG, HI_CFG_DEF_VAL);
552 }
553
554 static int wl12xx_boot(struct wl1271 *wl)
555 {
556 int ret;
557
558 ret = wl12xx_pre_boot(wl);
559 if (ret < 0)
560 goto out;
561
562 ret = wlcore_boot_upload_nvs(wl);
563 if (ret < 0)
564 goto out;
565
566 wl12xx_pre_upload(wl);
567
568 ret = wlcore_boot_upload_firmware(wl);
569 if (ret < 0)
570 goto out;
571
572 ret = wlcore_boot_run_firmware(wl);
573 if (ret < 0)
574 goto out;
575
576 wl12xx_enable_interrupts(wl);
577
578 out:
579 return ret;
580 }
581
582 static void wl12xx_trigger_cmd(struct wl1271 *wl)
583 {
584 wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_CMD);
585 }
586
587 static void wl12xx_ack_event(struct wl1271 *wl)
588 {
589 wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL12XX_INTR_TRIG_EVENT_ACK);
590 }
591
592 static u32 wl12xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
593 {
594 u32 blk_size = WL12XX_TX_HW_BLOCK_SIZE;
595 u32 align_len = wlcore_calc_packet_alignment(wl, len);
596
597 return (align_len + blk_size - 1) / blk_size + spare_blks;
598 }
599
600 static bool wl12xx_mac_in_fuse(struct wl1271 *wl)
601 {
602 bool supported = false;
603 u8 major, minor;
604
605 if (wl->chip.id == CHIP_ID_1283_PG20) {
606 major = WL128X_PG_GET_MAJOR(wl->hw_pg_ver);
607 minor = WL128X_PG_GET_MINOR(wl->hw_pg_ver);
608
609 /* in wl128x we have the MAC address if the PG is >= (2, 1) */
610 if (major > 2 || (major == 2 && minor >= 1))
611 supported = true;
612 } else {
613 major = WL127X_PG_GET_MAJOR(wl->hw_pg_ver);
614 minor = WL127X_PG_GET_MINOR(wl->hw_pg_ver);
615
616 /* in wl127x we have the MAC address if the PG is >= (3, 1) */
617 if (major == 3 && minor >= 1)
618 supported = true;
619 }
620
621 wl1271_debug(DEBUG_PROBE,
622 "PG Ver major = %d minor = %d, MAC %s present",
623 major, minor, supported ? "is" : "is not");
624
625 return supported;
626 }
627
628 static void wl12xx_get_fuse_mac(struct wl1271 *wl)
629 {
630 u32 mac1, mac2;
631
632 wlcore_set_partition(wl, &wl->ptable[PART_DRPW]);
633
634 mac1 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_1);
635 mac2 = wl1271_read32(wl, WL12XX_REG_FUSE_BD_ADDR_2);
636
637 /* these are the two parts of the BD_ADDR */
638 wl->fuse_oui_addr = ((mac2 & 0xffff) << 8) +
639 ((mac1 & 0xff000000) >> 24);
640 wl->fuse_nic_addr = mac1 & 0xffffff;
641
642 wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
643 }
644
645 static s8 wl12xx_get_pg_ver(struct wl1271 *wl)
646 {
647 u32 die_info;
648
649 if (wl->chip.id == CHIP_ID_1283_PG20)
650 die_info = wl12xx_top_reg_read(wl, WL128X_REG_FUSE_DATA_2_1);
651 else
652 die_info = wl12xx_top_reg_read(wl, WL127X_REG_FUSE_DATA_2_1);
653
654 return (s8) (die_info & PG_VER_MASK) >> PG_VER_OFFSET;
655 }
656
657 static void wl12xx_get_mac(struct wl1271 *wl)
658 {
659 if (wl12xx_mac_in_fuse(wl))
660 wl12xx_get_fuse_mac(wl);
661 }
662
663 static struct wlcore_ops wl12xx_ops = {
664 .identify_chip = wl12xx_identify_chip,
665 .boot = wl12xx_boot,
666 .trigger_cmd = wl12xx_trigger_cmd,
667 .ack_event = wl12xx_ack_event,
668 .calc_tx_blocks = wl12xx_calc_tx_blocks,
669 .get_pg_ver = wl12xx_get_pg_ver,
670 .get_mac = wl12xx_get_mac,
671 };
672
673 struct wl12xx_priv {
674 };
675
676 static int __devinit wl12xx_probe(struct platform_device *pdev)
677 {
678 struct wl1271 *wl;
679 struct ieee80211_hw *hw;
680 struct wl12xx_priv *priv;
681
682 hw = wlcore_alloc_hw(sizeof(*priv));
683 if (IS_ERR(hw)) {
684 wl1271_error("can't allocate hw");
685 return PTR_ERR(hw);
686 }
687
688 wl = hw->priv;
689 wl->ops = &wl12xx_ops;
690 wl->ptable = wl12xx_ptable;
691 wl->rtable = wl12xx_rtable;
692 wl->num_tx_desc = 16;
693 wl->normal_tx_spare = WL12XX_TX_HW_BLOCK_SPARE_DEFAULT;
694 wl->gem_tx_spare = WL12XX_TX_HW_BLOCK_GEM_SPARE;
695
696 return wlcore_probe(wl, pdev);
697 }
698
699 static const struct platform_device_id wl12xx_id_table[] __devinitconst = {
700 { "wl12xx", 0 },
701 { } /* Terminating Entry */
702 };
703 MODULE_DEVICE_TABLE(platform, wl12xx_id_table);
704
705 static struct platform_driver wl12xx_driver = {
706 .probe = wl12xx_probe,
707 .remove = __devexit_p(wlcore_remove),
708 .id_table = wl12xx_id_table,
709 .driver = {
710 .name = "wl12xx_driver",
711 .owner = THIS_MODULE,
712 }
713 };
714
715 static int __init wl12xx_init(void)
716 {
717 return platform_driver_register(&wl12xx_driver);
718 }
719 module_init(wl12xx_init);
720
721 static void __exit wl12xx_exit(void)
722 {
723 platform_driver_unregister(&wl12xx_driver);
724 }
725 module_exit(wl12xx_exit);
726
727 MODULE_LICENSE("GPL v2");
728 MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
729 MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
730 MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
731 MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
732 MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
733 MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
734 MODULE_FIRMWARE(WL128X_PLT_FW_NAME);