提交 0961e03b 编写于 作者: Y Yonglong Liu 提交者: Xie XiuQi

net: hns: modify promisc entry to avoid mismatch

driver inclusion
category: bugfix
bugzilla: NA
CVE: NA

---------------------------------------

1. change promisc tcam entry position to the END of 512 tcam entries.
2. separate one promisc entry to: mc & uc, to avoid the mismatch.
Signed-off-by: NYonglong Liu <liuyonglong@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 1ac3f5d4
......@@ -934,6 +934,74 @@ static void hns_dsaf_tcam_mc_cfg(
spin_unlock_bh(&dsaf_dev->tcam_lock);
}
/**
* hns_dsaf_tcam_uc_cfg_vague - INT
* @dsaf_dev: dsa fabric device struct pointer
* @address,
* @ptbl_tcam_data,
*/
static void
hns_dsaf_tcam_uc_cfg_vague(struct dsaf_device *dsaf_dev,
u32 address,
struct dsaf_tbl_tcam_data *ptbl_tcam_data,
struct dsaf_tbl_tcam_data *ptbl_tcam_mask,
struct dsaf_tbl_tcam_ucast_cfg *ptbl_tcam_ucast)
{
spin_lock_bh(&dsaf_dev->tcam_lock);
/*Write Addr*/
hns_dsaf_tbl_tcam_addr_cfg(dsaf_dev, address);
/*Write Tcam Data*/
hns_dsaf_tbl_tcam_data_cfg(dsaf_dev, ptbl_tcam_data);
/*Write Tcam ucast*/
hns_dsaf_tbl_tcam_ucast_cfg(dsaf_dev, ptbl_tcam_ucast);
/*Write Match Data*/
hns_dsaf_tbl_tcam_match_cfg(dsaf_dev, ptbl_tcam_mask);
/*Write Pulse*/
hns_dsaf_tbl_tcam_data_ucast_pul(dsaf_dev);
/*Restore Match Data*/
ptbl_tcam_mask->tbl_tcam_data_high = 0xffffffff;
ptbl_tcam_mask->tbl_tcam_data_low = 0xffffffff;
hns_dsaf_tbl_tcam_match_cfg(dsaf_dev, ptbl_tcam_mask);
spin_unlock_bh(&dsaf_dev->tcam_lock);
}
/**
* hns_dsaf_tcam_mc_cfg_vague - INT
* @dsaf_dev: dsa fabric device struct pointer
* @address,
* @ptbl_tcam_data,
* @ptbl_tcam_mask
* @ptbl_tcam_mcast
*/
static void
hns_dsaf_tcam_mc_cfg_vague(struct dsaf_device *dsaf_dev,
u32 address,
struct dsaf_tbl_tcam_data *ptbl_tcam_data,
struct dsaf_tbl_tcam_data *ptbl_tcam_mask,
struct dsaf_tbl_tcam_mcast_cfg *ptbl_tcam_mcast)
{
spin_lock_bh(&dsaf_dev->tcam_lock);
hns_dsaf_tbl_tcam_addr_cfg(dsaf_dev, address);
/*Write Tcam Data*/
hns_dsaf_tbl_tcam_data_cfg(dsaf_dev, ptbl_tcam_data);
/*Write Tcam mcast*/
hns_dsaf_tbl_tcam_mcast_cfg(dsaf_dev, ptbl_tcam_mcast);
/*Write Match Data*/
hns_dsaf_tbl_tcam_match_cfg(dsaf_dev, ptbl_tcam_mask);
/*Write Pulse*/
hns_dsaf_tbl_tcam_data_mcast_pul(dsaf_dev);
/*Restore Match Data*/
ptbl_tcam_mask->tbl_tcam_data_high = 0xffffffff;
ptbl_tcam_mask->tbl_tcam_data_low = 0xffffffff;
hns_dsaf_tbl_tcam_match_cfg(dsaf_dev, ptbl_tcam_mask);
spin_unlock_bh(&dsaf_dev->tcam_lock);
}
/**
* hns_dsaf_tcam_mc_invld - INT
* @dsaf_id: dsa fabric id
......@@ -1492,6 +1560,27 @@ static u16 hns_dsaf_find_empty_mac_entry(struct dsaf_device *dsaf_dev)
return DSAF_INVALID_ENTRY_IDX;
}
/**
* hns_dsaf_find_empty_mac_entry_reverse
* search dsa fabric soft empty-entry from the end
* @dsaf_dev: dsa fabric device struct pointer
*/
static u16 hns_dsaf_find_empty_mac_entry_reverse(struct dsaf_device *dsaf_dev)
{
struct dsaf_drv_priv *priv = hns_dsaf_dev_priv(dsaf_dev);
struct dsaf_drv_soft_mac_tbl *soft_mac_entry;
u32 i;
soft_mac_entry = priv->soft_mac_tbl + (DSAF_TCAM_SUM - 1);
for (i = (DSAF_TCAM_SUM - 1); i > 0; i--) {
/* search all entry from end to start.*/
if (soft_mac_entry->index == DSAF_INVALID_ENTRY_IDX)
return i;
soft_mac_entry--;
}
return DSAF_INVALID_ENTRY_IDX;
}
/**
* hns_dsaf_set_mac_key - set mac key
* @dsaf_dev: dsa fabric device struct pointer
......@@ -2673,58 +2762,167 @@ int hns_dsaf_get_regs_count(void)
return DSAF_DUMP_REGS_NUM;
}
/* Reserve the last TCAM entry for promisc support */
#define dsaf_promisc_tcam_entry(port) \
(DSAF_TCAM_SUM - DSAFV2_MAC_FUZZY_TCAM_NUM + (port))
void hns_dsaf_set_promisc_tcam(struct dsaf_device *dsaf_dev,
u32 port, bool enable)
#define MAC_NUM_OCTETS_PER_ADDR 6
static int set_promisc_tcam_enable(struct dsaf_device *dsaf_dev, u32 port)
{
struct dsaf_tbl_tcam_ucast_cfg tbl_tcam_ucast = {0, 1, 0, 0, 0x80};
struct dsaf_tbl_tcam_data tbl_tcam_data_mc = {0x01000000, port};
struct dsaf_tbl_tcam_data tbl_tcam_mask_uc = {0x01000000, 0xf};
struct dsaf_tbl_tcam_mcast_cfg tbl_tcam_mcast = {0, 0, {0} };
struct dsaf_drv_priv *priv = hns_dsaf_dev_priv(dsaf_dev);
struct dsaf_drv_soft_mac_tbl *soft_mac_entry = priv->soft_mac_tbl;
u16 entry_index;
struct dsaf_drv_tbl_tcam_key tbl_tcam_data, tbl_tcam_mask;
struct dsaf_tbl_tcam_mcast_cfg mac_data = {0};
struct dsaf_tbl_tcam_data tbl_tcam_data_uc = {0, port};
struct dsaf_drv_mac_single_dest_entry mask_entry;
struct dsaf_drv_tbl_tcam_key temp_key, mask_key;
struct dsaf_drv_soft_mac_tbl *soft_mac_entry;
u16 entry_index = DSAF_INVALID_ENTRY_IDX;
u8 addr[MAC_NUM_OCTETS_PER_ADDR] = {0};
struct dsaf_drv_tbl_tcam_key mac_key;
struct hns_mac_cb *mac_cb;
u8 port_num;
u16 mskid;
if ((AE_IS_VER1(dsaf_dev->dsaf_ver)) || HNS_DSAF_IS_DEBUG(dsaf_dev))
return;
/* promisc use vague table match with vlanid = 0 & macaddr = 0 */
hns_dsaf_set_mac_key(dsaf_dev, &mac_key, 0x00, port, addr);
entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
if (entry_index != DSAF_INVALID_ENTRY_IDX)
return -EINVAL;
/* put promisc tcam entry in the end. */
/* 1. set promisc unicast vague tcam entry. */
entry_index = hns_dsaf_find_empty_mac_entry_reverse(dsaf_dev);
if (entry_index == DSAF_INVALID_ENTRY_IDX) {
dev_err(dsaf_dev->dev,
"enable uc promisc failed (port:%#x)\n",
port);
return -EINVAL;
}
mac_cb = dsaf_dev->mac_cb[port];
(void)hns_mac_get_inner_port_num(mac_cb, 0, &port_num);
tbl_tcam_ucast.tbl_ucast_out_port = port_num;
/* config uc vague table */
hns_dsaf_tcam_uc_cfg_vague(dsaf_dev, entry_index,
&tbl_tcam_data_uc,
&tbl_tcam_mask_uc,
&tbl_tcam_ucast);
/* update software entry */
soft_mac_entry = priv->soft_mac_tbl;
soft_mac_entry += entry_index;
soft_mac_entry->index = entry_index;
soft_mac_entry->tcam_key.high.val = mac_key.high.val;
soft_mac_entry->tcam_key.low.val = mac_key.low.val;
/* step back to the START for mc. */
soft_mac_entry = priv->soft_mac_tbl;
/* find the tcam entry index for promisc */
entry_index = dsaf_promisc_tcam_entry(port);
memset(&tbl_tcam_data, 0, sizeof(tbl_tcam_data));
memset(&tbl_tcam_mask, 0, sizeof(tbl_tcam_mask));
/* config key mask */
if (enable) {
dsaf_set_field(tbl_tcam_data.low.bits.port_vlan,
DSAF_TBL_TCAM_KEY_PORT_M,
DSAF_TBL_TCAM_KEY_PORT_S, port);
dsaf_set_field(tbl_tcam_mask.low.bits.port_vlan,
DSAF_TBL_TCAM_KEY_PORT_M,
DSAF_TBL_TCAM_KEY_PORT_S, 0xf);
/* SUB_QID */
dsaf_set_bit(mac_data.tbl_mcast_port_msk[0],
DSAF_SERVICE_NW_NUM, true);
mac_data.tbl_mcast_item_vld = true; /* item_vld bit */
/* 2. set promisc multicast vague tcam entry. */
entry_index = hns_dsaf_find_empty_mac_entry_reverse(dsaf_dev);
if (entry_index == DSAF_INVALID_ENTRY_IDX) {
dev_err(dsaf_dev->dev,
"enable mc promisc failed (port:%#x)\n",
port);
return -EINVAL;
}
memset(&mask_entry, 0x0, sizeof(mask_entry));
memset(&mask_key, 0x0, sizeof(mask_key));
memset(&temp_key, 0x0, sizeof(temp_key));
mask_entry.addr[0] = 0x01;
hns_dsaf_set_mac_key(dsaf_dev, &mask_key,
mask_entry.in_vlan_id, port, mask_entry.addr);
tbl_tcam_mcast.tbl_mcast_item_vld = 1;
tbl_tcam_mcast.tbl_mcast_old_en = 0;
if (port < DSAF_SERVICE_NW_NUM) {
mskid = port;
} else if (port >= DSAF_BASE_INNER_PORT_NUM) {
mskid = port - DSAF_BASE_INNER_PORT_NUM + DSAF_SERVICE_NW_NUM;
} else {
mac_data.tbl_mcast_item_vld = false; /* item_vld bit */
dev_err(dsaf_dev->dev,
"%s,pnum(%d)error,key(%#x:%#x)\n",
dsaf_dev->ae_dev.name,
port,
mask_key.high.val,
mask_key.low.val);
return -EINVAL;
}
dsaf_set_bit(tbl_tcam_mcast.tbl_mcast_port_msk[mskid / 32],
mskid % 32,
1);
memcpy(&temp_key, &mask_key, sizeof(mask_key));
hns_dsaf_tcam_mc_cfg_vague(dsaf_dev,
entry_index,
&tbl_tcam_data_mc,
(struct dsaf_tbl_tcam_data *)(&mask_key),
&tbl_tcam_mcast);
/* update software entry */
soft_mac_entry += entry_index;
soft_mac_entry->index = entry_index;
soft_mac_entry->tcam_key.high.val = temp_key.high.val;
soft_mac_entry->tcam_key.low.val = temp_key.low.val;
dev_dbg(dsaf_dev->dev,
"set_promisc_entry, %s Mac key(%#x:%#x) entry_index%d\n",
dsaf_dev->ae_dev.name, tbl_tcam_data.high.val,
tbl_tcam_data.low.val, entry_index);
return 0;
}
/* config promisc entry with mask */
hns_dsaf_tcam_mc_cfg(dsaf_dev, entry_index,
(struct dsaf_tbl_tcam_data *)&tbl_tcam_data,
(struct dsaf_tbl_tcam_data *)&tbl_tcam_mask,
&mac_data);
static int set_promisc_tcam_disable(struct dsaf_device *dsaf_dev, u32 port)
{
struct dsaf_tbl_tcam_data tbl_tcam_data_mc = {0x01000000, port};
struct dsaf_tbl_tcam_ucast_cfg tbl_tcam_ucast = {0, 0, 0, 0, 0};
struct dsaf_tbl_tcam_mcast_cfg tbl_tcam_mcast = {0, 0, {0} };
struct dsaf_drv_priv *priv = hns_dsaf_dev_priv(dsaf_dev);
struct dsaf_tbl_tcam_data tbl_tcam_data_uc = {0, 0};
struct dsaf_tbl_tcam_data tbl_tcam_mask = {0, 0};
struct dsaf_drv_soft_mac_tbl *soft_mac_entry;
u16 entry_index = DSAF_INVALID_ENTRY_IDX;
u8 addr[MAC_NUM_OCTETS_PER_ADDR] = {0};
struct dsaf_drv_tbl_tcam_key mac_key;
/* config software entry */
/* 1. delete uc vague tcam entry. */
/* promisc use vague table match with vlanid = 0 & macaddr = 0 */
hns_dsaf_set_mac_key(dsaf_dev, &mac_key, 0x00, port, addr);
entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
if (entry_index == DSAF_INVALID_ENTRY_IDX)
return -EINVAL;
/* config uc vague table */
hns_dsaf_tcam_uc_cfg_vague(dsaf_dev, entry_index,
&tbl_tcam_data_uc,
&tbl_tcam_mask,
&tbl_tcam_ucast);
/* update soft management table. */
soft_mac_entry = priv->soft_mac_tbl;
soft_mac_entry += entry_index;
soft_mac_entry->index = enable ? entry_index : DSAF_INVALID_ENTRY_IDX;
soft_mac_entry->index = DSAF_INVALID_ENTRY_IDX;
/* step back to the START for mc. */
soft_mac_entry = priv->soft_mac_tbl;
/* 2. delete mc vague tcam entry. */
addr[0] = 0x01;
memset(&mac_key, 0x0, sizeof(mac_key));
hns_dsaf_set_mac_key(dsaf_dev, &mac_key, 0x00, port, addr);
entry_index = hns_dsaf_find_soft_mac_entry(dsaf_dev, &mac_key);
if (entry_index == DSAF_INVALID_ENTRY_IDX)
return -EINVAL;
/* config mc vague table */
hns_dsaf_tcam_mc_cfg_vague(dsaf_dev, entry_index,
&tbl_tcam_data_mc,
&tbl_tcam_mask,
&tbl_tcam_mcast);
/* update soft management table. */
soft_mac_entry += entry_index;
soft_mac_entry->index = DSAF_INVALID_ENTRY_IDX;
return 0;
}
/* Reserve the last TCAM entry for promisc support */
int hns_dsaf_set_promisc_tcam(struct dsaf_device *dsaf_dev,
u32 port, bool enable)
{
if (enable)
return set_promisc_tcam_enable(dsaf_dev, port);
return set_promisc_tcam_disable(dsaf_dev, port);
}
int hns_dsaf_wait_pkt_clean(struct dsaf_device *dsaf_dev, int port)
......
......@@ -452,7 +452,7 @@ void hns_dsaf_get_strings(int stringset, u8 *data, int port,
void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data);
int hns_dsaf_get_regs_count(void);
void hns_dsaf_set_promisc_mode(struct dsaf_device *dsaf_dev, u32 en);
void hns_dsaf_set_promisc_tcam(struct dsaf_device *dsaf_dev,
int hns_dsaf_set_promisc_tcam(struct dsaf_device *dsaf_dev,
u32 port, bool enable);
void hns_dsaf_get_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
......
......@@ -54,7 +54,7 @@ void hns_rcb_wait_fbd_clean(struct hnae_queue **qs, int q_num, u32 flag)
RCB_RING_TX_RING_FBDNUM_REG);
if (flag & RCB_INT_FLAG_RX)
fbd_num += dsaf_read_dev(qs[i],
RCB_RING_RX_RING_FBDNUM_REG);
RCB_RING_RX_RING_FBDNUM_REG);
if (!fbd_num)
i++;
if (wait_cnt >= 10000)
......@@ -63,7 +63,10 @@ void hns_rcb_wait_fbd_clean(struct hnae_queue **qs, int q_num, u32 flag)
if (i < q_num)
dev_err(qs[i]->handle->owner_dev,
"queue(%d) wait fbd(%d) clean fail!!\n", i, fbd_num);
"tx(1)/rx(2):%d, queue(%d) wait fbd(%d) clean fail!!\n",
flag,
i,
fbd_num);
}
int hns_rcb_wait_tx_ring_clean(struct hnae_queue *qs)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册