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

Commit 154d0c81 authored by Manish Chopra's avatar Manish Chopra Committed by David S. Miller
Browse files

qlcnic: VLAN enhancement for 84XX adapters



o Support multiple VLANs on 84xx VF devices

Signed-off-by: default avatarManish Chopra <manish.chopra@qlogic.com>
Signed-off-by: default avatarSucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 80c0e4f3
Loading
Loading
Loading
Loading
+16 −2
Original line number Diff line number Diff line
@@ -788,9 +788,10 @@ struct qlcnic_cardrsp_tx_ctx {
#define QLCNIC_MAC_VLAN_ADD	3
#define QLCNIC_MAC_VLAN_DEL	4

struct qlcnic_mac_list_s {
struct qlcnic_mac_vlan_list {
	struct list_head list;
	uint8_t mac_addr[ETH_ALEN+2];
	u16 vlan_id;
};

/* MAC Learn */
@@ -1637,7 +1638,6 @@ int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
void qlcnic_set_netdev_features(struct qlcnic_adapter *,
				struct qlcnic_esw_func_cfg *);
void qlcnic_sriov_vf_schedule_multi(struct net_device *);
void qlcnic_vf_add_mc_list(struct net_device *, u16);

/*
 * QLOGIC Board information
@@ -2136,4 +2136,18 @@ static inline bool qlcnic_sriov_vf_check(struct qlcnic_adapter *adapter)

	return status;
}

static inline bool qlcnic_83xx_pf_check(struct qlcnic_adapter *adapter)
{
	unsigned short device = adapter->pdev->device;

	return (device == PCI_DEVICE_ID_QLOGIC_QLE834X) ? true : false;
}

static inline bool qlcnic_83xx_vf_check(struct qlcnic_adapter *adapter)
{
	unsigned short device = adapter->pdev->device;

	return (device == PCI_DEVICE_ID_QLOGIC_VF_QLE834X) ? true : false;
}
#endif				/* __QLCNIC_H_ */
+1 −1
Original line number Diff line number Diff line
@@ -1637,7 +1637,7 @@ int qlcnic_83xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)

	cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
	qlcnic_83xx_set_interface_id_promisc(adapter, &temp);
	cmd->req.arg[1] = (mode ? 1 : 0) | temp;
	cmd->req.arg[1] = mode | temp;
	err = qlcnic_issue_cmd(adapter, cmd);
	if (!err)
		return err;
+5 −0
Original line number Diff line number Diff line
@@ -324,6 +324,11 @@ struct qlc_83xx_idc {
	char		**name;
};

enum qlcnic_vlan_operations {
	QLC_VLAN_ADD = 0,
	QLC_VLAN_DELETE
};

/* Device States */
enum qlcnic_83xx_states {
	QLC_83XX_IDC_DEV_UNKNOWN,
+22 −26
Original line number Diff line number Diff line
@@ -455,13 +455,13 @@ int qlcnic_82xx_sre_macaddr_change(struct qlcnic_adapter *adapter, u8 *addr,

int qlcnic_nic_del_mac(struct qlcnic_adapter *adapter, const u8 *addr)
{
	struct qlcnic_mac_vlan_list *cur;
	struct list_head *head;
	struct qlcnic_mac_list_s *cur;
	int err = -EINVAL;

	/* Delete MAC from the existing list */
	list_for_each(head, &adapter->mac_list) {
		cur = list_entry(head, struct qlcnic_mac_list_s, list);
		cur = list_entry(head, struct qlcnic_mac_vlan_list, list);
		if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0) {
			err = qlcnic_sre_macaddr_change(adapter, cur->mac_addr,
							0, QLCNIC_MAC_DEL);
@@ -477,17 +477,18 @@ int qlcnic_nic_del_mac(struct qlcnic_adapter *adapter, const u8 *addr)

int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr, u16 vlan)
{
	struct qlcnic_mac_vlan_list *cur;
	struct list_head *head;
	struct qlcnic_mac_list_s *cur;

	/* look up if already exists */
	list_for_each(head, &adapter->mac_list) {
		cur = list_entry(head, struct qlcnic_mac_list_s, list);
		if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0)
		cur = list_entry(head, struct qlcnic_mac_vlan_list, list);
		if (memcmp(addr, cur->mac_addr, ETH_ALEN) == 0 &&
		    cur->vlan_id == vlan)
			return 0;
	}

	cur = kzalloc(sizeof(struct qlcnic_mac_list_s), GFP_ATOMIC);
	cur = kzalloc(sizeof(*cur), GFP_ATOMIC);
	if (cur == NULL)
		return -ENOMEM;

@@ -499,6 +500,7 @@ int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr, u16 vlan)
		return -EIO;
	}

	cur->vlan_id = vlan;
	list_add_tail(&cur->list, &adapter->mac_list);
	return 0;
}
@@ -516,7 +518,6 @@ void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
	if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
		return;

	if (!qlcnic_sriov_vf_check(adapter))
	qlcnic_nic_add_mac(adapter, adapter->mac_addr, vlan);
	qlcnic_nic_add_mac(adapter, bcast_addr, vlan);

@@ -526,15 +527,11 @@ void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
	} else if ((netdev->flags & IFF_ALLMULTI) ||
		   (netdev_mc_count(netdev) > ahw->max_mc_count)) {
		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
	} else if (!netdev_mc_empty(netdev) &&
		   !qlcnic_sriov_vf_check(adapter)) {
	} else if (!netdev_mc_empty(netdev)) {
		netdev_for_each_mc_addr(ha, netdev)
			qlcnic_nic_add_mac(adapter, ha->addr, vlan);
	}

	if (qlcnic_sriov_vf_check(adapter))
		qlcnic_vf_add_mc_list(netdev, vlan);

	/* configure unicast MAC address, if there is not sufficient space
	 * to store all the unicast addresses then enable promiscuous mode
	 */
@@ -545,14 +542,12 @@ void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
			qlcnic_nic_add_mac(adapter, ha->addr, vlan);
	}

	if (!qlcnic_sriov_vf_check(adapter)) {
	if (mode == VPORT_MISS_MODE_ACCEPT_ALL &&
	    !adapter->fdb_mac_learn) {
		qlcnic_alloc_lb_filters_mem(adapter);
			adapter->drv_mac_learn = true;
		adapter->drv_mac_learn = 1;
	} else {
			adapter->drv_mac_learn = false;
		}
		adapter->drv_mac_learn = 0;
	}

	qlcnic_nic_set_promisc(adapter, mode);
@@ -561,16 +556,17 @@ void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
void qlcnic_set_multi(struct net_device *netdev)
{
	struct qlcnic_adapter *adapter = netdev_priv(netdev);
	struct qlcnic_mac_vlan_list *cur;
	struct netdev_hw_addr *ha;
	struct qlcnic_mac_list_s *cur;
	size_t temp;

	if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
		return;
	if (qlcnic_sriov_vf_check(adapter)) {
		if (!netdev_mc_empty(netdev)) {
			netdev_for_each_mc_addr(ha, netdev) {
				cur = kzalloc(sizeof(struct qlcnic_mac_list_s),
					      GFP_ATOMIC);
				temp = sizeof(struct qlcnic_mac_vlan_list);
				cur = kzalloc(temp, GFP_ATOMIC);
				if (cur == NULL)
					break;
				memcpy(cur->mac_addr,
@@ -605,11 +601,11 @@ int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)

void qlcnic_82xx_free_mac_list(struct qlcnic_adapter *adapter)
{
	struct qlcnic_mac_list_s *cur;
	struct list_head *head = &adapter->mac_list;
	struct qlcnic_mac_vlan_list *cur;

	while (!list_empty(head)) {
		cur = list_entry(head->next, struct qlcnic_mac_list_s, list);
		cur = list_entry(head->next, struct qlcnic_mac_vlan_list, list);
		qlcnic_sre_macaddr_change(adapter,
				cur->mac_addr, 0, QLCNIC_MAC_DEL);
		list_del(&cur->list);
+2 −2
Original line number Diff line number Diff line
@@ -308,11 +308,11 @@ int qlcnic_read_mac_addr(struct qlcnic_adapter *adapter)

static void qlcnic_delete_adapter_mac(struct qlcnic_adapter *adapter)
{
	struct qlcnic_mac_list_s *cur;
	struct qlcnic_mac_vlan_list *cur;
	struct list_head *head;

	list_for_each(head, &adapter->mac_list) {
		cur = list_entry(head, struct qlcnic_mac_list_s, list);
		cur = list_entry(head, struct qlcnic_mac_vlan_list, list);
		if (!memcmp(adapter->mac_addr, cur->mac_addr, ETH_ALEN)) {
			qlcnic_sre_macaddr_change(adapter, cur->mac_addr,
						  0, QLCNIC_MAC_DEL);
Loading