diff options
Diffstat (limited to 'drivers/net/wireless/microchip')
-rw-r--r-- | drivers/net/wireless/microchip/wilc1000/cfg80211.h | 4 | ||||
-rw-r--r-- | drivers/net/wireless/microchip/wilc1000/sdio.c | 103 | ||||
-rw-r--r-- | drivers/net/wireless/microchip/wilc1000/spi.c | 148 |
3 files changed, 113 insertions, 142 deletions
diff --git a/drivers/net/wireless/microchip/wilc1000/cfg80211.h b/drivers/net/wireless/microchip/wilc1000/cfg80211.h index 37b294cb3b37..8c65951cfaf9 100644 --- a/drivers/net/wireless/microchip/wilc1000/cfg80211.h +++ b/drivers/net/wireless/microchip/wilc1000/cfg80211.h @@ -8,15 +8,12 @@ #define WILC_CFG80211_H #include "netdev.h" -struct wiphy *wilc_cfg_alloc(void); int wilc_cfg80211_init(struct wilc **wilc, struct device *dev, int io_type, const struct wilc_hif_func *ops); struct wilc *wilc_create_wiphy(struct device *dev); void wilc_deinit_host_int(struct net_device *net); int wilc_init_host_int(struct net_device *net); void wilc_wfi_monitor_rx(struct net_device *mon_dev, u8 *buff, u32 size); -struct wilc_vif *wilc_netdev_interface(struct wilc *wl, const char *name, - enum nl80211_iftype type); void wilc_wfi_deinit_mon_interface(struct wilc *wl, bool rtnl_locked); struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, const char *name, @@ -24,7 +21,6 @@ struct net_device *wilc_wfi_init_mon_interface(struct wilc *wl, void wilc_update_mgmt_frame_registrations(struct wiphy *wiphy, struct wireless_dev *wdev, struct mgmt_frame_regs *upd); -struct wilc_vif *wilc_get_interface(struct wilc *wl); struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl); void wlan_deinit_locks(struct wilc *wilc); #endif diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c index a05bda7b9a3b..87948ba69a22 100644 --- a/drivers/net/wireless/microchip/wilc1000/sdio.c +++ b/drivers/net/wireless/microchip/wilc1000/sdio.c @@ -28,7 +28,6 @@ struct wilc_sdio { bool irq_gpio; u32 block_size; bool isinit; - int has_thrpt_enh3; u8 *cmd53_buf; }; @@ -722,21 +721,12 @@ static int wilc_sdio_init(struct wilc *wilc, bool resume) * make sure can read back chip id correctly **/ if (!resume) { - int rev; - ret = wilc_sdio_read_reg(wilc, WILC_CHIPID, &chipid); if (ret) { dev_err(&func->dev, "Fail cmd read chip id...\n"); return ret; } dev_err(&func->dev, "chipid (%08x)\n", chipid); - rev = FIELD_GET(WILC_CHIP_REV_FIELD, chipid); - if (rev > FIELD_GET(WILC_CHIP_REV_FIELD, WILC_1000_BASE_ID_2A)) - sdio_priv->has_thrpt_enh3 = 1; - else - sdio_priv->has_thrpt_enh3 = 0; - dev_info(&func->dev, "has_thrpt_enh3 = %d...\n", - sdio_priv->has_thrpt_enh3); } sdio_priv->isinit = true; @@ -809,102 +799,29 @@ static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val) struct sdio_func *func = dev_to_sdio_func(wilc->dev); struct wilc_sdio *sdio_priv = wilc->bus_data; int ret; - int vmm_ctl; - - if (sdio_priv->has_thrpt_enh3) { - u32 reg = 0; - - if (sdio_priv->irq_gpio) - reg = val & (BIT(MAX_NUM_INT) - 1); - - /* select VMM table 0 */ - if (val & SEL_VMM_TBL0) - reg |= BIT(5); - /* select VMM table 1 */ - if (val & SEL_VMM_TBL1) - reg |= BIT(6); - /* enable VMM */ - if (val & EN_VMM) - reg |= BIT(7); - if (reg) { - struct sdio_cmd52 cmd; - - cmd.read_write = 1; - cmd.function = 0; - cmd.raw = 0; - cmd.address = WILC_SDIO_IRQ_CLEAR_FLAG_REG; - cmd.data = reg; - - ret = wilc_sdio_cmd52(wilc, &cmd); - if (ret) { - dev_err(&func->dev, - "Failed cmd52, set (%02x) data (%d) ...\n", - cmd.address, __LINE__); - return ret; - } - } - return 0; - } - if (sdio_priv->irq_gpio) { - /* has_thrpt_enh2 uses register 0xf8 to clear interrupts. */ - /* - * Cannot clear multiple interrupts. - * Must clear each interrupt individually. - */ - u32 flags; - int i; - - flags = val & (BIT(MAX_NUM_INT) - 1); - for (i = 0; i < NUM_INT_EXT && flags; i++) { - if (flags & BIT(i)) { - struct sdio_cmd52 cmd; - - cmd.read_write = 1; - cmd.function = 0; - cmd.raw = 0; - cmd.address = WILC_SDIO_IRQ_CLEAR_FLAG_REG; - cmd.data = BIT(i); - - ret = wilc_sdio_cmd52(wilc, &cmd); - if (ret) { - dev_err(&func->dev, - "Failed cmd52, set (%02x) data (%d) ...\n", - cmd.address, __LINE__); - return ret; - } - flags &= ~BIT(i); - } - } + u32 reg = 0; - for (i = NUM_INT_EXT; i < MAX_NUM_INT && flags; i++) { - if (flags & BIT(i)) { - dev_err(&func->dev, - "Unexpected interrupt cleared %d...\n", - i); - flags &= ~BIT(i); - } - } - } + if (sdio_priv->irq_gpio) + reg = val & (BIT(MAX_NUM_INT) - 1); - vmm_ctl = 0; /* select VMM table 0 */ if (val & SEL_VMM_TBL0) - vmm_ctl |= BIT(0); + reg |= BIT(5); /* select VMM table 1 */ if (val & SEL_VMM_TBL1) - vmm_ctl |= BIT(1); + reg |= BIT(6); /* enable VMM */ if (val & EN_VMM) - vmm_ctl |= BIT(2); - - if (vmm_ctl) { + reg |= BIT(7); + if (reg) { struct sdio_cmd52 cmd; cmd.read_write = 1; cmd.function = 0; cmd.raw = 0; - cmd.address = WILC_SDIO_VMM_TBL_CTRL_REG; - cmd.data = vmm_ctl; + cmd.address = WILC_SDIO_IRQ_CLEAR_FLAG_REG; + cmd.data = reg; + ret = wilc_sdio_cmd52(wilc, &cmd); if (ret) { dev_err(&func->dev, diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c index b0fc5e68feec..77b4cdff73c3 100644 --- a/drivers/net/wireless/microchip/wilc1000/spi.c +++ b/drivers/net/wireless/microchip/wilc1000/spi.c @@ -74,6 +74,7 @@ static int wilc_spi_reset(struct wilc *wilc); #define CMD_SINGLE_READ 0xca #define CMD_RESET 0xcf +#define SPI_RETRY_MAX_LIMIT 10 #define SPI_ENABLE_VMM_RETRY_LIMIT 2 /* SPI response fields (section 11.1.2 in ATWILC1000 User Guide): */ @@ -830,59 +831,91 @@ static int wilc_spi_special_cmd(struct wilc *wilc, u8 cmd) return 0; } +static void wilc_spi_reset_cmd_sequence(struct wilc *wl, u8 attempt, u32 addr) +{ + struct spi_device *spi = to_spi_device(wl->dev); + struct wilc_spi *spi_priv = wl->bus_data; + + if (!spi_priv->probing_crc) + dev_err(&spi->dev, "Reset and retry %d %x\n", attempt, addr); + + usleep_range(1000, 1100); + wilc_spi_reset(wl); + usleep_range(1000, 1100); +} + static int wilc_spi_read_reg(struct wilc *wilc, u32 addr, u32 *data) { struct spi_device *spi = to_spi_device(wilc->dev); int result; u8 cmd = CMD_SINGLE_READ; u8 clockless = 0; + u8 i; - if (addr < WILC_SPI_CLOCKLESS_ADDR_LIMIT) { + if (addr <= WILC_SPI_CLOCKLESS_ADDR_LIMIT) { /* Clockless register */ cmd = CMD_INTERNAL_READ; clockless = 1; } - result = wilc_spi_single_read(wilc, cmd, addr, data, clockless); - if (result) { + for (i = 0; i < SPI_RETRY_MAX_LIMIT; i++) { + result = wilc_spi_single_read(wilc, cmd, addr, data, clockless); + if (!result) { + le32_to_cpus(data); + return 0; + } + + /* retry is not applicable for clockless registers */ + if (clockless) + break; + dev_err(&spi->dev, "Failed cmd, read reg (%08x)...\n", addr); - return result; + wilc_spi_reset_cmd_sequence(wilc, i, addr); } - le32_to_cpus(data); - - return 0; + return result; } static int wilc_spi_read(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { struct spi_device *spi = to_spi_device(wilc->dev); int result; + u8 i; if (size <= 4) return -EINVAL; - result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_READ, addr, buf, size); - if (result) { + for (i = 0; i < SPI_RETRY_MAX_LIMIT; i++) { + result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_READ, addr, + buf, size); + if (!result) + return 0; + dev_err(&spi->dev, "Failed cmd, read block (%08x)...\n", addr); - return result; + + wilc_spi_reset_cmd_sequence(wilc, i, addr); } - return 0; + return result; } static int spi_internal_write(struct wilc *wilc, u32 adr, u32 dat) { struct spi_device *spi = to_spi_device(wilc->dev); int result; + u8 i; - result = wilc_spi_write_cmd(wilc, CMD_INTERNAL_WRITE, adr, dat, 0); - if (result) { + for (i = 0; i < SPI_RETRY_MAX_LIMIT; i++) { + result = wilc_spi_write_cmd(wilc, CMD_INTERNAL_WRITE, adr, + dat, 0); + if (!result) + return 0; dev_err(&spi->dev, "Failed internal write cmd...\n"); - return result; + + wilc_spi_reset_cmd_sequence(wilc, i, adr); } - return 0; + return result; } static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data) @@ -890,17 +923,22 @@ static int spi_internal_read(struct wilc *wilc, u32 adr, u32 *data) struct spi_device *spi = to_spi_device(wilc->dev); struct wilc_spi *spi_priv = wilc->bus_data; int result; + u8 i; - result = wilc_spi_single_read(wilc, CMD_INTERNAL_READ, adr, data, 0); - if (result) { + for (i = 0; i < SPI_RETRY_MAX_LIMIT; i++) { + result = wilc_spi_single_read(wilc, CMD_INTERNAL_READ, adr, + data, 0); + if (!result) { + le32_to_cpus(data); + return 0; + } if (!spi_priv->probing_crc) dev_err(&spi->dev, "Failed internal read cmd...\n"); - return result; - } - le32_to_cpus(data); + wilc_spi_reset_cmd_sequence(wilc, i, adr); + } - return 0; + return result; } /******************************************** @@ -915,20 +953,27 @@ static int wilc_spi_write_reg(struct wilc *wilc, u32 addr, u32 data) int result; u8 cmd = CMD_SINGLE_WRITE; u8 clockless = 0; + u8 i; - if (addr < WILC_SPI_CLOCKLESS_ADDR_LIMIT) { + if (addr <= WILC_SPI_CLOCKLESS_ADDR_LIMIT) { /* Clockless register */ cmd = CMD_INTERNAL_WRITE; clockless = 1; } - result = wilc_spi_write_cmd(wilc, cmd, addr, data, clockless); - if (result) { + for (i = 0; i < SPI_RETRY_MAX_LIMIT; i++) { + result = wilc_spi_write_cmd(wilc, cmd, addr, data, clockless); + if (!result) + return 0; + dev_err(&spi->dev, "Failed cmd, write reg (%08x)...\n", addr); - return result; - } - return 0; + if (clockless) + break; + + wilc_spi_reset_cmd_sequence(wilc, i, addr); + } + return result; } static int spi_data_rsp(struct wilc *wilc, u8 cmd) @@ -981,6 +1026,7 @@ static int wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) { struct spi_device *spi = to_spi_device(wilc->dev); int result; + u8 i; /* * has to be greated than 4 @@ -988,26 +1034,38 @@ static int wilc_spi_write(struct wilc *wilc, u32 addr, u8 *buf, u32 size) if (size <= 4) return -EINVAL; - result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_WRITE, addr, NULL, size); - if (result) { - dev_err(&spi->dev, - "Failed cmd, write block (%08x)...\n", addr); - return result; - } + for (i = 0; i < SPI_RETRY_MAX_LIMIT; i++) { + result = wilc_spi_dma_rw(wilc, CMD_DMA_EXT_WRITE, addr, + NULL, size); + if (result) { + dev_err(&spi->dev, + "Failed cmd, write block (%08x)...\n", addr); + wilc_spi_reset_cmd_sequence(wilc, i, addr); + continue; + } - /* - * Data - */ - result = spi_data_write(wilc, buf, size); - if (result) { - dev_err(&spi->dev, "Failed block data write...\n"); - return result; - } + /* + * Data + */ + result = spi_data_write(wilc, buf, size); + if (result) { + dev_err(&spi->dev, "Failed block data write...\n"); + wilc_spi_reset_cmd_sequence(wilc, i, addr); + continue; + } - /* - * Data response - */ - return spi_data_rsp(wilc, CMD_DMA_EXT_WRITE); + /* + * Data response + */ + result = spi_data_rsp(wilc, CMD_DMA_EXT_WRITE); + if (result) { + dev_err(&spi->dev, "Failed block data rsp...\n"); + wilc_spi_reset_cmd_sequence(wilc, i, addr); + continue; + } + break; + } + return result; } /******************************************** |