Commit 59cf9277 authored by Alexis Lothoré's avatar Alexis Lothoré Committed by Kalle Valo

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: default avatarAlexis Lothoré <alexis.lothore@bootlin.com>
Signed-off-by: default avatarKalle Valo <kvalo@kernel.org>
Link: https://msgid.link/20240514-mac_addr_at_probe-v2-4-afef09f1cd10@bootlin.com
parent 5f1191ed
......@@ -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
......@@ -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 {
......
......@@ -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;
......
......@@ -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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment