Commit 5ada37b5 authored by Lisheng's avatar Lisheng Committed by David S. Miller

net: hns: add support of pause frame ctrl for HNS V2

The patch adds support of pause ctrl for HNS V2, and this feature is lost
by HNS V1:
       1) service ports can disable rx pause frame,
       2) debug ports can open tx/rx pause frame.

And this patch updates the REGs about the pause ctrl when updated
status function called by upper layer routine.
Signed-off-by: default avatarLisheng <lisheng011@huawei.com>
Signed-off-by: default avatarYisen Zhuang <Yisen.Zhuang@huawei.com>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7822ce73
...@@ -399,11 +399,16 @@ static void hns_ae_get_ring_bdnum_limit(struct hnae_queue *queue, ...@@ -399,11 +399,16 @@ static void hns_ae_get_ring_bdnum_limit(struct hnae_queue *queue,
static void hns_ae_get_pauseparam(struct hnae_handle *handle, static void hns_ae_get_pauseparam(struct hnae_handle *handle,
u32 *auto_neg, u32 *rx_en, u32 *tx_en) u32 *auto_neg, u32 *rx_en, u32 *tx_en)
{ {
assert(handle); struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
hns_mac_get_autoneg(hns_get_mac_cb(handle), auto_neg); hns_mac_get_autoneg(mac_cb, auto_neg);
hns_mac_get_pauseparam(hns_get_mac_cb(handle), rx_en, tx_en); hns_mac_get_pauseparam(mac_cb, rx_en, tx_en);
/* Service port's pause feature is provided by DSAF, not mac */
if (handle->port_type == HNAE_PORT_SERVICE)
hns_dsaf_get_rx_mac_pause_en(dsaf_dev, mac_cb->mac_id, rx_en);
} }
static int hns_ae_set_autoneg(struct hnae_handle *handle, u8 enable) static int hns_ae_set_autoneg(struct hnae_handle *handle, u8 enable)
...@@ -436,12 +441,21 @@ static int hns_ae_set_pauseparam(struct hnae_handle *handle, ...@@ -436,12 +441,21 @@ static int hns_ae_set_pauseparam(struct hnae_handle *handle,
u32 autoneg, u32 rx_en, u32 tx_en) u32 autoneg, u32 rx_en, u32 tx_en)
{ {
struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle); struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
int ret; int ret;
ret = hns_mac_set_autoneg(mac_cb, autoneg); ret = hns_mac_set_autoneg(mac_cb, autoneg);
if (ret) if (ret)
return ret; return ret;
/* Service port's pause feature is provided by DSAF, not mac */
if (handle->port_type == HNAE_PORT_SERVICE) {
ret = hns_dsaf_set_rx_mac_pause_en(dsaf_dev,
mac_cb->mac_id, rx_en);
if (ret)
return ret;
rx_en = 0;
}
return hns_mac_set_pauseparam(mac_cb, rx_en, tx_en); return hns_mac_set_pauseparam(mac_cb, rx_en, tx_en);
} }
......
...@@ -439,9 +439,8 @@ int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vmid, bool enable) ...@@ -439,9 +439,8 @@ int hns_mac_vm_config_bc_en(struct hns_mac_cb *mac_cb, u32 vmid, bool enable)
void hns_mac_reset(struct hns_mac_cb *mac_cb) void hns_mac_reset(struct hns_mac_cb *mac_cb)
{ {
struct mac_driver *drv; struct mac_driver *drv = hns_mac_get_drv(mac_cb);
bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);
drv = hns_mac_get_drv(mac_cb);
drv->mac_init(drv); drv->mac_init(drv);
...@@ -456,7 +455,7 @@ void hns_mac_reset(struct hns_mac_cb *mac_cb) ...@@ -456,7 +455,7 @@ void hns_mac_reset(struct hns_mac_cb *mac_cb)
if (drv->mac_pausefrm_cfg) { if (drv->mac_pausefrm_cfg) {
if (mac_cb->mac_type == HNAE_PORT_DEBUG) if (mac_cb->mac_type == HNAE_PORT_DEBUG)
drv->mac_pausefrm_cfg(drv, 0, 0); drv->mac_pausefrm_cfg(drv, !is_ver1, !is_ver1);
else /* mac rx must disable, dsaf pfc close instead of it*/ else /* mac rx must disable, dsaf pfc close instead of it*/
drv->mac_pausefrm_cfg(drv, 0, 1); drv->mac_pausefrm_cfg(drv, 0, 1);
} }
...@@ -561,14 +560,6 @@ void hns_mac_get_pauseparam(struct hns_mac_cb *mac_cb, u32 *rx_en, u32 *tx_en) ...@@ -561,14 +560,6 @@ void hns_mac_get_pauseparam(struct hns_mac_cb *mac_cb, u32 *rx_en, u32 *tx_en)
*rx_en = 0; *rx_en = 0;
*tx_en = 0; *tx_en = 0;
} }
/* Due to the chip defect, the service mac's rx pause CAN'T be enabled.
* We set the rx pause frm always be true (1), because DSAF deals with
* the rx pause frm instead of service mac. After all, we still support
* rx pause frm.
*/
if (mac_cb->mac_type == HNAE_PORT_SERVICE)
*rx_en = 1;
} }
/** /**
...@@ -602,20 +593,13 @@ int hns_mac_set_autoneg(struct hns_mac_cb *mac_cb, u8 enable) ...@@ -602,20 +593,13 @@ int hns_mac_set_autoneg(struct hns_mac_cb *mac_cb, u8 enable)
int hns_mac_set_pauseparam(struct hns_mac_cb *mac_cb, u32 rx_en, u32 tx_en) int hns_mac_set_pauseparam(struct hns_mac_cb *mac_cb, u32 rx_en, u32 tx_en)
{ {
struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb); struct mac_driver *mac_ctrl_drv = hns_mac_get_drv(mac_cb);
bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);
if (mac_cb->mac_type == HNAE_PORT_SERVICE) { if (mac_cb->mac_type == HNAE_PORT_DEBUG) {
if (!rx_en) { if (is_ver1 && (tx_en || rx_en)) {
dev_err(mac_cb->dev, "disable rx_pause is not allowed!"); dev_err(mac_cb->dev, "macv1 cann't enable tx/rx_pause!");
return -EINVAL; return -EINVAL;
} }
} else if (mac_cb->mac_type == HNAE_PORT_DEBUG) {
if (tx_en || rx_en) {
dev_err(mac_cb->dev, "enable tx_pause or enable rx_pause are not allowed!");
return -EINVAL;
}
} else {
dev_err(mac_cb->dev, "Unsupport this operation!");
return -EINVAL;
} }
if (mac_ctrl_drv->mac_pausefrm_cfg) if (mac_ctrl_drv->mac_pausefrm_cfg)
......
...@@ -1022,12 +1022,52 @@ static void hns_dsaf_tbl_tcam_init(struct dsaf_device *dsaf_dev) ...@@ -1022,12 +1022,52 @@ static void hns_dsaf_tbl_tcam_init(struct dsaf_device *dsaf_dev)
* @mac_cb: mac contrl block * @mac_cb: mac contrl block
*/ */
static void hns_dsaf_pfc_en_cfg(struct dsaf_device *dsaf_dev, static void hns_dsaf_pfc_en_cfg(struct dsaf_device *dsaf_dev,
int mac_id, int en) int mac_id, int tc_en)
{ {
if (!en) dsaf_write_dev(dsaf_dev, DSAF_PFC_EN_0_REG + mac_id * 4, tc_en);
dsaf_write_dev(dsaf_dev, DSAF_PFC_EN_0_REG + mac_id * 4, 0); }
static void hns_dsaf_set_pfc_pause(struct dsaf_device *dsaf_dev,
int mac_id, int tx_en, int rx_en)
{
if (AE_IS_VER1(dsaf_dev->dsaf_ver)) {
if (!tx_en || !rx_en)
dev_err(dsaf_dev->dev, "dsaf v1 can not close pfc!\n");
return;
}
dsaf_set_dev_bit(dsaf_dev, DSAF_PAUSE_CFG_REG + mac_id * 4,
DSAF_PFC_PAUSE_RX_EN_B, !!rx_en);
dsaf_set_dev_bit(dsaf_dev, DSAF_PAUSE_CFG_REG + mac_id * 4,
DSAF_PFC_PAUSE_TX_EN_B, !!tx_en);
}
int hns_dsaf_set_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
u32 en)
{
if (AE_IS_VER1(dsaf_dev->dsaf_ver)) {
if (!en)
dev_err(dsaf_dev->dev, "dsafv1 can't close rx_pause!\n");
return -EINVAL;
}
dsaf_set_dev_bit(dsaf_dev, DSAF_PAUSE_CFG_REG + mac_id * 4,
DSAF_MAC_PAUSE_RX_EN_B, !!en);
return 0;
}
void hns_dsaf_get_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
u32 *en)
{
if (AE_IS_VER1(dsaf_dev->dsaf_ver))
*en = 1;
else else
dsaf_write_dev(dsaf_dev, DSAF_PFC_EN_0_REG + mac_id * 4, 0xff); *en = dsaf_get_dev_bit(dsaf_dev,
DSAF_PAUSE_CFG_REG + mac_id * 4,
DSAF_MAC_PAUSE_RX_EN_B);
} }
/** /**
...@@ -1039,6 +1079,7 @@ static void hns_dsaf_comm_init(struct dsaf_device *dsaf_dev) ...@@ -1039,6 +1079,7 @@ static void hns_dsaf_comm_init(struct dsaf_device *dsaf_dev)
{ {
u32 i; u32 i;
u32 o_dsaf_cfg; u32 o_dsaf_cfg;
bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver);
o_dsaf_cfg = dsaf_read_dev(dsaf_dev, DSAF_CFG_0_REG); o_dsaf_cfg = dsaf_read_dev(dsaf_dev, DSAF_CFG_0_REG);
dsaf_set_bit(o_dsaf_cfg, DSAF_CFG_EN_S, dsaf_dev->dsaf_en); dsaf_set_bit(o_dsaf_cfg, DSAF_CFG_EN_S, dsaf_dev->dsaf_en);
...@@ -1064,8 +1105,10 @@ static void hns_dsaf_comm_init(struct dsaf_device *dsaf_dev) ...@@ -1064,8 +1105,10 @@ static void hns_dsaf_comm_init(struct dsaf_device *dsaf_dev)
hns_dsaf_sw_port_type_cfg(dsaf_dev, DSAF_SW_PORT_TYPE_NON_VLAN); hns_dsaf_sw_port_type_cfg(dsaf_dev, DSAF_SW_PORT_TYPE_NON_VLAN);
/*set dsaf pfc to 0 for parseing rx pause*/ /*set dsaf pfc to 0 for parseing rx pause*/
for (i = 0; i < DSAF_COMM_CHN; i++) for (i = 0; i < DSAF_COMM_CHN; i++) {
hns_dsaf_pfc_en_cfg(dsaf_dev, i, 0); hns_dsaf_pfc_en_cfg(dsaf_dev, i, 0);
hns_dsaf_set_pfc_pause(dsaf_dev, i, is_ver1, is_ver1);
}
/*msk and clr exception irqs */ /*msk and clr exception irqs */
for (i = 0; i < DSAF_COMM_CHN; i++) { for (i = 0; i < DSAF_COMM_CHN; i++) {
...@@ -2013,6 +2056,8 @@ void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 node_num) ...@@ -2013,6 +2056,8 @@ void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 node_num)
{ {
struct dsaf_hw_stats *hw_stats struct dsaf_hw_stats *hw_stats
= &dsaf_dev->hw_stats[node_num]; = &dsaf_dev->hw_stats[node_num];
bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver);
u32 reg_tmp;
hw_stats->pad_drop += dsaf_read_dev(dsaf_dev, hw_stats->pad_drop += dsaf_read_dev(dsaf_dev,
DSAF_INODE_PAD_DISCARD_NUM_0_REG + 0x80 * (u64)node_num); DSAF_INODE_PAD_DISCARD_NUM_0_REG + 0x80 * (u64)node_num);
...@@ -2022,8 +2067,12 @@ void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 node_num) ...@@ -2022,8 +2067,12 @@ void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 node_num)
DSAF_INODE_FINAL_IN_PKT_NUM_0_REG + 0x80 * (u64)node_num); DSAF_INODE_FINAL_IN_PKT_NUM_0_REG + 0x80 * (u64)node_num);
hw_stats->rx_pkt_id += dsaf_read_dev(dsaf_dev, hw_stats->rx_pkt_id += dsaf_read_dev(dsaf_dev,
DSAF_INODE_SBM_PID_NUM_0_REG + 0x80 * (u64)node_num); DSAF_INODE_SBM_PID_NUM_0_REG + 0x80 * (u64)node_num);
hw_stats->rx_pause_frame += dsaf_read_dev(dsaf_dev,
DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG + 0x80 * (u64)node_num); reg_tmp = is_ver1 ? DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG :
DSAFV2_INODE_FINAL_IN_PAUSE_NUM_0_REG;
hw_stats->rx_pause_frame +=
dsaf_read_dev(dsaf_dev, reg_tmp + 0x80 * (u64)node_num);
hw_stats->release_buf_num += dsaf_read_dev(dsaf_dev, hw_stats->release_buf_num += dsaf_read_dev(dsaf_dev,
DSAF_INODE_SBM_RELS_NUM_0_REG + 0x80 * (u64)node_num); DSAF_INODE_SBM_RELS_NUM_0_REG + 0x80 * (u64)node_num);
hw_stats->sbm_drop += dsaf_read_dev(dsaf_dev, hw_stats->sbm_drop += dsaf_read_dev(dsaf_dev,
...@@ -2056,6 +2105,8 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data) ...@@ -2056,6 +2105,8 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data)
u32 i = 0; u32 i = 0;
u32 j; u32 j;
u32 *p = data; u32 *p = data;
u32 reg_tmp;
bool is_ver1 = AE_IS_VER1(ddev->dsaf_ver);
/* dsaf common registers */ /* dsaf common registers */
p[0] = dsaf_read_dev(ddev, DSAF_SRAM_INIT_OVER_0_REG); p[0] = dsaf_read_dev(ddev, DSAF_SRAM_INIT_OVER_0_REG);
...@@ -2120,8 +2171,9 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data) ...@@ -2120,8 +2171,9 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data)
DSAF_INODE_FINAL_IN_PKT_NUM_0_REG + j * 0x80); DSAF_INODE_FINAL_IN_PKT_NUM_0_REG + j * 0x80);
p[190 + i] = dsaf_read_dev(ddev, p[190 + i] = dsaf_read_dev(ddev,
DSAF_INODE_SBM_PID_NUM_0_REG + j * 0x80); DSAF_INODE_SBM_PID_NUM_0_REG + j * 0x80);
p[193 + i] = dsaf_read_dev(ddev, reg_tmp = is_ver1 ? DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG :
DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG + j * 0x80); DSAFV2_INODE_FINAL_IN_PAUSE_NUM_0_REG;
p[193 + i] = dsaf_read_dev(ddev, reg_tmp + j * 0x80);
p[196 + i] = dsaf_read_dev(ddev, p[196 + i] = dsaf_read_dev(ddev,
DSAF_INODE_SBM_RELS_NUM_0_REG + j * 0x80); DSAF_INODE_SBM_RELS_NUM_0_REG + j * 0x80);
p[199 + i] = dsaf_read_dev(ddev, p[199 + i] = dsaf_read_dev(ddev,
...@@ -2368,8 +2420,11 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data) ...@@ -2368,8 +2420,11 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data)
p[496] = dsaf_read_dev(ddev, DSAF_NETPORT_CTRL_SIG_0_REG + port * 0x4); p[496] = dsaf_read_dev(ddev, DSAF_NETPORT_CTRL_SIG_0_REG + port * 0x4);
p[497] = dsaf_read_dev(ddev, DSAF_XGE_CTRL_SIG_CFG_0_REG + port * 0x4); p[497] = dsaf_read_dev(ddev, DSAF_XGE_CTRL_SIG_CFG_0_REG + port * 0x4);
if (!is_ver1)
p[498] = dsaf_read_dev(ddev, DSAF_PAUSE_CFG_REG + port * 0x4);
/* mark end of dsaf regs */ /* mark end of dsaf regs */
for (i = 498; i < 504; i++) for (i = 499; i < 504; i++)
p[i] = 0xdddddddd; p[i] = 0xdddddddd;
} }
......
...@@ -417,6 +417,11 @@ void hns_dsaf_get_strings(int stringset, u8 *data, int port); ...@@ -417,6 +417,11 @@ void hns_dsaf_get_strings(int stringset, u8 *data, int port);
void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data); void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data);
int hns_dsaf_get_regs_count(void); 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_mode(struct dsaf_device *dsaf_dev, u32 en);
void hns_dsaf_get_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
u32 *en);
int hns_dsaf_set_rx_mac_pause_en(struct dsaf_device *dsaf_dev, int mac_id,
u32 en);
void hns_dsaf_set_inner_lb(struct dsaf_device *dsaf_dev, u32 mac_id, u32 en); void hns_dsaf_set_inner_lb(struct dsaf_device *dsaf_dev, u32 mac_id, u32 en);
#endif /* __HNS_DSAF_MAIN_H__ */ #endif /* __HNS_DSAF_MAIN_H__ */
...@@ -332,10 +332,12 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb) ...@@ -332,10 +332,12 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb)
/* clr and msk except irq*/ /* clr and msk except irq*/
hns_ppe_exc_irq_en(ppe_cb, 0); hns_ppe_exc_irq_en(ppe_cb, 0);
if (ppe_common_cb->ppe_mode == PPE_COMMON_MODE_DEBUG) if (ppe_common_cb->ppe_mode == PPE_COMMON_MODE_DEBUG) {
hns_ppe_set_port_mode(ppe_cb, PPE_MODE_GE); hns_ppe_set_port_mode(ppe_cb, PPE_MODE_GE);
else dsaf_write_dev(ppe_cb, PPE_CFG_PAUSE_IDLE_CNT_REG, 0);
} else {
hns_ppe_set_port_mode(ppe_cb, PPE_MODE_XGE); hns_ppe_set_port_mode(ppe_cb, PPE_MODE_XGE);
}
hns_ppe_checksum_hw(ppe_cb, 0xffffffff); hns_ppe_checksum_hw(ppe_cb, 0xffffffff);
hns_ppe_cnt_clr_ce(ppe_cb); hns_ppe_cnt_clr_ce(ppe_cb);
......
...@@ -137,6 +137,7 @@ ...@@ -137,6 +137,7 @@
#define DSAF_PPE_INT_STS_0_REG 0x1E0 #define DSAF_PPE_INT_STS_0_REG 0x1E0
#define DSAF_ROCEE_INT_STS_0_REG 0x200 #define DSAF_ROCEE_INT_STS_0_REG 0x200
#define DSAFV2_SERDES_LBK_0_REG 0x220 #define DSAFV2_SERDES_LBK_0_REG 0x220
#define DSAF_PAUSE_CFG_REG 0x240
#define DSAF_PPE_QID_CFG_0_REG 0x300 #define DSAF_PPE_QID_CFG_0_REG 0x300
#define DSAF_SW_PORT_TYPE_0_REG 0x320 #define DSAF_SW_PORT_TYPE_0_REG 0x320
#define DSAF_STP_PORT_TYPE_0_REG 0x340 #define DSAF_STP_PORT_TYPE_0_REG 0x340
...@@ -155,6 +156,7 @@ ...@@ -155,6 +156,7 @@
#define DSAF_INODE_FINAL_IN_PKT_NUM_0_REG 0x1030 #define DSAF_INODE_FINAL_IN_PKT_NUM_0_REG 0x1030
#define DSAF_INODE_SBM_PID_NUM_0_REG 0x1038 #define DSAF_INODE_SBM_PID_NUM_0_REG 0x1038
#define DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG 0x103C #define DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG 0x103C
#define DSAFV2_INODE_FINAL_IN_PAUSE_NUM_0_REG 0x1024
#define DSAF_INODE_SBM_RELS_NUM_0_REG 0x104C #define DSAF_INODE_SBM_RELS_NUM_0_REG 0x104C
#define DSAF_INODE_SBM_DROP_NUM_0_REG 0x1050 #define DSAF_INODE_SBM_DROP_NUM_0_REG 0x1050
#define DSAF_INODE_CRC_FALSE_NUM_0_REG 0x1054 #define DSAF_INODE_CRC_FALSE_NUM_0_REG 0x1054
...@@ -711,6 +713,10 @@ ...@@ -711,6 +713,10 @@
#define DSAF_PFC_UNINT_CNT_M ((1ULL << 9) - 1) #define DSAF_PFC_UNINT_CNT_M ((1ULL << 9) - 1)
#define DSAF_PFC_UNINT_CNT_S 0 #define DSAF_PFC_UNINT_CNT_S 0
#define DSAF_MAC_PAUSE_RX_EN_B 2
#define DSAF_PFC_PAUSE_RX_EN_B 1
#define DSAF_PFC_PAUSE_TX_EN_B 0
#define DSAF_PPE_QID_CFG_M 0xFF #define DSAF_PPE_QID_CFG_M 0xFF
#define DSAF_PPE_QID_CFG_S 0 #define DSAF_PPE_QID_CFG_S 0
......
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