Commit 24307eef authored by Sathya Perla's avatar Sathya Perla Committed by David S. Miller

be2net: cleanup multicast_set cmd to avoid mc_list copy

Cleanup multicast_set method to avoid an extra copy of mc_list
 and unwanted promiscuos sets to BE.
Signed-off-by: default avatarSathya Perla <sathyap@serverengines.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6ac7b687
...@@ -274,6 +274,7 @@ struct be_adapter { ...@@ -274,6 +274,7 @@ struct be_adapter {
struct be_link_info link; struct be_link_info link;
u32 port_num; u32 port_num;
bool promiscuous;
}; };
extern struct ethtool_ops be_ethtool_ops; extern struct ethtool_ops be_ethtool_ops;
......
...@@ -927,8 +927,8 @@ int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, u8 port_num, bool en) ...@@ -927,8 +927,8 @@ int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, u8 port_num, bool en)
* Use MCC for this command as it may be called in BH context * Use MCC for this command as it may be called in BH context
* (mc == NULL) => multicast promiscous * (mc == NULL) => multicast promiscous
*/ */
int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id, u8 *mac_table, int be_cmd_multicast_set(struct be_ctrl_info *ctrl, u32 if_id,
u32 num, bool promiscuous) struct dev_mc_list *mc_list, u32 mc_count)
{ {
#define BE_MAX_MC 32 /* set mcast promisc if > 32 */ #define BE_MAX_MC 32 /* set mcast promisc if > 32 */
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
...@@ -947,11 +947,16 @@ int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id, u8 *mac_table, ...@@ -947,11 +947,16 @@ int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id, u8 *mac_table,
OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req)); OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req));
req->interface_id = if_id; req->interface_id = if_id;
req->promiscuous = promiscuous; if (mc_list && mc_count <= BE_MAX_MC) {
if (!promiscuous) { int i;
req->num_mac = cpu_to_le16(num); struct dev_mc_list *mc;
if (num)
memcpy(req->mac, mac_table, ETH_ALEN * num); req->num_mac = cpu_to_le16(mc_count);
for (mc = mc_list, i = 0; mc; mc = mc->next, i++)
memcpy(req->mac[i].byte, mc->dmi_addr, ETH_ALEN);
} else {
req->promiscuous = 1;
} }
be_mcc_notify_wait(ctrl); be_mcc_notify_wait(ctrl);
......
...@@ -716,8 +716,8 @@ extern int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id, ...@@ -716,8 +716,8 @@ extern int be_cmd_vlan_config(struct be_ctrl_info *ctrl, u32 if_id,
bool promiscuous); bool promiscuous);
extern int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl, extern int be_cmd_promiscuous_config(struct be_ctrl_info *ctrl,
u8 port_num, bool en); u8 port_num, bool en);
extern int be_cmd_mcast_mac_set(struct be_ctrl_info *ctrl, u32 if_id, extern int be_cmd_multicast_set(struct be_ctrl_info *ctrl, u32 if_id,
u8 *mac_table, u32 num, bool promiscuous); struct dev_mc_list *mc_list, u32 mc_count);
extern int be_cmd_set_flow_control(struct be_ctrl_info *ctrl, extern int be_cmd_set_flow_control(struct be_ctrl_info *ctrl,
u32 tx_fc, u32 rx_fc); u32 tx_fc, u32 rx_fc);
extern int be_cmd_get_flow_control(struct be_ctrl_info *ctrl, extern int be_cmd_get_flow_control(struct be_ctrl_info *ctrl,
......
...@@ -549,47 +549,32 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid) ...@@ -549,47 +549,32 @@ static void be_vlan_rem_vid(struct net_device *netdev, u16 vid)
be_vid_config(netdev); be_vid_config(netdev);
} }
static void be_set_multicast_filter(struct net_device *netdev) static void be_set_multicast_list(struct net_device *netdev)
{ {
struct be_adapter *adapter = netdev_priv(netdev); struct be_adapter *adapter = netdev_priv(netdev);
struct dev_mc_list *mc_ptr; struct be_ctrl_info *ctrl = &adapter->ctrl;
u8 mac_addr[32][ETH_ALEN];
int i = 0;
if (netdev->flags & IFF_ALLMULTI) { if (netdev->flags & IFF_PROMISC) {
/* set BE in Multicast promiscuous */ be_cmd_promiscuous_config(ctrl, adapter->port_num, 1);
be_cmd_mcast_mac_set(&adapter->ctrl, adapter->promiscuous = true;
adapter->if_handle, NULL, 0, true); goto done;
return;
} }
for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) { /* BE was previously in promiscous mode; disable it */
memcpy(&mac_addr[i][0], mc_ptr->dmi_addr, ETH_ALEN); if (adapter->promiscuous) {
if (++i >= 32) { adapter->promiscuous = false;
be_cmd_mcast_mac_set(&adapter->ctrl, be_cmd_promiscuous_config(ctrl, adapter->port_num, 0);
adapter->if_handle, &mac_addr[0][0], i, false);
i = 0;
}
} }
if (i) { if (netdev->flags & IFF_ALLMULTI) {
/* reset the promiscuous mode also. */ be_cmd_multicast_set(ctrl, adapter->if_handle, NULL, 0);
be_cmd_mcast_mac_set(&adapter->ctrl, goto done;
adapter->if_handle, &mac_addr[0][0], i, false);
} }
}
static void be_set_multicast_list(struct net_device *netdev)
{
struct be_adapter *adapter = netdev_priv(netdev);
if (netdev->flags & IFF_PROMISC) { be_cmd_multicast_set(ctrl, adapter->if_handle, netdev->mc_list,
be_cmd_promiscuous_config(&adapter->ctrl, adapter->port_num, 1); netdev->mc_count);
} else { done:
be_cmd_promiscuous_config(&adapter->ctrl, adapter->port_num, 0); return;
be_set_multicast_filter(netdev);
}
} }
static void be_rx_rate_update(struct be_adapter *adapter) static void be_rx_rate_update(struct be_adapter *adapter)
......
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