Skip to content

Commit

Permalink
net: hns: add support of pause frame ctrl for HNS V2
Browse files Browse the repository at this point in the history
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: Lisheng <lisheng011@huawei.com>
Signed-off-by: Yisen Zhuang <Yisen.Zhuang@huawei.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Lisheng authored and David S. Miller committed Apr 3, 2016
1 parent 7822ce7 commit 5ada37b
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 38 deletions.
20 changes: 17 additions & 3 deletions drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
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)
Expand Down Expand Up @@ -436,12 +441,21 @@ static int hns_ae_set_pauseparam(struct hnae_handle *handle,
u32 autoneg, u32 rx_en, u32 tx_en)
{
struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle);
struct dsaf_device *dsaf_dev = mac_cb->dsaf_dev;
int ret;

ret = hns_mac_set_autoneg(mac_cb, autoneg);
if (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);
}

Expand Down
30 changes: 7 additions & 23 deletions drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
struct mac_driver *drv;

drv = hns_mac_get_drv(mac_cb);
struct mac_driver *drv = hns_mac_get_drv(mac_cb);
bool is_ver1 = AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver);

drv->mac_init(drv);

Expand All @@ -456,7 +455,7 @@ void hns_mac_reset(struct hns_mac_cb *mac_cb)

if (drv->mac_pausefrm_cfg) {
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*/
drv->mac_pausefrm_cfg(drv, 0, 1);
}
Expand Down Expand Up @@ -561,14 +560,6 @@ void hns_mac_get_pauseparam(struct hns_mac_cb *mac_cb, u32 *rx_en, u32 *tx_en)
*rx_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;
}

/**
Expand Down Expand Up @@ -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)
{
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 (!rx_en) {
dev_err(mac_cb->dev, "disable rx_pause is not allowed!");
if (mac_cb->mac_type == HNAE_PORT_DEBUG) {
if (is_ver1 && (tx_en || rx_en)) {
dev_err(mac_cb->dev, "macv1 cann't enable tx/rx_pause!");
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)
Expand Down
75 changes: 65 additions & 10 deletions drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1022,12 +1022,52 @@ static void hns_dsaf_tbl_tcam_init(struct dsaf_device *dsaf_dev)
* @mac_cb: mac contrl block
*/
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, 0);
dsaf_write_dev(dsaf_dev, DSAF_PFC_EN_0_REG + mac_id * 4, tc_en);
}

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
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);
}

/**
Expand All @@ -1039,6 +1079,7 @@ static void hns_dsaf_comm_init(struct dsaf_device *dsaf_dev)
{
u32 i;
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);
dsaf_set_bit(o_dsaf_cfg, DSAF_CFG_EN_S, dsaf_dev->dsaf_en);
Expand All @@ -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);

/*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_set_pfc_pause(dsaf_dev, i, is_ver1, is_ver1);
}

/*msk and clr exception irqs */
for (i = 0; i < DSAF_COMM_CHN; i++) {
Expand Down Expand Up @@ -2013,6 +2056,8 @@ void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 node_num)
{
struct dsaf_hw_stats *hw_stats
= &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,
DSAF_INODE_PAD_DISCARD_NUM_0_REG + 0x80 * (u64)node_num);
Expand All @@ -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);
hw_stats->rx_pkt_id += dsaf_read_dev(dsaf_dev,
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,
DSAF_INODE_SBM_RELS_NUM_0_REG + 0x80 * (u64)node_num);
hw_stats->sbm_drop += dsaf_read_dev(dsaf_dev,
Expand Down Expand Up @@ -2056,6 +2105,8 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data)
u32 i = 0;
u32 j;
u32 *p = data;
u32 reg_tmp;
bool is_ver1 = AE_IS_VER1(ddev->dsaf_ver);

/* dsaf common registers */
p[0] = dsaf_read_dev(ddev, DSAF_SRAM_INIT_OVER_0_REG);
Expand Down Expand Up @@ -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);
p[190 + i] = dsaf_read_dev(ddev,
DSAF_INODE_SBM_PID_NUM_0_REG + j * 0x80);
p[193 + i] = dsaf_read_dev(ddev,
DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG + j * 0x80);
reg_tmp = is_ver1 ? DSAF_INODE_FINAL_IN_PAUSE_NUM_0_REG :
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,
DSAF_INODE_SBM_RELS_NUM_0_REG + j * 0x80);
p[199 + i] = dsaf_read_dev(ddev,
Expand Down Expand Up @@ -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[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 */
for (i = 498; i < 504; i++)
for (i = 499; i < 504; i++)
p[i] = 0xdddddddd;
}

Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
int hns_dsaf_get_regs_count(void);
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);

#endif /* __HNS_DSAF_MAIN_H__ */
6 changes: 4 additions & 2 deletions drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,10 +332,12 @@ static void hns_ppe_init_hw(struct hns_ppe_cb *ppe_cb)
/* clr and msk except irq*/
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);
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_checksum_hw(ppe_cb, 0xffffffff);
hns_ppe_cnt_clr_ce(ppe_cb);
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
#define DSAF_PPE_INT_STS_0_REG 0x1E0
#define DSAF_ROCEE_INT_STS_0_REG 0x200
#define DSAFV2_SERDES_LBK_0_REG 0x220
#define DSAF_PAUSE_CFG_REG 0x240
#define DSAF_PPE_QID_CFG_0_REG 0x300
#define DSAF_SW_PORT_TYPE_0_REG 0x320
#define DSAF_STP_PORT_TYPE_0_REG 0x340
Expand All @@ -155,6 +156,7 @@
#define DSAF_INODE_FINAL_IN_PKT_NUM_0_REG 0x1030
#define DSAF_INODE_SBM_PID_NUM_0_REG 0x1038
#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_DROP_NUM_0_REG 0x1050
#define DSAF_INODE_CRC_FALSE_NUM_0_REG 0x1054
Expand Down Expand Up @@ -711,6 +713,10 @@
#define DSAF_PFC_UNINT_CNT_M ((1ULL << 9) - 1)
#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_S 0

Expand Down

0 comments on commit 5ada37b

Please sign in to comment.