Message ID | 1528970937-26879-2-git-send-email-paolo.pisati@canonical.com |
---|---|
State | New |
Headers | show |
Series | UBUNTU: SAUCE: arm64: snapdragon: wcn36xx MAC | expand |
On 2018-06-14 12:08:56 , Paolo Pisati wrote: > BugLink: http://bugs.launchpad.net/bugs/1776491 > > By default, wcn36xx initializes itself with a dummy 00:00:00:00:00:00 MAC > address, preventing the interface from working until a valid MAC address was set. > > While not an issue on Ubuntu Classic (where the user can always set it > later on the command line or via /etc/network/interfaces), it became a problem > on Ubuntu Core where the wifi interface is probed during installation, > before the user has any chance to set a new MAC address. > > To overcome this scenario, the wcn36xx driver in Xenial had a couple of features: > > 1) during probe, if /lib/firmware/wlan/macaddr0 was present, its content was > used as the new MAC address > > 2) if that failed, a pseudo-random MAC addres was generated and set > > and this is a port of a the corresponding Xenial code to Bionic: > see xenial/snapdragon tree, > drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c::wcn36xx_msm_get_hw_mac(). > > Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com> > --- > drivers/net/wireless/ath/wcn36xx/Kconfig | 9 ++++++++ > drivers/net/wireless/ath/wcn36xx/main.c | 38 +++++++++++++++++++++++++++++++- > 2 files changed, 46 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/wireless/ath/wcn36xx/Kconfig b/drivers/net/wireless/ath/wcn36xx/Kconfig > index 20bf967..44d34a80 100644 > --- a/drivers/net/wireless/ath/wcn36xx/Kconfig > +++ b/drivers/net/wireless/ath/wcn36xx/Kconfig > @@ -16,3 +16,12 @@ config WCN36XX_DEBUGFS > Enabled debugfs support > > If unsure, say Y to make it easier to debug problems. > + > +config WCN36XX_SNAPDRAGON_HACKS > + bool "Dragonboard 410c WCN36XX MAC address generation hacks" > + default n > + depends on WCN36XX > + ---help--- > + Upon probe, WCN36XX will try to read its MAC address from > + a file located at /lib/firmware/wlan/macaddr0. If the file > + is not present, it will randomly generate a new MAC address. > diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c > index fcc98d4..ed0b973 100644 > --- a/drivers/net/wireless/ath/wcn36xx/main.c > +++ b/drivers/net/wireless/ath/wcn36xx/main.c > @@ -1265,6 +1265,14 @@ static int wcn36xx_probe(struct platform_device *pdev) > void *wcnss; > int ret; > const u8 *addr; > +#ifdef CONFIG_WCN36XX_SNAPDRAGON_HACKS > + int status; > + const struct firmware *addr_file = NULL; > + u8 tmp[18], _addr[ETH_ALEN]; > + static const u8 qcom_oui[3] = {0x00, 0x0A, 0xF5}; > + static const char *files = {"wlan/macaddr0"}; > +#endif > + > > wcn36xx_dbg(WCN36XX_DBG_MAC, "platform probe\n"); > > @@ -1298,7 +1306,35 @@ static int wcn36xx_probe(struct platform_device *pdev) > wcn36xx_err("invalid local-mac-address\n"); > ret = -EINVAL; > goto out_wq; > - } else if (addr) { > + } > +#ifdef CONFIG_WCN36XX_SNAPDRAGON_HACKS > + else if (addr == NULL) { > + addr = _addr; > + status = request_firmware(&addr_file, files, &pdev->dev); > + > + if (status < 0) { > + /* Assign a random mac with Qualcomm oui */ > + dev_err(&pdev->dev, "Failed (%d) to read macaddress" > + "file %s, using a random address instead", status, files); > + memcpy(addr, qcom_oui, 3); > + get_random_bytes(addr + 3, 3); > + } else { > + memset(tmp, 0, sizeof(tmp)); > + memcpy(tmp, addr_file->data, sizeof(tmp) - 1); > + sscanf(tmp, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", > + &addr[0], > + &addr[1], > + &addr[2], > + &addr[3], > + &addr[4], > + &addr[5]); > + > + release_firmware(addr_file); Not sure of the details of release_firmware(), but seems like calling it right after the memcpy() would be better. Probably not important though. > + } > + } > +#endif > + > + if (addr) { > wcn36xx_info("mac address: %pM\n", addr); > SET_IEEE80211_PERM_ADDR(wcn->hw, addr); > } > -- > 2.7.4 > > > -- > kernel-team mailing list > kernel-team@lists.ubuntu.com > https://lists.ubuntu.com/mailman/listinfo/kernel-team
diff --git a/drivers/net/wireless/ath/wcn36xx/Kconfig b/drivers/net/wireless/ath/wcn36xx/Kconfig index 20bf967..44d34a80 100644 --- a/drivers/net/wireless/ath/wcn36xx/Kconfig +++ b/drivers/net/wireless/ath/wcn36xx/Kconfig @@ -16,3 +16,12 @@ config WCN36XX_DEBUGFS Enabled debugfs support If unsure, say Y to make it easier to debug problems. + +config WCN36XX_SNAPDRAGON_HACKS + bool "Dragonboard 410c WCN36XX MAC address generation hacks" + default n + depends on WCN36XX + ---help--- + Upon probe, WCN36XX will try to read its MAC address from + a file located at /lib/firmware/wlan/macaddr0. If the file + is not present, it will randomly generate a new MAC address. diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index fcc98d4..ed0b973 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c @@ -1265,6 +1265,14 @@ static int wcn36xx_probe(struct platform_device *pdev) void *wcnss; int ret; const u8 *addr; +#ifdef CONFIG_WCN36XX_SNAPDRAGON_HACKS + int status; + const struct firmware *addr_file = NULL; + u8 tmp[18], _addr[ETH_ALEN]; + static const u8 qcom_oui[3] = {0x00, 0x0A, 0xF5}; + static const char *files = {"wlan/macaddr0"}; +#endif + wcn36xx_dbg(WCN36XX_DBG_MAC, "platform probe\n"); @@ -1298,7 +1306,35 @@ static int wcn36xx_probe(struct platform_device *pdev) wcn36xx_err("invalid local-mac-address\n"); ret = -EINVAL; goto out_wq; - } else if (addr) { + } +#ifdef CONFIG_WCN36XX_SNAPDRAGON_HACKS + else if (addr == NULL) { + addr = _addr; + status = request_firmware(&addr_file, files, &pdev->dev); + + if (status < 0) { + /* Assign a random mac with Qualcomm oui */ + dev_err(&pdev->dev, "Failed (%d) to read macaddress" + "file %s, using a random address instead", status, files); + memcpy(addr, qcom_oui, 3); + get_random_bytes(addr + 3, 3); + } else { + memset(tmp, 0, sizeof(tmp)); + memcpy(tmp, addr_file->data, sizeof(tmp) - 1); + sscanf(tmp, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", + &addr[0], + &addr[1], + &addr[2], + &addr[3], + &addr[4], + &addr[5]); + + release_firmware(addr_file); + } + } +#endif + + if (addr) { wcn36xx_info("mac address: %pM\n", addr); SET_IEEE80211_PERM_ADDR(wcn->hw, addr); }
BugLink: http://bugs.launchpad.net/bugs/1776491 By default, wcn36xx initializes itself with a dummy 00:00:00:00:00:00 MAC address, preventing the interface from working until a valid MAC address was set. While not an issue on Ubuntu Classic (where the user can always set it later on the command line or via /etc/network/interfaces), it became a problem on Ubuntu Core where the wifi interface is probed during installation, before the user has any chance to set a new MAC address. To overcome this scenario, the wcn36xx driver in Xenial had a couple of features: 1) during probe, if /lib/firmware/wlan/macaddr0 was present, its content was used as the new MAC address 2) if that failed, a pseudo-random MAC addres was generated and set and this is a port of a the corresponding Xenial code to Bionic: see xenial/snapdragon tree, drivers/net/wireless/ath/wcn36xx/wcn36xx-msm.c::wcn36xx_msm_get_hw_mac(). Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com> --- drivers/net/wireless/ath/wcn36xx/Kconfig | 9 ++++++++ drivers/net/wireless/ath/wcn36xx/main.c | 38 +++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-)