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

be2net: support configuration of 64 multicast addresses instead of 32

To send upto 64 addresses in the multicast-set cmd, the non-embeeded cmd format
that provides for a bigger buffer is used instead of an embedded format.
Signed-off-by: default avatarSathya Perla <sathyap@serverengines.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9d4fb27d
...@@ -254,6 +254,7 @@ struct be_adapter { ...@@ -254,6 +254,7 @@ struct be_adapter {
struct vlan_group *vlan_grp; struct vlan_group *vlan_grp;
u16 num_vlans; u16 num_vlans;
u8 vlan_tag[VLAN_GROUP_ARRAY_LEN]; u8 vlan_tag[VLAN_GROUP_ARRAY_LEN];
struct be_dma_mem mc_cmd_mem;
struct be_stats_obj stats; struct be_stats_obj stats;
/* Work queue used to perform periodic tasks like getting statistics */ /* Work queue used to perform periodic tasks like getting statistics */
......
...@@ -990,24 +990,30 @@ int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en) ...@@ -990,24 +990,30 @@ int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en)
* (mc == NULL) => multicast promiscous * (mc == NULL) => multicast promiscous
*/ */
int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
struct dev_mc_list *mc_list, u32 mc_count) struct dev_mc_list *mc_list, u32 mc_count,
struct be_dma_mem *mem)
{ {
#define BE_MAX_MC 32 /* set mcast promisc if > 32 */
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
struct be_cmd_req_mcast_mac_config *req; struct be_cmd_req_mcast_mac_config *req = mem->va;
struct be_sge *sge;
int status;
spin_lock_bh(&adapter->mcc_lock); spin_lock_bh(&adapter->mcc_lock);
wrb = wrb_from_mccq(adapter); wrb = wrb_from_mccq(adapter);
req = embedded_payload(wrb); sge = nonembedded_sgl(wrb);
memset(req, 0, sizeof(*req));
be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
sge->pa_hi = cpu_to_le32(upper_32_bits(mem->dma));
sge->pa_lo = cpu_to_le32(mem->dma & 0xFFFFFFFF);
sge->len = cpu_to_le32(mem->size);
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req)); OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req));
req->interface_id = if_id; req->interface_id = if_id;
if (mc_list && mc_count <= BE_MAX_MC) { if (mc_list) {
int i; int i;
struct dev_mc_list *mc; struct dev_mc_list *mc;
...@@ -1019,11 +1025,10 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, ...@@ -1019,11 +1025,10 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
req->promiscuous = 1; req->promiscuous = 1;
} }
be_mcc_notify_wait(adapter); status = be_mcc_notify_wait(adapter);
spin_unlock_bh(&adapter->mcc_lock); spin_unlock_bh(&adapter->mcc_lock);
return status;
return 0;
} }
/* Uses synchrounous mcc */ /* Uses synchrounous mcc */
......
...@@ -591,6 +591,8 @@ struct be_cmd_req_promiscuous_config { ...@@ -591,6 +591,8 @@ struct be_cmd_req_promiscuous_config {
u16 rsvd0; u16 rsvd0;
} __packed; } __packed;
/******************** Multicast MAC Config *******************/
#define BE_MAX_MC 64 /* set mcast promisc if > 64 */
struct macaddr { struct macaddr {
u8 byte[ETH_ALEN]; u8 byte[ETH_ALEN];
}; };
...@@ -600,7 +602,7 @@ struct be_cmd_req_mcast_mac_config { ...@@ -600,7 +602,7 @@ struct be_cmd_req_mcast_mac_config {
u16 num_mac; u16 num_mac;
u8 promiscuous; u8 promiscuous;
u8 interface_id; u8 interface_id;
struct macaddr mac[32]; struct macaddr mac[BE_MAX_MC];
} __packed; } __packed;
static inline struct be_hw_stats * static inline struct be_hw_stats *
...@@ -829,7 +831,8 @@ extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, ...@@ -829,7 +831,8 @@ extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id,
extern int be_cmd_promiscuous_config(struct be_adapter *adapter, extern int be_cmd_promiscuous_config(struct be_adapter *adapter,
u8 port_num, bool en); u8 port_num, bool en);
extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
struct dev_mc_list *mc_list, u32 mc_count); struct dev_mc_list *mc_list, u32 mc_count,
struct be_dma_mem *mem);
extern int be_cmd_set_flow_control(struct be_adapter *adapter, extern int be_cmd_set_flow_control(struct be_adapter *adapter,
u32 tx_fc, u32 rx_fc); u32 tx_fc, u32 rx_fc);
extern int be_cmd_get_flow_control(struct be_adapter *adapter, extern int be_cmd_get_flow_control(struct be_adapter *adapter,
......
...@@ -562,13 +562,15 @@ static void be_set_multicast_list(struct net_device *netdev) ...@@ -562,13 +562,15 @@ static void be_set_multicast_list(struct net_device *netdev)
be_cmd_promiscuous_config(adapter, adapter->port_num, 0); be_cmd_promiscuous_config(adapter, adapter->port_num, 0);
} }
if (netdev->flags & IFF_ALLMULTI) { /* Enable multicast promisc if num configured exceeds what we support */
be_cmd_multicast_set(adapter, adapter->if_handle, NULL, 0); if (netdev->flags & IFF_ALLMULTI || netdev->mc_count > BE_MAX_MC) {
be_cmd_multicast_set(adapter, adapter->if_handle, NULL, 0,
&adapter->mc_cmd_mem);
goto done; goto done;
} }
be_cmd_multicast_set(adapter, adapter->if_handle, netdev->mc_list, be_cmd_multicast_set(adapter, adapter->if_handle, netdev->mc_list,
netdev->mc_count); netdev->mc_count, &adapter->mc_cmd_mem);
done: done:
return; return;
} }
...@@ -2009,34 +2011,61 @@ static void be_ctrl_cleanup(struct be_adapter *adapter) ...@@ -2009,34 +2011,61 @@ static void be_ctrl_cleanup(struct be_adapter *adapter)
if (mem->va) if (mem->va)
pci_free_consistent(adapter->pdev, mem->size, pci_free_consistent(adapter->pdev, mem->size,
mem->va, mem->dma); mem->va, mem->dma);
mem = &adapter->mc_cmd_mem;
if (mem->va)
pci_free_consistent(adapter->pdev, mem->size,
mem->va, mem->dma);
} }
static int be_ctrl_init(struct be_adapter *adapter) static int be_ctrl_init(struct be_adapter *adapter)
{ {
struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced; struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced;
struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem; struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem;
struct be_dma_mem *mc_cmd_mem = &adapter->mc_cmd_mem;
int status; int status;
status = be_map_pci_bars(adapter); status = be_map_pci_bars(adapter);
if (status) if (status)
return status; goto done;
mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16; mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16;
mbox_mem_alloc->va = pci_alloc_consistent(adapter->pdev, mbox_mem_alloc->va = pci_alloc_consistent(adapter->pdev,
mbox_mem_alloc->size, &mbox_mem_alloc->dma); mbox_mem_alloc->size, &mbox_mem_alloc->dma);
if (!mbox_mem_alloc->va) { if (!mbox_mem_alloc->va) {
be_unmap_pci_bars(adapter); status = -ENOMEM;
return -1; goto unmap_pci_bars;
} }
mbox_mem_align->size = sizeof(struct be_mcc_mailbox); mbox_mem_align->size = sizeof(struct be_mcc_mailbox);
mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16); mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16);
mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16); mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
mc_cmd_mem->size = sizeof(struct be_cmd_req_mcast_mac_config);
mc_cmd_mem->va = pci_alloc_consistent(adapter->pdev, mc_cmd_mem->size,
&mc_cmd_mem->dma);
if (mc_cmd_mem->va == NULL) {
status = -ENOMEM;
goto free_mbox;
}
memset(mc_cmd_mem->va, 0, mc_cmd_mem->size);
spin_lock_init(&adapter->mbox_lock); spin_lock_init(&adapter->mbox_lock);
spin_lock_init(&adapter->mcc_lock); spin_lock_init(&adapter->mcc_lock);
spin_lock_init(&adapter->mcc_cq_lock); spin_lock_init(&adapter->mcc_cq_lock);
return 0; return 0;
free_mbox:
pci_free_consistent(adapter->pdev, mbox_mem_alloc->size,
mbox_mem_alloc->va, mbox_mem_alloc->dma);
unmap_pci_bars:
be_unmap_pci_bars(adapter);
done:
return status;
} }
static void be_stats_cleanup(struct be_adapter *adapter) static void be_stats_cleanup(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