mwifiex: p2p: use separate device address
authorXinming Hu <huxm@marvell.com>
Mon, 7 Aug 2017 01:36:06 +0000 (01:36 +0000)
committerKalle Valo <kvalo@codeaurora.org>
Tue, 8 Aug 2017 11:49:58 +0000 (14:49 +0300)
Per below statement about p2p device address in WFA P2P
spec $2.4.3:

The P2P Device Address of a P2P Device shall be its globally
administered MAC address, or its globally administered MAC
address with the locally administered bit set.

This patch follow above statement, using a separate device
address for p2p interface

Signed-off-by: Xinming Hu <huxm@marvell.com>
Signed-off-by: Cathy Luo <cluo@marvell.com>
Signed-off-by: Ganapathi Bhat <gbhat@marvell.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/marvell/mwifiex/cfg80211.c
drivers/net/wireless/marvell/mwifiex/main.c
drivers/net/wireless/marvell/mwifiex/main.h

index 945d444d99a9d4e5447417f5ce01b183a653bfc5..b16b19af812df565daf57c02ddc8aca9b3cd3402 100644 (file)
@@ -915,6 +915,8 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
        adapter->rx_locked = false;
        spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
 
+       mwifiex_set_mac_address(priv, dev);
+
        return 0;
 }
 
@@ -2955,6 +2957,8 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
        }
 
        mwifiex_init_priv_params(priv, dev);
+       mwifiex_set_mac_address(priv, dev);
+
        priv->netdev = dev;
 
        ret = mwifiex_send_cmd(priv, HostCmd_CMD_SET_BSS_MODE,
@@ -2982,7 +2986,6 @@ struct wireless_dev *mwifiex_add_virtual_intf(struct wiphy *wiphy,
        dev_net_set(dev, wiphy_net(wiphy));
        dev->ieee80211_ptr = &priv->wdev;
        dev->ieee80211_ptr->iftype = priv->bss_mode;
-       memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
        SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
 
        dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
index d67d70002ea9bf534c4f0023c542a8641048e8b5..ee40b739b2897e01bd223e2f9eb298d6d760785c 100644 (file)
@@ -940,31 +940,44 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
        return 0;
 }
 
-/*
- * CFG802.11 network device handler for setting MAC address.
- */
-static int
-mwifiex_set_mac_address(struct net_device *dev, void *addr)
+int mwifiex_set_mac_address(struct mwifiex_private *priv,
+                           struct net_device *dev)
 {
-       struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
-       struct sockaddr *hw_addr = addr;
        int ret;
+       u64 mac_addr;
 
-       memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
+       if (priv->bss_type != MWIFIEX_BSS_TYPE_P2P)
+               goto done;
+
+       mac_addr = ether_addr_to_u64(priv->curr_addr);
+       mac_addr |= BIT_ULL(MWIFIEX_MAC_LOCAL_ADMIN_BIT);
+       u64_to_ether_addr(mac_addr, priv->curr_addr);
 
        /* Send request to firmware */
        ret = mwifiex_send_cmd(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
                               HostCmd_ACT_GEN_SET, 0, NULL, true);
 
-       if (!ret)
-               memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
-       else
+       if (ret) {
                mwifiex_dbg(priv->adapter, ERROR,
                            "set mac address failed: ret=%d\n", ret);
+               return ret;
+       }
 
+done:
        memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
+       return 0;
+}
 
-       return ret;
+/* CFG802.11 network device handler for setting MAC address.
+ */
+static int
+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;
+
+       memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
+       return mwifiex_set_mac_address(priv, dev);
 }
 
 /*
@@ -1257,7 +1270,7 @@ static const struct net_device_ops mwifiex_netdev_ops = {
        .ndo_open = mwifiex_open,
        .ndo_stop = mwifiex_close,
        .ndo_start_xmit = mwifiex_hard_start_xmit,
-       .ndo_set_mac_address = mwifiex_set_mac_address,
+       .ndo_set_mac_address = mwifiex_ndo_set_mac_address,
        .ndo_validate_addr = eth_validate_addr,
        .ndo_tx_timeout = mwifiex_tx_timeout,
        .ndo_get_stats = mwifiex_get_stats,
@@ -1301,7 +1314,6 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
        priv->gen_idx = MWIFIEX_AUTO_IDX_MASK;
        priv->num_tx_timeout = 0;
        ether_addr_copy(priv->curr_addr, priv->adapter->perm_addr);
-       memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
 
        if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA ||
            GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_UAP) {
index 537a0ad795ff699bb4a703c663077db6261e9185..0aaae0878742fa0160bd053cd8303313df06f2b0 100644 (file)
@@ -165,6 +165,8 @@ enum {
 /* Address alignment */
 #define MWIFIEX_ALIGN_ADDR(p, a) (((long)(p) + (a) - 1) & ~((a) - 1))
 
+#define MWIFIEX_MAC_LOCAL_ADMIN_BIT            41
+
 /**
  *enum mwifiex_debug_level  -  marvell wifi debug level
  */
@@ -1671,6 +1673,8 @@ void mwifiex_process_tx_pause_event(struct mwifiex_private *priv,
 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);
 
 #ifdef CONFIG_DEBUG_FS
 void mwifiex_debugfs_init(void);