be2net: use RX_FILTER cmd to program multicast addresses
Use this cmd for both promiscous and multicast address programming. Get rid of the old MULTICAST_SET cmd. Signed-off-by: Sathya Perla <sathya.perla@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c0e64ef489
commit
5b8821b787
@ -334,7 +334,7 @@ struct be_adapter {
|
|||||||
u8 vlan_tag[VLAN_N_VID];
|
u8 vlan_tag[VLAN_N_VID];
|
||||||
u8 vlan_prio_bmap; /* Available Priority BitMap */
|
u8 vlan_prio_bmap; /* Available Priority BitMap */
|
||||||
u16 recommended_prio; /* Recommended Priority */
|
u16 recommended_prio; /* Recommended Priority */
|
||||||
struct be_dma_mem mc_cmd_mem;
|
struct be_dma_mem rx_filter; /* Cmd DMA mem for rx-filter */
|
||||||
|
|
||||||
struct be_dma_mem stats_cmd;
|
struct be_dma_mem stats_cmd;
|
||||||
/* Work queue used to perform periodic tasks like getting statistics */
|
/* Work queue used to perform periodic tasks like getting statistics */
|
||||||
@ -381,6 +381,8 @@ struct be_adapter {
|
|||||||
#define BE_GEN2 2
|
#define BE_GEN2 2
|
||||||
#define BE_GEN3 3
|
#define BE_GEN3 3
|
||||||
|
|
||||||
|
#define ON 1
|
||||||
|
#define OFF 0
|
||||||
#define lancer_chip(adapter) ((adapter->pdev->device == OC_DEVICE_ID3) || \
|
#define lancer_chip(adapter) ((adapter->pdev->device == OC_DEVICE_ID3) || \
|
||||||
(adapter->pdev->device == OC_DEVICE_ID4))
|
(adapter->pdev->device == OC_DEVICE_ID4))
|
||||||
|
|
||||||
|
@ -1548,27 +1548,14 @@ err:
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Uses MCC for this command as it may be called in BH context
|
int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
|
||||||
* Uses synchronous mcc
|
|
||||||
*/
|
|
||||||
int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en)
|
|
||||||
{
|
{
|
||||||
struct be_mcc_wrb *wrb;
|
struct be_mcc_wrb *wrb;
|
||||||
struct be_cmd_req_rx_filter *req;
|
struct be_dma_mem *mem = &adapter->rx_filter;
|
||||||
struct be_dma_mem promiscous_cmd;
|
struct be_cmd_req_rx_filter *req = mem->va;
|
||||||
struct be_sge *sge;
|
struct be_sge *sge;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
memset(&promiscous_cmd, 0, sizeof(struct be_dma_mem));
|
|
||||||
promiscous_cmd.size = sizeof(struct be_cmd_req_rx_filter);
|
|
||||||
promiscous_cmd.va = pci_alloc_consistent(adapter->pdev,
|
|
||||||
promiscous_cmd.size, &promiscous_cmd.dma);
|
|
||||||
if (!promiscous_cmd.va) {
|
|
||||||
dev_err(&adapter->pdev->dev,
|
|
||||||
"Memory allocation failure\n");
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
spin_lock_bh(&adapter->mcc_lock);
|
spin_lock_bh(&adapter->mcc_lock);
|
||||||
|
|
||||||
wrb = wrb_from_mccq(adapter);
|
wrb = wrb_from_mccq(adapter);
|
||||||
@ -1576,81 +1563,35 @@ int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en)
|
|||||||
status = -EBUSY;
|
status = -EBUSY;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
req = promiscous_cmd.va;
|
|
||||||
sge = nonembedded_sgl(wrb);
|
sge = nonembedded_sgl(wrb);
|
||||||
|
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_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
|
be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
|
||||||
OPCODE_COMMON_NTWK_RX_FILTER);
|
OPCODE_COMMON_NTWK_RX_FILTER);
|
||||||
|
|
||||||
|
memset(req, 0, sizeof(*req));
|
||||||
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
|
be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
|
||||||
OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req));
|
OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req));
|
||||||
|
|
||||||
req->if_id = cpu_to_le32(adapter->if_handle);
|
req->if_id = cpu_to_le32(adapter->if_handle);
|
||||||
req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS
|
if (flags & IFF_PROMISC) {
|
||||||
| BE_IF_FLAGS_VLAN_PROMISCUOUS);
|
req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS |
|
||||||
if (en)
|
BE_IF_FLAGS_VLAN_PROMISCUOUS);
|
||||||
req->if_flags = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS
|
if (value == ON)
|
||||||
| BE_IF_FLAGS_VLAN_PROMISCUOUS);
|
req->if_flags = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS |
|
||||||
|
BE_IF_FLAGS_VLAN_PROMISCUOUS);
|
||||||
sge->pa_hi = cpu_to_le32(upper_32_bits(promiscous_cmd.dma));
|
} else if (flags & IFF_ALLMULTI) {
|
||||||
sge->pa_lo = cpu_to_le32(promiscous_cmd.dma & 0xFFFFFFFF);
|
req->if_flags_mask = req->if_flags =
|
||||||
sge->len = cpu_to_le32(promiscous_cmd.size);
|
cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS);
|
||||||
|
|
||||||
status = be_mcc_notify_wait(adapter);
|
|
||||||
|
|
||||||
err:
|
|
||||||
spin_unlock_bh(&adapter->mcc_lock);
|
|
||||||
pci_free_consistent(adapter->pdev, promiscous_cmd.size,
|
|
||||||
promiscous_cmd.va, promiscous_cmd.dma);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Uses MCC for this command as it may be called in BH context
|
|
||||||
* (mc == NULL) => multicast promiscuous
|
|
||||||
*/
|
|
||||||
int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
|
|
||||||
struct net_device *netdev, struct be_dma_mem *mem)
|
|
||||||
{
|
|
||||||
struct be_mcc_wrb *wrb;
|
|
||||||
struct be_cmd_req_mcast_mac_config *req = mem->va;
|
|
||||||
struct be_sge *sge;
|
|
||||||
int status;
|
|
||||||
|
|
||||||
spin_lock_bh(&adapter->mcc_lock);
|
|
||||||
|
|
||||||
wrb = wrb_from_mccq(adapter);
|
|
||||||
if (!wrb) {
|
|
||||||
status = -EBUSY;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
sge = nonembedded_sgl(wrb);
|
|
||||||
memset(req, 0, sizeof(*req));
|
|
||||||
|
|
||||||
be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
|
|
||||||
OPCODE_COMMON_NTWK_MULTICAST_SET);
|
|
||||||
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,
|
|
||||||
OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req));
|
|
||||||
|
|
||||||
req->interface_id = if_id;
|
|
||||||
if (netdev) {
|
|
||||||
int i;
|
|
||||||
struct netdev_hw_addr *ha;
|
|
||||||
|
|
||||||
req->num_mac = cpu_to_le16(netdev_mc_count(netdev));
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
netdev_for_each_mc_addr(ha, netdev)
|
|
||||||
memcpy(req->mac[i++].byte, ha->addr, ETH_ALEN);
|
|
||||||
} else {
|
} else {
|
||||||
req->promiscuous = 1;
|
struct netdev_hw_addr *ha;
|
||||||
}
|
int i = 0;
|
||||||
|
|
||||||
status = be_mcc_notify_wait(adapter);
|
req->mcast_num = cpu_to_le16(netdev_mc_count(adapter->netdev));
|
||||||
|
netdev_for_each_mc_addr(ha, adapter->netdev)
|
||||||
|
memcpy(req->mcast_mac[i++].byte, ha->addr, ETH_ALEN);
|
||||||
|
}
|
||||||
|
|
||||||
err:
|
err:
|
||||||
spin_unlock_bh(&adapter->mcc_lock);
|
spin_unlock_bh(&adapter->mcc_lock);
|
||||||
|
@ -910,21 +910,12 @@ struct be_cmd_req_vlan_config {
|
|||||||
u16 normal_vlan[64];
|
u16 normal_vlan[64];
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/******************** Multicast MAC Config *******************/
|
/******************* RX FILTER ******************************/
|
||||||
#define BE_MAX_MC 64 /* set mcast promisc if > 64 */
|
#define BE_MAX_MC 64 /* set mcast promisc if > 64 */
|
||||||
struct macaddr {
|
struct macaddr {
|
||||||
u8 byte[ETH_ALEN];
|
u8 byte[ETH_ALEN];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct be_cmd_req_mcast_mac_config {
|
|
||||||
struct be_cmd_req_hdr hdr;
|
|
||||||
u16 num_mac;
|
|
||||||
u8 promiscuous;
|
|
||||||
u8 interface_id;
|
|
||||||
struct macaddr mac[BE_MAX_MC];
|
|
||||||
} __packed;
|
|
||||||
|
|
||||||
/******************* RX FILTER ******************************/
|
|
||||||
struct be_cmd_req_rx_filter {
|
struct be_cmd_req_rx_filter {
|
||||||
struct be_cmd_req_hdr hdr;
|
struct be_cmd_req_hdr hdr;
|
||||||
u32 global_flags_mask;
|
u32 global_flags_mask;
|
||||||
@ -932,11 +923,10 @@ struct be_cmd_req_rx_filter {
|
|||||||
u32 if_flags_mask;
|
u32 if_flags_mask;
|
||||||
u32 if_flags;
|
u32 if_flags;
|
||||||
u32 if_id;
|
u32 if_id;
|
||||||
u32 multicast_num;
|
u32 mcast_num;
|
||||||
struct macaddr mac[BE_MAX_MC];
|
struct macaddr mcast_mac[BE_MAX_MC];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/******************** Link Status Query *******************/
|
/******************** Link Status Query *******************/
|
||||||
struct be_cmd_req_link_status {
|
struct be_cmd_req_link_status {
|
||||||
struct be_cmd_req_hdr hdr;
|
struct be_cmd_req_hdr hdr;
|
||||||
@ -1455,9 +1445,7 @@ extern int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd);
|
|||||||
extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id,
|
extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id,
|
||||||
u16 *vtag_array, u32 num, bool untagged,
|
u16 *vtag_array, u32 num, bool untagged,
|
||||||
bool promiscuous);
|
bool promiscuous);
|
||||||
extern int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en);
|
extern int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 status);
|
||||||
extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
|
|
||||||
struct net_device *netdev, 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,
|
||||||
|
@ -782,7 +782,7 @@ static void be_set_multicast_list(struct net_device *netdev)
|
|||||||
struct be_adapter *adapter = netdev_priv(netdev);
|
struct be_adapter *adapter = netdev_priv(netdev);
|
||||||
|
|
||||||
if (netdev->flags & IFF_PROMISC) {
|
if (netdev->flags & IFF_PROMISC) {
|
||||||
be_cmd_promiscuous_config(adapter, true);
|
be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
|
||||||
adapter->promiscuous = true;
|
adapter->promiscuous = true;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -790,7 +790,7 @@ static void be_set_multicast_list(struct net_device *netdev)
|
|||||||
/* BE was previously in promiscuous mode; disable it */
|
/* BE was previously in promiscuous mode; disable it */
|
||||||
if (adapter->promiscuous) {
|
if (adapter->promiscuous) {
|
||||||
adapter->promiscuous = false;
|
adapter->promiscuous = false;
|
||||||
be_cmd_promiscuous_config(adapter, false);
|
be_cmd_rx_filter(adapter, IFF_PROMISC, OFF);
|
||||||
|
|
||||||
if (adapter->vlans_added)
|
if (adapter->vlans_added)
|
||||||
be_vid_config(adapter, false, 0);
|
be_vid_config(adapter, false, 0);
|
||||||
@ -799,13 +799,11 @@ static void be_set_multicast_list(struct net_device *netdev)
|
|||||||
/* Enable multicast promisc if num configured exceeds what we support */
|
/* Enable multicast promisc if num configured exceeds what we support */
|
||||||
if (netdev->flags & IFF_ALLMULTI ||
|
if (netdev->flags & IFF_ALLMULTI ||
|
||||||
netdev_mc_count(netdev) > BE_MAX_MC) {
|
netdev_mc_count(netdev) > BE_MAX_MC) {
|
||||||
be_cmd_multicast_set(adapter, adapter->if_handle, NULL,
|
be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
|
||||||
&adapter->mc_cmd_mem);
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
be_cmd_multicast_set(adapter, adapter->if_handle, netdev,
|
be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
|
||||||
&adapter->mc_cmd_mem);
|
|
||||||
done:
|
done:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2976,7 +2974,7 @@ static void be_ctrl_cleanup(struct be_adapter *adapter)
|
|||||||
dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va,
|
dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va,
|
||||||
mem->dma);
|
mem->dma);
|
||||||
|
|
||||||
mem = &adapter->mc_cmd_mem;
|
mem = &adapter->rx_filter;
|
||||||
if (mem->va)
|
if (mem->va)
|
||||||
dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va,
|
dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va,
|
||||||
mem->dma);
|
mem->dma);
|
||||||
@ -2986,7 +2984,7 @@ 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;
|
struct be_dma_mem *rx_filter = &adapter->rx_filter;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
status = be_map_pci_bars(adapter);
|
status = be_map_pci_bars(adapter);
|
||||||
@ -3002,21 +3000,19 @@ static int be_ctrl_init(struct be_adapter *adapter)
|
|||||||
status = -ENOMEM;
|
status = -ENOMEM;
|
||||||
goto unmap_pci_bars;
|
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);
|
rx_filter->size = sizeof(struct be_cmd_req_rx_filter);
|
||||||
mc_cmd_mem->va = dma_alloc_coherent(&adapter->pdev->dev,
|
rx_filter->va = dma_alloc_coherent(&adapter->pdev->dev, rx_filter->size,
|
||||||
mc_cmd_mem->size, &mc_cmd_mem->dma,
|
&rx_filter->dma, GFP_KERNEL);
|
||||||
GFP_KERNEL);
|
if (rx_filter->va == NULL) {
|
||||||
if (mc_cmd_mem->va == NULL) {
|
|
||||||
status = -ENOMEM;
|
status = -ENOMEM;
|
||||||
goto free_mbox;
|
goto free_mbox;
|
||||||
}
|
}
|
||||||
memset(mc_cmd_mem->va, 0, mc_cmd_mem->size);
|
memset(rx_filter->va, 0, rx_filter->size);
|
||||||
|
|
||||||
mutex_init(&adapter->mbox_lock);
|
mutex_init(&adapter->mbox_lock);
|
||||||
spin_lock_init(&adapter->mcc_lock);
|
spin_lock_init(&adapter->mcc_lock);
|
||||||
|
Loading…
Reference in New Issue
Block a user