Skip to content

Commit

Permalink
Merge branch 'hns3-promisc-next'
Browse files Browse the repository at this point in the history
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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Oct 12, 2018
2 parents 5886d93 + 829edbd commit 139ce90
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 14 deletions.
11 changes: 11 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hnae3.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,15 @@ struct hnae3_unic_private_info {
#define HNAE3_SUPPORT_VF BIT(3)
#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_client *client;
struct pci_dev *pdev;
Expand All @@ -521,6 +530,8 @@ struct hnae3_handle {
};

u32 numa_node_mask; /* for multi-chip support */

u8 netdev_flags;
};

#define hnae3_set_field(origin, mask, shift, val) \
Expand Down
84 changes: 73 additions & 11 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,23 +459,81 @@ static int hns3_nic_mc_unsync(struct net_device *netdev,
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)
{
struct hnae3_handle *h = hns3_get_handle(netdev);
u8 new_flags;
int ret;

if (h->ae_algo->ops->set_promisc_mode) {
if (netdev->flags & IFF_PROMISC)
h->ae_algo->ops->set_promisc_mode(h, true, true);
else if (netdev->flags & IFF_ALLMULTI)
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))
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) {
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");
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);
}
}
}

Expand Down Expand Up @@ -3607,11 +3665,15 @@ static int hns3_reset_notify_init_enet(struct hnae3_handle *handle)
{
struct net_device *netdev = handle->kinfo.netdev;
struct hns3_nic_priv *priv = netdev_priv(netdev);
bool vlan_filter_enable;
int ret;

hns3_init_mac_addr(netdev, false);
hns3_nic_set_rx_mode(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 */
if (!(handle->flags & HNAE3_SUPPORT_VF))
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/hisilicon/hns3/hns3_enet.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
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
void hns3_dcbnl_setup(struct hnae3_handle *handle);
#else
Expand Down
10 changes: 9 additions & 1 deletion drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ struct hns3_link_mode_mapping {
static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
{
struct hnae3_handle *h = hns3_get_handle(ndev);
bool vlan_filter_enable;
int ret;

if (!h->ae_algo->ops->set_loopback ||
Expand All @@ -91,7 +92,14 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
if (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;
}
Expand Down
9 changes: 7 additions & 2 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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_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,
Expand Down Expand Up @@ -5902,7 +5906,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
{
#define HCLGE_DEF_VLAN_TYPE 0x8100

struct hnae3_handle *handle;
struct hnae3_handle *handle = &hdev->vport[0].nic;
struct hclge_vport *vport;
int ret;
int i;
Expand All @@ -5925,6 +5929,8 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
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_sec_vlan_type = HCLGE_DEF_VLAN_TYPE;
hdev->vlan_type_cfg.rx_ot_fst_vlan_type = HCLGE_DEF_VLAN_TYPE;
Expand Down Expand Up @@ -5969,7 +5975,6 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
return ret;
}

handle = &hdev->vport[0].nic;
return hclge_set_vlan_filter(handle, htons(ETH_P_8021Q), 0, false);
}

Expand Down

0 comments on commit 139ce90

Please sign in to comment.