Commit 8b5d10e4 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'net-hns3-refactor-for-MAC-table'



Huazhong Tan says:

====================
net: hns3: refactor for MAC table

This patchset refactors the MAC table management, configure
the MAC address asynchronously, instead of synchronously.
Base on this change, it also refines the handle of promisc
mode and filter table entries restoring after reset.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d4833896 039ba863
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ enum HCLGE_MBX_OPCODE {
	HCLGE_MBX_GET_MEDIA_TYPE,       /* (VF -> PF) get media type */
	HCLGE_MBX_PUSH_PROMISC_INFO,	/* (PF -> VF) push vf promisc info */
	HCLGE_MBX_VF_UNINIT,            /* (VF -> PF) vf is unintializing */
	HCLGE_MBX_HANDLE_VF_TBL,	/* (VF -> PF) store/clear hw table */

	HCLGE_MBX_GET_VF_FLR_STATUS = 200, /* (M7 -> PF) get vf flr status */
	HCLGE_MBX_PUSH_LINK_STATUS,	/* (M7 -> PF) get port link status */
@@ -70,6 +71,10 @@ enum hclge_mbx_vlan_cfg_subcode {
	HCLGE_MBX_GET_PORT_BASE_VLAN_STATE,	/* get port based vlan state */
};

enum hclge_mbx_tbl_cfg_subcode {
	HCLGE_MBX_VPORT_LIST_CLEAR,
};

#define HCLGE_MBX_MAX_MSG_SIZE	14
#define HCLGE_MBX_MAX_RESP_DATA_SIZE	8U
#define HCLGE_MBX_MAX_RING_CHAIN_PARAM_NUM	4
+3 −5
Original line number Diff line number Diff line
@@ -233,7 +233,6 @@ struct hnae3_ae_dev {
	struct list_head node;
	u32 flag;
	unsigned long hw_err_reset_req;
	enum hnae3_reset_type reset_type;
	void *priv;
};

@@ -270,6 +269,8 @@ struct hnae3_ae_dev {
 *   Set loopback
 * set_promisc_mode
 *   Set promisc mode
 * request_update_promisc_mode
 *   request to hclge(vf) to update promisc mode
 * set_mtu()
 *   set mtu
 * get_pauseparam()
@@ -354,8 +355,6 @@ struct hnae3_ae_dev {
 *   Set vlan filter config of Ports
 * set_vf_vlan_filter()
 *   Set vlan filter config of vf
 * restore_vlan_table()
 *   Restore vlan filter entries after reset
 * enable_hw_strip_rxvtag()
 *   Enable/disable hardware strip vlan tag of packets received
 * set_gro_en
@@ -408,6 +407,7 @@ struct hnae3_ae_ops {

	int (*set_promisc_mode)(struct hnae3_handle *handle, bool en_uc_pmc,
				bool en_mc_pmc);
	void (*request_update_promisc_mode)(struct hnae3_handle *handle);
	int (*set_mtu)(struct hnae3_handle *handle, int new_mtu);

	void (*get_pauseparam)(struct hnae3_handle *handle,
@@ -525,7 +525,6 @@ struct hnae3_ae_ops {
				struct ethtool_rxnfc *cmd);
	int (*get_fd_all_rules)(struct hnae3_handle *handle,
				struct ethtool_rxnfc *cmd, u32 *rule_locs);
	int (*restore_fd_rules)(struct hnae3_handle *handle);
	void (*enable_fd)(struct hnae3_handle *handle, bool enable);
	int (*add_arfs_entry)(struct hnae3_handle *handle, u16 queue_id,
			      u16 flow_id, struct flow_keys *fkeys);
@@ -539,7 +538,6 @@ struct hnae3_ae_ops {
	void (*set_timer_task)(struct hnae3_handle *handle, bool enable);
	int (*mac_connect_phy)(struct hnae3_handle *handle);
	void (*mac_disconnect_phy)(struct hnae3_handle *handle);
	void (*restore_vlan_table)(struct hnae3_handle *handle);
	int (*get_vf_config)(struct hnae3_handle *handle, int vf,
			     struct ifla_vf_info *ivf);
	int (*set_vf_link_state)(struct hnae3_handle *handle, int vf,
+2 −0
Original line number Diff line number Diff line
@@ -262,6 +262,8 @@ static void hns3_dbg_help(struct hnae3_handle *h)
	dev_info(&h->pdev->dev, "dump mac tnl status\n");
	dev_info(&h->pdev->dev, "dump loopback\n");
	dev_info(&h->pdev->dev, "dump qs shaper [qs id]\n");
	dev_info(&h->pdev->dev, "dump uc mac list <func id>\n");
	dev_info(&h->pdev->dev, "dump mc mac list <func id>\n");

	memset(printf_buf, 0, HNS3_DBG_BUF_LEN);
	strncat(printf_buf, "dump reg [[bios common] [ssu <port_id>]",
+25 −127
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@
	} while (0)

static void hns3_clear_all_ring(struct hnae3_handle *h, bool force);
static void hns3_remove_hw_addr(struct net_device *netdev);

static const char hns3_driver_name[] = "hns3";
static const char hns3_driver_string[] =
@@ -548,6 +547,13 @@ static int hns3_nic_uc_unsync(struct net_device *netdev,
{
	struct hnae3_handle *h = hns3_get_handle(netdev);

	/* need ignore the request of removing device address, because
	 * we store the device address and other addresses of uc list
	 * in the function's mac filter list.
	 */
	if (ether_addr_equal(addr, netdev->dev_addr))
		return 0;

	if (h->ae_algo->ops->rm_uc_addr)
		return h->ae_algo->ops->rm_uc_addr(h, addr);

@@ -595,34 +601,25 @@ static void hns3_nic_set_rx_mode(struct net_device *netdev)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);
	u8 new_flags;
	int ret;

	new_flags = hns3_get_netdev_flags(netdev);

	ret = __dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync);
	if (ret) {
		netdev_err(netdev, "sync uc address fail\n");
		if (ret == -ENOSPC)
			new_flags |= HNAE3_OVERFLOW_UPE;
	}

	if (netdev->flags & IFF_MULTICAST) {
		ret = __dev_mc_sync(netdev, hns3_nic_mc_sync,
				    hns3_nic_mc_unsync);
		if (ret) {
			netdev_err(netdev, "sync mc address fail\n");
			if (ret == -ENOSPC)
				new_flags |= HNAE3_OVERFLOW_MPE;
		}
	}
	__dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync);
	__dev_mc_sync(netdev, hns3_nic_mc_sync, hns3_nic_mc_unsync);

	/* User mode Promisc mode enable and vlan filtering is disabled to
	 * let all packets in. MAC-VLAN Table overflow Promisc enabled and
	 * vlan fitering is enabled
	 * let all packets in.
	 */
	hns3_enable_vlan_filter(netdev, new_flags & HNAE3_VLAN_FLTR);
	h->netdev_flags = new_flags;
	hns3_update_promisc_mode(netdev, new_flags);
	hns3_request_update_promisc_mode(h);
}

void hns3_request_update_promisc_mode(struct hnae3_handle *handle)
{
	const struct hnae3_ae_ops *ops = handle->ae_algo->ops;

	if (ops->request_update_promisc_mode)
		ops->request_update_promisc_mode(handle);
}

int hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags)
@@ -2105,7 +2102,6 @@ static int hns3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)

	ae_dev->pdev = pdev;
	ae_dev->flag = ent->driver_data;
	ae_dev->reset_type = HNAE3_NONE_RESET;
	hns3_get_dev_capability(pdev, ae_dev);
	pci_set_drvdata(pdev, ae_dev);

@@ -3907,9 +3903,11 @@ static int hns3_init_mac_addr(struct net_device *netdev)
		eth_hw_addr_random(netdev);
		dev_warn(priv->dev, "using random MAC address %pM\n",
			 netdev->dev_addr);
	} else {
	} else if (!ether_addr_equal(netdev->dev_addr, mac_addr_temp)) {
		ether_addr_copy(netdev->dev_addr, mac_addr_temp);
		ether_addr_copy(netdev->perm_addr, mac_addr_temp);
	} else {
		return 0;
	}

	if (h->ae_algo->ops->set_mac_addr)
@@ -3937,17 +3935,6 @@ static void hns3_uninit_phy(struct net_device *netdev)
		h->ae_algo->ops->mac_disconnect_phy(h);
}

static int hns3_restore_fd_rules(struct net_device *netdev)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);
	int ret = 0;

	if (h->ae_algo->ops->restore_fd_rules)
		ret = h->ae_algo->ops->restore_fd_rules(h);

	return ret;
}

static void hns3_del_all_fd_rules(struct net_device *netdev, bool clear_list)
{
	struct hnae3_handle *h = hns3_get_handle(netdev);
@@ -4119,8 +4106,6 @@ static void hns3_client_uninit(struct hnae3_handle *handle, bool reset)
	struct hns3_nic_priv *priv = netdev_priv(netdev);
	int ret;

	hns3_remove_hw_addr(netdev);

	if (netdev->reg_state != NETREG_UNINITIALIZED)
		unregister_netdev(netdev);

@@ -4191,56 +4176,6 @@ static int hns3_client_setup_tc(struct hnae3_handle *handle, u8 tc)
	return hns3_nic_set_real_num_queue(ndev);
}

static int hns3_recover_hw_addr(struct net_device *ndev)
{
	struct netdev_hw_addr_list *list;
	struct netdev_hw_addr *ha, *tmp;
	int ret = 0;

	netif_addr_lock_bh(ndev);
	/* go through and sync uc_addr entries to the device */
	list = &ndev->uc;
	list_for_each_entry_safe(ha, tmp, &list->list, list) {
		ret = hns3_nic_uc_sync(ndev, ha->addr);
		if (ret)
			goto out;
	}

	/* go through and sync mc_addr entries to the device */
	list = &ndev->mc;
	list_for_each_entry_safe(ha, tmp, &list->list, list) {
		ret = hns3_nic_mc_sync(ndev, ha->addr);
		if (ret)
			goto out;
	}

out:
	netif_addr_unlock_bh(ndev);
	return ret;
}

static void hns3_remove_hw_addr(struct net_device *netdev)
{
	struct netdev_hw_addr_list *list;
	struct netdev_hw_addr *ha, *tmp;

	hns3_nic_uc_unsync(netdev, netdev->dev_addr);

	netif_addr_lock_bh(netdev);
	/* go through and unsync uc_addr entries to the device */
	list = &netdev->uc;
	list_for_each_entry_safe(ha, tmp, &list->list, list)
		hns3_nic_uc_unsync(netdev, ha->addr);

	/* go through and unsync mc_addr entries to the device */
	list = &netdev->mc;
	list_for_each_entry_safe(ha, tmp, &list->list, list)
		if (ha->refcount > 1)
			hns3_nic_mc_unsync(netdev, ha->addr);

	netif_addr_unlock_bh(netdev);
}

static void hns3_clear_tx_ring(struct hns3_enet_ring *ring)
{
	while (ring->next_to_clean != ring->next_to_use) {
@@ -4399,7 +4334,6 @@ static void hns3_restore_coal(struct hns3_nic_priv *priv)

static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
{
	struct hnae3_ae_dev *ae_dev = pci_get_drvdata(handle->pdev);
	struct hnae3_knic_private_info *kinfo = &handle->kinfo;
	struct net_device *ndev = kinfo->netdev;
	struct hns3_nic_priv *priv = netdev_priv(ndev);
@@ -4407,15 +4341,6 @@ static int hns3_reset_notify_down_enet(struct hnae3_handle *handle)
	if (test_and_set_bit(HNS3_NIC_STATE_RESETTING, &priv->state))
		return 0;

	/* it is cumbersome for hardware to pick-and-choose entries for deletion
	 * from table space. Hence, for function reset software intervention is
	 * required to delete the entries
	 */
	if (hns3_dev_ongoing_func_reset(ae_dev)) {
		hns3_remove_hw_addr(ndev);
		hns3_del_all_fd_rules(ndev, false);
	}

	if (!netif_running(ndev))
		return 0;

@@ -4482,6 +4407,9 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
		goto err_init_irq_fail;
	}

	if (!hns3_is_phys_func(handle->pdev))
		hns3_init_mac_addr(netdev);

	ret = hns3_client_start(handle);
	if (ret) {
		dev_err(priv->dev, "hns3_client_start fail! ret=%d\n", ret);
@@ -4507,33 +4435,6 @@ err_put_ring:
	return ret;
}

static int hns3_reset_notify_restore_enet(struct hnae3_handle *handle)
{
	struct net_device *netdev = handle->kinfo.netdev;
	bool vlan_filter_enable;
	int ret;

	ret = hns3_init_mac_addr(netdev);
	if (ret)
		return ret;

	ret = hns3_recover_hw_addr(netdev);
	if (ret)
		return ret;

	ret = hns3_update_promisc_mode(netdev, handle->netdev_flags);
	if (ret)
		return ret;

	vlan_filter_enable = netdev->flags & IFF_PROMISC ? false : true;
	hns3_enable_vlan_filter(netdev, vlan_filter_enable);

	if (handle->ae_algo->ops->restore_vlan_table)
		handle->ae_algo->ops->restore_vlan_table(handle);

	return hns3_restore_fd_rules(netdev);
}

static int hns3_reset_notify_uninit_enet(struct hnae3_handle *handle)
{
	struct net_device *netdev = handle->kinfo.netdev;
@@ -4583,9 +4484,6 @@ static int hns3_reset_notify(struct hnae3_handle *handle,
	case HNAE3_UNINIT_CLIENT:
		ret = hns3_reset_notify_uninit_enet(handle);
		break;
	case HNAE3_RESTORE_CLIENT:
		ret = hns3_reset_notify_restore_enet(handle);
		break;
	default:
		break;
	}
+1 −9
Original line number Diff line number Diff line
@@ -576,15 +576,6 @@ static inline void hns3_write_reg(void __iomem *base, u32 reg, u32 value)
	writel(value, reg_addr + reg);
}

static inline bool hns3_dev_ongoing_func_reset(struct hnae3_ae_dev *ae_dev)
{
	return (ae_dev && (ae_dev->reset_type == HNAE3_FUNC_RESET ||
			   ae_dev->reset_type == HNAE3_FLR_RESET ||
			   ae_dev->reset_type == HNAE3_VF_FUNC_RESET ||
			   ae_dev->reset_type == HNAE3_VF_FULL_RESET ||
			   ae_dev->reset_type == HNAE3_VF_PF_FUNC_RESET));
}

#define hns3_read_dev(a, reg) \
	hns3_read_reg((a)->io_base, (reg))

@@ -658,6 +649,7 @@ void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,

void hns3_enable_vlan_filter(struct net_device *netdev, bool enable);
int hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags);
void hns3_request_update_promisc_mode(struct hnae3_handle *handle);

#ifdef CONFIG_HNS3_DCB
void hns3_dcbnl_setup(struct hnae3_handle *handle);
Loading