]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: wilc1000: add function to read mac address from eFuse
authorAlexis Lothoré <alexis.lothore@bootlin.com>
Tue, 14 May 2024 15:51:22 +0000 (17:51 +0200)
committerKalle Valo <kvalo@kernel.org>
Fri, 17 May 2024 08:01:51 +0000 (11:01 +0300)
wilc driver currently reads and sets mac address by firmware calls. It
means that we can not access mac address if no interface has been brought
up (so firmware is up and running). Another way to get mac address is to
read it directly from eFUSE.

Add a function helper to read the mac address written in eFuse, without
firmware assistance

Signed-off-by: Alexis Lothoré <alexis.lothore@bootlin.com>
Signed-off-by: Kalle Valo <kvalo@kernel.org>
Link: https://msgid.link/20240514-mac_addr_at_probe-v2-4-afef09f1cd10@bootlin.com
drivers/net/wireless/microchip/wilc1000/fw.h
drivers/net/wireless/microchip/wilc1000/netdev.h
drivers/net/wireless/microchip/wilc1000/wlan.c
drivers/net/wireless/microchip/wilc1000/wlan.h

index 5c5cac4aab029bf0bf9b985a01f03527500cff14..7a930e89614caf9406c64d06dc892ed728e2d6b5 100644 (file)
 #define WILC_MAX_RATES_SUPPORTED               12
 #define WILC_MAX_NUM_PMKIDS                    16
 #define WILC_MAX_NUM_SCANNED_CH                        14
+#define WILC_NVMEM_MAX_NUM_BANK                        6
+#define WILC_NVMEM_BANK_BASE                   0x30000000
+#define WILC_NVMEM_LOW_BANK_OFFSET             0x102c
+#define WILC_NVMEM_HIGH_BANK_OFFSET            0x1380
+#define WILC_NVMEM_IS_BANK_USED                        BIT(31)
+#define WILC_NVMEM_IS_BANK_INVALID             BIT(30)
 
 struct wilc_assoc_resp {
        __le16 capab_info;
@@ -127,4 +133,11 @@ struct wilc_external_auth_param {
        __le32 key_mgmt_suites;
        __le16 status;
 } __packed;
+
+static inline u32 get_bank_offset_from_bank_index(unsigned int i)
+{
+       return (((i) < 2) ? WILC_NVMEM_LOW_BANK_OFFSET + ((i) * 32) :
+               WILC_NVMEM_HIGH_BANK_OFFSET + ((i) - 2) * 16);
+}
+
 #endif
index eecee3973d6a420cce81f721ea1c9a24de0bcccd..20ba030022a15e52b97a9cf91a1e3d856dfc2046 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/if_arp.h>
 #include <linux/gpio/consumer.h>
 #include <linux/rculist.h>
+#include <uapi/linux/if_ether.h>
 
 #include "hif.h"
 #include "wlan.h"
@@ -278,6 +279,7 @@ struct wilc {
        struct ieee80211_rate bitrates[ARRAY_SIZE(wilc_bitrates)];
        struct ieee80211_supported_band band;
        u32 cipher_suites[ARRAY_SIZE(wilc_cipher_suites)];
+       u8 nv_mac_address[ETH_ALEN];
 };
 
 struct wilc_wfi_mon_priv {
index 37c32d17856ea70e4aa15146463c08807da59e84..b3fee8c8b7ad49174b540d71a65b6adbea559dae 100644 (file)
@@ -1472,6 +1472,55 @@ u32 wilc_get_chipid(struct wilc *wilc, bool update)
        return wilc->chipid;
 }
 
+int wilc_load_mac_from_nv(struct wilc *wl)
+{
+       int ret = -EINVAL;
+       unsigned int i;
+
+       acquire_bus(wl, WILC_BUS_ACQUIRE_AND_WAKEUP);
+
+       for (i = 0; i < WILC_NVMEM_MAX_NUM_BANK; i++) {
+               int bank_offset = get_bank_offset_from_bank_index(i);
+               u32 reg1, reg2;
+               u8 invalid;
+               u8 used;
+
+               ret = wl->hif_func->hif_read_reg(wl,
+                                                WILC_NVMEM_BANK_BASE + bank_offset,
+                                                &reg1);
+               if (ret) {
+                       pr_err("Can not read address %d lower part", i);
+                       break;
+               }
+               ret = wl->hif_func->hif_read_reg(wl,
+                                                WILC_NVMEM_BANK_BASE + bank_offset + 4,
+                                                &reg2);
+               if (ret) {
+                       pr_err("Can not read address %d upper part", i);
+                       break;
+               }
+
+               used = FIELD_GET(WILC_NVMEM_IS_BANK_USED, reg1);
+               invalid = FIELD_GET(WILC_NVMEM_IS_BANK_INVALID, reg1);
+               if (!used || invalid)
+                       continue;
+
+               wl->nv_mac_address[0] = FIELD_GET(GENMASK(23, 16), reg1);
+               wl->nv_mac_address[1] = FIELD_GET(GENMASK(15, 8), reg1);
+               wl->nv_mac_address[2] = FIELD_GET(GENMASK(7, 0), reg1);
+               wl->nv_mac_address[3] = FIELD_GET(GENMASK(31, 24), reg2);
+               wl->nv_mac_address[4] = FIELD_GET(GENMASK(23, 16), reg2);
+               wl->nv_mac_address[5] = FIELD_GET(GENMASK(15, 8), reg2);
+
+               ret = 0;
+               break;
+       }
+
+       release_bus(wl, WILC_BUS_RELEASE_ALLOW_SLEEP);
+       return ret;
+}
+EXPORT_SYMBOL_GPL(wilc_load_mac_from_nv);
+
 int wilc_wlan_init(struct net_device *dev)
 {
        int ret = 0;
index 54643d8fef04e45f834ff207131730be60b8812b..d72a0a81bbda2cd8cbd61eee0bf49af070ceb8da 100644 (file)
@@ -445,4 +445,5 @@ int wilc_send_config_pkt(struct wilc_vif *vif, u8 mode, struct wid *wids,
                         u32 count);
 int wilc_wlan_init(struct net_device *dev);
 u32 wilc_get_chipid(struct wilc *wilc, bool update);
+int wilc_load_mac_from_nv(struct wilc *wilc);
 #endif