net: hns3: add vlan offload config command

This patch adds vlan offload config commands, initializes
the rules of tx/rx vlan tag handle for hw.

Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: Jian Shen <shenjian15@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Peng Li 2017-12-22 12:21:46 +08:00 committed by David S. Miller
parent 7564094cd9
commit 5f6ea83fc9
3 changed files with 233 additions and 6 deletions

View File

@ -180,6 +180,10 @@ enum hclge_opcode_type {
/* Promisuous mode command */
HCLGE_OPC_CFG_PROMISC_MODE = 0x0E01,
/* Vlan offload command */
HCLGE_OPC_VLAN_PORT_TX_CFG = 0x0F01,
HCLGE_OPC_VLAN_PORT_RX_CFG = 0x0F02,
/* Interrupts cmd */
HCLGE_OPC_ADD_RING_TO_VECTOR = 0x1503,
HCLGE_OPC_DEL_RING_TO_VECTOR = 0x1504,
@ -670,6 +674,47 @@ struct hclge_vlan_filter_vf_cfg_cmd {
u8 vf_bitmap[16];
};
#define HCLGE_ACCEPT_TAG_B 0
#define HCLGE_ACCEPT_UNTAG_B 1
#define HCLGE_PORT_INS_TAG1_EN_B 2
#define HCLGE_PORT_INS_TAG2_EN_B 3
#define HCLGE_CFG_NIC_ROCE_SEL_B 4
struct hclge_vport_vtag_tx_cfg_cmd {
u8 vport_vlan_cfg;
u8 vf_offset;
u8 rsv1[2];
__le16 def_vlan_tag1;
__le16 def_vlan_tag2;
u8 vf_bitmap[8];
u8 rsv2[8];
};
#define HCLGE_REM_TAG1_EN_B 0
#define HCLGE_REM_TAG2_EN_B 1
#define HCLGE_SHOW_TAG1_EN_B 2
#define HCLGE_SHOW_TAG2_EN_B 3
struct hclge_vport_vtag_rx_cfg_cmd {
u8 vport_vlan_cfg;
u8 vf_offset;
u8 rsv1[6];
u8 vf_bitmap[8];
u8 rsv2[8];
};
struct hclge_tx_vlan_type_cfg_cmd {
__le16 ot_vlan_type;
__le16 in_vlan_type;
u8 rsv[20];
};
struct hclge_rx_vlan_type_cfg_cmd {
__le16 ot_fst_vlan_type;
__le16 ot_sec_vlan_type;
__le16 in_fst_vlan_type;
__le16 in_sec_vlan_type;
u8 rsv[16];
};
struct hclge_cfg_com_tqp_queue_cmd {
__le16 tqp_id;
__le16 stream_id;

View File

@ -4380,23 +4380,169 @@ static int hclge_set_vf_vlan_filter(struct hnae3_handle *handle, int vfid,
return hclge_set_vf_vlan_common(hdev, vfid, false, vlan, qos, proto);
}
static int hclge_set_vlan_tx_offload_cfg(struct hclge_vport *vport)
{
struct hclge_tx_vtag_cfg *vcfg = &vport->txvlan_cfg;
struct hclge_vport_vtag_tx_cfg_cmd *req;
struct hclge_dev *hdev = vport->back;
struct hclge_desc desc;
int status;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_PORT_TX_CFG, false);
req = (struct hclge_vport_vtag_tx_cfg_cmd *)desc.data;
req->def_vlan_tag1 = cpu_to_le16(vcfg->default_tag1);
req->def_vlan_tag2 = cpu_to_le16(vcfg->default_tag2);
hnae_set_bit(req->vport_vlan_cfg, HCLGE_ACCEPT_TAG_B,
vcfg->accept_tag ? 1 : 0);
hnae_set_bit(req->vport_vlan_cfg, HCLGE_ACCEPT_UNTAG_B,
vcfg->accept_untag ? 1 : 0);
hnae_set_bit(req->vport_vlan_cfg, HCLGE_PORT_INS_TAG1_EN_B,
vcfg->insert_tag1_en ? 1 : 0);
hnae_set_bit(req->vport_vlan_cfg, HCLGE_PORT_INS_TAG2_EN_B,
vcfg->insert_tag2_en ? 1 : 0);
hnae_set_bit(req->vport_vlan_cfg, HCLGE_CFG_NIC_ROCE_SEL_B, 0);
req->vf_offset = vport->vport_id / HCLGE_VF_NUM_PER_CMD;
req->vf_bitmap[req->vf_offset] =
1 << (vport->vport_id % HCLGE_VF_NUM_PER_BYTE);
status = hclge_cmd_send(&hdev->hw, &desc, 1);
if (status)
dev_err(&hdev->pdev->dev,
"Send port txvlan cfg command fail, ret =%d\n",
status);
return status;
}
static int hclge_set_vlan_rx_offload_cfg(struct hclge_vport *vport)
{
struct hclge_rx_vtag_cfg *vcfg = &vport->rxvlan_cfg;
struct hclge_vport_vtag_rx_cfg_cmd *req;
struct hclge_dev *hdev = vport->back;
struct hclge_desc desc;
int status;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_VLAN_PORT_RX_CFG, false);
req = (struct hclge_vport_vtag_rx_cfg_cmd *)desc.data;
hnae_set_bit(req->vport_vlan_cfg, HCLGE_REM_TAG1_EN_B,
vcfg->strip_tag1_en ? 1 : 0);
hnae_set_bit(req->vport_vlan_cfg, HCLGE_REM_TAG2_EN_B,
vcfg->strip_tag2_en ? 1 : 0);
hnae_set_bit(req->vport_vlan_cfg, HCLGE_SHOW_TAG1_EN_B,
vcfg->vlan1_vlan_prionly ? 1 : 0);
hnae_set_bit(req->vport_vlan_cfg, HCLGE_SHOW_TAG2_EN_B,
vcfg->vlan2_vlan_prionly ? 1 : 0);
req->vf_offset = vport->vport_id / HCLGE_VF_NUM_PER_CMD;
req->vf_bitmap[req->vf_offset] =
1 << (vport->vport_id % HCLGE_VF_NUM_PER_BYTE);
status = hclge_cmd_send(&hdev->hw, &desc, 1);
if (status)
dev_err(&hdev->pdev->dev,
"Send port rxvlan cfg command fail, ret =%d\n",
status);
return status;
}
static int hclge_set_vlan_protocol_type(struct hclge_dev *hdev)
{
struct hclge_rx_vlan_type_cfg_cmd *rx_req;
struct hclge_tx_vlan_type_cfg_cmd *tx_req;
struct hclge_desc desc;
int status;
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MAC_VLAN_TYPE_ID, false);
rx_req = (struct hclge_rx_vlan_type_cfg_cmd *)desc.data;
rx_req->ot_fst_vlan_type =
cpu_to_le16(hdev->vlan_type_cfg.rx_ot_fst_vlan_type);
rx_req->ot_sec_vlan_type =
cpu_to_le16(hdev->vlan_type_cfg.rx_ot_sec_vlan_type);
rx_req->in_fst_vlan_type =
cpu_to_le16(hdev->vlan_type_cfg.rx_in_fst_vlan_type);
rx_req->in_sec_vlan_type =
cpu_to_le16(hdev->vlan_type_cfg.rx_in_sec_vlan_type);
status = hclge_cmd_send(&hdev->hw, &desc, 1);
if (status) {
dev_err(&hdev->pdev->dev,
"Send rxvlan protocol type command fail, ret =%d\n",
status);
return status;
}
hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_MAC_VLAN_INSERT, false);
tx_req = (struct hclge_tx_vlan_type_cfg_cmd *)&desc.data;
tx_req->ot_vlan_type = cpu_to_le16(hdev->vlan_type_cfg.tx_ot_vlan_type);
tx_req->in_vlan_type = cpu_to_le16(hdev->vlan_type_cfg.tx_in_vlan_type);
status = hclge_cmd_send(&hdev->hw, &desc, 1);
if (status)
dev_err(&hdev->pdev->dev,
"Send txvlan protocol type command fail, ret =%d\n",
status);
return status;
}
static int hclge_init_vlan_config(struct hclge_dev *hdev)
{
#define HCLGE_VLAN_TYPE_VF_TABLE 0
#define HCLGE_VLAN_TYPE_PORT_TABLE 1
#define HCLGE_FILTER_TYPE_VF 0
#define HCLGE_FILTER_TYPE_PORT 1
#define HCLGE_DEF_VLAN_TYPE 0x8100
struct hnae3_handle *handle;
struct hclge_vport *vport;
int ret;
int i;
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_VLAN_TYPE_VF_TABLE,
true);
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_VF, true);
if (ret)
return ret;
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_VLAN_TYPE_PORT_TABLE,
true);
ret = hclge_set_vlan_filter_ctrl(hdev, HCLGE_FILTER_TYPE_PORT, true);
if (ret)
return ret;
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;
hdev->vlan_type_cfg.rx_ot_sec_vlan_type = HCLGE_DEF_VLAN_TYPE;
hdev->vlan_type_cfg.tx_ot_vlan_type = HCLGE_DEF_VLAN_TYPE;
hdev->vlan_type_cfg.tx_in_vlan_type = HCLGE_DEF_VLAN_TYPE;
ret = hclge_set_vlan_protocol_type(hdev);
if (ret)
return ret;
for (i = 0; i < hdev->num_alloc_vport; i++) {
vport = &hdev->vport[i];
vport->txvlan_cfg.accept_tag = true;
vport->txvlan_cfg.accept_untag = true;
vport->txvlan_cfg.insert_tag1_en = false;
vport->txvlan_cfg.insert_tag2_en = false;
vport->txvlan_cfg.default_tag1 = 0;
vport->txvlan_cfg.default_tag2 = 0;
ret = hclge_set_vlan_tx_offload_cfg(vport);
if (ret)
return ret;
vport->rxvlan_cfg.strip_tag1_en = false;
vport->rxvlan_cfg.strip_tag2_en = true;
vport->rxvlan_cfg.vlan1_vlan_prionly = false;
vport->rxvlan_cfg.vlan2_vlan_prionly = false;
ret = hclge_set_vlan_rx_offload_cfg(vport);
if (ret)
return ret;
}
handle = &hdev->vport[0].nic;
return hclge_set_port_vlan_filter(handle, htons(ETH_P_8021Q), 0, false);
}

View File

@ -79,6 +79,10 @@
#define HCLGE_PHY_MDIX_STATUS_B (6)
#define HCLGE_PHY_SPEED_DUP_RESOLVE_B (11)
/* Factor used to calculate offset and bitmap of VF num */
#define HCLGE_VF_NUM_PER_CMD 64
#define HCLGE_VF_NUM_PER_BYTE 8
/* Reset related Registers */
#define HCLGE_MISC_RESET_STS_REG 0x20700
#define HCLGE_GLOBAL_RESET_REG 0x20A00
@ -424,6 +428,15 @@ struct hclge_hw_stats {
struct hclge_32_bit_stats all_32_bit_stats;
};
struct hclge_vlan_type_cfg {
u16 rx_ot_fst_vlan_type;
u16 rx_ot_sec_vlan_type;
u16 rx_in_fst_vlan_type;
u16 rx_in_sec_vlan_type;
u16 tx_ot_vlan_type;
u16 tx_in_vlan_type;
};
struct hclge_dev {
struct pci_dev *pdev;
struct hnae3_ae_dev *ae_dev;
@ -510,6 +523,26 @@ struct hclge_dev {
enum hclge_mta_dmac_sel_type mta_mac_sel_type;
bool enable_mta; /* Mutilcast filter enable */
bool accept_mta_mc; /* Whether accept mta filter multicast */
struct hclge_vlan_type_cfg vlan_type_cfg;
};
/* VPort level vlan tag configuration for TX direction */
struct hclge_tx_vtag_cfg {
bool accept_tag; /* Whether accept tagged packet from host */
bool accept_untag; /* Whether accept untagged packet from host */
bool insert_tag1_en; /* Whether insert inner vlan tag */
bool insert_tag2_en; /* Whether insert outer vlan tag */
u16 default_tag1; /* The default inner vlan tag to insert */
u16 default_tag2; /* The default outer vlan tag to insert */
};
/* VPort level vlan tag configuration for RX direction */
struct hclge_rx_vtag_cfg {
bool strip_tag1_en; /* Whether strip inner vlan tag */
bool strip_tag2_en; /* Whether strip outer vlan tag */
bool vlan1_vlan_prionly;/* Inner VLAN Tag up to descriptor Enable */
bool vlan2_vlan_prionly;/* Outer VLAN Tag up to descriptor Enable */
};
struct hclge_vport {
@ -524,6 +557,9 @@ struct hclge_vport {
u16 bw_limit; /* VSI BW Limit (0 = disabled) */
u8 dwrr;
struct hclge_tx_vtag_cfg txvlan_cfg;
struct hclge_rx_vtag_cfg rxvlan_cfg;
int vport_id;
struct hclge_dev *back; /* Back reference to associated dev */
struct hnae3_handle nic;