@@ -962,8 +962,6 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
adapter->rx_locked = false;
spin_unlock_bh(&adapter->rx_proc_lock);
- mwifiex_set_mac_address(priv, dev, false, NULL);
-
return 0;
}
@@ -3115,7 +3113,7 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
priv->netdev = dev;
if (!adapter->mfg_mode) {
- mwifiex_set_mac_address(priv, dev, false, NULL);
+ mwifiex_set_default_mac_address(priv, dev);
ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
HostCmd_ACT_GEN_SET, 0, NULL, true);
@@ -139,7 +139,6 @@ enum mwifiex_bss_type {
MWIFIEX_BSS_TYPE_STA = 0,
MWIFIEX_BSS_TYPE_UAP = 1,
MWIFIEX_BSS_TYPE_P2P = 2,
- MWIFIEX_BSS_TYPE_ANY = 0xff,
};
enum mwifiex_bss_role {
@@ -71,7 +71,6 @@ int mwifiex_init_priv(struct mwifiex_private *priv)
u32 i;
priv->media_connected = false;
- eth_broadcast_addr(priv->curr_addr);
priv->port_open = false;
priv->usb_port = MWIFIEX_USB_EP_DATA;
priv->pkt_tx_ctrl = 0;
@@ -971,34 +971,16 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
}
int mwifiex_set_mac_address(struct mwifiex_private *priv,
- struct net_device *dev, bool external,
- u8 *new_mac)
+ struct net_device *dev, u8 *new_mac)
{
int ret;
- u64 mac_addr, old_mac_addr;
+ u64 old_mac_addr;
- old_mac_addr = ether_addr_to_u64(priv->curr_addr);
+ netdev_info(dev, "%s: old: %pM new: %pM\n", __func__, priv->curr_addr, new_mac);
- if (external) {
- mac_addr = ether_addr_to_u64(new_mac);
- } else {
- /* Internal mac address change */
- if (priv->bss_type == MWIFIEX_BSS_TYPE_ANY)
- return -EOPNOTSUPP;
-
- mac_addr = old_mac_addr;
-
- if (priv->bss_type == MWIFIEX_BSS_TYPE_P2P) {
- mac_addr |= BIT_ULL(MWIFIEX_MAC_LOCAL_ADMIN_BIT);
- mac_addr += priv->bss_num;
- } else if (priv->adapter->priv[0] != priv) {
- /* Set mac address based on bss_type/bss_num */
- mac_addr ^= BIT_ULL(priv->bss_type + 8);
- mac_addr += priv->bss_num;
- }
- }
+ old_mac_addr = ether_addr_to_u64(priv->curr_addr);
- u64_to_ether_addr(mac_addr, priv->curr_addr);
+ ether_addr_copy(priv->curr_addr, new_mac);
/* Send request to firmware */
ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
@@ -1015,6 +997,26 @@ int mwifiex_set_mac_address(struct mwifiex_private *priv,
return 0;
}
+int mwifiex_set_default_mac_address(struct mwifiex_private *priv,
+ struct net_device *dev)
+{
+ int priv_num;
+ u8 mac[ETH_ALEN];
+
+ ether_addr_copy(mac, priv->adapter->perm_addr);
+
+ for (priv_num = 0; priv_num < priv->adapter->priv_num; priv_num++)
+ if (priv == priv->adapter->priv[priv_num])
+ break;
+
+ if (priv_num) {
+ eth_addr_add(mac, priv_num);
+ mac[0] |= 0x2;
+ }
+
+ return mwifiex_set_mac_address(priv, dev, mac);
+}
+
/* CFG802.11 network device handler for setting MAC address.
*/
static int
@@ -1023,7 +1025,7 @@ mwifiex_ndo_set_mac_address(struct net_device *dev, void *addr)
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
struct sockaddr *hw_addr = addr;
- return mwifiex_set_mac_address(priv, dev, true, hw_addr->sa_data);
+ return mwifiex_set_mac_address(priv, dev, hw_addr->sa_data);
}
/*
@@ -1364,10 +1366,6 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
priv->assocresp_idx = MWIFIEX_AUTO_IDX_MASK;
priv->gen_idx = MWIFIEX_AUTO_IDX_MASK;
priv->num_tx_timeout = 0;
- if (is_valid_ether_addr(dev->dev_addr))
- ether_addr_copy(priv->curr_addr, dev->dev_addr);
- else
- ether_addr_copy(priv->curr_addr, priv->adapter->perm_addr);
if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
@@ -1694,8 +1694,9 @@ void mwifiex_process_multi_chan_event(struct mwifiex_private *priv,
struct sk_buff *event_skb);
void mwifiex_multi_chan_resync(struct mwifiex_adapter *adapter);
int mwifiex_set_mac_address(struct mwifiex_private *priv,
- struct net_device *dev,
- bool external, u8 *new_mac);
+ struct net_device *dev, u8 *new_mac);
+int mwifiex_set_default_mac_address(struct mwifiex_private *priv,
+ struct net_device *dev);
void mwifiex_devdump_tmo_func(unsigned long function_context);
#ifdef CONFIG_DEBUG_FS
The mwifiex driver tries to derive the MAC addresses of the virtual interfaces from the permanent address by adding the bss_num of the particular interface used. It does so each time the virtual interface is changed from AP to station or the other way round. This means that the devices MAC address changes during a change_virtual_intf call which is pretty unexpected by userspace. Furthermore the driver doesn't use the permanent address to add the bss_num to, but instead the current MAC address increases each time we do a change_virtual_intf. Fix this by initializing the MAC address once from the permanent MAC address during creation of the virtual interface and never touch it again. This also means that userspace can set a different MAC address which then stays like this forever and is not unexpectedly changed by the driver. The downstream driver at [1] always sets the locally admistered bit for MAC addresses derived from the permanent MAC address. This implies that only one MAC address is reserved for a mwifiex chip. Let's follow suit and do the same for upstream as well to not risk having the same MAC address for different devices. With this patch MWIFIEX_BSS_TYPE_ANY becomes unused, so it's removed. [1] https://github.com/nxp-imx/mwifiex/blob/lf-6.6.3_1.0.0/mxm_wifiex/wlan_src/mlinux/moal_main.c#L8383 Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/net/wireless/marvell/mwifiex/cfg80211.c | 4 +- drivers/net/wireless/marvell/mwifiex/decl.h | 1 - drivers/net/wireless/marvell/mwifiex/init.c | 1 - drivers/net/wireless/marvell/mwifiex/main.c | 54 ++++++++++++------------- drivers/net/wireless/marvell/mwifiex/main.h | 5 ++- 5 files changed, 30 insertions(+), 35 deletions(-)