Commit 139ce90a authored by David S. Miller's avatar David S. Miller

Merge branch 'hns3-promisc-next'

Salil Mehta says:

====================
Fixes & small enhancements related to the promisc mode in HNS3

This patch-set presents some fixes and enhancements related to promiscuous
mode and MAC VLAN Table full condition in HNS3 Ethernet Driver.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5886d932 829edbd8
...@@ -503,6 +503,15 @@ struct hnae3_unic_private_info { ...@@ -503,6 +503,15 @@ struct hnae3_unic_private_info {
#define HNAE3_SUPPORT_VF BIT(3) #define HNAE3_SUPPORT_VF BIT(3)
#define HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK BIT(4) #define HNAE3_SUPPORT_SERDES_PARALLEL_LOOPBACK BIT(4)
#define HNAE3_USER_UPE BIT(0) /* unicast promisc enabled by user */
#define HNAE3_USER_MPE BIT(1) /* mulitcast promisc enabled by user */
#define HNAE3_BPE BIT(2) /* broadcast promisc enable */
#define HNAE3_OVERFLOW_UPE BIT(3) /* unicast mac vlan overflow */
#define HNAE3_OVERFLOW_MPE BIT(4) /* multicast mac vlan overflow */
#define HNAE3_VLAN_FLTR BIT(5) /* enable vlan filter */
#define HNAE3_UPE (HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE)
#define HNAE3_MPE (HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE)
struct hnae3_handle { struct hnae3_handle {
struct hnae3_client *client; struct hnae3_client *client;
struct pci_dev *pdev; struct pci_dev *pdev;
...@@ -521,6 +530,8 @@ struct hnae3_handle { ...@@ -521,6 +530,8 @@ struct hnae3_handle {
}; };
u32 numa_node_mask; /* for multi-chip support */ u32 numa_node_mask; /* for multi-chip support */
u8 netdev_flags;
}; };
#define hnae3_set_field(origin, mask, shift, val) \ #define hnae3_set_field(origin, mask, shift, val) \
......
...@@ -459,23 +459,81 @@ static int hns3_nic_mc_unsync(struct net_device *netdev, ...@@ -459,23 +459,81 @@ static int hns3_nic_mc_unsync(struct net_device *netdev,
return 0; return 0;
} }
static u8 hns3_get_netdev_flags(struct net_device *netdev)
{
u8 flags = 0;
if (netdev->flags & IFF_PROMISC) {
flags = HNAE3_USER_UPE | HNAE3_USER_MPE;
} else {
flags |= HNAE3_VLAN_FLTR;
if (netdev->flags & IFF_ALLMULTI)
flags |= HNAE3_USER_MPE;
}
return flags;
}
static void hns3_nic_set_rx_mode(struct net_device *netdev) static void hns3_nic_set_rx_mode(struct net_device *netdev)
{ {
struct hnae3_handle *h = hns3_get_handle(netdev); struct hnae3_handle *h = hns3_get_handle(netdev);
u8 new_flags;
int ret;
if (h->ae_algo->ops->set_promisc_mode) { new_flags = hns3_get_netdev_flags(netdev);
if (netdev->flags & IFF_PROMISC)
h->ae_algo->ops->set_promisc_mode(h, true, true); ret = __dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync);
else if (netdev->flags & IFF_ALLMULTI) if (ret) {
h->ae_algo->ops->set_promisc_mode(h, false, true);
else
h->ae_algo->ops->set_promisc_mode(h, false, false);
}
if (__dev_uc_sync(netdev, hns3_nic_uc_sync, hns3_nic_uc_unsync))
netdev_err(netdev, "sync uc address fail\n"); netdev_err(netdev, "sync uc address fail\n");
if (ret == -ENOSPC)
new_flags |= HNAE3_OVERFLOW_UPE;
}
if (netdev->flags & IFF_MULTICAST) { if (netdev->flags & IFF_MULTICAST) {
if (__dev_mc_sync(netdev, hns3_nic_mc_sync, hns3_nic_mc_unsync)) ret = __dev_mc_sync(netdev, hns3_nic_mc_sync,
hns3_nic_mc_unsync);
if (ret) {
netdev_err(netdev, "sync mc address fail\n"); netdev_err(netdev, "sync mc address fail\n");
if (ret == -ENOSPC)
new_flags |= HNAE3_OVERFLOW_MPE;
}
}
hns3_update_promisc_mode(netdev, new_flags);
/* 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
*/
hns3_enable_vlan_filter(netdev, new_flags & HNAE3_VLAN_FLTR);
h->netdev_flags = new_flags;
}
void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = priv->ae_handle;
if (h->ae_algo->ops->set_promisc_mode) {
h->ae_algo->ops->set_promisc_mode(h,
promisc_flags & HNAE3_UPE,
promisc_flags & HNAE3_MPE);
}
}
void hns3_enable_vlan_filter(struct net_device *netdev, bool enable)
{
struct hns3_nic_priv *priv = netdev_priv(netdev);
struct hnae3_handle *h = priv->ae_handle;
bool last_state;
if (h->pdev->revision >= 0x21 && h->ae_algo->ops->enable_vlan_filter) {
last_state = h->netdev_flags & HNAE3_VLAN_FLTR ? true : false;
if (enable != last_state) {
netdev_info(netdev,
"%s vlan filter\n",
enable ? "enable" : "disable");
h->ae_algo->ops->enable_vlan_filter(h, enable);
}
} }
} }
...@@ -3607,11 +3665,15 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle) ...@@ -3607,11 +3665,15 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
{ {
struct net_device *netdev = handle->kinfo.netdev; struct net_device *netdev = handle->kinfo.netdev;
struct hns3_nic_priv *priv = netdev_priv(netdev); struct hns3_nic_priv *priv = netdev_priv(netdev);
bool vlan_filter_enable;
int ret; int ret;
hns3_init_mac_addr(netdev, false); hns3_init_mac_addr(netdev, false);
hns3_nic_set_rx_mode(netdev);
hns3_recover_hw_addr(netdev); hns3_recover_hw_addr(netdev);
hns3_update_promisc_mode(netdev, handle->netdev_flags);
vlan_filter_enable = netdev->flags & IFF_PROMISC ? false : true;
hns3_enable_vlan_filter(netdev, vlan_filter_enable);
/* Hardware table is only clear when pf resets */ /* Hardware table is only clear when pf resets */
if (!(handle->flags & HNAE3_SUPPORT_VF)) if (!(handle->flags & HNAE3_SUPPORT_VF))
......
...@@ -640,6 +640,9 @@ void hns3_set_vector_coalesce_tx_gl(struct hns3_enet_tqp_vector *tqp_vector, ...@@ -640,6 +640,9 @@ void hns3_set_vector_coalesce_tx_gl(struct hns3_enet_tqp_vector *tqp_vector,
void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector, void hns3_set_vector_coalesce_rl(struct hns3_enet_tqp_vector *tqp_vector,
u32 rl_value); u32 rl_value);
void hns3_enable_vlan_filter(struct net_device *netdev, bool enable);
void hns3_update_promisc_mode(struct net_device *netdev, u8 promisc_flags);
#ifdef CONFIG_HNS3_DCB #ifdef CONFIG_HNS3_DCB
void hns3_dcbnl_setup(struct hnae3_handle *handle); void hns3_dcbnl_setup(struct hnae3_handle *handle);
#else #else
......
...@@ -71,6 +71,7 @@ struct hns3_link_mode_mapping { ...@@ -71,6 +71,7 @@ struct hns3_link_mode_mapping {
static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en) static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
{ {
struct hnae3_handle *h = hns3_get_handle(ndev); struct hnae3_handle *h = hns3_get_handle(ndev);
bool vlan_filter_enable;
int ret; int ret;
if (!h->ae_algo->ops->set_loopback || if (!h->ae_algo->ops->set_loopback ||
...@@ -91,7 +92,14 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en) ...@@ -91,7 +92,14 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
if (ret) if (ret)
return ret; return ret;
h->ae_algo->ops->set_promisc_mode(h, en, en); if (en) {
h->ae_algo->ops->set_promisc_mode(h, true, true);
} else {
/* recover promisc mode before loopback test */
hns3_update_promisc_mode(ndev, h->netdev_flags);
vlan_filter_enable = ndev->flags & IFF_PROMISC ? false : true;
hns3_enable_vlan_filter(ndev, vlan_filter_enable);
}
return ret; return ret;
} }
......
...@@ -5606,6 +5606,10 @@ static void hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable) ...@@ -5606,6 +5606,10 @@ static void hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable)
hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
HCLGE_FILTER_FE_EGRESS_V1_B, enable); HCLGE_FILTER_FE_EGRESS_V1_B, enable);
} }
if (enable)
handle->netdev_flags |= HNAE3_VLAN_FLTR;
else
handle->netdev_flags &= ~HNAE3_VLAN_FLTR;
} }
static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid, static int hclge_set_vf_vlan_common(struct hclge_dev *hdev, int vfid,
...@@ -5902,7 +5906,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) ...@@ -5902,7 +5906,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
{ {
#define HCLGE_DEF_VLAN_TYPE 0x8100 #define HCLGE_DEF_VLAN_TYPE 0x8100
struct hnae3_handle *handle; struct hnae3_handle *handle = &hdev->vport[0].nic;
struct hclge_vport *vport; struct hclge_vport *vport;
int ret; int ret;
int i; int i;
...@@ -5925,6 +5929,8 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) ...@@ -5925,6 +5929,8 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
return ret; return ret;
} }
handle->netdev_flags |= HNAE3_VLAN_FLTR;
hdev->vlan_type_cfg.rx_in_fst_vlan_type = HCLGE_DEF_VLAN_TYPE; hdev->vlan_type_cfg.rx_in_fst_vlan_type = HCLGE_DEF_VLAN_TYPE;
hdev->vlan_type_cfg.rx_in_sec_vlan_type = HCLGE_DEF_VLAN_TYPE; hdev->vlan_type_cfg.rx_in_sec_vlan_type = HCLGE_DEF_VLAN_TYPE;
hdev->vlan_type_cfg.rx_ot_fst_vlan_type = HCLGE_DEF_VLAN_TYPE; hdev->vlan_type_cfg.rx_ot_fst_vlan_type = HCLGE_DEF_VLAN_TYPE;
...@@ -5969,7 +5975,6 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) ...@@ -5969,7 +5975,6 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
return ret; return ret;
} }
handle = &hdev->vport[0].nic;
return hclge_set_vlan_filter(handle, htons(ETH_P_8021Q), 0, false); return hclge_set_vlan_filter(handle, htons(ETH_P_8021Q), 0, false);
} }
......
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