Commit 6f7dd16c authored by Luciano Coelho's avatar Luciano Coelho

wlcore/wl12xx: add chip-specific identify chip operation

Move the code that identifies the chip ID and selects the appropriate
firmware to an operation implemented by the lower driver.  Also move
the quirks definitions into wlcore.h and rename to WLCORE_QUIRK_*.
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent 00782136
...@@ -29,9 +29,6 @@ ...@@ -29,9 +29,6 @@
#include "reg.h" #include "reg.h"
static struct wlcore_ops wl12xx_ops = {
};
static struct wlcore_partition_set wl12xx_ptable[PART_TABLE_LEN] = { static struct wlcore_partition_set wl12xx_ptable[PART_TABLE_LEN] = {
[PART_DOWN] = { [PART_DOWN] = {
.mem = { .mem = {
...@@ -131,6 +128,62 @@ static const int wl12xx_rtable[REG_TABLE_LEN] = { ...@@ -131,6 +128,62 @@ static const int wl12xx_rtable[REG_TABLE_LEN] = {
[REG_RAW_FW_STATUS_ADDR] = FW_STATUS_ADDR, [REG_RAW_FW_STATUS_ADDR] = FW_STATUS_ADDR,
}; };
/* TODO: maybe move to a new header file? */
#define WL127X_FW_NAME_MULTI "ti-connectivity/wl127x-fw-4-mr.bin"
#define WL127X_FW_NAME_SINGLE "ti-connectivity/wl127x-fw-4-sr.bin"
#define WL127X_PLT_FW_NAME "ti-connectivity/wl127x-fw-4-plt.bin"
#define WL128X_FW_NAME_MULTI "ti-connectivity/wl128x-fw-4-mr.bin"
#define WL128X_FW_NAME_SINGLE "ti-connectivity/wl128x-fw-4-sr.bin"
#define WL128X_PLT_FW_NAME "ti-connectivity/wl128x-fw-4-plt.bin"
static int wl12xx_identify_chip(struct wl1271 *wl)
{
int ret = 0;
switch (wl->chip.id) {
case CHIP_ID_1271_PG10:
wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
wl->chip.id);
wl->quirks |= WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
wl->plt_fw_name = WL127X_PLT_FW_NAME;
wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
wl->mr_fw_name = WL127X_FW_NAME_MULTI;
break;
case CHIP_ID_1271_PG20:
wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
wl->chip.id);
wl->quirks |= WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
wl->plt_fw_name = WL127X_PLT_FW_NAME;
wl->sr_fw_name = WL127X_FW_NAME_SINGLE;
wl->mr_fw_name = WL127X_FW_NAME_MULTI;
break;
case CHIP_ID_1283_PG20:
wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
wl->chip.id);
wl->plt_fw_name = WL128X_PLT_FW_NAME;
wl->sr_fw_name = WL128X_FW_NAME_SINGLE;
wl->mr_fw_name = WL128X_FW_NAME_MULTI;
break;
case CHIP_ID_1283_PG10:
default:
wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
ret = -ENODEV;
goto out;
}
out:
return ret;
}
static struct wlcore_ops wl12xx_ops = {
.identify_chip = wl12xx_identify_chip,
};
static int __devinit wl12xx_probe(struct platform_device *pdev) static int __devinit wl12xx_probe(struct platform_device *pdev)
{ {
struct wl1271 *wl; struct wl1271 *wl;
...@@ -180,3 +233,9 @@ module_exit(wl12xx_exit); ...@@ -180,3 +233,9 @@ module_exit(wl12xx_exit);
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>"); MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
MODULE_FIRMWARE(WL127X_FW_NAME_SINGLE);
MODULE_FIRMWARE(WL127X_FW_NAME_MULTI);
MODULE_FIRMWARE(WL127X_PLT_FW_NAME);
MODULE_FIRMWARE(WL128X_FW_NAME_SINGLE);
MODULE_FIRMWARE(WL128X_FW_NAME_MULTI);
MODULE_FIRMWARE(WL128X_PLT_FW_NAME);
...@@ -447,7 +447,6 @@ b12-b0 - Supported Rate indicator bits as defined below. ...@@ -447,7 +447,6 @@ b12-b0 - Supported Rate indicator bits as defined below.
#define CLK_REQ_OUTN_SEL 0x700 #define CLK_REQ_OUTN_SEL 0x700
#define WU_COUNTER_PAUSE_VAL 0x3FF #define WU_COUNTER_PAUSE_VAL 0x3FF
#define WELP_ARM_COMMAND_VAL 0x4
/* PLL configuration algorithm for wl128x */ /* PLL configuration algorithm for wl128x */
#define SYS_CLK_CFG_REG 0x2200 #define SYS_CLK_CFG_REG 0x2200
......
...@@ -58,11 +58,11 @@ static unsigned int wl12xx_get_fw_ver_quirks(struct wl1271 *wl) ...@@ -58,11 +58,11 @@ static unsigned int wl12xx_get_fw_ver_quirks(struct wl1271 *wl)
/* Only new station firmwares support routing fw logs to the host */ /* Only new station firmwares support routing fw logs to the host */
if ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) && if ((fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_STA) &&
(fw_ver[FW_VER_MINOR] < FW_VER_MINOR_FWLOG_STA_MIN)) (fw_ver[FW_VER_MINOR] < FW_VER_MINOR_FWLOG_STA_MIN))
quirks |= WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED; quirks |= WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED;
/* This feature is not yet supported for AP mode */ /* This feature is not yet supported for AP mode */
if (fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP) if (fw_ver[FW_VER_IF_TYPE] == FW_VER_IF_TYPE_AP)
quirks |= WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED; quirks |= WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED;
return quirks; return quirks;
} }
...@@ -641,7 +641,7 @@ static int wl127x_boot_clk(struct wl1271 *wl) ...@@ -641,7 +641,7 @@ static int wl127x_boot_clk(struct wl1271 *wl)
u32 clk; u32 clk;
if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3) if (WL127X_PG_GET_MAJOR(wl->hw_pg_ver) < 3)
wl->quirks |= WL12XX_QUIRK_END_OF_TRANSACTION; wl->quirks |= WLCORE_QUIRK_END_OF_TRANSACTION;
if (wl->ref_clock == CONF_REF_CLK_19_2_E || if (wl->ref_clock == CONF_REF_CLK_19_2_E ||
wl->ref_clock == CONF_REF_CLK_38_4_E || wl->ref_clock == CONF_REF_CLK_38_4_E ||
......
...@@ -318,7 +318,7 @@ static int wl12xx_init_fwlog(struct wl1271 *wl) ...@@ -318,7 +318,7 @@ static int wl12xx_init_fwlog(struct wl1271 *wl)
{ {
int ret; int ret;
if (wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED) if (wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED)
return 0; return 0;
ret = wl12xx_cmd_config_fwlog(wl); ret = wl12xx_cmd_config_fwlog(wl);
...@@ -500,7 +500,7 @@ int wl1271_chip_specific_init(struct wl1271 *wl) ...@@ -500,7 +500,7 @@ int wl1271_chip_specific_init(struct wl1271 *wl)
if (wl->chip.id == CHIP_ID_1283_PG20) { if (wl->chip.id == CHIP_ID_1283_PG20) {
u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE; u32 host_cfg_bitmap = HOST_IF_CFG_RX_FIFO_ENABLE;
if (!(wl->quirks & WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT)) if (!(wl->quirks & WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT))
/* Enable SDIO padding */ /* Enable SDIO padding */
host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK; host_cfg_bitmap |= HOST_IF_CFG_TX_PAD_TO_SDIO_BLK;
......
...@@ -1055,10 +1055,7 @@ static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt) ...@@ -1055,10 +1055,7 @@ static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
if (plt) { if (plt) {
fw_type = WL12XX_FW_TYPE_PLT; fw_type = WL12XX_FW_TYPE_PLT;
if (wl->chip.id == CHIP_ID_1283_PG20) fw_name = wl->plt_fw_name;
fw_name = WL128X_PLT_FW_NAME;
else
fw_name = WL127X_PLT_FW_NAME;
} else { } else {
/* /*
* we can't call wl12xx_get_vif_count() here because * we can't call wl12xx_get_vif_count() here because
...@@ -1066,16 +1063,10 @@ static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt) ...@@ -1066,16 +1063,10 @@ static int wl12xx_fetch_firmware(struct wl1271 *wl, bool plt)
*/ */
if (wl->last_vif_count > 1) { if (wl->last_vif_count > 1) {
fw_type = WL12XX_FW_TYPE_MULTI; fw_type = WL12XX_FW_TYPE_MULTI;
if (wl->chip.id == CHIP_ID_1283_PG20) fw_name = wl->mr_fw_name;
fw_name = WL128X_FW_NAME_MULTI;
else
fw_name = WL127X_FW_NAME_MULTI;
} else { } else {
fw_type = WL12XX_FW_TYPE_NORMAL; fw_type = WL12XX_FW_TYPE_NORMAL;
if (wl->chip.id == CHIP_ID_1283_PG20) fw_name = wl->sr_fw_name;
fw_name = WL128X_FW_NAME_SINGLE;
else
fw_name = WL127X_FW_NAME_SINGLE;
} }
} }
...@@ -1182,7 +1173,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl) ...@@ -1182,7 +1173,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
u32 first_addr; u32 first_addr;
u8 *block; u8 *block;
if ((wl->quirks & WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED) || if ((wl->quirks & WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED) ||
(wl->conf.fwlog.mode != WL12XX_FWLOG_ON_DEMAND) || (wl->conf.fwlog.mode != WL12XX_FWLOG_ON_DEMAND) ||
(wl->conf.fwlog.mem_blocks == 0)) (wl->conf.fwlog.mem_blocks == 0))
return; return;
...@@ -1356,43 +1347,17 @@ static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt) ...@@ -1356,43 +1347,17 @@ static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt)
* chip types. * chip types.
*/ */
if (!wl1271_set_block_size(wl)) if (!wl1271_set_block_size(wl))
wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT; wl->quirks |= WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
switch (wl->chip.id) {
case CHIP_ID_1271_PG10:
wl1271_warning("chip id 0x%x (1271 PG10) support is obsolete",
wl->chip.id);
ret = wl1271_setup(wl); ret = wl->ops->identify_chip(wl);
if (ret < 0) if (ret < 0)
goto out; goto out;
wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
break;
case CHIP_ID_1271_PG20:
wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1271 PG20)",
wl->chip.id);
ret = wl1271_setup(wl);
if (ret < 0)
goto out;
wl->quirks |= WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT;
break;
case CHIP_ID_1283_PG20: /* TODO: make sure the lower driver has set things up correctly */
wl1271_debug(DEBUG_BOOT, "chip id 0x%x (1283 PG20)",
wl->chip.id);
ret = wl1271_setup(wl); ret = wl1271_setup(wl);
if (ret < 0) if (ret < 0)
goto out;
break;
case CHIP_ID_1283_PG10:
default:
wl1271_warning("unsupported chip id: 0x%x", wl->chip.id);
ret = -ENODEV;
goto out; goto out;
}
ret = wl12xx_fetch_firmware(wl, plt); ret = wl12xx_fetch_firmware(wl, plt);
if (ret < 0) if (ret < 0)
......
...@@ -282,7 +282,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status) ...@@ -282,7 +282,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl12xx_fw_status *status)
* Write the driver's packet counter to the FW. This is only required * Write the driver's packet counter to the FW. This is only required
* for older hardware revisions * for older hardware revisions
*/ */
if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION)
wl1271_write32(wl, WL12XX_REG_RX_DRIVER_COUNTER, wl1271_write32(wl, WL12XX_REG_RX_DRIVER_COUNTER,
wl->rx_counter); wl->rx_counter);
......
...@@ -175,7 +175,7 @@ u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif, ...@@ -175,7 +175,7 @@ u8 wl12xx_tx_get_hlid(struct wl1271 *wl, struct wl12xx_vif *wlvif,
static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl, static unsigned int wl12xx_calc_packet_alignment(struct wl1271 *wl,
unsigned int packet_length) unsigned int packet_length)
{ {
if (wl->quirks & WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT) if (wl->quirks & WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT)
return ALIGN(packet_length, WL1271_TX_ALIGN_TO); return ALIGN(packet_length, WL1271_TX_ALIGN_TO);
else else
return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE); return ALIGN(packet_length, WL12XX_BUS_BLOCK_SIZE);
...@@ -767,7 +767,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl) ...@@ -767,7 +767,7 @@ void wl1271_tx_work_locked(struct wl1271 *wl)
* Interrupt the firmware with the new packets. This is only * Interrupt the firmware with the new packets. This is only
* required for older hardware revisions * required for older hardware revisions
*/ */
if (wl->quirks & WL12XX_QUIRK_END_OF_TRANSACTION) if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION)
wl1271_write32(wl, WL12XX_HOST_WR_ACCESS, wl1271_write32(wl, WL12XX_HOST_WR_ACCESS,
wl->tx_packets_count); wl->tx_packets_count);
......
...@@ -451,17 +451,6 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen); ...@@ -451,17 +451,6 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen);
#define HW_BG_RATES_MASK 0xffff #define HW_BG_RATES_MASK 0xffff
#define HW_HT_RATES_OFFSET 16 #define HW_HT_RATES_OFFSET 16
/* Quirks */
/* Each RX/TX transaction requires an end-of-transaction transfer */
#define WL12XX_QUIRK_END_OF_TRANSACTION BIT(0)
/* wl127x and SPI don't support SDIO block size alignment */
#define WL12XX_QUIRK_NO_BLOCKSIZE_ALIGNMENT BIT(2)
/* Older firmwares did not implement the FW logger over bus feature */
#define WL12XX_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4)
#define WL12XX_HW_BLOCK_SIZE 256 #define WL12XX_HW_BLOCK_SIZE 256
#endif #endif
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "event.h" #include "event.h"
struct wlcore_ops { struct wlcore_ops {
int (*identify_chip)(struct wl1271 *wl);
}; };
enum wlcore_partitions { enum wlcore_partitions {
...@@ -291,6 +292,10 @@ struct wl1271 { ...@@ -291,6 +292,10 @@ struct wl1271 {
const struct wlcore_partition_set *ptable; const struct wlcore_partition_set *ptable;
/* pointer to the lower driver register table */ /* pointer to the lower driver register table */
const int *rtable; const int *rtable;
/* name of the firmwares to load - for PLT, single role, multi-role */
const char *plt_fw_name;
const char *sr_fw_name;
const char *mr_fw_name;
}; };
int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev); int __devinit wlcore_probe(struct wl1271 *wl, struct platform_device *pdev);
...@@ -301,6 +306,17 @@ int wlcore_free_hw(struct wl1271 *wl); ...@@ -301,6 +306,17 @@ int wlcore_free_hw(struct wl1271 *wl);
/* Firmware image load chunk size */ /* Firmware image load chunk size */
#define CHUNK_SIZE 16384 #define CHUNK_SIZE 16384
/* Quirks */
/* Each RX/TX transaction requires an end-of-transaction transfer */
#define WLCORE_QUIRK_END_OF_TRANSACTION BIT(0)
/* wl127x and SPI don't support SDIO block size alignment */
#define WLCORE_QUIRK_NO_BLOCKSIZE_ALIGNMENT BIT(2)
/* Older firmwares did not implement the FW logger over bus feature */
#define WLCORE_QUIRK_FWLOG_NOT_IMPLEMENTED BIT(4)
/* TODO: move to the lower drivers when all usages are abstracted */ /* TODO: move to the lower drivers when all usages are abstracted */
#define CHIP_ID_1271_PG10 (0x4030101) #define CHIP_ID_1271_PG10 (0x4030101)
#define CHIP_ID_1271_PG20 (0x4030111) #define CHIP_ID_1271_PG20 (0x4030111)
...@@ -381,4 +397,6 @@ int wlcore_free_hw(struct wl1271 *wl); ...@@ -381,4 +397,6 @@ int wlcore_free_hw(struct wl1271 *wl);
#define ECPU_CONTROL_HALT 0x00000101 #define ECPU_CONTROL_HALT 0x00000101
#define WELP_ARM_COMMAND_VAL 0x4
#endif /* __WLCORE_H__ */ #endif /* __WLCORE_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment