summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/microchip/wilc1000
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/microchip/wilc1000')
-rw-r--r--drivers/net/wireless/microchip/wilc1000/cfg80211.h4
-rw-r--r--drivers/net/wireless/microchip/wilc1000/sdio.c103
-rw-r--r--drivers/net/wireless/microchip/wilc1000/spi.c148
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;
}
/********************************************