Commit b0f0ad39 authored by Ido Yariv's avatar Ido Yariv Committed by Luciano Coelho

wlcore: Propagate errors from wl1271_raw_write32

Propagate errors from wl1271_raw_write32 and request for recovery when
appropriate.
Also rename prefixes of wlcore functions which their prototypes had to
be changed.
Signed-off-by: default avatarIdo Yariv <ido@wizery.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent 6134323f
This diff is collapsed.
...@@ -38,14 +38,14 @@ int wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val) ...@@ -38,14 +38,14 @@ int wl18xx_top_reg_write(struct wl1271 *wl, int addr, u16 val)
goto out; goto out;
tmp = (tmp & 0xffff0000) | val; tmp = (tmp & 0xffff0000) | val;
wl1271_write32(wl, addr, tmp); ret = wlcore_write32(wl, addr, tmp);
} else { } else {
ret = wlcore_read32(wl, addr - 2, &tmp); ret = wlcore_read32(wl, addr - 2, &tmp);
if (ret < 0) if (ret < 0)
goto out; goto out;
tmp = (tmp & 0xffff) | (val << 16); tmp = (tmp & 0xffff) | (val << 16);
wl1271_write32(wl, addr - 2, tmp); ret = wlcore_write32(wl, addr - 2, tmp);
} }
out: out:
......
...@@ -641,7 +641,9 @@ static int wl18xx_set_clk(struct wl1271 *wl) ...@@ -641,7 +641,9 @@ static int wl18xx_set_clk(struct wl1271 *wl)
u16 clk_freq; u16 clk_freq;
int ret; int ret;
wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
if (ret < 0)
goto out;
/* TODO: PG2: apparently we need to read the clk type */ /* TODO: PG2: apparently we need to read the clk type */
...@@ -699,13 +701,20 @@ static int wl18xx_set_clk(struct wl1271 *wl) ...@@ -699,13 +701,20 @@ static int wl18xx_set_clk(struct wl1271 *wl)
return ret; return ret;
} }
static void wl18xx_boot_soft_reset(struct wl1271 *wl) static int wl18xx_boot_soft_reset(struct wl1271 *wl)
{ {
int ret;
/* disable Rx/Tx */ /* disable Rx/Tx */
wl1271_write32(wl, WL18XX_ENABLE, 0x0); ret = wlcore_write32(wl, WL18XX_ENABLE, 0x0);
if (ret < 0)
goto out;
/* disable auto calibration on start*/ /* disable auto calibration on start*/
wl1271_write32(wl, WL18XX_SPARE_A2, 0xffff); ret = wlcore_write32(wl, WL18XX_SPARE_A2, 0xffff);
out:
return ret;
} }
static int wl18xx_pre_boot(struct wl1271 *wl) static int wl18xx_pre_boot(struct wl1271 *wl)
...@@ -717,15 +726,22 @@ static int wl18xx_pre_boot(struct wl1271 *wl) ...@@ -717,15 +726,22 @@ static int wl18xx_pre_boot(struct wl1271 *wl)
goto out; goto out;
/* Continue the ELP wake up sequence */ /* Continue the ELP wake up sequence */
wl1271_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL); ret = wlcore_write32(wl, WL18XX_WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL);
if (ret < 0)
goto out;
udelay(500); udelay(500);
wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
if (ret < 0)
goto out;
/* Disable interrupts */ /* Disable interrupts */
wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL); ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);
if (ret < 0)
goto out;
wl18xx_boot_soft_reset(wl); ret = wl18xx_boot_soft_reset(wl);
out: out:
return ret; return ret;
...@@ -736,10 +752,14 @@ static int wl18xx_pre_upload(struct wl1271 *wl) ...@@ -736,10 +752,14 @@ static int wl18xx_pre_upload(struct wl1271 *wl)
u32 tmp; u32 tmp;
int ret; int ret;
wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
if (ret < 0)
goto out;
/* TODO: check if this is all needed */ /* TODO: check if this is all needed */
wl1271_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND); ret = wlcore_write32(wl, WL18XX_EEPROMLESS_IND, WL18XX_EEPROMLESS_IND);
if (ret < 0)
goto out;
ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp); ret = wlcore_read_reg(wl, REG_CHIP_ID_B, &tmp);
if (ret < 0) if (ret < 0)
...@@ -765,16 +785,21 @@ static int wl18xx_set_mac_and_phy(struct wl1271 *wl) ...@@ -765,16 +785,21 @@ static int wl18xx_set_mac_and_phy(struct wl1271 *wl)
else else
len = sizeof(struct wl18xx_mac_and_phy_params); len = sizeof(struct wl18xx_mac_and_phy_params);
wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]); ret = wlcore_set_partition(wl, &wl->ptable[PART_PHY_INIT]);
if (ret < 0)
goto out;
ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)&priv->conf.phy, ret = wlcore_write(wl, WL18XX_PHY_INIT_MEM_ADDR, (u8 *)&priv->conf.phy,
len, false); len, false);
out:
return ret; return ret;
} }
static void wl18xx_enable_interrupts(struct wl1271 *wl) static int wl18xx_enable_interrupts(struct wl1271 *wl)
{ {
u32 event_mask, intr_mask; u32 event_mask, intr_mask;
int ret;
if (wl->chip.id == CHIP_ID_185x_PG10) { if (wl->chip.id == CHIP_ID_185x_PG10) {
event_mask = WL18XX_ACX_EVENTS_VECTOR_PG1; event_mask = WL18XX_ACX_EVENTS_VECTOR_PG1;
...@@ -784,11 +809,17 @@ static void wl18xx_enable_interrupts(struct wl1271 *wl) ...@@ -784,11 +809,17 @@ static void wl18xx_enable_interrupts(struct wl1271 *wl)
intr_mask = WL18XX_INTR_MASK_PG2; intr_mask = WL18XX_INTR_MASK_PG2;
} }
wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask); ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK, event_mask);
if (ret < 0)
goto out;
wlcore_enable_interrupts(wl); wlcore_enable_interrupts(wl);
wlcore_write_reg(wl, REG_INTERRUPT_MASK,
ret = wlcore_write_reg(wl, REG_INTERRUPT_MASK,
WL1271_ACX_INTR_ALL & ~intr_mask); WL1271_ACX_INTR_ALL & ~intr_mask);
out:
return ret;
} }
static int wl18xx_boot(struct wl1271 *wl) static int wl18xx_boot(struct wl1271 *wl)
...@@ -815,7 +846,7 @@ static int wl18xx_boot(struct wl1271 *wl) ...@@ -815,7 +846,7 @@ static int wl18xx_boot(struct wl1271 *wl)
if (ret < 0) if (ret < 0)
goto out; goto out;
wl18xx_enable_interrupts(wl); ret = wl18xx_enable_interrupts(wl);
out: out:
return ret; return ret;
...@@ -833,9 +864,10 @@ static int wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr, ...@@ -833,9 +864,10 @@ static int wl18xx_trigger_cmd(struct wl1271 *wl, int cmd_box_addr,
WL18XX_CMD_MAX_SIZE, false); WL18XX_CMD_MAX_SIZE, false);
} }
static void wl18xx_ack_event(struct wl1271 *wl) static int wl18xx_ack_event(struct wl1271 *wl)
{ {
wlcore_write_reg(wl, REG_INTERRUPT_TRIG, WL18XX_INTR_TRIG_EVENT_ACK); return wlcore_write_reg(wl, REG_INTERRUPT_TRIG,
WL18XX_INTR_TRIG_EVENT_ACK);
} }
static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks) static u32 wl18xx_calc_tx_blocks(struct wl1271 *wl, u32 len, u32 spare_blks)
...@@ -1038,7 +1070,9 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver) ...@@ -1038,7 +1070,9 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
u32 fuse; u32 fuse;
int ret; int ret;
wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
if (ret < 0)
goto out;
ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse); ret = wlcore_read32(wl, WL18XX_REG_FUSE_DATA_1_3, &fuse);
if (ret < 0) if (ret < 0)
...@@ -1047,7 +1081,7 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver) ...@@ -1047,7 +1081,7 @@ static int wl18xx_get_pg_ver(struct wl1271 *wl, s8 *ver)
if (ver) if (ver)
*ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET; *ver = (fuse & WL18XX_PG_VER_MASK) >> WL18XX_PG_VER_OFFSET;
wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
out: out:
return ret; return ret;
...@@ -1116,7 +1150,11 @@ static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev) ...@@ -1116,7 +1150,11 @@ static int wl18xx_conf_init(struct wl1271 *wl, struct device *dev)
static int wl18xx_plt_init(struct wl1271 *wl) static int wl18xx_plt_init(struct wl1271 *wl)
{ {
wl1271_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT); int ret;
ret = wlcore_write32(wl, WL18XX_SCR_PAD8, WL18XX_SCR_PAD8_PLT);
if (ret < 0)
return ret;
return wl->ops->boot(wl); return wl->ops->boot(wl);
} }
...@@ -1126,7 +1164,9 @@ static int wl18xx_get_mac(struct wl1271 *wl) ...@@ -1126,7 +1164,9 @@ static int wl18xx_get_mac(struct wl1271 *wl)
u32 mac1, mac2; u32 mac1, mac2;
int ret; int ret;
wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]); ret = wlcore_set_partition(wl, &wl->ptable[PART_TOP_PRCM_ELP_SOC]);
if (ret < 0)
goto out;
ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1, &mac1); ret = wlcore_read32(wl, WL18XX_REG_FUSE_BD_ADDR_1, &mac1);
if (ret < 0) if (ret < 0)
...@@ -1141,7 +1181,7 @@ static int wl18xx_get_mac(struct wl1271 *wl) ...@@ -1141,7 +1181,7 @@ static int wl18xx_get_mac(struct wl1271 *wl)
((mac1 & 0xff000000) >> 24); ((mac1 & 0xff000000) >> 24);
wl->fuse_nic_addr = (mac1 & 0xffffff); wl->fuse_nic_addr = (mac1 & 0xffffff);
wlcore_set_partition(wl, &wl->ptable[PART_DOWN]); ret = wlcore_set_partition(wl, &wl->ptable[PART_DOWN]);
out: out:
return ret; return ret;
......
...@@ -45,7 +45,7 @@ static int wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag) ...@@ -45,7 +45,7 @@ static int wl1271_boot_set_ecpu_ctrl(struct wl1271 *wl, u32 flag)
/* 10.5.1 run the firmware (II) */ /* 10.5.1 run the firmware (II) */
cpu_ctrl |= flag; cpu_ctrl |= flag;
wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl); ret = wlcore_write_reg(wl, REG_ECPU_CONTROL, cpu_ctrl);
out: out:
return ret; return ret;
...@@ -139,7 +139,9 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, ...@@ -139,7 +139,9 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
memcpy(&partition, &wl->ptable[PART_DOWN], sizeof(partition)); memcpy(&partition, &wl->ptable[PART_DOWN], sizeof(partition));
partition.mem.start = dest; partition.mem.start = dest;
wlcore_set_partition(wl, &partition); ret = wlcore_set_partition(wl, &partition);
if (ret < 0)
return ret;
/* 10.1 set partition limit and chunk num */ /* 10.1 set partition limit and chunk num */
chunk_num = 0; chunk_num = 0;
...@@ -153,7 +155,9 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf, ...@@ -153,7 +155,9 @@ static int wl1271_boot_upload_firmware_chunk(struct wl1271 *wl, void *buf,
partition_limit = chunk_num * CHUNK_SIZE + partition_limit = chunk_num * CHUNK_SIZE +
wl->ptable[PART_DOWN].mem.size; wl->ptable[PART_DOWN].mem.size;
partition.mem.start = addr; partition.mem.start = addr;
wlcore_set_partition(wl, &partition); ret = wlcore_set_partition(wl, &partition);
if (ret < 0)
return ret;
} }
/* 10.3 upload the chunk */ /* 10.3 upload the chunk */
...@@ -320,7 +324,9 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl) ...@@ -320,7 +324,9 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl)
wl1271_debug(DEBUG_BOOT, wl1271_debug(DEBUG_BOOT,
"nvs burst write 0x%x: 0x%x", "nvs burst write 0x%x: 0x%x",
dest_addr, val); dest_addr, val);
wl1271_write32(wl, dest_addr, val); ret = wlcore_write32(wl, dest_addr, val);
if (ret < 0)
return ret;
nvs_ptr += 4; nvs_ptr += 4;
dest_addr += 4; dest_addr += 4;
...@@ -346,7 +352,9 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl) ...@@ -346,7 +352,9 @@ int wlcore_boot_upload_nvs(struct wl1271 *wl)
nvs_len -= nvs_ptr - (u8 *)wl->nvs; nvs_len -= nvs_ptr - (u8 *)wl->nvs;
/* Now we must set the partition correctly */ /* Now we must set the partition correctly */
wlcore_set_partition(wl, &wl->ptable[PART_WORK]); ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
if (ret < 0)
return ret;
/* Copy the NVS tables to a new block to ensure alignment */ /* Copy the NVS tables to a new block to ensure alignment */
nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL); nvs_aligned = kmemdup(nvs_ptr, nvs_len, GFP_KERNEL);
...@@ -372,7 +380,9 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) ...@@ -372,7 +380,9 @@ int wlcore_boot_run_firmware(struct wl1271 *wl)
u32 chip_id, intr; u32 chip_id, intr;
/* Make sure we have the boot partition */ /* Make sure we have the boot partition */
wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
if (ret < 0)
return ret;
ret = wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT); ret = wl1271_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
if (ret < 0) if (ret < 0)
...@@ -404,8 +414,10 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) ...@@ -404,8 +414,10 @@ int wlcore_boot_run_firmware(struct wl1271 *wl)
} }
/* check that ACX_INTR_INIT_COMPLETE is enabled */ /* check that ACX_INTR_INIT_COMPLETE is enabled */
else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) { else if (intr & WL1271_ACX_INTR_INIT_COMPLETE) {
wlcore_write_reg(wl, REG_INTERRUPT_ACK, ret = wlcore_write_reg(wl, REG_INTERRUPT_ACK,
WL1271_ACX_INTR_INIT_COMPLETE); WL1271_ACX_INTR_INIT_COMPLETE);
if (ret < 0)
return ret;
break; break;
} }
} }
...@@ -469,9 +481,9 @@ int wlcore_boot_run_firmware(struct wl1271 *wl) ...@@ -469,9 +481,9 @@ int wlcore_boot_run_firmware(struct wl1271 *wl)
} }
/* set the working partition to its "running" mode offset */ /* set the working partition to its "running" mode offset */
wlcore_set_partition(wl, &wl->ptable[PART_WORK]); ret = wlcore_set_partition(wl, &wl->ptable[PART_WORK]);
/* firmware startup completed */ /* firmware startup completed */
return 0; return ret;
} }
EXPORT_SYMBOL_GPL(wlcore_boot_run_firmware); EXPORT_SYMBOL_GPL(wlcore_boot_run_firmware);
...@@ -116,7 +116,11 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len, ...@@ -116,7 +116,11 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
goto fail; goto fail;
} }
wlcore_write_reg(wl, REG_INTERRUPT_ACK, WL1271_ACX_INTR_CMD_COMPLETE); ret = wlcore_write_reg(wl, REG_INTERRUPT_ACK,
WL1271_ACX_INTR_CMD_COMPLETE);
if (ret < 0)
goto fail;
return 0; return 0;
fail: fail:
......
...@@ -318,7 +318,7 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num) ...@@ -318,7 +318,7 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
* TODO: we just need this because one bit is in a different * TODO: we just need this because one bit is in a different
* place. Is there any better way? * place. Is there any better way?
*/ */
wl->ops->ack_event(wl); ret = wl->ops->ack_event(wl);
return 0; return ret;
} }
...@@ -128,9 +128,11 @@ EXPORT_SYMBOL_GPL(wlcore_translate_addr); ...@@ -128,9 +128,11 @@ EXPORT_SYMBOL_GPL(wlcore_translate_addr);
* | | * | |
* *
*/ */
void wlcore_set_partition(struct wl1271 *wl, int wlcore_set_partition(struct wl1271 *wl,
const struct wlcore_partition_set *p) const struct wlcore_partition_set *p)
{ {
int ret;
/* copy partition info */ /* copy partition info */
memcpy(&wl->curr_part, p, sizeof(*p)); memcpy(&wl->curr_part, p, sizeof(*p));
...@@ -143,28 +145,41 @@ void wlcore_set_partition(struct wl1271 *wl, ...@@ -143,28 +145,41 @@ void wlcore_set_partition(struct wl1271 *wl,
wl1271_debug(DEBUG_IO, "mem3_start %08X mem3_size %08X", wl1271_debug(DEBUG_IO, "mem3_start %08X mem3_size %08X",
p->mem3.start, p->mem3.size); p->mem3.start, p->mem3.size);
wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start); ret = wlcore_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start);
wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size); if (ret < 0)
wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start); goto out;
wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);
wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start); ret = wlcore_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size);
wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size); if (ret < 0)
goto out;
ret = wlcore_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start);
if (ret < 0)
goto out;
ret = wlcore_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);
if (ret < 0)
goto out;
ret = wlcore_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start);
if (ret < 0)
goto out;
ret = wlcore_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size);
if (ret < 0)
goto out;
/* /*
* We don't need the size of the last partition, as it is * We don't need the size of the last partition, as it is
* automatically calculated based on the total memory size and * automatically calculated based on the total memory size and
* the sizes of the previous partitions. * the sizes of the previous partitions.
*/ */
wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start); ret = wlcore_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start);
}
EXPORT_SYMBOL_GPL(wlcore_set_partition);
void wlcore_select_partition(struct wl1271 *wl, u8 part) out:
{ return ret;
wl1271_debug(DEBUG_IO, "setting partition %d", part);
wlcore_set_partition(wl, &wl->ptable[part]);
} }
EXPORT_SYMBOL_GPL(wlcore_select_partition); EXPORT_SYMBOL_GPL(wlcore_set_partition);
void wl1271_io_reset(struct wl1271 *wl) void wl1271_io_reset(struct wl1271 *wl)
{ {
......
...@@ -92,10 +92,10 @@ static inline int wlcore_raw_read32(struct wl1271 *wl, int addr, u32 *val) ...@@ -92,10 +92,10 @@ static inline int wlcore_raw_read32(struct wl1271 *wl, int addr, u32 *val)
return 0; return 0;
} }
static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val) static inline int wlcore_raw_write32(struct wl1271 *wl, int addr, u32 val)
{ {
wl->buffer_32 = cpu_to_le32(val); wl->buffer_32 = cpu_to_le32(val);
wlcore_raw_write(wl, addr, &wl->buffer_32, return wlcore_raw_write(wl, addr, &wl->buffer_32,
sizeof(wl->buffer_32), false); sizeof(wl->buffer_32), false);
} }
...@@ -150,9 +150,9 @@ static inline int wlcore_read32(struct wl1271 *wl, int addr, u32 *val) ...@@ -150,9 +150,9 @@ static inline int wlcore_read32(struct wl1271 *wl, int addr, u32 *val)
return wlcore_raw_read32(wl, wlcore_translate_addr(wl, addr), val); return wlcore_raw_read32(wl, wlcore_translate_addr(wl, addr), val);
} }
static inline void wl1271_write32(struct wl1271 *wl, int addr, u32 val) static inline int wlcore_write32(struct wl1271 *wl, int addr, u32 val)
{ {
wl1271_raw_write32(wl, wlcore_translate_addr(wl, addr), val); return wlcore_raw_write32(wl, wlcore_translate_addr(wl, addr), val);
} }
static inline int wlcore_read_reg(struct wl1271 *wl, int reg, u32 *val) static inline int wlcore_read_reg(struct wl1271 *wl, int reg, u32 *val)
...@@ -162,9 +162,11 @@ static inline int wlcore_read_reg(struct wl1271 *wl, int reg, u32 *val) ...@@ -162,9 +162,11 @@ static inline int wlcore_read_reg(struct wl1271 *wl, int reg, u32 *val)
val); val);
} }
static inline void wlcore_write_reg(struct wl1271 *wl, int reg, u32 val) static inline int wlcore_write_reg(struct wl1271 *wl, int reg, u32 val)
{ {
wl1271_raw_write32(wl, wlcore_translate_addr(wl, wl->rtable[reg]), val); return wlcore_raw_write32(wl,
wlcore_translate_addr(wl, wl->rtable[reg]),
val);
} }
static inline void wl1271_power_off(struct wl1271 *wl) static inline void wl1271_power_off(struct wl1271 *wl)
...@@ -188,7 +190,7 @@ static inline int wl1271_power_on(struct wl1271 *wl) ...@@ -188,7 +190,7 @@ static inline int wl1271_power_on(struct wl1271 *wl)
return ret; return ret;
} }
void wlcore_set_partition(struct wl1271 *wl, int wlcore_set_partition(struct wl1271 *wl,
const struct wlcore_partition_set *p); const struct wlcore_partition_set *p);
bool wl1271_set_block_size(struct wl1271 *wl); bool wl1271_set_block_size(struct wl1271 *wl);
...@@ -197,6 +199,4 @@ bool wl1271_set_block_size(struct wl1271 *wl); ...@@ -197,6 +199,4 @@ bool wl1271_set_block_size(struct wl1271 *wl);
int wl1271_tx_dummy_packet(struct wl1271 *wl); int wl1271_tx_dummy_packet(struct wl1271 *wl);
void wlcore_select_partition(struct wl1271 *wl, u8 part);
#endif #endif
...@@ -882,7 +882,9 @@ static void wlcore_print_recovery(struct wl1271 *wl) ...@@ -882,7 +882,9 @@ static void wlcore_print_recovery(struct wl1271 *wl)
wl->chip.fw_ver_str); wl->chip.fw_ver_str);
/* change partitions momentarily so we can read the FW pc */ /* change partitions momentarily so we can read the FW pc */
wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
if (ret < 0)
return;
ret = wlcore_read_reg(wl, REG_PC_ON_RECOVERY, &pc); ret = wlcore_read_reg(wl, REG_PC_ON_RECOVERY, &pc);
if (ret < 0) if (ret < 0)
...@@ -967,9 +969,9 @@ static void wl1271_recovery_work(struct work_struct *work) ...@@ -967,9 +969,9 @@ static void wl1271_recovery_work(struct work_struct *work)
mutex_unlock(&wl->mutex); mutex_unlock(&wl->mutex);
} }
static void wl1271_fw_wakeup(struct wl1271 *wl) static int wlcore_fw_wakeup(struct wl1271 *wl)
{ {
wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP); return wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
} }
static int wl1271_setup(struct wl1271 *wl) static int wl1271_setup(struct wl1271 *wl)
...@@ -1005,13 +1007,21 @@ static int wl12xx_set_power_on(struct wl1271 *wl) ...@@ -1005,13 +1007,21 @@ static int wl12xx_set_power_on(struct wl1271 *wl)
wl1271_io_reset(wl); wl1271_io_reset(wl);
wl1271_io_init(wl); wl1271_io_init(wl);
wlcore_set_partition(wl, &wl->ptable[PART_BOOT]); ret = wlcore_set_partition(wl, &wl->ptable[PART_BOOT]);
if (ret < 0)
goto fail;
/* ELP module wake up */ /* ELP module wake up */
wl1271_fw_wakeup(wl); ret = wlcore_fw_wakeup(wl);
if (ret < 0)
goto fail;
out: out:
return ret; return ret;
fail:
wl1271_power_off(wl);
return ret;
} }
static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt) static int wl12xx_chip_wakeup(struct wl1271 *wl, bool plt)
......
...@@ -35,6 +35,7 @@ void wl1271_elp_work(struct work_struct *work) ...@@ -35,6 +35,7 @@ void wl1271_elp_work(struct work_struct *work)
struct delayed_work *dwork; struct delayed_work *dwork;
struct wl1271 *wl; struct wl1271 *wl;
struct wl12xx_vif *wlvif; struct wl12xx_vif *wlvif;
int ret;
dwork = container_of(work, struct delayed_work, work); dwork = container_of(work, struct delayed_work, work);
wl = container_of(dwork, struct wl1271, elp_work); wl = container_of(dwork, struct wl1271, elp_work);
...@@ -63,7 +64,12 @@ void wl1271_elp_work(struct work_struct *work) ...@@ -63,7 +64,12 @@ void wl1271_elp_work(struct work_struct *work)
} }
wl1271_debug(DEBUG_PSM, "chip to elp"); wl1271_debug(DEBUG_PSM, "chip to elp");
wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP); ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_SLEEP);
if (ret < 0) {
wl12xx_queue_recovery_work(wl);
goto out;
}
set_bit(WL1271_FLAG_IN_ELP, &wl->flags); set_bit(WL1271_FLAG_IN_ELP, &wl->flags);
out: out:
...@@ -135,7 +141,11 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl) ...@@ -135,7 +141,11 @@ int wl1271_ps_elp_wakeup(struct wl1271 *wl)
wl->elp_compl = &compl; wl->elp_compl = &compl;
spin_unlock_irqrestore(&wl->wl_lock, flags); spin_unlock_irqrestore(&wl->wl_lock, flags);
wl1271_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP); ret = wlcore_raw_write32(wl, HW_ACCESS_ELP_CTRL_REG, ELPCTRL_WAKE_UP);
if (ret < 0) {
wl12xx_queue_recovery_work(wl);
goto err;
}
if (!pending) { if (!pending) {
ret = wait_for_completion_timeout( ret = wait_for_completion_timeout(
......
...@@ -279,9 +279,12 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status) ...@@ -279,9 +279,12 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *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 & WLCORE_QUIRK_END_OF_TRANSACTION) if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION) {
wl1271_write32(wl, WL12XX_REG_RX_DRIVER_COUNTER, ret = wlcore_write32(wl, WL12XX_REG_RX_DRIVER_COUNTER,
wl->rx_counter); wl->rx_counter);
if (ret < 0)
goto out;
}
wl12xx_rearm_rx_streaming(wl, active_hlids); wl12xx_rearm_rx_streaming(wl, active_hlids);
......
...@@ -746,9 +746,12 @@ int wlcore_tx_work_locked(struct wl1271 *wl) ...@@ -746,9 +746,12 @@ int wlcore_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 & WLCORE_QUIRK_END_OF_TRANSACTION) if (wl->quirks & WLCORE_QUIRK_END_OF_TRANSACTION) {
wl1271_write32(wl, WL12XX_HOST_WR_ACCESS, ret = wlcore_write32(wl, WL12XX_HOST_WR_ACCESS,
wl->tx_packets_count); wl->tx_packets_count);
if (ret < 0)
goto out;
}
wl1271_handle_tx_low_watermark(wl); wl1271_handle_tx_low_watermark(wl);
} }
...@@ -911,9 +914,11 @@ int wlcore_tx_complete(struct wl1271 *wl) ...@@ -911,9 +914,11 @@ int wlcore_tx_complete(struct wl1271 *wl)
fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter); fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter);
/* write host counter to chipset (to ack) */ /* write host counter to chipset (to ack) */
wl1271_write32(wl, le32_to_cpu(memmap->tx_result) + ret = wlcore_write32(wl, le32_to_cpu(memmap->tx_result) +
offsetof(struct wl1271_tx_hw_res_if, offsetof(struct wl1271_tx_hw_res_if,
tx_result_host_counter), fw_counter); tx_result_host_counter), fw_counter);
if (ret < 0)
goto out;
count = fw_counter - wl->tx_results_count; count = fw_counter - wl->tx_results_count;
wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count); wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count);
......
...@@ -43,7 +43,7 @@ struct wlcore_ops { ...@@ -43,7 +43,7 @@ struct wlcore_ops {
int (*plt_init)(struct wl1271 *wl); int (*plt_init)(struct wl1271 *wl);
int (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr, int (*trigger_cmd)(struct wl1271 *wl, int cmd_box_addr,
void *buf, size_t len); void *buf, size_t len);
void (*ack_event)(struct wl1271 *wl); int (*ack_event)(struct wl1271 *wl);
u32 (*calc_tx_blocks)(struct wl1271 *wl, u32 len, u32 spare_blks); u32 (*calc_tx_blocks)(struct wl1271 *wl, u32 len, u32 spare_blks);
void (*set_tx_desc_blocks)(struct wl1271 *wl, void (*set_tx_desc_blocks)(struct wl1271 *wl,
struct wl1271_tx_hw_descr *desc, struct wl1271_tx_hw_descr *desc,
......
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