Commit 7fc6d3ab authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'net-hns3-add-vlan-filter-control-support'

Huazhong Tan says:

====================
net: hns3: add VLAN filter control support

This patchset add VLAN filter control support for HNS3 driver.
====================

Link: https://lore.kernel.org/r/1622428725-30049-1-git-send-email-tanhuazhong@huawei.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 0c2c366e 0ca821da
...@@ -20,7 +20,7 @@ enum HCLGE_MBX_OPCODE { ...@@ -20,7 +20,7 @@ enum HCLGE_MBX_OPCODE {
HCLGE_MBX_API_NEGOTIATE, /* (VF -> PF) negotiate API version */ HCLGE_MBX_API_NEGOTIATE, /* (VF -> PF) negotiate API version */
HCLGE_MBX_GET_QINFO, /* (VF -> PF) get queue config */ HCLGE_MBX_GET_QINFO, /* (VF -> PF) get queue config */
HCLGE_MBX_GET_QDEPTH, /* (VF -> PF) get queue depth */ HCLGE_MBX_GET_QDEPTH, /* (VF -> PF) get queue depth */
HCLGE_MBX_GET_TCINFO, /* (VF -> PF) get TC config */ HCLGE_MBX_GET_BASIC_INFO, /* (VF -> PF) get basic info */
HCLGE_MBX_GET_RETA, /* (VF -> PF) get RETA */ HCLGE_MBX_GET_RETA, /* (VF -> PF) get RETA */
HCLGE_MBX_GET_RSS_KEY, /* (VF -> PF) get RSS key */ HCLGE_MBX_GET_RSS_KEY, /* (VF -> PF) get RSS key */
HCLGE_MBX_GET_MAC_ADDR, /* (VF -> PF) get MAC addr */ HCLGE_MBX_GET_MAC_ADDR, /* (VF -> PF) get MAC addr */
...@@ -69,6 +69,7 @@ enum hclge_mbx_vlan_cfg_subcode { ...@@ -69,6 +69,7 @@ enum hclge_mbx_vlan_cfg_subcode {
HCLGE_MBX_VLAN_RX_OFF_CFG, /* set rx side vlan offload */ HCLGE_MBX_VLAN_RX_OFF_CFG, /* set rx side vlan offload */
HCLGE_MBX_PORT_BASE_VLAN_CFG, /* set port based vlan configuration */ HCLGE_MBX_PORT_BASE_VLAN_CFG, /* set port based vlan configuration */
HCLGE_MBX_GET_PORT_BASE_VLAN_STATE, /* get port based vlan state */ HCLGE_MBX_GET_PORT_BASE_VLAN_STATE, /* get port based vlan state */
HCLGE_MBX_ENABLE_VLAN_FILTER,
}; };
enum hclge_mbx_tbl_cfg_subcode { enum hclge_mbx_tbl_cfg_subcode {
...@@ -85,6 +86,13 @@ struct hclge_ring_chain_param { ...@@ -85,6 +86,13 @@ struct hclge_ring_chain_param {
u8 int_gl_index; u8 int_gl_index;
}; };
struct hclge_basic_info {
u8 hw_tc_map;
u8 rsv;
u16 mbx_api_version;
u32 pf_caps;
};
struct hclgevf_mbx_resp_status { struct hclgevf_mbx_resp_status {
struct mutex mbx_mutex; /* protects against contending sync cmd resp */ struct mutex mbx_mutex; /* protects against contending sync cmd resp */
u32 origin_mbx_msg; u32 origin_mbx_msg;
......
...@@ -92,6 +92,8 @@ enum HNAE3_DEV_CAP_BITS { ...@@ -92,6 +92,8 @@ enum HNAE3_DEV_CAP_BITS {
HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B, HNAE3_DEV_SUPPORT_UDP_TUNNEL_CSUM_B,
HNAE3_DEV_SUPPORT_PAUSE_B, HNAE3_DEV_SUPPORT_PAUSE_B,
HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B,
HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B,
HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B,
}; };
#define hnae3_dev_fd_supported(hdev) \ #define hnae3_dev_fd_supported(hdev) \
...@@ -145,6 +147,9 @@ enum HNAE3_DEV_CAP_BITS { ...@@ -145,6 +147,9 @@ enum HNAE3_DEV_CAP_BITS {
#define hnae3_ae_dev_rxd_adv_layout_supported(ae_dev) \ #define hnae3_ae_dev_rxd_adv_layout_supported(ae_dev) \
test_bit(HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, (ae_dev)->caps) test_bit(HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, (ae_dev)->caps)
enum HNAE3_PF_CAP_BITS {
HNAE3_PF_SUPPORT_VLAN_FLTR_MDF_B = 0,
};
#define ring_ptr_move_fw(ring, p) \ #define ring_ptr_move_fw(ring, p) \
((ring)->p = ((ring)->p + 1) % (ring)->desc_num) ((ring)->p = ((ring)->p + 1) % (ring)->desc_num)
#define ring_ptr_move_bw(ring, p) \ #define ring_ptr_move_bw(ring, p) \
...@@ -283,6 +288,7 @@ enum hnae3_dbg_cmd { ...@@ -283,6 +288,7 @@ enum hnae3_dbg_cmd {
HNAE3_DBG_CMD_REG_TQP, HNAE3_DBG_CMD_REG_TQP,
HNAE3_DBG_CMD_REG_MAC, HNAE3_DBG_CMD_REG_MAC,
HNAE3_DBG_CMD_REG_DCB, HNAE3_DBG_CMD_REG_DCB,
HNAE3_DBG_CMD_VLAN_CONFIG,
HNAE3_DBG_CMD_QUEUE_MAP, HNAE3_DBG_CMD_QUEUE_MAP,
HNAE3_DBG_CMD_RX_QUEUE_INFO, HNAE3_DBG_CMD_RX_QUEUE_INFO,
HNAE3_DBG_CMD_TX_QUEUE_INFO, HNAE3_DBG_CMD_TX_QUEUE_INFO,
...@@ -631,7 +637,7 @@ struct hnae3_ae_ops { ...@@ -631,7 +637,7 @@ struct hnae3_ae_ops {
void (*get_mdix_mode)(struct hnae3_handle *handle, void (*get_mdix_mode)(struct hnae3_handle *handle,
u8 *tp_mdix_ctrl, u8 *tp_mdix); u8 *tp_mdix_ctrl, u8 *tp_mdix);
void (*enable_vlan_filter)(struct hnae3_handle *handle, bool enable); int (*enable_vlan_filter)(struct hnae3_handle *handle, bool enable);
int (*set_vlan_filter)(struct hnae3_handle *handle, __be16 proto, int (*set_vlan_filter)(struct hnae3_handle *handle, __be16 proto,
u16 vlan_id, bool is_kill); u16 vlan_id, bool is_kill);
int (*set_vf_vlan_filter)(struct hnae3_handle *handle, int vfid, int (*set_vf_vlan_filter)(struct hnae3_handle *handle, int vfid,
...@@ -783,7 +789,6 @@ struct hnae3_roce_private_info { ...@@ -783,7 +789,6 @@ struct hnae3_roce_private_info {
#define HNAE3_BPE BIT(2) /* broadcast promisc enable */ #define HNAE3_BPE BIT(2) /* broadcast promisc enable */
#define HNAE3_OVERFLOW_UPE BIT(3) /* unicast mac vlan overflow */ #define HNAE3_OVERFLOW_UPE BIT(3) /* unicast mac vlan overflow */
#define HNAE3_OVERFLOW_MPE BIT(4) /* multicast 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_UPE (HNAE3_USER_UPE | HNAE3_OVERFLOW_UPE)
#define HNAE3_MPE (HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE) #define HNAE3_MPE (HNAE3_USER_MPE | HNAE3_OVERFLOW_MPE)
......
...@@ -309,6 +309,13 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = { ...@@ -309,6 +309,13 @@ static struct hns3_dbg_cmd_info hns3_dbg_cmd[] = {
.buf_len = HNS3_DBG_READ_LEN, .buf_len = HNS3_DBG_READ_LEN,
.init = hns3_dbg_common_file_init, .init = hns3_dbg_common_file_init,
}, },
{
.name = "vlan_config",
.cmd = HNAE3_DBG_CMD_VLAN_CONFIG,
.dentry = HNS3_DBG_DENTRY_COMMON,
.buf_len = HNS3_DBG_READ_LEN,
.init = hns3_dbg_common_file_init,
},
}; };
static struct hns3_dbg_cap_info hns3_dbg_cap[] = { static struct hns3_dbg_cap_info hns3_dbg_cap[] = {
...@@ -345,7 +352,13 @@ static struct hns3_dbg_cap_info hns3_dbg_cap[] = { ...@@ -345,7 +352,13 @@ static struct hns3_dbg_cap_info hns3_dbg_cap[] = {
}, { }, {
.name = "support rxd advanced layout", .name = "support rxd advanced layout",
.cap_bit = HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, .cap_bit = HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B,
}, }, {
.name = "support port vlan bypass",
.cap_bit = HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B,
}, {
.name = "support modify vlan filter state",
.cap_bit = HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B,
}
}; };
static void hns3_dbg_fill_content(char *content, u16 len, static void hns3_dbg_fill_content(char *content, u16 len,
......
...@@ -908,13 +908,10 @@ static u8 hns3_get_netdev_flags(struct net_device *netdev) ...@@ -908,13 +908,10 @@ static u8 hns3_get_netdev_flags(struct net_device *netdev)
{ {
u8 flags = 0; u8 flags = 0;
if (netdev->flags & IFF_PROMISC) { if (netdev->flags & IFF_PROMISC)
flags = HNAE3_USER_UPE | HNAE3_USER_MPE | HNAE3_BPE; flags = HNAE3_USER_UPE | HNAE3_USER_MPE | HNAE3_BPE;
} else { else if (netdev->flags & IFF_ALLMULTI)
flags |= HNAE3_VLAN_FLTR; flags = HNAE3_USER_MPE;
if (netdev->flags & IFF_ALLMULTI)
flags |= HNAE3_USER_MPE;
}
return flags; return flags;
} }
...@@ -944,25 +941,6 @@ void hns3_request_update_promisc_mode(struct hnae3_handle *handle) ...@@ -944,25 +941,6 @@ void hns3_request_update_promisc_mode(struct hnae3_handle *handle)
ops->request_update_promisc_mode(handle); ops->request_update_promisc_mode(handle);
} }
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;
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
bool last_state;
if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2 &&
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);
}
}
}
static int hns3_set_tso(struct sk_buff *skb, u32 *paylen_fdop_ol4cs, static int hns3_set_tso(struct sk_buff *skb, u32 *paylen_fdop_ol4cs,
u16 *mss, u32 *type_cs_vlan_tso, u32 *send_bytes) u16 *mss, u32 *type_cs_vlan_tso, u32 *send_bytes)
{ {
...@@ -1980,6 +1958,14 @@ static int hns3_nic_set_features(struct net_device *netdev, ...@@ -1980,6 +1958,14 @@ static int hns3_nic_set_features(struct net_device *netdev,
return -EINVAL; return -EINVAL;
} }
if ((changed & NETIF_F_HW_VLAN_CTAG_FILTER) &&
h->ae_algo->ops->enable_vlan_filter) {
enable = !!(features & NETIF_F_HW_VLAN_CTAG_FILTER);
ret = h->ae_algo->ops->enable_vlan_filter(h, enable);
if (ret)
return ret;
}
netdev->features = features; netdev->features = features;
return 0; return 0;
} }
...@@ -2825,6 +2811,9 @@ static void hns3_set_default_feature(struct net_device *netdev) ...@@ -2825,6 +2811,9 @@ static void hns3_set_default_feature(struct net_device *netdev)
netdev->hw_features |= NETIF_F_HW_TC; netdev->hw_features |= NETIF_F_HW_TC;
netdev->features |= NETIF_F_HW_TC; netdev->features |= NETIF_F_HW_TC;
} }
if (test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps))
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
} }
static int hns3_alloc_buffer(struct hns3_enet_ring *ring, static int hns3_alloc_buffer(struct hns3_enet_ring *ring,
......
...@@ -643,7 +643,6 @@ void hns3_set_vector_coalesce_rx_ql(struct hns3_enet_tqp_vector *tqp_vector, ...@@ -643,7 +643,6 @@ void hns3_set_vector_coalesce_rx_ql(struct hns3_enet_tqp_vector *tqp_vector,
void hns3_set_vector_coalesce_tx_ql(struct hns3_enet_tqp_vector *tqp_vector, void hns3_set_vector_coalesce_tx_ql(struct hns3_enet_tqp_vector *tqp_vector,
u32 ql_value); u32 ql_value);
void hns3_enable_vlan_filter(struct net_device *netdev, bool enable);
void hns3_request_update_promisc_mode(struct hnae3_handle *handle); void hns3_request_update_promisc_mode(struct hnae3_handle *handle);
#ifdef CONFIG_HNS3_DCB #ifdef CONFIG_HNS3_DCB
......
...@@ -88,7 +88,6 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en) ...@@ -88,7 +88,6 @@ 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);
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev); struct hnae3_ae_dev *ae_dev = pci_get_drvdata(h->pdev);
bool vlan_filter_enable;
int ret; int ret;
if (!h->ae_algo->ops->set_loopback || if (!h->ae_algo->ops->set_loopback ||
...@@ -110,14 +109,11 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en) ...@@ -110,14 +109,11 @@ static int hns3_lp_setup(struct net_device *ndev, enum hnae3_loop loop, bool en)
if (ret || ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) if (ret || ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2)
return ret; return ret;
if (en) { if (en)
h->ae_algo->ops->set_promisc_mode(h, true, true); h->ae_algo->ops->set_promisc_mode(h, true, true);
} else { else
/* recover promisc mode before loopback test */ /* recover promisc mode before loopback test */
hns3_request_update_promisc_mode(h); hns3_request_update_promisc_mode(h);
vlan_filter_enable = ndev->flags & IFF_PROMISC ? false : true;
hns3_enable_vlan_filter(ndev, vlan_filter_enable);
}
return ret; return ret;
} }
......
...@@ -388,6 +388,10 @@ static void hclge_parse_capability(struct hclge_dev *hdev, ...@@ -388,6 +388,10 @@ static void hclge_parse_capability(struct hclge_dev *hdev,
set_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps); set_bit(HNAE3_DEV_SUPPORT_PHY_IMP_B, ae_dev->caps);
if (hnae3_get_bit(caps, HCLGE_CAP_RXD_ADV_LAYOUT_B)) if (hnae3_get_bit(caps, HCLGE_CAP_RXD_ADV_LAYOUT_B))
set_bit(HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, ae_dev->caps); set_bit(HNAE3_DEV_SUPPORT_RXD_ADV_LAYOUT_B, ae_dev->caps);
if (hnae3_get_bit(caps, HCLGE_CAP_PORT_VLAN_BYPASS_B)) {
set_bit(HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B, ae_dev->caps);
set_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps);
}
} }
static __le32 hclge_build_api_caps(void) static __le32 hclge_build_api_caps(void)
......
...@@ -236,6 +236,7 @@ enum hclge_opcode_type { ...@@ -236,6 +236,7 @@ enum hclge_opcode_type {
HCLGE_OPC_VLAN_FILTER_CTRL = 0x1100, HCLGE_OPC_VLAN_FILTER_CTRL = 0x1100,
HCLGE_OPC_VLAN_FILTER_PF_CFG = 0x1101, HCLGE_OPC_VLAN_FILTER_PF_CFG = 0x1101,
HCLGE_OPC_VLAN_FILTER_VF_CFG = 0x1102, HCLGE_OPC_VLAN_FILTER_VF_CFG = 0x1102,
HCLGE_OPC_PORT_VLAN_BYPASS = 0x1103,
/* Flow Director commands */ /* Flow Director commands */
HCLGE_OPC_FD_MODE_CTRL = 0x1200, HCLGE_OPC_FD_MODE_CTRL = 0x1200,
...@@ -392,6 +393,7 @@ enum HCLGE_CAP_BITS { ...@@ -392,6 +393,7 @@ enum HCLGE_CAP_BITS {
HCLGE_CAP_FEC_B = 13, HCLGE_CAP_FEC_B = 13,
HCLGE_CAP_PAUSE_B = 14, HCLGE_CAP_PAUSE_B = 14,
HCLGE_CAP_RXD_ADV_LAYOUT_B = 15, HCLGE_CAP_RXD_ADV_LAYOUT_B = 15,
HCLGE_CAP_PORT_VLAN_BYPASS_B = 17,
}; };
enum HCLGE_API_CAP_BITS { enum HCLGE_API_CAP_BITS {
...@@ -527,6 +529,8 @@ struct hclge_pf_res_cmd { ...@@ -527,6 +529,8 @@ struct hclge_pf_res_cmd {
#define HCLGE_CFG_SPEED_ABILITY_M GENMASK(7, 0) #define HCLGE_CFG_SPEED_ABILITY_M GENMASK(7, 0)
#define HCLGE_CFG_SPEED_ABILITY_EXT_S 10 #define HCLGE_CFG_SPEED_ABILITY_EXT_S 10
#define HCLGE_CFG_SPEED_ABILITY_EXT_M GENMASK(15, 10) #define HCLGE_CFG_SPEED_ABILITY_EXT_M GENMASK(15, 10)
#define HCLGE_CFG_VLAN_FLTR_CAP_S 8
#define HCLGE_CFG_VLAN_FLTR_CAP_M GENMASK(9, 8)
#define HCLGE_CFG_UMV_TBL_SPACE_S 16 #define HCLGE_CFG_UMV_TBL_SPACE_S 16
#define HCLGE_CFG_UMV_TBL_SPACE_M GENMASK(31, 16) #define HCLGE_CFG_UMV_TBL_SPACE_M GENMASK(31, 16)
#define HCLGE_CFG_PF_RSS_SIZE_S 0 #define HCLGE_CFG_PF_RSS_SIZE_S 0
...@@ -811,6 +815,14 @@ struct hclge_vlan_filter_vf_cfg_cmd { ...@@ -811,6 +815,14 @@ struct hclge_vlan_filter_vf_cfg_cmd {
u8 vf_bitmap[HCLGE_MAX_VF_BYTES]; u8 vf_bitmap[HCLGE_MAX_VF_BYTES];
}; };
#define HCLGE_INGRESS_BYPASS_B 0
struct hclge_port_vlan_filter_bypass_cmd {
u8 bypass_state;
u8 rsv1[3];
u8 vf_id;
u8 rsv2[19];
};
#define HCLGE_SWITCH_ANTI_SPOOF_B 0U #define HCLGE_SWITCH_ANTI_SPOOF_B 0U
#define HCLGE_SWITCH_ALW_LPBK_B 1U #define HCLGE_SWITCH_ALW_LPBK_B 1U
#define HCLGE_SWITCH_ALW_LCL_LPBK_B 2U #define HCLGE_SWITCH_ALW_LCL_LPBK_B 2U
......
...@@ -1894,6 +1894,285 @@ static void hclge_dbg_dump_mac_list(struct hclge_dev *hdev, char *buf, int len, ...@@ -1894,6 +1894,285 @@ static void hclge_dbg_dump_mac_list(struct hclge_dev *hdev, char *buf, int len,
} }
} }
static int hclge_get_vlan_rx_offload_cfg(struct hclge_dev *hdev, u8 vf_id,
struct hclge_dbg_vlan_cfg *vlan_cfg)
{
struct hclge_vport_vtag_rx_cfg_cmd *req;
struct hclge_desc desc;
u16 bmap_index;
u8 rx_cfg;
int ret;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_PORT_RX_CFG, true);
req = (struct hclge_vport_vtag_rx_cfg_cmd *)desc.data;
req->vf_offset = vf_id / HCLGE_VF_NUM_PER_CMD;
bmap_index = vf_id % HCLGE_VF_NUM_PER_CMD / HCLGE_VF_NUM_PER_BYTE;
req->vf_bitmap[bmap_index] = 1U << (vf_id % HCLGE_VF_NUM_PER_BYTE);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
dev_err(&hdev->pdev->dev,
"failed to get vport%u rxvlan cfg, ret = %d\n",
vf_id, ret);
return ret;
}
rx_cfg = req->vport_vlan_cfg;
vlan_cfg->strip_tag1 = hnae3_get_bit(rx_cfg, HCLGE_REM_TAG1_EN_B);
vlan_cfg->strip_tag2 = hnae3_get_bit(rx_cfg, HCLGE_REM_TAG2_EN_B);
vlan_cfg->drop_tag1 = hnae3_get_bit(rx_cfg, HCLGE_DISCARD_TAG1_EN_B);
vlan_cfg->drop_tag2 = hnae3_get_bit(rx_cfg, HCLGE_DISCARD_TAG2_EN_B);
vlan_cfg->pri_only1 = hnae3_get_bit(rx_cfg, HCLGE_SHOW_TAG1_EN_B);
vlan_cfg->pri_only2 = hnae3_get_bit(rx_cfg, HCLGE_SHOW_TAG2_EN_B);
return 0;
}
static int hclge_get_vlan_tx_offload_cfg(struct hclge_dev *hdev, u8 vf_id,
struct hclge_dbg_vlan_cfg *vlan_cfg)
{
struct hclge_vport_vtag_tx_cfg_cmd *req;
struct hclge_desc desc;
u16 bmap_index;
u8 tx_cfg;
int ret;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_PORT_TX_CFG, true);
req = (struct hclge_vport_vtag_tx_cfg_cmd *)desc.data;
req->vf_offset = vf_id / HCLGE_VF_NUM_PER_CMD;
bmap_index = vf_id % HCLGE_VF_NUM_PER_CMD / HCLGE_VF_NUM_PER_BYTE;
req->vf_bitmap[bmap_index] = 1U << (vf_id % HCLGE_VF_NUM_PER_BYTE);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
dev_err(&hdev->pdev->dev,
"failed to get vport%u txvlan cfg, ret = %d\n",
vf_id, ret);
return ret;
}
tx_cfg = req->vport_vlan_cfg;
vlan_cfg->pvid = le16_to_cpu(req->def_vlan_tag1);
vlan_cfg->accept_tag1 = hnae3_get_bit(tx_cfg, HCLGE_ACCEPT_TAG1_B);
vlan_cfg->accept_tag2 = hnae3_get_bit(tx_cfg, HCLGE_ACCEPT_TAG2_B);
vlan_cfg->accept_untag1 = hnae3_get_bit(tx_cfg, HCLGE_ACCEPT_UNTAG1_B);
vlan_cfg->accept_untag2 = hnae3_get_bit(tx_cfg, HCLGE_ACCEPT_UNTAG2_B);
vlan_cfg->insert_tag1 = hnae3_get_bit(tx_cfg, HCLGE_PORT_INS_TAG1_EN_B);
vlan_cfg->insert_tag2 = hnae3_get_bit(tx_cfg, HCLGE_PORT_INS_TAG2_EN_B);
vlan_cfg->shift_tag = hnae3_get_bit(tx_cfg, HCLGE_TAG_SHIFT_MODE_EN_B);
return 0;
}
static int hclge_get_vlan_filter_config_cmd(struct hclge_dev *hdev,
u8 vlan_type, u8 vf_id,
struct hclge_desc *desc)
{
struct hclge_vlan_filter_ctrl_cmd *req;
int ret;
hclge_cmd_setup_basic_desc(desc, HCLGE_OPC_VLAN_FILTER_CTRL, true);
req = (struct hclge_vlan_filter_ctrl_cmd *)desc->data;
req->vlan_type = vlan_type;
req->vf_id = vf_id;
ret = hclge_cmd_send(&hdev->hw, desc, 1);
if (ret)
dev_err(&hdev->pdev->dev,
"failed to get vport%u vlan filter config, ret = %d.\n",
vf_id, ret);
return ret;
}
static int hclge_get_vlan_filter_state(struct hclge_dev *hdev, u8 vlan_type,
u8 vf_id, u8 *vlan_fe)
{
struct hclge_vlan_filter_ctrl_cmd *req;
struct hclge_desc desc;
int ret;
ret = hclge_get_vlan_filter_config_cmd(hdev, vlan_type, vf_id, &desc);
if (ret)
return ret;
req = (struct hclge_vlan_filter_ctrl_cmd *)desc.data;
*vlan_fe = req->vlan_fe;
return 0;
}
static int hclge_get_port_vlan_filter_bypass_state(struct hclge_dev *hdev,
u8 vf_id, u8 *bypass_en)
{
struct hclge_port_vlan_filter_bypass_cmd *req;
struct hclge_desc desc;
int ret;
if (!test_bit(HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B, hdev->ae_dev->caps))
return 0;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PORT_VLAN_BYPASS, true);
req = (struct hclge_port_vlan_filter_bypass_cmd *)desc.data;
req->vf_id = vf_id;
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret) {
dev_err(&hdev->pdev->dev,
"failed to get vport%u port vlan filter bypass state, ret = %d.\n",
vf_id, ret);
return ret;
}
*bypass_en = hnae3_get_bit(req->bypass_state, HCLGE_INGRESS_BYPASS_B);
return 0;
}
static const struct hclge_dbg_item vlan_filter_items[] = {
{ "FUNC_ID", 2 },
{ "I_VF_VLAN_FILTER", 2 },
{ "E_VF_VLAN_FILTER", 2 },
{ "PORT_VLAN_FILTER_BYPASS", 0 }
};
static const struct hclge_dbg_item vlan_offload_items[] = {
{ "FUNC_ID", 2 },
{ "PVID", 4 },
{ "ACCEPT_TAG1", 2 },
{ "ACCEPT_TAG2", 2 },
{ "ACCEPT_UNTAG1", 2 },
{ "ACCEPT_UNTAG2", 2 },
{ "INSERT_TAG1", 2 },
{ "INSERT_TAG2", 2 },
{ "SHIFT_TAG", 2 },
{ "STRIP_TAG1", 2 },
{ "STRIP_TAG2", 2 },
{ "DROP_TAG1", 2 },
{ "DROP_TAG2", 2 },
{ "PRI_ONLY_TAG1", 2 },
{ "PRI_ONLY_TAG2", 0 }
};
static int hclge_dbg_dump_vlan_filter_config(struct hclge_dev *hdev, char *buf,
int len, int *pos)
{
char content[HCLGE_DBG_VLAN_FLTR_INFO_LEN], str_id[HCLGE_DBG_ID_LEN];
const char *result[ARRAY_SIZE(vlan_filter_items)];
u8 i, j, vlan_fe, bypass, ingress, egress;
u8 func_num = pci_num_vf(hdev->pdev) + 1; /* pf and enabled vf num */
int ret;
ret = hclge_get_vlan_filter_state(hdev, HCLGE_FILTER_TYPE_PORT, 0,
&vlan_fe);
if (ret)
return ret;
ingress = vlan_fe & HCLGE_FILTER_FE_NIC_INGRESS_B;
egress = vlan_fe & HCLGE_FILTER_FE_NIC_EGRESS_B ? 1 : 0;
*pos += scnprintf(buf, len, "I_PORT_VLAN_FILTER: %s\n",
state_str[ingress]);
*pos += scnprintf(buf + *pos, len - *pos, "E_PORT_VLAN_FILTER: %s\n",
state_str[egress]);
hclge_dbg_fill_content(content, sizeof(content), vlan_filter_items,
NULL, ARRAY_SIZE(vlan_filter_items));
*pos += scnprintf(buf + *pos, len - *pos, "%s", content);
for (i = 0; i < func_num; i++) {
ret = hclge_get_vlan_filter_state(hdev, HCLGE_FILTER_TYPE_VF, i,
&vlan_fe);
if (ret)
return ret;
ingress = vlan_fe & HCLGE_FILTER_FE_NIC_INGRESS_B;
egress = vlan_fe & HCLGE_FILTER_FE_NIC_EGRESS_B ? 1 : 0;
ret = hclge_get_port_vlan_filter_bypass_state(hdev, i, &bypass);
if (ret)
return ret;
j = 0;
result[j++] = hclge_dbg_get_func_id_str(str_id, i);
result[j++] = state_str[ingress];
result[j++] = state_str[egress];
result[j++] =
test_bit(HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B,
hdev->ae_dev->caps) ? state_str[bypass] : "NA";
hclge_dbg_fill_content(content, sizeof(content),
vlan_filter_items, result,
ARRAY_SIZE(vlan_filter_items));
*pos += scnprintf(buf + *pos, len - *pos, "%s", content);
}
*pos += scnprintf(buf + *pos, len - *pos, "\n");
return 0;
}
static int hclge_dbg_dump_vlan_offload_config(struct hclge_dev *hdev, char *buf,
int len, int *pos)
{
char str_id[HCLGE_DBG_ID_LEN], str_pvid[HCLGE_DBG_ID_LEN];
const char *result[ARRAY_SIZE(vlan_offload_items)];
char content[HCLGE_DBG_VLAN_OFFLOAD_INFO_LEN];
u8 func_num = pci_num_vf(hdev->pdev) + 1; /* pf and enabled vf num */
struct hclge_dbg_vlan_cfg vlan_cfg;
int ret;
u8 i, j;
hclge_dbg_fill_content(content, sizeof(content), vlan_offload_items,
NULL, ARRAY_SIZE(vlan_offload_items));
*pos += scnprintf(buf + *pos, len - *pos, "%s", content);
for (i = 0; i < func_num; i++) {
ret = hclge_get_vlan_tx_offload_cfg(hdev, i, &vlan_cfg);
if (ret)
return ret;
ret = hclge_get_vlan_rx_offload_cfg(hdev, i, &vlan_cfg);
if (ret)
return ret;
sprintf(str_pvid, "%u", vlan_cfg.pvid);
j = 0;
result[j++] = hclge_dbg_get_func_id_str(str_id, i);
result[j++] = str_pvid;
result[j++] = state_str[vlan_cfg.accept_tag1];
result[j++] = state_str[vlan_cfg.accept_tag2];
result[j++] = state_str[vlan_cfg.accept_untag1];
result[j++] = state_str[vlan_cfg.accept_untag2];
result[j++] = state_str[vlan_cfg.insert_tag1];
result[j++] = state_str[vlan_cfg.insert_tag2];
result[j++] = state_str[vlan_cfg.shift_tag];
result[j++] = state_str[vlan_cfg.strip_tag1];
result[j++] = state_str[vlan_cfg.strip_tag2];
result[j++] = state_str[vlan_cfg.drop_tag1];
result[j++] = state_str[vlan_cfg.drop_tag2];
result[j++] = state_str[vlan_cfg.pri_only1];
result[j++] = state_str[vlan_cfg.pri_only2];
hclge_dbg_fill_content(content, sizeof(content),
vlan_offload_items, result,
ARRAY_SIZE(vlan_offload_items));
*pos += scnprintf(buf + *pos, len - *pos, "%s", content);
}
return 0;
}
static int hclge_dbg_dump_vlan_config(struct hclge_dev *hdev, char *buf,
int len)
{
int pos = 0;
int ret;
ret = hclge_dbg_dump_vlan_filter_config(hdev, buf, len, &pos);
if (ret)
return ret;
return hclge_dbg_dump_vlan_offload_config(hdev, buf, len, &pos);
}
static int hclge_dbg_dump_mac_uc(struct hclge_dev *hdev, char *buf, int len) static int hclge_dbg_dump_mac_uc(struct hclge_dev *hdev, char *buf, int len)
{ {
hclge_dbg_dump_mac_list(hdev, buf, len, true); hclge_dbg_dump_mac_list(hdev, buf, len, true);
...@@ -2037,6 +2316,10 @@ static const struct hclge_dbg_func hclge_dbg_cmd_func[] = { ...@@ -2037,6 +2316,10 @@ static const struct hclge_dbg_func hclge_dbg_cmd_func[] = {
.cmd = HNAE3_DBG_CMD_SERV_INFO, .cmd = HNAE3_DBG_CMD_SERV_INFO,
.dbg_dump = hclge_dbg_dump_serv_info, .dbg_dump = hclge_dbg_dump_serv_info,
}, },
{
.cmd = HNAE3_DBG_CMD_VLAN_CONFIG,
.dbg_dump = hclge_dbg_dump_vlan_config,
},
}; };
int hclge_dbg_read_cmd(struct hnae3_handle *handle, enum hnae3_dbg_cmd cmd, int hclge_dbg_read_cmd(struct hnae3_handle *handle, enum hnae3_dbg_cmd cmd,
......
...@@ -735,6 +735,8 @@ static const struct hclge_dbg_dfx_message hclge_dbg_tqp_reg[] = { ...@@ -735,6 +735,8 @@ static const struct hclge_dbg_dfx_message hclge_dbg_tqp_reg[] = {
}; };
#define HCLGE_DBG_INFO_LEN 256 #define HCLGE_DBG_INFO_LEN 256
#define HCLGE_DBG_VLAN_FLTR_INFO_LEN 256
#define HCLGE_DBG_VLAN_OFFLOAD_INFO_LEN 512
#define HCLGE_DBG_ID_LEN 16 #define HCLGE_DBG_ID_LEN 16
#define HCLGE_DBG_ITEM_NAME_LEN 32 #define HCLGE_DBG_ITEM_NAME_LEN 32
#define HCLGE_DBG_DATA_STR_LEN 32 #define HCLGE_DBG_DATA_STR_LEN 32
...@@ -747,4 +749,21 @@ struct hclge_dbg_item { ...@@ -747,4 +749,21 @@ struct hclge_dbg_item {
u16 interval; /* blank numbers after the item */ u16 interval; /* blank numbers after the item */
}; };
struct hclge_dbg_vlan_cfg {
u16 pvid;
u8 accept_tag1;
u8 accept_tag2;
u8 accept_untag1;
u8 accept_untag2;
u8 insert_tag1;
u8 insert_tag2;
u8 shift_tag;
u8 strip_tag1;
u8 strip_tag2;
u8 drop_tag1;
u8 drop_tag2;
u8 pri_only1;
u8 pri_only2;
};
#endif #endif
...@@ -1334,6 +1334,10 @@ static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc) ...@@ -1334,6 +1334,10 @@ static void hclge_parse_cfg(struct hclge_cfg *cfg, struct hclge_desc *desc)
HCLGE_CFG_SPEED_ABILITY_EXT_S); HCLGE_CFG_SPEED_ABILITY_EXT_S);
cfg->speed_ability |= speed_ability_ext << SPEED_ABILITY_EXT_SHIFT; cfg->speed_ability |= speed_ability_ext << SPEED_ABILITY_EXT_SHIFT;
cfg->vlan_fliter_cap = hnae3_get_field(__le32_to_cpu(req->param[1]),
HCLGE_CFG_VLAN_FLTR_CAP_M,
HCLGE_CFG_VLAN_FLTR_CAP_S);
cfg->umv_space = hnae3_get_field(__le32_to_cpu(req->param[1]), cfg->umv_space = hnae3_get_field(__le32_to_cpu(req->param[1]),
HCLGE_CFG_UMV_TBL_SPACE_M, HCLGE_CFG_UMV_TBL_SPACE_M,
HCLGE_CFG_UMV_TBL_SPACE_S); HCLGE_CFG_UMV_TBL_SPACE_S);
...@@ -1513,6 +1517,7 @@ static void hclge_init_kdump_kernel_config(struct hclge_dev *hdev) ...@@ -1513,6 +1517,7 @@ static void hclge_init_kdump_kernel_config(struct hclge_dev *hdev)
static int hclge_configure(struct hclge_dev *hdev) static int hclge_configure(struct hclge_dev *hdev)
{ {
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(hdev->pdev);
struct hclge_cfg cfg; struct hclge_cfg cfg;
unsigned int i; unsigned int i;
int ret; int ret;
...@@ -1534,6 +1539,8 @@ static int hclge_configure(struct hclge_dev *hdev) ...@@ -1534,6 +1539,8 @@ static int hclge_configure(struct hclge_dev *hdev)
hdev->tc_max = cfg.tc_num; hdev->tc_max = cfg.tc_num;
hdev->tm_info.hw_pfc_map = 0; hdev->tm_info.hw_pfc_map = 0;
hdev->wanted_umv_size = cfg.umv_space; hdev->wanted_umv_size = cfg.umv_space;
if (cfg.vlan_fliter_cap == HCLGE_VLAN_FLTR_CAN_MDF)
set_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps);
if (hnae3_dev_fd_supported(hdev)) { if (hnae3_dev_fd_supported(hdev)) {
hdev->fd_en = true; hdev->fd_en = true;
...@@ -1843,6 +1850,7 @@ static int hclge_alloc_vport(struct hclge_dev *hdev) ...@@ -1843,6 +1850,7 @@ static int hclge_alloc_vport(struct hclge_dev *hdev)
vport->mps = HCLGE_MAC_DEFAULT_FRAME; vport->mps = HCLGE_MAC_DEFAULT_FRAME;
vport->port_base_vlan_cfg.state = HNAE3_PORT_BASE_VLAN_DISABLE; vport->port_base_vlan_cfg.state = HNAE3_PORT_BASE_VLAN_DISABLE;
vport->rxvlan_cfg.rx_vlan_offload_en = true; vport->rxvlan_cfg.rx_vlan_offload_en = true;
vport->req_vlan_fltr_en = true;
INIT_LIST_HEAD(&vport->vlan_list); INIT_LIST_HEAD(&vport->vlan_list);
INIT_LIST_HEAD(&vport->uc_mac_list); INIT_LIST_HEAD(&vport->uc_mac_list);
INIT_LIST_HEAD(&vport->mc_mac_list); INIT_LIST_HEAD(&vport->mc_mac_list);
...@@ -9381,6 +9389,28 @@ static int hclge_do_ioctl(struct hnae3_handle *handle, struct ifreq *ifr, ...@@ -9381,6 +9389,28 @@ static int hclge_do_ioctl(struct hnae3_handle *handle, struct ifreq *ifr,
return phy_mii_ioctl(hdev->hw.mac.phydev, ifr, cmd); return phy_mii_ioctl(hdev->hw.mac.phydev, ifr, cmd);
} }
static int hclge_set_port_vlan_filter_bypass(struct hclge_dev *hdev, u8 vf_id,
bool bypass_en)
{
struct hclge_port_vlan_filter_bypass_cmd *req;
struct hclge_desc desc;
int ret;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PORT_VLAN_BYPASS, false);
req = (struct hclge_port_vlan_filter_bypass_cmd *)desc.data;
req->vf_id = vf_id;
hnae3_set_bit(req->bypass_state, HCLGE_INGRESS_BYPASS_B,
bypass_en ? 1 : 0);
ret = hclge_cmd_send(&hdev->hw, &desc, 1);
if (ret)
dev_err(&hdev->pdev->dev,
"failed to set vport%u port vlan filter bypass state, ret = %d.\n",
vf_id, ret);
return ret;
}
static int hclge_set_vlan_filter_ctrl(struct hclge_dev *hdev, u8 vlan_type, static int hclge_set_vlan_filter_ctrl(struct hclge_dev *hdev, u8 vlan_type,
u8 fe_type, bool filter_en, u8 vf_id) u8 fe_type, bool filter_en, u8 vf_id)
{ {
...@@ -9414,37 +9444,99 @@ static int hclge_set_vlan_filter_ctrl(struct hclge_dev *hdev, u8 vlan_type, ...@@ -9414,37 +9444,99 @@ static int hclge_set_vlan_filter_ctrl(struct hclge_dev *hdev, u8 vlan_type,
return ret; return ret;
} }
#define HCLGE_FILTER_TYPE_VF 0 static int hclge_set_vport_vlan_filter(struct hclge_vport *vport, bool enable)
#define HCLGE_FILTER_TYPE_PORT 1 {
#define HCLGE_FILTER_FE_EGRESS_V1_B BIT(0) struct hclge_dev *hdev = vport->back;
#define HCLGE_FILTER_FE_NIC_INGRESS_B BIT(0) struct hnae3_ae_dev *ae_dev = hdev->ae_dev;
#define HCLGE_FILTER_FE_NIC_EGRESS_B BIT(1) int ret;
#define HCLGE_FILTER_FE_ROCE_INGRESS_B BIT(2)
#define HCLGE_FILTER_FE_ROCE_EGRESS_B BIT(3) if (hdev->ae_dev->dev_version < HNAE3_DEVICE_VERSION_V2)
#define HCLGE_FILTER_FE_EGRESS (HCLGE_FILTER_FE_NIC_EGRESS_B \ return hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
| HCLGE_FILTER_FE_ROCE_EGRESS_B) HCLGE_FILTER_FE_EGRESS_V1_B,
#define HCLGE_FILTER_FE_INGRESS (HCLGE_FILTER_FE_NIC_INGRESS_B \ enable, vport->vport_id);
| HCLGE_FILTER_FE_ROCE_INGRESS_B)
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF,
HCLGE_FILTER_FE_EGRESS, enable,
vport->vport_id);
if (ret)
return ret;
if (test_bit(HNAE3_DEV_SUPPORT_PORT_VLAN_BYPASS_B, ae_dev->caps))
ret = hclge_set_port_vlan_filter_bypass(hdev, vport->vport_id,
!enable);
else if (!vport->vport_id)
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT,
HCLGE_FILTER_FE_INGRESS,
enable, 0);
static void hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable) return ret;
}
static bool hclge_need_enable_vport_vlan_filter(struct hclge_vport *vport)
{ {
struct hclge_vport *vport = hclge_get_vport(handle); struct hnae3_handle *handle = &vport->nic;
struct hclge_vport_vlan_cfg *vlan, *tmp;
struct hclge_dev *hdev = vport->back; struct hclge_dev *hdev = vport->back;
if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V2) { if (vport->vport_id) {
hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, if (vport->port_base_vlan_cfg.state !=
HCLGE_FILTER_FE_EGRESS, enable, 0); HNAE3_PORT_BASE_VLAN_DISABLE)
hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT, return true;
HCLGE_FILTER_FE_INGRESS, enable, 0);
} else { if (vport->vf_info.trusted && vport->vf_info.request_uc_en)
hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, return false;
HCLGE_FILTER_FE_EGRESS_V1_B, enable, } else if (handle->netdev_flags & HNAE3_USER_UPE) {
0); return false;
} }
if (enable)
handle->netdev_flags |= HNAE3_VLAN_FLTR; if (!vport->req_vlan_fltr_en)
else return false;
handle->netdev_flags &= ~HNAE3_VLAN_FLTR;
/* compatible with former device, always enable vlan filter */
if (!test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, hdev->ae_dev->caps))
return true;
list_for_each_entry_safe(vlan, tmp, &vport->vlan_list, node)
if (vlan->vlan_id != 0)
return true;
return false;
}
int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en)
{
struct hclge_dev *hdev = vport->back;
bool need_en;
int ret;
mutex_lock(&hdev->vport_lock);
vport->req_vlan_fltr_en = request_en;
need_en = hclge_need_enable_vport_vlan_filter(vport);
if (need_en == vport->cur_vlan_fltr_en) {
mutex_unlock(&hdev->vport_lock);
return 0;
}
ret = hclge_set_vport_vlan_filter(vport, need_en);
if (ret) {
mutex_unlock(&hdev->vport_lock);
return ret;
}
vport->cur_vlan_fltr_en = need_en;
mutex_unlock(&hdev->vport_lock);
return 0;
}
static int hclge_enable_vlan_filter(struct hnae3_handle *handle, bool enable)
{
struct hclge_vport *vport = hclge_get_vport(handle);
return hclge_enable_vport_vlan_filter(vport, enable);
} }
static int hclge_set_vf_vlan_filter_cmd(struct hclge_dev *hdev, u16 vfid, static int hclge_set_vf_vlan_filter_cmd(struct hclge_dev *hdev, u16 vfid,
...@@ -9724,7 +9816,7 @@ static int hclge_set_vlan_rx_offload_cfg(struct hclge_vport *vport) ...@@ -9724,7 +9816,7 @@ static int hclge_set_vlan_rx_offload_cfg(struct hclge_vport *vport)
static int hclge_vlan_offload_cfg(struct hclge_vport *vport, static int hclge_vlan_offload_cfg(struct hclge_vport *vport,
u16 port_base_vlan_state, u16 port_base_vlan_state,
u16 vlan_tag) u16 vlan_tag, u8 qos)
{ {
int ret; int ret;
...@@ -9738,7 +9830,8 @@ static int hclge_vlan_offload_cfg(struct hclge_vport *vport, ...@@ -9738,7 +9830,8 @@ static int hclge_vlan_offload_cfg(struct hclge_vport *vport,
vport->txvlan_cfg.accept_tag1 = vport->txvlan_cfg.accept_tag1 =
ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3; ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3;
vport->txvlan_cfg.insert_tag1_en = true; vport->txvlan_cfg.insert_tag1_en = true;
vport->txvlan_cfg.default_tag1 = vlan_tag; vport->txvlan_cfg.default_tag1 = (qos << VLAN_PRIO_SHIFT) |
vlan_tag;
} }
vport->txvlan_cfg.accept_untag1 = true; vport->txvlan_cfg.accept_untag1 = true;
...@@ -9837,6 +9930,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) ...@@ -9837,6 +9930,7 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
vport->vport_id); vport->vport_id);
if (ret) if (ret)
return ret; return ret;
vport->cur_vlan_fltr_en = true;
} }
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT, ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT,
...@@ -9852,8 +9946,6 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) ...@@ -9852,8 +9946,6 @@ 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;
...@@ -9867,13 +9959,15 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev) ...@@ -9867,13 +9959,15 @@ static int hclge_init_vlan_config(struct hclge_dev *hdev)
for (i = 0; i < hdev->num_alloc_vport; i++) { for (i = 0; i < hdev->num_alloc_vport; i++) {
u16 vlan_tag; u16 vlan_tag;
u8 qos;
vport = &hdev->vport[i]; vport = &hdev->vport[i];
vlan_tag = vport->port_base_vlan_cfg.vlan_info.vlan_tag; vlan_tag = vport->port_base_vlan_cfg.vlan_info.vlan_tag;
qos = vport->port_base_vlan_cfg.vlan_info.qos;
ret = hclge_vlan_offload_cfg(vport, ret = hclge_vlan_offload_cfg(vport,
vport->port_base_vlan_cfg.state, vport->port_base_vlan_cfg.state,
vlan_tag); vlan_tag, qos);
if (ret) if (ret)
return ret; return ret;
} }
...@@ -10074,6 +10168,14 @@ int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable) ...@@ -10074,6 +10168,14 @@ int hclge_en_hw_strip_rxvtag(struct hnae3_handle *handle, bool enable)
return hclge_set_vlan_rx_offload_cfg(vport); return hclge_set_vlan_rx_offload_cfg(vport);
} }
static void hclge_set_vport_vlan_fltr_change(struct hclge_vport *vport)
{
struct hclge_dev *hdev = vport->back;
if (test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, hdev->ae_dev->caps))
set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE, &vport->state);
}
static int hclge_update_vlan_filter_entries(struct hclge_vport *vport, static int hclge_update_vlan_filter_entries(struct hclge_vport *vport,
u16 port_base_vlan_state, u16 port_base_vlan_state,
struct hclge_vlan_info *new_info, struct hclge_vlan_info *new_info,
...@@ -10084,6 +10186,10 @@ static int hclge_update_vlan_filter_entries(struct hclge_vport *vport, ...@@ -10084,6 +10186,10 @@ static int hclge_update_vlan_filter_entries(struct hclge_vport *vport,
if (port_base_vlan_state == HNAE3_PORT_BASE_VLAN_ENABLE) { if (port_base_vlan_state == HNAE3_PORT_BASE_VLAN_ENABLE) {
hclge_rm_vport_all_vlan_table(vport, false); hclge_rm_vport_all_vlan_table(vport, false);
/* force clear VLAN 0 */
ret = hclge_set_vf_vlan_common(hdev, vport->vport_id, true, 0);
if (ret)
return ret;
return hclge_set_vlan_filter_hw(hdev, return hclge_set_vlan_filter_hw(hdev,
htons(new_info->vlan_proto), htons(new_info->vlan_proto),
vport->vport_id, vport->vport_id,
...@@ -10091,6 +10197,11 @@ static int hclge_update_vlan_filter_entries(struct hclge_vport *vport, ...@@ -10091,6 +10197,11 @@ static int hclge_update_vlan_filter_entries(struct hclge_vport *vport,
false); false);
} }
/* force add VLAN 0 */
ret = hclge_set_vf_vlan_common(hdev, vport->vport_id, false, 0);
if (ret)
return ret;
ret = hclge_set_vlan_filter_hw(hdev, htons(old_info->vlan_proto), ret = hclge_set_vlan_filter_hw(hdev, htons(old_info->vlan_proto),
vport->vport_id, old_info->vlan_tag, vport->vport_id, old_info->vlan_tag,
true); true);
...@@ -10100,6 +10211,18 @@ static int hclge_update_vlan_filter_entries(struct hclge_vport *vport, ...@@ -10100,6 +10211,18 @@ static int hclge_update_vlan_filter_entries(struct hclge_vport *vport,
return hclge_add_vport_all_vlan_table(vport); return hclge_add_vport_all_vlan_table(vport);
} }
static bool hclge_need_update_vlan_filter(const struct hclge_vlan_info *new_cfg,
const struct hclge_vlan_info *old_cfg)
{
if (new_cfg->vlan_tag != old_cfg->vlan_tag)
return true;
if (new_cfg->vlan_tag == 0 && (new_cfg->qos == 0 || old_cfg->qos == 0))
return true;
return false;
}
int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state, int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state,
struct hclge_vlan_info *vlan_info) struct hclge_vlan_info *vlan_info)
{ {
...@@ -10110,10 +10233,14 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state, ...@@ -10110,10 +10233,14 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state,
old_vlan_info = &vport->port_base_vlan_cfg.vlan_info; old_vlan_info = &vport->port_base_vlan_cfg.vlan_info;
ret = hclge_vlan_offload_cfg(vport, state, vlan_info->vlan_tag); ret = hclge_vlan_offload_cfg(vport, state, vlan_info->vlan_tag,
vlan_info->qos);
if (ret) if (ret)
return ret; return ret;
if (!hclge_need_update_vlan_filter(vlan_info, old_vlan_info))
goto out;
if (state == HNAE3_PORT_BASE_VLAN_MODIFY) { if (state == HNAE3_PORT_BASE_VLAN_MODIFY) {
/* add new VLAN tag */ /* add new VLAN tag */
ret = hclge_set_vlan_filter_hw(hdev, ret = hclge_set_vlan_filter_hw(hdev,
...@@ -10125,15 +10252,23 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state, ...@@ -10125,15 +10252,23 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state,
return ret; return ret;
/* remove old VLAN tag */ /* remove old VLAN tag */
if (old_vlan_info->vlan_tag == 0)
ret = hclge_set_vf_vlan_common(hdev, vport->vport_id,
true, 0);
else
ret = hclge_set_vlan_filter_hw(hdev, ret = hclge_set_vlan_filter_hw(hdev,
htons(old_vlan_info->vlan_proto), htons(ETH_P_8021Q),
vport->vport_id, vport->vport_id,
old_vlan_info->vlan_tag, old_vlan_info->vlan_tag,
true); true);
if (ret) if (ret) {
dev_err(&hdev->pdev->dev,
"failed to clear vport%u port base vlan %u, ret = %d.\n",
vport->vport_id, old_vlan_info->vlan_tag, ret);
return ret; return ret;
}
goto update; goto out;
} }
ret = hclge_update_vlan_filter_entries(vport, state, vlan_info, ret = hclge_update_vlan_filter_entries(vport, state, vlan_info,
...@@ -10141,38 +10276,38 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state, ...@@ -10141,38 +10276,38 @@ int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state,
if (ret) if (ret)
return ret; return ret;
/* update state only when disable/enable port based VLAN */ out:
vport->port_base_vlan_cfg.state = state; vport->port_base_vlan_cfg.state = state;
if (state == HNAE3_PORT_BASE_VLAN_DISABLE) if (state == HNAE3_PORT_BASE_VLAN_DISABLE)
nic->port_base_vlan_state = HNAE3_PORT_BASE_VLAN_DISABLE; nic->port_base_vlan_state = HNAE3_PORT_BASE_VLAN_DISABLE;
else else
nic->port_base_vlan_state = HNAE3_PORT_BASE_VLAN_ENABLE; nic->port_base_vlan_state = HNAE3_PORT_BASE_VLAN_ENABLE;
update: vport->port_base_vlan_cfg.vlan_info = *vlan_info;
vport->port_base_vlan_cfg.vlan_info.vlan_tag = vlan_info->vlan_tag; hclge_set_vport_vlan_fltr_change(vport);
vport->port_base_vlan_cfg.vlan_info.qos = vlan_info->qos;
vport->port_base_vlan_cfg.vlan_info.vlan_proto = vlan_info->vlan_proto;
return 0; return 0;
} }
static u16 hclge_get_port_base_vlan_state(struct hclge_vport *vport, static u16 hclge_get_port_base_vlan_state(struct hclge_vport *vport,
enum hnae3_port_base_vlan_state state, enum hnae3_port_base_vlan_state state,
u16 vlan) u16 vlan, u8 qos)
{ {
if (state == HNAE3_PORT_BASE_VLAN_DISABLE) { if (state == HNAE3_PORT_BASE_VLAN_DISABLE) {
if (!vlan) if (!vlan && !qos)
return HNAE3_PORT_BASE_VLAN_NOCHANGE; return HNAE3_PORT_BASE_VLAN_NOCHANGE;
else
return HNAE3_PORT_BASE_VLAN_ENABLE; return HNAE3_PORT_BASE_VLAN_ENABLE;
} else { }
if (!vlan)
if (!vlan && !qos)
return HNAE3_PORT_BASE_VLAN_DISABLE; return HNAE3_PORT_BASE_VLAN_DISABLE;
else if (vport->port_base_vlan_cfg.vlan_info.vlan_tag == vlan)
if (vport->port_base_vlan_cfg.vlan_info.vlan_tag == vlan &&
vport->port_base_vlan_cfg.vlan_info.qos == qos)
return HNAE3_PORT_BASE_VLAN_NOCHANGE; return HNAE3_PORT_BASE_VLAN_NOCHANGE;
else
return HNAE3_PORT_BASE_VLAN_MODIFY; return HNAE3_PORT_BASE_VLAN_MODIFY;
}
} }
static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid, static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
...@@ -10200,7 +10335,7 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid, ...@@ -10200,7 +10335,7 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
state = hclge_get_port_base_vlan_state(vport, state = hclge_get_port_base_vlan_state(vport,
vport->port_base_vlan_cfg.state, vport->port_base_vlan_cfg.state,
vlan); vlan, qos);
if (state == HNAE3_PORT_BASE_VLAN_NOCHANGE) if (state == HNAE3_PORT_BASE_VLAN_NOCHANGE)
return 0; return 0;
...@@ -10223,8 +10358,7 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid, ...@@ -10223,8 +10358,7 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state)) test_bit(HCLGE_VPORT_STATE_ALIVE, &vport->state))
hclge_push_vf_port_base_vlan_info(&hdev->vport[0], hclge_push_vf_port_base_vlan_info(&hdev->vport[0],
vport->vport_id, state, vport->vport_id, state,
vlan, qos, &vlan_info);
ntohs(proto));
return 0; return 0;
} }
...@@ -10294,9 +10428,37 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto, ...@@ -10294,9 +10428,37 @@ int hclge_set_vlan_filter(struct hnae3_handle *handle, __be16 proto,
*/ */
set_bit(vlan_id, vport->vlan_del_fail_bmap); set_bit(vlan_id, vport->vlan_del_fail_bmap);
} }
hclge_set_vport_vlan_fltr_change(vport);
return ret; return ret;
} }
static void hclge_sync_vlan_fltr_state(struct hclge_dev *hdev)
{
struct hclge_vport *vport;
int ret;
u16 i;
for (i = 0; i < hdev->num_alloc_vport; i++) {
vport = &hdev->vport[i];
if (!test_and_clear_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
&vport->state))
continue;
ret = hclge_enable_vport_vlan_filter(vport,
vport->req_vlan_fltr_en);
if (ret) {
dev_err(&hdev->pdev->dev,
"failed to sync vlan filter state for vport%u, ret = %d\n",
vport->vport_id, ret);
set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
&vport->state);
return;
}
}
}
static void hclge_sync_vlan_filter(struct hclge_dev *hdev) static void hclge_sync_vlan_filter(struct hclge_dev *hdev)
{ {
#define HCLGE_MAX_SYNC_COUNT 60 #define HCLGE_MAX_SYNC_COUNT 60
...@@ -10319,6 +10481,7 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev) ...@@ -10319,6 +10481,7 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev)
clear_bit(vlan_id, vport->vlan_del_fail_bmap); clear_bit(vlan_id, vport->vlan_del_fail_bmap);
hclge_rm_vport_vlan_table(vport, vlan_id, false); hclge_rm_vport_vlan_table(vport, vlan_id, false);
hclge_set_vport_vlan_fltr_change(vport);
sync_cnt++; sync_cnt++;
if (sync_cnt >= HCLGE_MAX_SYNC_COUNT) if (sync_cnt >= HCLGE_MAX_SYNC_COUNT)
...@@ -10328,6 +10491,8 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev) ...@@ -10328,6 +10491,8 @@ static void hclge_sync_vlan_filter(struct hclge_dev *hdev)
VLAN_N_VID); VLAN_N_VID);
} }
} }
hclge_sync_vlan_fltr_state(hdev);
} }
static int hclge_set_mac_mtu(struct hclge_dev *hdev, int new_mps) static int hclge_set_mac_mtu(struct hclge_dev *hdev, int new_mps)
...@@ -12418,8 +12583,8 @@ static void hclge_sync_promisc_mode(struct hclge_dev *hdev) ...@@ -12418,8 +12583,8 @@ static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
if (!ret) { if (!ret) {
clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE, clear_bit(HCLGE_VPORT_STATE_PROMISC_CHANGE,
&vport->state); &vport->state);
hclge_enable_vlan_filter(handle, set_bit(HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
tmp_flags & HNAE3_VLAN_FLTR); &vport->state);
} }
} }
...@@ -12447,6 +12612,7 @@ static void hclge_sync_promisc_mode(struct hclge_dev *hdev) ...@@ -12447,6 +12612,7 @@ static void hclge_sync_promisc_mode(struct hclge_dev *hdev)
&vport->state); &vport->state);
return; return;
} }
hclge_set_vport_vlan_fltr_change(vport);
} }
} }
......
...@@ -321,6 +321,22 @@ enum hclge_fc_mode { ...@@ -321,6 +321,22 @@ enum hclge_fc_mode {
HCLGE_FC_DEFAULT HCLGE_FC_DEFAULT
}; };
#define HCLGE_FILTER_TYPE_VF 0
#define HCLGE_FILTER_TYPE_PORT 1
#define HCLGE_FILTER_FE_EGRESS_V1_B BIT(0)
#define HCLGE_FILTER_FE_NIC_INGRESS_B BIT(0)
#define HCLGE_FILTER_FE_NIC_EGRESS_B BIT(1)
#define HCLGE_FILTER_FE_ROCE_INGRESS_B BIT(2)
#define HCLGE_FILTER_FE_ROCE_EGRESS_B BIT(3)
#define HCLGE_FILTER_FE_EGRESS (HCLGE_FILTER_FE_NIC_EGRESS_B \
| HCLGE_FILTER_FE_ROCE_EGRESS_B)
#define HCLGE_FILTER_FE_INGRESS (HCLGE_FILTER_FE_NIC_INGRESS_B \
| HCLGE_FILTER_FE_ROCE_INGRESS_B)
enum hclge_vlan_fltr_cap {
HCLGE_VLAN_FLTR_DEF,
HCLGE_VLAN_FLTR_CAN_MDF,
};
enum hclge_link_fail_code { enum hclge_link_fail_code {
HCLGE_LF_NORMAL, HCLGE_LF_NORMAL,
HCLGE_LF_REF_CLOCK_LOST, HCLGE_LF_REF_CLOCK_LOST,
...@@ -351,6 +367,7 @@ struct hclge_tc_info { ...@@ -351,6 +367,7 @@ struct hclge_tc_info {
struct hclge_cfg { struct hclge_cfg {
u8 tc_num; u8 tc_num;
u8 vlan_fliter_cap;
u16 tqp_desc_num; u16 tqp_desc_num;
u16 rx_buf_len; u16 rx_buf_len;
u16 vf_rss_size_max; u16 vf_rss_size_max;
...@@ -759,9 +776,14 @@ struct hclge_mac_tnl_stats { ...@@ -759,9 +776,14 @@ struct hclge_mac_tnl_stats {
struct hclge_vf_vlan_cfg { struct hclge_vf_vlan_cfg {
u8 mbx_cmd; u8 mbx_cmd;
u8 subcode; u8 subcode;
union {
struct {
u8 is_kill; u8 is_kill;
u16 vlan; u16 vlan;
u16 proto; u16 proto;
};
u8 enable;
};
}; };
#pragma pack() #pragma pack()
...@@ -952,6 +974,7 @@ enum HCLGE_VPORT_STATE { ...@@ -952,6 +974,7 @@ enum HCLGE_VPORT_STATE {
HCLGE_VPORT_STATE_ALIVE, HCLGE_VPORT_STATE_ALIVE,
HCLGE_VPORT_STATE_MAC_TBL_CHANGE, HCLGE_VPORT_STATE_MAC_TBL_CHANGE,
HCLGE_VPORT_STATE_PROMISC_CHANGE, HCLGE_VPORT_STATE_PROMISC_CHANGE,
HCLGE_VPORT_STATE_VLAN_FLTR_CHANGE,
HCLGE_VPORT_STATE_MAX HCLGE_VPORT_STATE_MAX
}; };
...@@ -993,6 +1016,8 @@ struct hclge_vport { ...@@ -993,6 +1016,8 @@ struct hclge_vport {
u32 bw_limit; /* VSI BW Limit (0 = disabled) */ u32 bw_limit; /* VSI BW Limit (0 = disabled) */
u8 dwrr; u8 dwrr;
bool req_vlan_fltr_en;
bool cur_vlan_fltr_en;
unsigned long vlan_del_fail_bmap[BITS_TO_LONGS(VLAN_N_VID)]; unsigned long vlan_del_fail_bmap[BITS_TO_LONGS(VLAN_N_VID)];
struct hclge_port_base_vlan_config port_base_vlan_cfg; struct hclge_port_base_vlan_config port_base_vlan_cfg;
struct hclge_tx_vtag_cfg txvlan_cfg; struct hclge_tx_vtag_cfg txvlan_cfg;
...@@ -1084,8 +1109,8 @@ void hclge_restore_vport_vlan_table(struct hclge_vport *vport); ...@@ -1084,8 +1109,8 @@ void hclge_restore_vport_vlan_table(struct hclge_vport *vport);
int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state, int hclge_update_port_base_vlan_cfg(struct hclge_vport *vport, u16 state,
struct hclge_vlan_info *vlan_info); struct hclge_vlan_info *vlan_info);
int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid, int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid,
u16 state, u16 vlan_tag, u16 qos, u16 state,
u16 vlan_proto); struct hclge_vlan_info *vlan_info);
void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time); void hclge_task_schedule(struct hclge_dev *hdev, unsigned long delay_time);
int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev, int hclge_query_bd_num_cmd_send(struct hclge_dev *hdev,
struct hclge_desc *desc); struct hclge_desc *desc);
...@@ -1094,4 +1119,5 @@ void hclge_report_hw_error(struct hclge_dev *hdev, ...@@ -1094,4 +1119,5 @@ void hclge_report_hw_error(struct hclge_dev *hdev,
void hclge_inform_vf_promisc_info(struct hclge_vport *vport); void hclge_inform_vf_promisc_info(struct hclge_vport *vport);
int hclge_dbg_dump_rst_info(struct hclge_dev *hdev, char *buf, int len); int hclge_dbg_dump_rst_info(struct hclge_dev *hdev, char *buf, int len);
int hclge_push_vf_link_status(struct hclge_vport *vport); int hclge_push_vf_link_status(struct hclge_vport *vport);
int hclge_enable_vport_vlan_filter(struct hclge_vport *vport, bool request_en);
#endif #endif
...@@ -318,17 +318,17 @@ static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport, ...@@ -318,17 +318,17 @@ static int hclge_set_vf_mc_mac_addr(struct hclge_vport *vport,
} }
int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid, int hclge_push_vf_port_base_vlan_info(struct hclge_vport *vport, u8 vfid,
u16 state, u16 vlan_tag, u16 qos, u16 state,
u16 vlan_proto) struct hclge_vlan_info *vlan_info)
{ {
#define MSG_DATA_SIZE 8 #define MSG_DATA_SIZE 8
u8 msg_data[MSG_DATA_SIZE]; u8 msg_data[MSG_DATA_SIZE];
memcpy(&msg_data[0], &state, sizeof(u16)); memcpy(&msg_data[0], &state, sizeof(u16));
memcpy(&msg_data[2], &vlan_proto, sizeof(u16)); memcpy(&msg_data[2], &vlan_info->vlan_proto, sizeof(u16));
memcpy(&msg_data[4], &qos, sizeof(u16)); memcpy(&msg_data[4], &vlan_info->qos, sizeof(u16));
memcpy(&msg_data[6], &vlan_tag, sizeof(u16)); memcpy(&msg_data[6], &vlan_info->vlan_tag, sizeof(u16));
return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data), return hclge_send_mbx_msg(vport, msg_data, sizeof(msg_data),
HCLGE_MBX_PUSH_VLAN_INFO, vfid); HCLGE_MBX_PUSH_VLAN_INFO, vfid);
...@@ -341,49 +341,35 @@ static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport, ...@@ -341,49 +341,35 @@ static int hclge_set_vf_vlan_cfg(struct hclge_vport *vport,
#define HCLGE_MBX_VLAN_STATE_OFFSET 0 #define HCLGE_MBX_VLAN_STATE_OFFSET 0
#define HCLGE_MBX_VLAN_INFO_OFFSET 2 #define HCLGE_MBX_VLAN_INFO_OFFSET 2
struct hnae3_handle *handle = &vport->nic;
struct hclge_dev *hdev = vport->back;
struct hclge_vf_vlan_cfg *msg_cmd; struct hclge_vf_vlan_cfg *msg_cmd;
int status = 0;
msg_cmd = (struct hclge_vf_vlan_cfg *)&mbx_req->msg; msg_cmd = (struct hclge_vf_vlan_cfg *)&mbx_req->msg;
if (msg_cmd->subcode == HCLGE_MBX_VLAN_FILTER) { switch (msg_cmd->subcode) {
struct hnae3_handle *handle = &vport->nic; case HCLGE_MBX_VLAN_FILTER:
u16 vlan, proto; return hclge_set_vlan_filter(handle,
bool is_kill; cpu_to_be16(msg_cmd->proto),
msg_cmd->vlan, msg_cmd->is_kill);
is_kill = !!msg_cmd->is_kill; case HCLGE_MBX_VLAN_RX_OFF_CFG:
vlan = msg_cmd->vlan; return hclge_en_hw_strip_rxvtag(handle, msg_cmd->enable);
proto = msg_cmd->proto; case HCLGE_MBX_GET_PORT_BASE_VLAN_STATE:
status = hclge_set_vlan_filter(handle, cpu_to_be16(proto),
vlan, is_kill);
} else if (msg_cmd->subcode == HCLGE_MBX_VLAN_RX_OFF_CFG) {
struct hnae3_handle *handle = &vport->nic;
bool en = msg_cmd->is_kill ? true : false;
status = hclge_en_hw_strip_rxvtag(handle, en);
} else if (msg_cmd->subcode == HCLGE_MBX_PORT_BASE_VLAN_CFG) {
struct hclge_vlan_info *vlan_info;
u16 *state;
state = (u16 *)&mbx_req->msg.data[HCLGE_MBX_VLAN_STATE_OFFSET];
vlan_info = (struct hclge_vlan_info *)
&mbx_req->msg.data[HCLGE_MBX_VLAN_INFO_OFFSET];
status = hclge_update_port_base_vlan_cfg(vport, *state,
vlan_info);
} else if (msg_cmd->subcode == HCLGE_MBX_GET_PORT_BASE_VLAN_STATE) {
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(vport->nic.pdev);
/* vf does not need to know about the port based VLAN state /* vf does not need to know about the port based VLAN state
* on device HNAE3_DEVICE_VERSION_V3. So always return disable * on device HNAE3_DEVICE_VERSION_V3. So always return disable
* on device HNAE3_DEVICE_VERSION_V3 if vf queries the port * on device HNAE3_DEVICE_VERSION_V3 if vf queries the port
* based VLAN state. * based VLAN state.
*/ */
resp_msg->data[0] = resp_msg->data[0] =
ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3 ? hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3 ?
HNAE3_PORT_BASE_VLAN_DISABLE : HNAE3_PORT_BASE_VLAN_DISABLE :
vport->port_base_vlan_cfg.state; vport->port_base_vlan_cfg.state;
resp_msg->len = sizeof(u8); resp_msg->len = sizeof(u8);
return 0;
case HCLGE_MBX_ENABLE_VLAN_FILTER:
return hclge_enable_vport_vlan_filter(vport, msg_cmd->enable);
default:
return 0;
} }
return status;
} }
static int hclge_set_vf_alive(struct hclge_vport *vport, static int hclge_set_vf_alive(struct hclge_vport *vport,
...@@ -400,16 +386,23 @@ static int hclge_set_vf_alive(struct hclge_vport *vport, ...@@ -400,16 +386,23 @@ static int hclge_set_vf_alive(struct hclge_vport *vport,
return ret; return ret;
} }
static void hclge_get_vf_tcinfo(struct hclge_vport *vport, static void hclge_get_basic_info(struct hclge_vport *vport,
struct hclge_respond_to_vf_msg *resp_msg) struct hclge_respond_to_vf_msg *resp_msg)
{ {
struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
struct hnae3_ae_dev *ae_dev = vport->back->ae_dev;
struct hclge_basic_info *basic_info;
unsigned int i; unsigned int i;
basic_info = (struct hclge_basic_info *)resp_msg->data;
for (i = 0; i < kinfo->tc_info.num_tc; i++) for (i = 0; i < kinfo->tc_info.num_tc; i++)
resp_msg->data[0] |= BIT(i); basic_info->hw_tc_map |= BIT(i);
resp_msg->len = sizeof(u8); if (test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps))
hnae3_set_bit(basic_info->pf_caps,
HNAE3_PF_SUPPORT_VLAN_FLTR_MDF_B, 1);
resp_msg->len = HCLGE_MBX_MAX_RESP_DATA_SIZE;
} }
static void hclge_get_vf_queue_info(struct hclge_vport *vport, static void hclge_get_vf_queue_info(struct hclge_vport *vport,
...@@ -768,8 +761,8 @@ void hclge_mbx_handler(struct hclge_dev *hdev) ...@@ -768,8 +761,8 @@ void hclge_mbx_handler(struct hclge_dev *hdev)
case HCLGE_MBX_GET_QDEPTH: case HCLGE_MBX_GET_QDEPTH:
hclge_get_vf_queue_depth(vport, &resp_msg); hclge_get_vf_queue_depth(vport, &resp_msg);
break; break;
case HCLGE_MBX_GET_TCINFO: case HCLGE_MBX_GET_BASIC_INFO:
hclge_get_vf_tcinfo(vport, &resp_msg); hclge_get_basic_info(vport, &resp_msg);
break; break;
case HCLGE_MBX_GET_LINK_STATUS: case HCLGE_MBX_GET_LINK_STATUS:
ret = hclge_push_vf_link_status(vport); ret = hclge_push_vf_link_status(vport);
......
...@@ -243,23 +243,31 @@ static void hclgevf_build_send_msg(struct hclge_vf_to_pf_msg *msg, u8 code, ...@@ -243,23 +243,31 @@ static void hclgevf_build_send_msg(struct hclge_vf_to_pf_msg *msg, u8 code,
} }
} }
static int hclgevf_get_tc_info(struct hclgevf_dev *hdev) static int hclgevf_get_basic_info(struct hclgevf_dev *hdev)
{ {
struct hnae3_ae_dev *ae_dev = hdev->ae_dev;
u8 resp_msg[HCLGE_MBX_MAX_RESP_DATA_SIZE];
struct hclge_basic_info *basic_info;
struct hclge_vf_to_pf_msg send_msg; struct hclge_vf_to_pf_msg send_msg;
u8 resp_msg; unsigned long caps;
int status; int status;
hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_TCINFO, 0); hclgevf_build_send_msg(&send_msg, HCLGE_MBX_GET_BASIC_INFO, 0);
status = hclgevf_send_mbx_msg(hdev, &send_msg, true, &resp_msg, status = hclgevf_send_mbx_msg(hdev, &send_msg, true, resp_msg,
sizeof(resp_msg)); sizeof(resp_msg));
if (status) { if (status) {
dev_err(&hdev->pdev->dev, dev_err(&hdev->pdev->dev,
"VF request to get TC info from PF failed %d", "failed to get basic info from pf, ret = %d", status);
status);
return status; return status;
} }
hdev->hw_tc_map = resp_msg; basic_info = (struct hclge_basic_info *)resp_msg;
hdev->hw_tc_map = basic_info->hw_tc_map;
hdev->mbx_api_version = basic_info->mbx_api_version;
caps = basic_info->pf_caps;
if (test_bit(HNAE3_PF_SUPPORT_VLAN_FLTR_MDF_B, &caps))
set_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps);
return 0; return 0;
} }
...@@ -1642,6 +1650,22 @@ static void hclgevf_uninit_mac_list(struct hclgevf_dev *hdev) ...@@ -1642,6 +1650,22 @@ static void hclgevf_uninit_mac_list(struct hclgevf_dev *hdev)
spin_unlock_bh(&hdev->mac_table.mac_list_lock); spin_unlock_bh(&hdev->mac_table.mac_list_lock);
} }
static int hclgevf_enable_vlan_filter(struct hnae3_handle *handle, bool enable)
{
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
struct hnae3_ae_dev *ae_dev = hdev->ae_dev;
struct hclge_vf_to_pf_msg send_msg;
if (!test_bit(HNAE3_DEV_SUPPORT_VLAN_FLTR_MDF_B, ae_dev->caps))
return -EOPNOTSUPP;
hclgevf_build_send_msg(&send_msg, HCLGE_MBX_SET_VLAN,
HCLGE_MBX_ENABLE_VLAN_FILTER);
send_msg.data[0] = enable ? 1 : 0;
return hclgevf_send_mbx_msg(hdev, &send_msg, true, NULL, 0);
}
static int hclgevf_set_vlan_filter(struct hnae3_handle *handle, static int hclgevf_set_vlan_filter(struct hnae3_handle *handle,
__be16 proto, u16 vlan_id, __be16 proto, u16 vlan_id,
bool is_kill) bool is_kill)
...@@ -2466,6 +2490,10 @@ static int hclgevf_configure(struct hclgevf_dev *hdev) ...@@ -2466,6 +2490,10 @@ static int hclgevf_configure(struct hclgevf_dev *hdev)
{ {
int ret; int ret;
ret = hclgevf_get_basic_info(hdev);
if (ret)
return ret;
/* get current port based vlan state from PF */ /* get current port based vlan state from PF */
ret = hclgevf_get_port_base_vlan_filter_state(hdev); ret = hclgevf_get_port_base_vlan_filter_state(hdev);
if (ret) if (ret)
...@@ -2481,12 +2509,7 @@ static int hclgevf_configure(struct hclgevf_dev *hdev) ...@@ -2481,12 +2509,7 @@ static int hclgevf_configure(struct hclgevf_dev *hdev)
if (ret) if (ret)
return ret; return ret;
ret = hclgevf_get_pf_media_type(hdev); return hclgevf_get_pf_media_type(hdev);
if (ret)
return ret;
/* get tc configuration from PF */
return hclgevf_get_tc_info(hdev);
} }
static int hclgevf_alloc_hdev(struct hnae3_ae_dev *ae_dev) static int hclgevf_alloc_hdev(struct hnae3_ae_dev *ae_dev)
...@@ -3801,6 +3824,7 @@ static const struct hnae3_ae_ops hclgevf_ops = { ...@@ -3801,6 +3824,7 @@ static const struct hnae3_ae_ops hclgevf_ops = {
.get_tc_size = hclgevf_get_tc_size, .get_tc_size = hclgevf_get_tc_size,
.get_fw_version = hclgevf_get_fw_version, .get_fw_version = hclgevf_get_fw_version,
.set_vlan_filter = hclgevf_set_vlan_filter, .set_vlan_filter = hclgevf_set_vlan_filter,
.enable_vlan_filter = hclgevf_enable_vlan_filter,
.enable_hw_strip_rxvtag = hclgevf_en_hw_strip_rxvtag, .enable_hw_strip_rxvtag = hclgevf_en_hw_strip_rxvtag,
.reset_event = hclgevf_reset_event, .reset_event = hclgevf_reset_event,
.set_default_reset_request = hclgevf_set_def_reset_request, .set_default_reset_request = hclgevf_set_def_reset_request,
......
...@@ -285,6 +285,7 @@ struct hclgevf_dev { ...@@ -285,6 +285,7 @@ struct hclgevf_dev {
struct semaphore reset_sem; /* protect reset process */ struct semaphore reset_sem; /* protect reset process */
u32 fw_version; u32 fw_version;
u16 mbx_api_version;
u16 num_tqps; /* num task queue pairs of this VF */ u16 num_tqps; /* num task queue pairs of this VF */
u16 alloc_rss_size; /* allocated RSS task queue */ u16 alloc_rss_size; /* allocated RSS task queue */
......
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