1

wifi: wilc1000: add function to read mac address from eFuse

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
This commit is contained in:
Alexis Lothoré 2024-05-14 17:51:22 +02:00 committed by Kalle Valo
parent 5f1191ed38
commit 59cf9277c1
4 changed files with 65 additions and 0 deletions

View File

@ -13,6 +13,12 @@
#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

View 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 {

View 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;

View 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