Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -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 */
+14 −9
Original line number Original line Diff line number Diff line
@@ -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,
		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 */
+5 −2
Original line number Original line Diff line number Diff line
@@ -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 {
	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,
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,
+35 −6
Original line number Original line Diff line number Diff line
@@ -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)
	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)