]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: wilc1000: Add WILC3000 support
authorAjay Singh <ajay.kathat@microchip.com>
Fri, 4 Oct 2024 11:44:16 +0000 (13:44 +0200)
committerKalle Valo <kvalo@kernel.org>
Thu, 17 Oct 2024 16:47:42 +0000 (19:47 +0300)
Add support for the WILC3000 chip. The chip is similar to WILC1000,
except that the register layout is slightly different and it does
not support WPA3/SAE.

Reviewed-by: Alexis Lothoré <alexis.lothore@bootlin.com>
Tested-by: Alexis Lothoré <alexis.lothore@bootlin.com>
Tested-on: WILC1000SD 07 SDIO WILC_WIFI_FW_REL_16_1_2
Tested-on: WILC1000SD 07 SPI WILC_WIFI_FW_REL_16_1_2
Tested-on: WILC3000 A SDIO WILC_WIFI_FW_REL_16_1_1
Tested-on: WILC3000 A SPI WILC_WIFI_FW_REL_16_1_1
Signed-off-by: Ajay Singh <ajay.kathat@microchip.com>
Signed-off-by: Marek Vasut <marex@denx.de>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://patch.msgid.link/20241004114551.40236-7-marex@denx.de
drivers/net/wireless/microchip/wilc1000/cfg80211.c
drivers/net/wireless/microchip/wilc1000/netdev.c
drivers/net/wireless/microchip/wilc1000/sdio.c
drivers/net/wireless/microchip/wilc1000/spi.c
drivers/net/wireless/microchip/wilc1000/wlan.c
drivers/net/wireless/microchip/wilc1000/wlan.h

index 283f8df046884b12387ac37f6e75ea77dcea9398..b0dae6f7c633b31904f46d4393cd4c2d8b69ed6e 100644 (file)
@@ -1855,7 +1855,9 @@ EXPORT_SYMBOL_GPL(wilc_cfg80211_init);
 
 int wilc_cfg80211_register(struct wilc *wilc)
 {
-       wilc->wiphy->features |= NL80211_FEATURE_SAE;
+       /* WPA3/SAE supported only on WILC1000 */
+       if (is_wilc1000(wilc->chipid))
+               wilc->wiphy->features |= NL80211_FEATURE_SAE;
 
        return wiphy_register(wilc->wiphy);
 }
index 086e70d833e064adc3ce9152d4fc18fda17d27c4..3bb13aa33413a37920ef9260bd52fcd16ed38869 100644 (file)
 #define __WILC1000_FW(api)             WILC1000_FW_PREFIX #api ".bin"
 #define WILC1000_FW(api)               __WILC1000_FW(api)
 
+#define WILC3000_API_VER               1
+
+#define WILC3000_FW_PREFIX             "atmel/wilc3000_wifi_firmware-"
+#define __WILC3000_FW(api)             WILC3000_FW_PREFIX #api ".bin"
+#define WILC3000_FW(api)               __WILC3000_FW(api)
+
 static irqreturn_t isr_uh_routine(int irq, void *user_data)
 {
        struct wilc *wilc = user_data;
@@ -196,19 +202,23 @@ static int wilc_wlan_get_firmware(struct net_device *dev)
        struct wilc_vif *vif = netdev_priv(dev);
        struct wilc *wilc = vif->wilc;
        const struct firmware *wilc_fw;
+       char *firmware;
        int ret;
 
-       if (!is_wilc1000(wilc->chipid))
+       if (is_wilc1000(wilc->chipid))
+               firmware = WILC1000_FW(WILC1000_API_VER);
+       else if (is_wilc3000(wilc->chipid))
+               firmware = WILC3000_FW(WILC3000_API_VER);
+       else
                return -EINVAL;
 
-       netdev_info(dev, "WILC1000 loading firmware [%s]\n",
-                   WILC1000_FW(WILC1000_API_VER));
+       netdev_info(dev, "WILC%d loading firmware [%s]\n",
+                   is_wilc1000(wilc->chipid) ? 1000 : 3000,
+                   firmware);
 
-       ret = request_firmware(&wilc_fw, WILC1000_FW(WILC1000_API_VER),
-                              wilc->dev);
+       ret = request_firmware(&wilc_fw, firmware, wilc->dev);
        if (ret != 0) {
-               netdev_err(dev, "%s - firmware not available\n",
-                          WILC1000_FW(WILC1000_API_VER));
+               netdev_err(dev, "%s - firmware not available\n", firmware);
                return -EINVAL;
        }
        wilc->firmware = wilc_fw;
@@ -233,7 +243,7 @@ static int wilc_start_firmware(struct net_device *dev)
        return 0;
 }
 
-static int wilc1000_firmware_download(struct net_device *dev)
+static int wilc_firmware_download(struct net_device *dev)
 {
        struct wilc_vif *vif = netdev_priv(dev);
        struct wilc *wilc = vif->wilc;
@@ -528,7 +538,7 @@ static int wilc_wlan_initialize(struct net_device *dev, struct wilc_vif *vif)
                if (ret)
                        goto fail_irq_enable;
 
-               ret = wilc1000_firmware_download(dev);
+               ret = wilc_firmware_download(dev);
                if (ret)
                        goto fail_irq_enable;
 
@@ -1014,3 +1024,4 @@ EXPORT_SYMBOL_GPL(wilc_netdev_ifc_init);
 MODULE_DESCRIPTION("Atmel WILC1000 core wireless driver");
 MODULE_LICENSE("GPL");
 MODULE_FIRMWARE(WILC1000_FW(WILC1000_API_VER));
+MODULE_FIRMWARE(WILC3000_FW(WILC3000_API_VER));
index 56a929281d6a709ca03fe1cd0120a8de10474ed1..5262c8846c13df28cf65ec8c5ad0ef9d6677c98b 100644 (file)
@@ -810,13 +810,19 @@ static int wilc_sdio_read_int(struct wilc *wilc, u32 *int_status)
                cmd.address = WILC_SDIO_EXT_IRQ_FLAG_REG;
        } else {
                cmd.function = 0;
-               cmd.address = WILC_SDIO_IRQ_FLAG_REG;
+               cmd.address = is_wilc1000(wilc->chipid) ?
+                             WILC1000_SDIO_IRQ_FLAG_REG :
+                             WILC3000_SDIO_IRQ_FLAG_REG;
        }
        cmd.raw = 0;
        cmd.read_write = 0;
        cmd.data = 0;
        wilc_sdio_cmd52(wilc, &cmd);
        irq_flags = cmd.data;
+
+       if (sdio_priv->irq_gpio)
+               irq_flags &= is_wilc1000(wilc->chipid) ? 0x1f : 0x0f;
+
        tmp |= FIELD_PREP(IRG_FLAGS_MASK, cmd.data);
 
        if (FIELD_GET(UNHANDLED_IRQ_MASK, irq_flags))
@@ -838,22 +844,56 @@ static int wilc_sdio_clear_int_ext(struct wilc *wilc, u32 val)
        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 (is_wilc1000(wilc->chipid)) {
+               /* 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);
+       } else {
+               if (sdio_priv->irq_gpio && reg) {
+                       struct sdio_cmd52 cmd;
+
+                       cmd.read_write = 1;
+                       cmd.function = 0;
+                       cmd.raw = 0;
+                       cmd.address = WILC3000_SDIO_IRQ_FLAG_REG;
+                       cmd.data = reg;
+
+                       ret = wilc_sdio_cmd52(wilc, &cmd);
+                       if (ret) {
+                               dev_err(&func->dev,
+                                       "Failed cmd52, set 0xfe data (%d) ...\n",
+                                       __LINE__);
+                               return ret;
+                       }
+               }
+
+               reg = 0;
+               /* select VMM table 0 */
+               if (val & SEL_VMM_TBL0)
+                       reg |= BIT(0);
+               /* select VMM table 1 */
+               if (val & SEL_VMM_TBL1)
+                       reg |= BIT(1);
+               /* enable VMM */
+               if (val & EN_VMM)
+                       reg |= BIT(2);
+       }
+
        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.address = is_wilc1000(wilc->chipid) ?
+                             WILC1000_SDIO_IRQ_CLEAR_FLAG_REG :
+                             WILC3000_SDIO_VMM_TBL_CTRL_REG;
                cmd.data = reg;
 
                ret = wilc_sdio_cmd52(wilc, &cmd);
index 28d211ee6009694f72b59110bdbd5caaebff0cc5..ce2a9cdd6aa7877ed4c2517f9549a00bdc8dc874 100644 (file)
@@ -1233,7 +1233,7 @@ static int wilc_validate_chipid(struct wilc *wilc)
                dev_err(&spi->dev, "Fail cmd read chip id...\n");
                return ret;
        }
-       if (!is_wilc1000(chipid)) {
+       if (!is_wilc1000(chipid) && !is_wilc3000(chipid)) {
                dev_err(&spi->dev, "Unknown chip id 0x%x\n", chipid);
                return -ENODEV;
        }
index 521caa498035ea3e7513a30fc2f43e9ce52bb598..9d80adc45d6be14c8818e8ef1643db6875cf57d2 100644 (file)
@@ -541,7 +541,7 @@ static struct rxq_entry_t *wilc_wlan_rxq_remove(struct wilc *wilc)
        return rqe;
 }
 
-static int chip_allow_sleep(struct wilc *wilc)
+static int chip_allow_sleep_wilc1000(struct wilc *wilc)
 {
        u32 reg = 0;
        const struct wilc_hif_func *hif_func = wilc->hif_func;
@@ -601,7 +601,41 @@ static int chip_allow_sleep(struct wilc *wilc)
        return 0;
 }
 
-static int chip_wakeup(struct wilc *wilc)
+static int chip_allow_sleep_wilc3000(struct wilc *wilc)
+{
+       u32 reg = 0;
+       int ret;
+       const struct wilc_hif_func *hif_func = wilc->hif_func;
+
+       if (wilc->io_type == WILC_HIF_SDIO) {
+               ret = hif_func->hif_read_reg(wilc, WILC_SDIO_WAKEUP_REG, &reg);
+               if (ret)
+                       return ret;
+               ret = hif_func->hif_write_reg(wilc, WILC_SDIO_WAKEUP_REG,
+                                             reg & ~WILC_SDIO_WAKEUP_BIT);
+               if (ret)
+                       return ret;
+       } else {
+               ret = hif_func->hif_read_reg(wilc, WILC_SPI_WAKEUP_REG, &reg);
+               if (ret)
+                       return ret;
+               ret = hif_func->hif_write_reg(wilc, WILC_SPI_WAKEUP_REG,
+                                             reg & ~WILC_SPI_WAKEUP_BIT);
+               if (ret)
+                       return ret;
+       }
+       return 0;
+}
+
+static int chip_allow_sleep(struct wilc *wilc)
+{
+       if (is_wilc1000(wilc->chipid))
+               return chip_allow_sleep_wilc1000(wilc);
+       else
+               return chip_allow_sleep_wilc3000(wilc);
+}
+
+static int chip_wakeup_wilc1000(struct wilc *wilc)
 {
        u32 ret = 0;
        u32 clk_status_val = 0, trials = 0;
@@ -613,15 +647,15 @@ static int chip_wakeup(struct wilc *wilc)
        if (wilc->io_type == WILC_HIF_SDIO) {
                wakeup_reg = WILC_SDIO_WAKEUP_REG;
                wakeup_bit = WILC_SDIO_WAKEUP_BIT;
-               clk_status_reg = WILC_SDIO_CLK_STATUS_REG;
-               clk_status_bit = WILC_SDIO_CLK_STATUS_BIT;
+               clk_status_reg = WILC1000_SDIO_CLK_STATUS_REG;
+               clk_status_bit = WILC1000_SDIO_CLK_STATUS_BIT;
                from_host_to_fw_reg = WILC_SDIO_HOST_TO_FW_REG;
                from_host_to_fw_bit = WILC_SDIO_HOST_TO_FW_BIT;
        } else {
                wakeup_reg = WILC_SPI_WAKEUP_REG;
                wakeup_bit = WILC_SPI_WAKEUP_BIT;
-               clk_status_reg = WILC_SPI_CLK_STATUS_REG;
-               clk_status_bit = WILC_SPI_CLK_STATUS_BIT;
+               clk_status_reg = WILC1000_SPI_CLK_STATUS_REG;
+               clk_status_bit = WILC1000_SPI_CLK_STATUS_BIT;
                from_host_to_fw_reg = WILC_SPI_HOST_TO_FW_REG;
                from_host_to_fw_bit = WILC_SPI_HOST_TO_FW_BIT;
        }
@@ -663,6 +697,74 @@ static int chip_wakeup(struct wilc *wilc)
        return 0;
 }
 
+static int chip_wakeup_wilc3000(struct wilc *wilc)
+{
+       u32 wakeup_reg_val, clk_status_reg_val, trials = 0;
+       u32 wakeup_reg, wakeup_bit;
+       u32 clk_status_reg, clk_status_bit;
+       int wake_seq_trials = 5;
+       const struct wilc_hif_func *hif_func = wilc->hif_func;
+
+       if (wilc->io_type == WILC_HIF_SDIO) {
+               wakeup_reg = WILC_SDIO_WAKEUP_REG;
+               wakeup_bit = WILC_SDIO_WAKEUP_BIT;
+               clk_status_reg = WILC3000_SDIO_CLK_STATUS_REG;
+               clk_status_bit = WILC3000_SDIO_CLK_STATUS_BIT;
+       } else {
+               wakeup_reg = WILC_SPI_WAKEUP_REG;
+               wakeup_bit = WILC_SPI_WAKEUP_BIT;
+               clk_status_reg = WILC3000_SPI_CLK_STATUS_REG;
+               clk_status_bit = WILC3000_SPI_CLK_STATUS_BIT;
+       }
+
+       hif_func->hif_read_reg(wilc, wakeup_reg, &wakeup_reg_val);
+       do {
+               hif_func->hif_write_reg(wilc, wakeup_reg, wakeup_reg_val |
+                                                         wakeup_bit);
+               /* Check the clock status */
+               hif_func->hif_read_reg(wilc, clk_status_reg,
+                                      &clk_status_reg_val);
+
+               /* In case of clocks off, wait 1ms, and check it again.
+                * if still off, wait for another 1ms, for a total wait of 3ms.
+                * If still off, redo the wake up sequence
+                */
+               while ((clk_status_reg_val & clk_status_bit) == 0 &&
+                      (++trials % 4) != 0) {
+                       /* Wait for the chip to stabilize*/
+                       usleep_range(1000, 1100);
+
+                       /* Make sure chip is awake. This is an extra step that
+                        * can be removed later to avoid the bus access
+                        * overhead
+                        */
+                       hif_func->hif_read_reg(wilc, clk_status_reg,
+                                              &clk_status_reg_val);
+               }
+               /* in case of failure, Reset the wakeup bit to introduce a new
+                * edge on the next loop
+                */
+               if ((clk_status_reg_val & clk_status_bit) == 0) {
+                       hif_func->hif_write_reg(wilc, wakeup_reg,
+                                               wakeup_reg_val & (~wakeup_bit));
+                       /* added wait before wakeup sequence retry */
+                       usleep_range(200, 300);
+               }
+       } while ((clk_status_reg_val & clk_status_bit) == 0 && wake_seq_trials-- > 0);
+       if (!wake_seq_trials)
+               dev_err(wilc->dev, "clocks still OFF. Wake up failed\n");
+
+       return 0;
+}
+
+static int chip_wakeup(struct wilc *wilc)
+{
+       if (is_wilc1000(wilc->chipid))
+               return chip_wakeup_wilc1000(wilc);
+       else
+               return chip_wakeup_wilc3000(wilc);
+}
+
 static inline int acquire_bus(struct wilc *wilc, enum bus_acquire acquire)
 {
        int ret = 0;
@@ -695,7 +797,9 @@ int host_wakeup_notify(struct wilc *wilc)
        if (ret)
                return ret;
 
-       wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_2, 1);
+       wilc->hif_func->hif_write_reg(wilc, is_wilc1000(wilc->chipid) ?
+                                           WILC1000_CORTUS_INTERRUPT_2 :
+                                           WILC3000_CORTUS_INTERRUPT_2, 1);
        return release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
 }
 EXPORT_SYMBOL_GPL(host_wakeup_notify);
@@ -707,7 +811,9 @@ int host_sleep_notify(struct wilc *wilc)
        if (ret)
                return ret;
 
-       wilc->hif_func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_1, 1);
+       wilc->hif_func->hif_write_reg(wilc, is_wilc1000(wilc->chipid) ?
+                                           WILC1000_CORTUS_INTERRUPT_1 :
+                                           WILC3000_CORTUS_INTERRUPT_1, 1);
        return release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
 }
 EXPORT_SYMBOL_GPL(host_sleep_notify);
@@ -842,19 +948,45 @@ int wilc_wlan_handle_txq(struct wilc *wilc, u32 *txq_count)
                if (ret)
                        break;
 
-               ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
-               if (ret)
-                       break;
+               if (is_wilc1000(wilc->chipid)) {
+                       ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x2);
+                       if (ret)
+                               break;
 
-               do {
-                       ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
+                       do {
+                               ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
+                               if (ret)
+                                       break;
+                               if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) {
+                                       entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
+                                       break;
+                               }
+                       } while (--timeout);
+               } else {
+                       ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0);
                        if (ret)
                                break;
-                       if (FIELD_GET(WILC_VMM_ENTRY_AVAILABLE, reg)) {
-                               entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
+
+                       /* interrupt firmware */
+                       ret = func->hif_write_reg(wilc, WILC_CORTUS_INTERRUPT_BASE, 1);
+                       if (ret)
                                break;
-                       }
-               } while (--timeout);
+
+                       do {
+                               ret = func->hif_read_reg(wilc, WILC_CORTUS_INTERRUPT_BASE, &reg);
+                               if (ret)
+                                       break;
+                               if (reg == 0) {
+                                       /* Get the entries */
+                                       ret = func->hif_read_reg(wilc, WILC_HOST_VMM_CTL, &reg);
+                                       if (ret)
+                                               break;
+
+                                       entries = FIELD_GET(WILC_VMM_ENTRY_COUNT, reg);
+                                       break;
+                               }
+                       } while (--timeout);
+               }
                if (timeout <= 0) {
                        ret = func->hif_write_reg(wilc, WILC_HOST_VMM_CTL, 0x0);
                        break;
@@ -1212,6 +1344,9 @@ int wilc_wlan_start(struct wilc *wilc)
        if (wilc->io_type == WILC_HIF_SDIO && wilc->dev_irq_num)
                reg |= WILC_HAVE_SDIO_IRQ_GPIO;
 
+       if (is_wilc3000(wilc->chipid))
+               reg |= WILC_HAVE_SLEEP_CLK_SRC_RTC;
+
        ret = wilc->hif_func->hif_write_reg(wilc, WILC_GP_REG_1, reg);
        if (ret)
                goto release;
@@ -1462,21 +1597,25 @@ int wilc_get_chipid(struct wilc *wilc)
        u32 rfrevid = 0;
 
        if (wilc->chipid == 0) {
-               wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
-               wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID,
-                                            &rfrevid);
-               if (!is_wilc1000(chipid)) {
-                       wilc->chipid = 0;
-                       return -EINVAL;
-               }
-               if (chipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */
-                       if (rfrevid != 0x1)
-                               chipid = WILC_1000_BASE_ID_2A_REV1;
-               } else if (chipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */
-                       if (rfrevid == 0x4)
-                               chipid = WILC_1000_BASE_ID_2B_REV1;
-                       else if (rfrevid != 0x3)
-                               chipid = WILC_1000_BASE_ID_2B_REV2;
+               wilc->hif_func->hif_read_reg(wilc, WILC3000_CHIP_ID, &chipid);
+               if (!is_wilc3000(chipid)) {
+                       wilc->hif_func->hif_read_reg(wilc, WILC_CHIPID, &chipid);
+                       wilc->hif_func->hif_read_reg(wilc, WILC_RF_REVISION_ID,
+                                                    &rfrevid);
+
+                       if (!is_wilc1000(chipid)) {
+                               wilc->chipid = 0;
+                               return -EINVAL;
+                       }
+                       if (chipid == WILC_1000_BASE_ID_2A) { /* 0x1002A0 */
+                               if (rfrevid != 0x1)
+                                       chipid = WILC_1000_BASE_ID_2A_REV1;
+                       } else if (chipid == WILC_1000_BASE_ID_2B) { /* 0x1002B0 */
+                               if (rfrevid == 0x4)
+                                       chipid = WILC_1000_BASE_ID_2B_REV1;
+                               else if (rfrevid != 0x3)
+                                       chipid = WILC_1000_BASE_ID_2B_REV2;
+                       }
                }
 
                wilc->chipid = chipid;
@@ -1526,6 +1665,21 @@ static int init_chip(struct net_device *dev)
                }
        }
 
+       if (is_wilc3000(wilc->chipid)) {
+               ret = wilc->hif_func->hif_read_reg(wilc, WILC3000_BOOTROM_STATUS, &reg);
+               if (ret) {
+                       netdev_err(dev, "failed to read WILC3000 BootROM status register\n");
+                       goto release;
+               }
+
+               ret = wilc->hif_func->hif_write_reg(wilc, WILC3000_CORTUS_BOOT_REGISTER_2,
+                                                   WILC_CORTUS_BOOT_FROM_IRAM);
+               if (ret) {
+                       netdev_err(dev, "failed to write WILC3000 Boot register\n");
+                       goto release;
+               }
+       }
+
 release:
        rv = release_bus(wilc, WILC_BUS_RELEASE_ALLOW_SLEEP);
 
@@ -1607,7 +1761,7 @@ int wilc_wlan_init(struct net_device *dev)
                if (ret)
                        goto fail;
 
-               if (!is_wilc1000(wilc->chipid)) {
+               if (!is_wilc1000(wilc->chipid) && !is_wilc3000(wilc->chipid)) {
                        netdev_err(dev, "Unsupported chipid: %x\n", wilc->chipid);
                        ret = -EINVAL;
                        goto fail;
index 552590823e44423eff9a3ed111952e1fcf8fe1ce..b9e7f9222eadde6d736e1d0a403f84ec19399632 100644 (file)
 #define WILC_SPI_WAKEUP_REG            0x1
 #define WILC_SPI_WAKEUP_BIT            BIT(1)
 
-#define WILC_SPI_CLK_STATUS_REG        0x0f
-#define WILC_SPI_CLK_STATUS_BIT        BIT(2)
+/* WILC1000 specific */
+#define WILC1000_SPI_CLK_STATUS_REG    0x0f
+#define WILC1000_SPI_CLK_STATUS_BIT    BIT(2)
+
+/* WILC3000 specific */
+#define WILC3000_SPI_CLK_STATUS_REG    0x13
+#define WILC3000_SPI_CLK_STATUS_BIT    BIT(2)
+
 #define WILC_SPI_HOST_TO_FW_REG                0x0b
 #define WILC_SPI_HOST_TO_FW_BIT                BIT(0)
 
 #define WILC_SDIO_WAKEUP_REG           0xf0
 #define WILC_SDIO_WAKEUP_BIT           BIT(0)
 
-#define WILC_SDIO_CLK_STATUS_REG       0xf1
-#define WILC_SDIO_CLK_STATUS_BIT       BIT(0)
+/* WILC1000 */
+#define WILC1000_SDIO_CLK_STATUS_REG   0xf1
+#define WILC1000_SDIO_CLK_STATUS_BIT   BIT(0)
+
+#define WILC1000_SDIO_IRQ_FLAG_REG     0xf7
+#define WILC1000_SDIO_IRQ_CLEAR_FLAG_REG       0xf8
+
+/* WILC3000 specific */
+#define WILC3000_SDIO_CLK_STATUS_REG   0xf0 /* clk & wakeup are on same reg */
+#define WILC3000_SDIO_CLK_STATUS_BIT   BIT(4)
+
+#define WILC3000_SDIO_VMM_TBL_CTRL_REG 0xf1
+#define WILC3000_SDIO_IRQ_FLAG_REG     0xfe
 
+/* Common vendor specific CCCR register */
 #define WILC_SDIO_INTERRUPT_DATA_SZ_REG        0xf2 /* Read size (2 bytes) */
 
 #define WILC_SDIO_VMM_TBL_CTRL_REG     0xf6
-#define WILC_SDIO_IRQ_FLAG_REG         0xf7
-#define WILC_SDIO_IRQ_CLEAR_FLAG_REG   0xf8
 
 #define WILC_SDIO_HOST_TO_FW_REG       0xfa
 #define WILC_SDIO_HOST_TO_FW_BIT       BIT(0)
 #define WILC_HAVE_USE_IRQ_AS_HOST_WAKE BIT(8)
 
 #define WILC_CORTUS_INTERRUPT_BASE     0x10A8
-#define WILC_CORTUS_INTERRUPT_1                (WILC_CORTUS_INTERRUPT_BASE + 0x4)
-#define WILC_CORTUS_INTERRUPT_2                (WILC_CORTUS_INTERRUPT_BASE + 0x8)
+#define WILC1000_CORTUS_INTERRUPT_1    (WILC_CORTUS_INTERRUPT_BASE + 0x4)
+#define WILC3000_CORTUS_INTERRUPT_1    (WILC_CORTUS_INTERRUPT_BASE + 0x14)
+
+#define WILC1000_CORTUS_INTERRUPT_2    (WILC_CORTUS_INTERRUPT_BASE + 0x8)
+#define WILC3000_CORTUS_INTERRUPT_2    (WILC_CORTUS_INTERRUPT_BASE + 0x18)
 
 /* tx control register 1 to 4 for RX */
 #define WILC_REG_4_TO_1_RX             0x1e1c
 
 #define WILC_CORTUS_RESET_MUX_SEL      0x1118
 #define WILC_CORTUS_BOOT_REGISTER      0xc0000
+#define WILC3000_BOOTROM_STATUS                0x207ac
+#define WILC3000_CORTUS_BOOT_REGISTER_2        0x4f0000
+#define WILC3000_CHIP_ID               0x3b0000
 
 #define WILC_CORTUS_BOOT_FROM_IRAM     0x71
 
 #define WILC_1000_BASE_ID_2B_REV1      (WILC_1000_BASE_ID_2B + 1)
 #define WILC_1000_BASE_ID_2B_REV2      (WILC_1000_BASE_ID_2B + 2)
 
+#define WILC_3000_BASE_ID              0x300000
+
 #define WILC_CHIP_REV_FIELD            GENMASK(11, 0)
 
 /********************************************
@@ -413,6 +437,11 @@ static inline bool is_wilc1000(u32 id)
        return (id & (~WILC_CHIP_REV_FIELD)) == WILC_1000_BASE_ID;
 }
 
+static inline bool is_wilc3000(u32 id)
+{
+       return (id & (~WILC_CHIP_REV_FIELD)) == WILC_3000_BASE_ID;
+}
+
 int wilc_wlan_firmware_download(struct wilc *wilc, const u8 *buffer,
                                u32 buffer_size);
 int wilc_wlan_start(struct wilc *wilc);