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: Sathya Perla <sathyap@serverengines.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6ac7b687cb
commit
24307eef74
|
@ -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)
|
||||||
* 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,
|
||||||
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,
|
||||||
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)
|
||||||
be_vid_config(netdev);
|
be_vid_config(netdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void be_set_multicast_filter(struct net_device *netdev)
|
|
||||||
{
|
|
||||||
struct be_adapter *adapter = netdev_priv(netdev);
|
|
||||||
struct dev_mc_list *mc_ptr;
|
|
||||||
u8 mac_addr[32][ETH_ALEN];
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
if (netdev->flags & IFF_ALLMULTI) {
|
|
||||||
/* set BE in Multicast promiscuous */
|
|
||||||
be_cmd_mcast_mac_set(&adapter->ctrl,
|
|
||||||
adapter->if_handle, NULL, 0, true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
|
|
||||||
memcpy(&mac_addr[i][0], mc_ptr->dmi_addr, ETH_ALEN);
|
|
||||||
if (++i >= 32) {
|
|
||||||
be_cmd_mcast_mac_set(&adapter->ctrl,
|
|
||||||
adapter->if_handle, &mac_addr[0][0], i, false);
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i) {
|
|
||||||
/* reset the promiscuous mode also. */
|
|
||||||
be_cmd_mcast_mac_set(&adapter->ctrl,
|
|
||||||
adapter->if_handle, &mac_addr[0][0], i, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void be_set_multicast_list(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 be_ctrl_info *ctrl = &adapter->ctrl;
|
||||||
|
|
||||||
if (netdev->flags & IFF_PROMISC) {
|
if (netdev->flags & IFF_PROMISC) {
|
||||||
be_cmd_promiscuous_config(&adapter->ctrl, adapter->port_num, 1);
|
be_cmd_promiscuous_config(ctrl, adapter->port_num, 1);
|
||||||
} else {
|
adapter->promiscuous = true;
|
||||||
be_cmd_promiscuous_config(&adapter->ctrl, adapter->port_num, 0);
|
goto done;
|
||||||
be_set_multicast_filter(netdev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* BE was previously in promiscous mode; disable it */
|
||||||
|
if (adapter->promiscuous) {
|
||||||
|
adapter->promiscuous = false;
|
||||||
|
be_cmd_promiscuous_config(ctrl, adapter->port_num, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (netdev->flags & IFF_ALLMULTI) {
|
||||||
|
be_cmd_multicast_set(ctrl, adapter->if_handle, NULL, 0);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
be_cmd_multicast_set(ctrl, adapter->if_handle, netdev->mc_list,
|
||||||
|
netdev->mc_count);
|
||||||
|
done:
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void be_rx_rate_update(struct be_adapter *adapter)
|
static void be_rx_rate_update(struct be_adapter *adapter)
|
||||||
|
|
Loading…
Reference in New Issue