diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c b/drivers/net/ethernet/hisilicon/hns/hnae.c index 5d3047cc8380..c54c6fac0d1d 100644 --- a/drivers/net/ethernet/hisilicon/hns/hnae.c +++ b/drivers/net/ethernet/hisilicon/hns/hnae.c @@ -400,7 +400,6 @@ int hnae_ae_register(struct hnae_ae_dev *hdev, struct module *owner) if (!hdev->ops || !hdev->ops->get_handle || !hdev->ops->toggle_ring_irq || - !hdev->ops->toggle_queue_status || !hdev->ops->get_status || !hdev->ops->adjust_link) return -EINVAL; diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.h b/drivers/net/ethernet/hisilicon/hns/hnae.h index 529cb1341270..3869322690ac 100644 --- a/drivers/net/ethernet/hisilicon/hns/hnae.h +++ b/drivers/net/ethernet/hisilicon/hns/hnae.h @@ -454,7 +454,6 @@ struct hnae_ae_ops { int (*get_info)(struct hnae_handle *handle, u8 *auto_neg, u16 *speed, u8 *duplex); void (*toggle_ring_irq)(struct hnae_ring *ring, u32 val); - void (*toggle_queue_status)(struct hnae_queue *queue, u32 val); void (*adjust_link)(struct hnae_handle *handle, int speed, int duplex); int (*set_loopback)(struct hnae_handle *handle, enum hnae_loop loop_mode, int en); @@ -473,6 +472,11 @@ struct hnae_ae_ops { int (*set_coalesce_usecs)(struct hnae_handle *handle, u32 timeout); int (*set_coalesce_frames)(struct hnae_handle *handle, u32 coalesce_frames); + void (*get_coalesce_range)(struct hnae_handle *handle, + u32 *tx_frames_low, u32 *rx_frames_low, + u32 *tx_frames_high, u32 *rx_frames_high, + u32 *tx_usecs_low, u32 *rx_usecs_low, + u32 *tx_usecs_high, u32 *rx_usecs_high); void (*set_promisc_mode)(struct hnae_handle *handle, u32 en); int (*get_mac_addr)(struct hnae_handle *handle, void **p); int (*set_mac_addr)(struct hnae_handle *handle, void *p); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c index d37b778b4a1b..835521bf1bbc 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ae_adapt.c @@ -247,12 +247,21 @@ static void hns_ae_set_tso_stats(struct hnae_handle *handle, int enable) static int hns_ae_start(struct hnae_handle *handle) { int ret; + int k; struct hns_mac_cb *mac_cb = hns_get_mac_cb(handle); ret = hns_mac_vm_config_bc_en(mac_cb, 0, true); if (ret) return ret; + for (k = 0; k < handle->q_num; k++) { + if (AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) + hns_rcb_int_clr_hw(handle->qs[k], + RCB_INT_FLAG_TX | RCB_INT_FLAG_RX); + else + hns_rcbv2_int_clr_hw(handle->qs[k], + RCB_INT_FLAG_TX | RCB_INT_FLAG_RX); + } hns_ae_ring_enable_all(handle, 1); msleep(100); @@ -313,18 +322,6 @@ static void hns_aev2_toggle_ring_irq(struct hnae_ring *ring, u32 mask) hns_rcbv2_int_ctrl_hw(ring->q, flag, mask); } -static void hns_ae_toggle_queue_status(struct hnae_queue *queue, u32 val) -{ - struct dsaf_device *dsaf_dev = hns_ae_get_dsaf_dev(queue->dev); - - if (AE_IS_VER1(dsaf_dev->dsaf_ver)) - hns_rcb_int_clr_hw(queue, RCB_INT_FLAG_TX | RCB_INT_FLAG_RX); - else - hns_rcbv2_int_clr_hw(queue, RCB_INT_FLAG_TX | RCB_INT_FLAG_RX); - - hns_rcb_start(queue, val); -} - static int hns_ae_get_link_status(struct hnae_handle *handle) { u32 link_status; @@ -465,6 +462,30 @@ static int hns_ae_set_coalesce_frames(struct hnae_handle *handle, ring_pair->port_id_in_comm, coalesce_frames); } +static void hns_ae_get_coalesce_range(struct hnae_handle *handle, + u32 *tx_frames_low, u32 *rx_frames_low, + u32 *tx_frames_high, u32 *rx_frames_high, + u32 *tx_usecs_low, u32 *rx_usecs_low, + u32 *tx_usecs_high, u32 *rx_usecs_high) +{ + struct dsaf_device *dsaf_dev; + + dsaf_dev = hns_ae_get_dsaf_dev(handle->dev); + + *tx_frames_low = HNS_RCB_MIN_COALESCED_FRAMES; + *rx_frames_low = HNS_RCB_MIN_COALESCED_FRAMES; + *tx_frames_high = + (dsaf_dev->desc_num - 1 > HNS_RCB_MAX_COALESCED_FRAMES) ? + HNS_RCB_MAX_COALESCED_FRAMES : dsaf_dev->desc_num - 1; + *rx_frames_high = + (dsaf_dev->desc_num - 1 > HNS_RCB_MAX_COALESCED_FRAMES) ? + HNS_RCB_MAX_COALESCED_FRAMES : dsaf_dev->desc_num - 1; + *tx_usecs_low = 0; + *rx_usecs_low = 0; + *tx_usecs_high = HNS_RCB_MAX_COALESCED_USECS; + *rx_usecs_high = HNS_RCB_MAX_COALESCED_USECS; +} + void hns_ae_update_stats(struct hnae_handle *handle, struct net_device_stats *net_stats) { @@ -587,6 +608,7 @@ void hns_ae_get_strings(struct hnae_handle *handle, int idx; struct hns_mac_cb *mac_cb; struct hns_ppe_cb *ppe_cb; + struct dsaf_device *dsaf_dev = hns_ae_get_dsaf_dev(handle->dev); u8 *p = data; struct hnae_vf_cb *vf_cb; @@ -609,13 +631,14 @@ void hns_ae_get_strings(struct hnae_handle *handle, p += ETH_GSTRING_LEN * hns_mac_get_sset_count(mac_cb, stringset); if (mac_cb->mac_type == HNAE_PORT_SERVICE) - hns_dsaf_get_strings(stringset, p, port); + hns_dsaf_get_strings(stringset, p, port, dsaf_dev); } int hns_ae_get_sset_count(struct hnae_handle *handle, int stringset) { u32 sset_count = 0; struct hns_mac_cb *mac_cb; + struct dsaf_device *dsaf_dev = hns_ae_get_dsaf_dev(handle->dev); assert(handle); @@ -626,7 +649,7 @@ int hns_ae_get_sset_count(struct hnae_handle *handle, int stringset) sset_count += hns_mac_get_sset_count(mac_cb, stringset); if (mac_cb->mac_type == HNAE_PORT_SERVICE) - sset_count += hns_dsaf_get_sset_count(stringset); + sset_count += hns_dsaf_get_sset_count(dsaf_dev, stringset); return sset_count; } @@ -782,7 +805,6 @@ static struct hnae_ae_ops hns_dsaf_ops = { .stop = hns_ae_stop, .reset = hns_ae_reset, .toggle_ring_irq = hns_ae_toggle_ring_irq, - .toggle_queue_status = hns_ae_toggle_queue_status, .get_status = hns_ae_get_link_status, .get_info = hns_ae_get_mac_info, .adjust_link = hns_ae_adjust_link, @@ -796,6 +818,7 @@ static struct hnae_ae_ops hns_dsaf_ops = { .get_rx_max_coalesced_frames = hns_ae_get_rx_max_coalesced_frames, .set_coalesce_usecs = hns_ae_set_coalesce_usecs, .set_coalesce_frames = hns_ae_set_coalesce_frames, + .get_coalesce_range = hns_ae_get_coalesce_range, .set_promisc_mode = hns_ae_set_promisc_mode, .set_mac_addr = hns_ae_set_mac_address, .set_mc_addr = hns_ae_set_multicast_one, diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c index ac03c4a53e08..67e8e1323205 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.c @@ -176,7 +176,7 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) desc_num > HNS_DSAF_MAX_DESC_CNT) { dev_err(dsaf_dev->dev, "get desc-num(%d) fail, ret=%d!\n", desc_num, ret); - goto unmap_base_addr; + return -EINVAL; } dsaf_dev->desc_num = desc_num; @@ -192,7 +192,7 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) if (ret < 0) { dev_err(dsaf_dev->dev, "get buf-size fail, ret=%d!\r\n", ret); - goto unmap_base_addr; + return ret; } dsaf_dev->buf_size = buf_size; @@ -200,7 +200,7 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) if (dsaf_dev->buf_size_type < 0) { dev_err(dsaf_dev->dev, "buf_size(%d) is wrong!\n", buf_size); - goto unmap_base_addr; + return -EINVAL; } dsaf_dev->misc_op = hns_misc_op_get(dsaf_dev); @@ -213,32 +213,6 @@ int hns_dsaf_get_cfg(struct dsaf_device *dsaf_dev) dev_err(dsaf_dev->dev, "set mask to 64bit fail!\n"); return 0; - -unmap_base_addr: - if (dsaf_dev->io_base) - iounmap(dsaf_dev->io_base); - if (dsaf_dev->ppe_base) - iounmap(dsaf_dev->ppe_base); - if (dsaf_dev->sds_base) - iounmap(dsaf_dev->sds_base); - if (dsaf_dev->sc_base) - iounmap(dsaf_dev->sc_base); - return ret; -} - -static void hns_dsaf_free_cfg(struct dsaf_device *dsaf_dev) -{ - if (dsaf_dev->io_base) - iounmap(dsaf_dev->io_base); - - if (dsaf_dev->ppe_base) - iounmap(dsaf_dev->ppe_base); - - if (dsaf_dev->sds_base) - iounmap(dsaf_dev->sds_base); - - if (dsaf_dev->sc_base) - iounmap(dsaf_dev->sc_base); } /** @@ -542,10 +516,10 @@ static void hns_dsafv2_sbm_bp_wl_cfg(struct dsaf_device *dsaf_dev) o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg); dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG3_SET_BUF_NUM_NO_PFC_M, - DSAFV2_SBM_CFG3_SET_BUF_NUM_NO_PFC_S, 110); + DSAFV2_SBM_CFG3_SET_BUF_NUM_NO_PFC_S, 48); dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG3_RESET_BUF_NUM_NO_PFC_M, - DSAFV2_SBM_CFG3_RESET_BUF_NUM_NO_PFC_S, 160); + DSAFV2_SBM_CFG3_RESET_BUF_NUM_NO_PFC_S, 80); dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg); /* for no enable pfc mode */ @@ -553,29 +527,39 @@ static void hns_dsafv2_sbm_bp_wl_cfg(struct dsaf_device *dsaf_dev) o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg); dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG4_SET_BUF_NUM_NO_PFC_M, - DSAFV2_SBM_CFG4_SET_BUF_NUM_NO_PFC_S, 128); + DSAFV2_SBM_CFG4_SET_BUF_NUM_NO_PFC_S, 192); dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_M, - DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_S, 192); + DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_S, 240); dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg); } /* PPE */ - reg = DSAF_SBM_BP_CFG_2_PPE_REG_0_REG + 0x80 * i; - o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg); - dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG2_SET_BUF_NUM_M, - DSAFV2_SBM_CFG2_SET_BUF_NUM_S, 10); - dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG2_RESET_BUF_NUM_M, - DSAFV2_SBM_CFG2_RESET_BUF_NUM_S, 12); - dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg); + for (i = 0; i < DSAFV2_SBM_PPE_CHN; i++) { + reg = DSAF_SBM_BP_CFG_2_PPE_REG_0_REG + 0x80 * i; + o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg); + dsaf_set_field(o_sbm_bp_cfg, + DSAFV2_SBM_CFG2_PPE_SET_BUF_NUM_M, + DSAFV2_SBM_CFG2_PPE_SET_BUF_NUM_S, 2); + dsaf_set_field(o_sbm_bp_cfg, + DSAFV2_SBM_CFG2_PPE_RESET_BUF_NUM_M, + DSAFV2_SBM_CFG2_PPE_RESET_BUF_NUM_S, 3); + dsaf_set_field(o_sbm_bp_cfg, + DSAFV2_SBM_CFG2_PPE_CFG_USEFUL_NUM_M, + DSAFV2_SBM_CFG2_PPE_CFG_USEFUL_NUM_S, 52); + dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg); + } + /* RoCEE */ for (i = 0; i < DASFV2_ROCEE_CRD_NUM; i++) { reg = DSAFV2_SBM_BP_CFG_2_ROCEE_REG_0_REG + 0x80 * i; o_sbm_bp_cfg = dsaf_read_dev(dsaf_dev, reg); - dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG2_SET_BUF_NUM_M, - DSAFV2_SBM_CFG2_SET_BUF_NUM_S, 2); - dsaf_set_field(o_sbm_bp_cfg, DSAFV2_SBM_CFG2_RESET_BUF_NUM_M, - DSAFV2_SBM_CFG2_RESET_BUF_NUM_S, 4); + dsaf_set_field(o_sbm_bp_cfg, + DSAFV2_SBM_CFG2_ROCEE_SET_BUF_NUM_M, + DSAFV2_SBM_CFG2_ROCEE_SET_BUF_NUM_S, 2); + dsaf_set_field(o_sbm_bp_cfg, + DSAFV2_SBM_CFG2_ROCEE_RESET_BUF_NUM_M, + DSAFV2_SBM_CFG2_ROCEE_RESET_BUF_NUM_S, 4); dsaf_write_dev(dsaf_dev, reg, o_sbm_bp_cfg); } } @@ -886,6 +870,8 @@ static void hns_dsaf_single_line_tbl_cfg( struct dsaf_device *dsaf_dev, u32 address, struct dsaf_tbl_line_cfg *ptbl_line) { + spin_lock_bh(&dsaf_dev->tcam_lock); + /*Write Addr*/ hns_dsaf_tbl_line_addr_cfg(dsaf_dev, address); @@ -894,6 +880,8 @@ static void hns_dsaf_single_line_tbl_cfg( /*Write Plus*/ hns_dsaf_tbl_line_pul(dsaf_dev); + + spin_unlock_bh(&dsaf_dev->tcam_lock); } /** @@ -907,6 +895,8 @@ static void hns_dsaf_tcam_uc_cfg( struct dsaf_tbl_tcam_data *ptbl_tcam_data, 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*/ @@ -915,6 +905,8 @@ static void hns_dsaf_tcam_uc_cfg( hns_dsaf_tbl_tcam_ucast_cfg(dsaf_dev, ptbl_tcam_ucast); /*Write Plus*/ hns_dsaf_tbl_tcam_data_ucast_pul(dsaf_dev); + + spin_unlock_bh(&dsaf_dev->tcam_lock); } /** @@ -929,6 +921,8 @@ static void hns_dsaf_tcam_mc_cfg( struct dsaf_tbl_tcam_data *ptbl_tcam_data, struct dsaf_tbl_tcam_mcast_cfg *ptbl_tcam_mcast) { + spin_lock_bh(&dsaf_dev->tcam_lock); + /*Write Addr*/ hns_dsaf_tbl_tcam_addr_cfg(dsaf_dev, address); /*Write Tcam Data*/ @@ -937,6 +931,8 @@ static void hns_dsaf_tcam_mc_cfg( hns_dsaf_tbl_tcam_mcast_cfg(dsaf_dev, ptbl_tcam_mcast); /*Write Plus*/ hns_dsaf_tbl_tcam_data_mcast_pul(dsaf_dev); + + spin_unlock_bh(&dsaf_dev->tcam_lock); } /** @@ -946,6 +942,8 @@ static void hns_dsaf_tcam_mc_cfg( */ static void hns_dsaf_tcam_mc_invld(struct dsaf_device *dsaf_dev, u32 address) { + spin_lock_bh(&dsaf_dev->tcam_lock); + /*Write Addr*/ hns_dsaf_tbl_tcam_addr_cfg(dsaf_dev, address); @@ -958,6 +956,8 @@ static void hns_dsaf_tcam_mc_invld(struct dsaf_device *dsaf_dev, u32 address) /*Write Plus*/ hns_dsaf_tbl_tcam_mcast_pul(dsaf_dev); + + spin_unlock_bh(&dsaf_dev->tcam_lock); } /** @@ -975,6 +975,8 @@ static void hns_dsaf_tcam_uc_get( u32 tcam_read_data0; u32 tcam_read_data4; + spin_lock_bh(&dsaf_dev->tcam_lock); + /*Write Addr*/ hns_dsaf_tbl_tcam_addr_cfg(dsaf_dev, address); @@ -983,9 +985,9 @@ static void hns_dsaf_tcam_uc_get( /*read tcam data*/ ptbl_tcam_data->tbl_tcam_data_high - = dsaf_read_dev(dsaf_dev, DSAF_TBL_TCAM_RDATA_LOW_0_REG); - ptbl_tcam_data->tbl_tcam_data_low = dsaf_read_dev(dsaf_dev, DSAF_TBL_TCAM_RDATA_HIGH_0_REG); + ptbl_tcam_data->tbl_tcam_data_low + = dsaf_read_dev(dsaf_dev, DSAF_TBL_TCAM_RDATA_LOW_0_REG); /*read tcam mcast*/ tcam_read_data0 = dsaf_read_dev(dsaf_dev, @@ -1007,6 +1009,8 @@ static void hns_dsaf_tcam_uc_get( DSAF_TBL_UCAST_CFG1_OUT_PORT_S); ptbl_tcam_ucast->tbl_ucast_dvc = dsaf_get_bit(tcam_read_data0, DSAF_TBL_UCAST_CFG1_DVC_S); + + spin_unlock_bh(&dsaf_dev->tcam_lock); } /** @@ -1023,6 +1027,8 @@ static void hns_dsaf_tcam_mc_get( { u32 data_tmp; + spin_lock_bh(&dsaf_dev->tcam_lock); + /*Write Addr*/ hns_dsaf_tbl_tcam_addr_cfg(dsaf_dev, address); @@ -1031,9 +1037,9 @@ static void hns_dsaf_tcam_mc_get( /*read tcam data*/ ptbl_tcam_data->tbl_tcam_data_high = - dsaf_read_dev(dsaf_dev, DSAF_TBL_TCAM_RDATA_LOW_0_REG); - ptbl_tcam_data->tbl_tcam_data_low = dsaf_read_dev(dsaf_dev, DSAF_TBL_TCAM_RDATA_HIGH_0_REG); + ptbl_tcam_data->tbl_tcam_data_low = + dsaf_read_dev(dsaf_dev, DSAF_TBL_TCAM_RDATA_LOW_0_REG); /*read tcam mcast*/ ptbl_tcam_mcast->tbl_mcast_port_msk[0] = @@ -1053,6 +1059,8 @@ static void hns_dsaf_tcam_mc_get( ptbl_tcam_mcast->tbl_mcast_port_msk[4] = dsaf_get_field(data_tmp, DSAF_TBL_MCAST_CFG4_VM128_112_M, DSAF_TBL_MCAST_CFG4_VM128_112_S); + + spin_unlock_bh(&dsaf_dev->tcam_lock); } /** @@ -1114,10 +1122,10 @@ 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) + if (!en) { dev_err(dsaf_dev->dev, "dsafv1 can't close rx_pause!\n"); - - return -EINVAL; + return -EINVAL; + } } dsaf_set_dev_bit(dsaf_dev, DSAF_PAUSE_CFG_REG + mac_id * 4, @@ -1377,6 +1385,7 @@ static int hns_dsaf_init(struct dsaf_device *dsaf_dev) if (HNS_DSAF_IS_DEBUG(dsaf_dev)) return 0; + spin_lock_init(&dsaf_dev->tcam_lock); ret = hns_dsaf_init_hw(dsaf_dev); if (ret) return ret; @@ -2122,11 +2131,24 @@ void hns_dsaf_fix_mac_mode(struct hns_mac_cb *mac_cb) hns_dsaf_port_work_rate_cfg(dsaf_dev, mac_id, mode); } +static u32 hns_dsaf_get_inode_prio_reg(int index) +{ + int base_index, offset; + u32 base_addr = DSAF_INODE_IN_PRIO_PAUSE_BASE_REG; + + base_index = (index + 1) / DSAF_REG_PER_ZONE; + offset = (index + 1) % DSAF_REG_PER_ZONE; + + return base_addr + DSAF_INODE_IN_PRIO_PAUSE_BASE_OFFSET * base_index + + DSAF_INODE_IN_PRIO_PAUSE_OFFSET * offset; +} + 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); + int i; u32 reg_tmp; hw_stats->pad_drop += dsaf_read_dev(dsaf_dev, @@ -2161,6 +2183,18 @@ void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 node_num) hw_stats->stp_drop += dsaf_read_dev(dsaf_dev, DSAF_INODE_IN_DATA_STP_DISC_0_REG + 0x80 * (u64)node_num); + /* pfc pause frame statistics stored in dsaf inode*/ + if ((node_num < DSAF_SERVICE_NW_NUM) && !is_ver1) { + for (i = 0; i < DSAF_PRIO_NR; i++) { + reg_tmp = hns_dsaf_get_inode_prio_reg(i); + hw_stats->rx_pfc[i] += dsaf_read_dev(dsaf_dev, + reg_tmp + 0x4 * (u64)node_num); + hw_stats->tx_pfc[i] += dsaf_read_dev(dsaf_dev, + DSAF_XOD_XGE_PFC_PRIO_CNT_BASE_REG + + DSAF_XOD_XGE_PFC_PRIO_CNT_OFFSET * i + + 0xF0 * (u64)node_num); + } + } hw_stats->tx_pkts += dsaf_read_dev(dsaf_dev, DSAF_XOD_RCVPKT_CNT_0_REG + 0x90 * (u64)node_num); } @@ -2498,9 +2532,12 @@ void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data) p[i] = 0xdddddddd; } -static char *hns_dsaf_get_node_stats_strings(char *data, int node) +static char *hns_dsaf_get_node_stats_strings(char *data, int node, + struct dsaf_device *dsaf_dev) { char *buff = data; + int i; + bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver); snprintf(buff, ETH_GSTRING_LEN, "innod%d_pad_drop_pkts", node); buff = buff + ETH_GSTRING_LEN; @@ -2528,6 +2565,18 @@ static char *hns_dsaf_get_node_stats_strings(char *data, int node) buff = buff + ETH_GSTRING_LEN; snprintf(buff, ETH_GSTRING_LEN, "innod%d_stp_drop_pkts", node); buff = buff + ETH_GSTRING_LEN; + if ((node < DSAF_SERVICE_NW_NUM) && (!is_ver1)) { + for (i = 0; i < DSAF_PRIO_NR; i++) { + snprintf(buff, ETH_GSTRING_LEN, + "inod%d_pfc_prio%d_pkts", node, i); + buff = buff + ETH_GSTRING_LEN; + } + for (i = 0; i < DSAF_PRIO_NR; i++) { + snprintf(buff, ETH_GSTRING_LEN, + "onod%d_pfc_prio%d_pkts", node, i); + buff = buff + ETH_GSTRING_LEN; + } + } snprintf(buff, ETH_GSTRING_LEN, "onnod%d_tx_pkts", node); buff = buff + ETH_GSTRING_LEN; @@ -2538,7 +2587,9 @@ static u64 *hns_dsaf_get_node_stats(struct dsaf_device *ddev, u64 *data, int node_num) { u64 *p = data; + int i; struct dsaf_hw_stats *hw_stats = &ddev->hw_stats[node_num]; + bool is_ver1 = AE_IS_VER1(ddev->dsaf_ver); p[0] = hw_stats->pad_drop; p[1] = hw_stats->man_pkts; @@ -2553,8 +2604,16 @@ static u64 *hns_dsaf_get_node_stats(struct dsaf_device *ddev, u64 *data, p[10] = hw_stats->local_addr_false; p[11] = hw_stats->vlan_drop; p[12] = hw_stats->stp_drop; - p[13] = hw_stats->tx_pkts; + if ((node_num < DSAF_SERVICE_NW_NUM) && (!is_ver1)) { + for (i = 0; i < DSAF_PRIO_NR; i++) { + p[13 + i] = hw_stats->rx_pfc[i]; + p[13 + i + DSAF_PRIO_NR] = hw_stats->tx_pfc[i]; + } + p[29] = hw_stats->tx_pkts; + return &p[30]; + } + p[13] = hw_stats->tx_pkts; return &p[14]; } @@ -2582,11 +2641,16 @@ void hns_dsaf_get_stats(struct dsaf_device *ddev, u64 *data, int port) *@stringset: type of values in data *return dsaf string name count */ -int hns_dsaf_get_sset_count(int stringset) +int hns_dsaf_get_sset_count(struct dsaf_device *dsaf_dev, int stringset) { - if (stringset == ETH_SS_STATS) - return DSAF_STATIC_NUM; + bool is_ver1 = AE_IS_VER1(dsaf_dev->dsaf_ver); + if (stringset == ETH_SS_STATS) { + if (is_ver1) + return DSAF_STATIC_NUM; + else + return DSAF_V2_STATIC_NUM; + } return 0; } @@ -2596,7 +2660,8 @@ int hns_dsaf_get_sset_count(int stringset) *@data:strings name value *@port:port index */ -void hns_dsaf_get_strings(int stringset, u8 *data, int port) +void hns_dsaf_get_strings(int stringset, u8 *data, int port, + struct dsaf_device *dsaf_dev) { char *buff = (char *)data; int node = port; @@ -2605,11 +2670,11 @@ void hns_dsaf_get_strings(int stringset, u8 *data, int port) return; /* for ge/xge node info */ - buff = hns_dsaf_get_node_stats_strings(buff, node); + buff = hns_dsaf_get_node_stats_strings(buff, node, dsaf_dev); /* for ppe node info */ node = port + DSAF_PPE_INODE_BASE; - (void)hns_dsaf_get_node_stats_strings(buff, node); + (void)hns_dsaf_get_node_stats_strings(buff, node, dsaf_dev); } /** @@ -2645,7 +2710,7 @@ static int hns_dsaf_probe(struct platform_device *pdev) ret = hns_dsaf_init(dsaf_dev); if (ret) - goto free_cfg; + goto free_dev; ret = hns_mac_init(dsaf_dev); if (ret) @@ -2670,9 +2735,6 @@ uninit_mac: uninit_dsaf: hns_dsaf_free(dsaf_dev); -free_cfg: - hns_dsaf_free_cfg(dsaf_dev); - free_dev: hns_dsaf_free_dev(dsaf_dev); @@ -2695,8 +2757,6 @@ static int hns_dsaf_remove(struct platform_device *pdev) hns_dsaf_free(dsaf_dev); - hns_dsaf_free_cfg(dsaf_dev); - hns_dsaf_free_dev(dsaf_dev); return 0; diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h index 2e55b3cc4515..1daf018d9071 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_main.h @@ -39,6 +39,9 @@ struct hns_mac_cb; #define DSAF_DUMP_REGS_NUM 504 #define DSAF_STATIC_NUM 28 +#define DSAF_V2_STATIC_NUM 44 +#define DSAF_PRIO_NR 8 +#define DSAF_REG_PER_ZONE 3 #define DSAF_STATS_READ(p, offset) (*((u64 *)((u8 *)(p) + (offset)))) #define HNS_DSAF_IS_DEBUG(dev) (dev->dsaf_mode == DSAF_MODE_DISABLE_SP) @@ -176,6 +179,8 @@ struct dsaf_hw_stats { u64 local_addr_false; u64 vlan_drop; u64 stp_drop; + u64 rx_pfc[DSAF_PRIO_NR]; + u64 tx_pfc[DSAF_PRIO_NR]; u64 tx_pkts; }; @@ -317,6 +322,8 @@ struct dsaf_device { struct dsaf_hw_stats hw_stats[DSAF_NODE_NUM]; struct dsaf_int_stat int_stat; + /* make sure tcam table config spinlock */ + spinlock_t tcam_lock; }; static inline void *hns_dsaf_dev_priv(const struct dsaf_device *dsaf_dev) @@ -417,9 +424,10 @@ void hns_dsaf_ae_uninit(struct dsaf_device *dsaf_dev); void hns_dsaf_update_stats(struct dsaf_device *dsaf_dev, u32 inode_num); -int hns_dsaf_get_sset_count(int stringset); +int hns_dsaf_get_sset_count(struct dsaf_device *dsaf_dev, int stringset); void hns_dsaf_get_stats(struct dsaf_device *ddev, u64 *data, int port); -void hns_dsaf_get_strings(int stringset, u8 *data, int port); +void hns_dsaf_get_strings(int stringset, u8 *data, int port, + struct dsaf_device *dsaf_dev); void hns_dsaf_get_regs(struct dsaf_device *ddev, u32 port, void *data); int hns_dsaf_get_regs_count(void); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c index 96cb628a7c5f..8473287d4c8b 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_misc.c @@ -86,9 +86,10 @@ static void hns_cpld_set_led(struct hns_mac_cb *mac_cb, int link_status, mac_cb->cpld_led_value = value; } } else { - dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg, - CPLD_LED_DEFAULT_VALUE); - mac_cb->cpld_led_value = CPLD_LED_DEFAULT_VALUE; + value = (mac_cb->cpld_led_value) & (0x1 << DSAF_LED_ANCHOR_B); + dsaf_write_syscon(mac_cb->cpld_ctrl, + mac_cb->cpld_ctrl_reg, value); + mac_cb->cpld_led_value = value; } } @@ -114,7 +115,7 @@ static int cpld_set_led_id(struct hns_mac_cb *mac_cb, CPLD_LED_ON_VALUE); dsaf_write_syscon(mac_cb->cpld_ctrl, mac_cb->cpld_ctrl_reg, mac_cb->cpld_led_value); - return 2; + break; case HNAE_LED_INACTIVE: dsaf_set_bit(mac_cb->cpld_led_value, DSAF_LED_ANCHOR_B, CPLD_LED_DEFAULT_VALUE); @@ -122,7 +123,8 @@ static int cpld_set_led_id(struct hns_mac_cb *mac_cb, mac_cb->cpld_led_value); break; default: - break; + dev_err(mac_cb->dev, "invalid led state: %d!", status); + return -EINVAL; } return 0; @@ -271,7 +273,11 @@ static void hns_dsaf_ge_srst_by_port(struct dsaf_device *dsaf_dev, u32 port, } } else { reg_val_1 = 0x15540 << dsaf_dev->reset_offset; - reg_val_2 = 0x100 << dsaf_dev->reset_offset; + + if (AE_IS_VER1(dsaf_dev->dsaf_ver)) + reg_val_2 = 0x100 << dsaf_dev->reset_offset; + else + reg_val_2 = 0x40 << dsaf_dev->reset_offset; if (!dereset) { dsaf_write_sub(dsaf_dev, DSAF_SUB_SC_GE_RESET_REQ1_REG, @@ -431,11 +437,6 @@ int hns_mac_get_sfp_prsnt(struct hns_mac_cb *mac_cb, int *sfp_prsnt) */ static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en) { - /* port 0-3 hilink4 base is serdes_vaddr + 0x00280000 - * port 4-7 hilink3 base is serdes_vaddr + 0x00200000 - */ - u8 *base_addr = (u8 *)mac_cb->serdes_vaddr + - (mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000); const u8 lane_id[] = { 0, /* mac 0 -> lane 0 */ 1, /* mac 1 -> lane 1 */ @@ -461,11 +462,30 @@ static int hns_mac_config_sds_loopback(struct hns_mac_cb *mac_cb, bool en) } if (mac_cb->serdes_ctrl) { - u32 origin = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset); + u32 origin; + + if (!AE_IS_VER1(mac_cb->dsaf_dev->dsaf_ver)) { +#define HILINK_ACCESS_SEL_CFG 0x40008 + /* hilink4 & hilink3 use the same xge training and + * xge u adaptor. There is a hilink access sel cfg + * register to select which one to be configed + */ + if ((!HNS_DSAF_IS_DEBUG(mac_cb->dsaf_dev)) && + (mac_cb->mac_id <= 3)) + dsaf_write_syscon(mac_cb->serdes_ctrl, + HILINK_ACCESS_SEL_CFG, 0); + else + dsaf_write_syscon(mac_cb->serdes_ctrl, + HILINK_ACCESS_SEL_CFG, 3); + } + + origin = dsaf_read_syscon(mac_cb->serdes_ctrl, reg_offset); dsaf_set_field(origin, 1ull << 10, 10, en); dsaf_write_syscon(mac_cb->serdes_ctrl, reg_offset, origin); } else { + u8 *base_addr = (u8 *)mac_cb->serdes_vaddr + + (mac_cb->mac_id <= 3 ? 0x00280000 : 0x00200000); dsaf_set_reg_field(base_addr, reg_offset, 1ull << 10, 10, en); } diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c index 3ce24097fcf4..ef1107777c08 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c @@ -540,7 +540,7 @@ int hns_rcb_set_coalesce_usecs( } if (timeout > HNS_RCB_MAX_COALESCED_USECS) { dev_err(rcb_common->dsaf_dev->dev, - "error: not support coalesce %dus!\n", timeout); + "error: coalesce_usecs setting supports 0~1023us\n"); return -EINVAL; } hns_rcb_set_port_timeout(rcb_common, port_idx, timeout); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h index bd54dac82ee0..99b4e1ba0a94 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.h @@ -40,7 +40,7 @@ struct rcb_common_cb; #define HNS_RCB_DEF_COALESCED_FRAMES 50 #define HNS_RCB_CLK_FREQ_MHZ 350 #define HNS_RCB_MAX_COALESCED_USECS 0x3ff -#define HNS_RCB_DEF_COALESCED_USECS 3 +#define HNS_RCB_DEF_COALESCED_USECS 50 #define HNS_RCB_COMMON_ENDIAN 1 diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h index 7c3b5103d151..235f74444b1d 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h +++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_reg.h @@ -32,7 +32,7 @@ #define DSAFV2_SBM_NUM 8 #define DSAFV2_SBM_XGE_CHN 6 #define DSAFV2_SBM_PPE_CHN 1 -#define DASFV2_ROCEE_CRD_NUM 8 +#define DASFV2_ROCEE_CRD_NUM 1 #define DSAF_VOQ_NUM DSAF_NODE_NUM #define DSAF_INODE_NUM DSAF_NODE_NUM @@ -166,6 +166,9 @@ #define DSAF_INODE_GE_FC_EN_0_REG 0x1B00 #define DSAF_INODE_VC0_IN_PKT_NUM_0_REG 0x1B50 #define DSAF_INODE_VC1_IN_PKT_NUM_0_REG 0x1C00 +#define DSAF_INODE_IN_PRIO_PAUSE_BASE_REG 0x1C00 +#define DSAF_INODE_IN_PRIO_PAUSE_BASE_OFFSET 0x100 +#define DSAF_INODE_IN_PRIO_PAUSE_OFFSET 0x50 #define DSAF_SBM_CFG_REG_0_REG 0x2000 #define DSAF_SBM_BP_CFG_0_XGE_REG_0_REG 0x2004 @@ -175,7 +178,7 @@ #define DSAF_SBM_BP_CFG_2_XGE_REG_0_REG 0x200C #define DSAF_SBM_BP_CFG_2_PPE_REG_0_REG 0x230C #define DSAF_SBM_BP_CFG_2_ROCEE_REG_0_REG 0x260C -#define DSAFV2_SBM_BP_CFG_2_ROCEE_REG_0_REG 0x238C +#define DSAFV2_SBM_BP_CFG_2_ROCEE_REG_0_REG 0x238C #define DSAF_SBM_FREE_CNT_0_0_REG 0x2010 #define DSAF_SBM_FREE_CNT_1_0_REG 0x2014 #define DSAF_SBM_BP_CNT_0_0_REG 0x2018 @@ -232,6 +235,8 @@ #define DSAF_XOD_ROCEE_RCVIN0_CNT_0_REG 0x3074 #define DSAF_XOD_ROCEE_RCVIN1_CNT_0_REG 0x3078 #define DSAF_XOD_FIFO_STATUS_0_REG 0x307C +#define DSAF_XOD_XGE_PFC_PRIO_CNT_BASE_REG 0x3A00 +#define DSAF_XOD_XGE_PFC_PRIO_CNT_OFFSET 0x4 #define DSAF_VOQ_ECC_INVERT_EN_0_REG 0x4004 #define DSAF_VOQ_SRAM_PKT_NUM_0_REG 0x4008 @@ -791,6 +796,18 @@ #define DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_S 9 #define DSAFV2_SBM_CFG4_RESET_BUF_NUM_NO_PFC_M (((1ULL << 9) - 1) << 9) +#define DSAFV2_SBM_CFG2_ROCEE_SET_BUF_NUM_S 0 +#define DSAFV2_SBM_CFG2_ROCEE_SET_BUF_NUM_M (((1ULL << 8) - 1) << 0) +#define DSAFV2_SBM_CFG2_ROCEE_RESET_BUF_NUM_S 8 +#define DSAFV2_SBM_CFG2_ROCEE_RESET_BUF_NUM_M (((1ULL << 8) - 1) << 8) + +#define DSAFV2_SBM_CFG2_PPE_SET_BUF_NUM_S (0) +#define DSAFV2_SBM_CFG2_PPE_SET_BUF_NUM_M (((1ULL << 6) - 1) << 0) +#define DSAFV2_SBM_CFG2_PPE_RESET_BUF_NUM_S (6) +#define DSAFV2_SBM_CFG2_PPE_RESET_BUF_NUM_M (((1ULL << 6) - 1) << 6) +#define DSAFV2_SBM_CFG2_PPE_CFG_USEFUL_NUM_S (12) +#define DSAFV2_SBM_CFG2_PPE_CFG_USEFUL_NUM_M (((1ULL << 6) - 1) << 12) + #define DSAF_TBL_TCAM_ADDR_S 0 #define DSAF_TBL_TCAM_ADDR_M ((1ULL << 9) - 1) diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c b/drivers/net/ethernet/hisilicon/hns/hns_enet.c index ad742a6f5879..d5297ecfe4a5 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c @@ -600,6 +600,7 @@ static int hns_nic_poll_rx_skb(struct hns_nic_ring_data *ring_data, ring->stats.sw_err_cnt++; return -ENOMEM; } + skb_reset_mac_header(skb); prefetchw(skb->data); length = le16_to_cpu(desc->rx.pkt_len); @@ -767,10 +768,10 @@ recv: clean_count = 0; } - /* poll one pkg*/ + /* poll one pkt*/ err = hns_nic_poll_rx_skb(ring_data, &skb, &bnum); if (unlikely(!skb)) /* this fault cannot be repaired */ - break; + goto out; recv_bds += bnum; clean_count += bnum; @@ -796,6 +797,7 @@ recv: } } +out: /* make all data has been write before submit */ if (clean_count > 0) hns_nic_alloc_rx_buffers(ring_data, clean_count); @@ -990,8 +992,26 @@ static void hns_nic_adjust_link(struct net_device *ndev) { struct hns_nic_priv *priv = netdev_priv(ndev); struct hnae_handle *h = priv->ae_handle; + int state = 1; - h->dev->ops->adjust_link(h, ndev->phydev->speed, ndev->phydev->duplex); + if (priv->phy) { + h->dev->ops->adjust_link(h, ndev->phydev->speed, + ndev->phydev->duplex); + state = priv->phy->link; + } + state = state && h->dev->ops->get_status(h); + + if (state != priv->link) { + if (state) { + netif_carrier_on(ndev); + netif_tx_wake_all_queues(ndev); + netdev_info(ndev, "link up\n"); + } else { + netif_carrier_off(ndev); + netdev_info(ndev, "link down\n"); + } + priv->link = state; + } } /** @@ -1181,7 +1201,7 @@ static int hns_nic_net_up(struct net_device *ndev) { struct hns_nic_priv *priv = netdev_priv(ndev); struct hnae_handle *h = priv->ae_handle; - int i, j, k; + int i, j; int ret; ret = hns_nic_init_irq(priv); @@ -1196,9 +1216,6 @@ static int hns_nic_net_up(struct net_device *ndev) goto out_has_some_queues; } - for (k = 0; k < h->q_num; k++) - h->dev->ops->toggle_queue_status(h->qs[k], 1); - ret = h->dev->ops->set_mac_addr(h, ndev->dev_addr); if (ret) goto out_set_mac_addr_err; @@ -1218,8 +1235,6 @@ static int hns_nic_net_up(struct net_device *ndev) out_start_err: netif_stop_queue(ndev); out_set_mac_addr_err: - for (k = 0; k < h->q_num; k++) - h->dev->ops->toggle_queue_status(h->qs[k], 0); out_has_some_queues: for (j = i - 1; j >= 0; j--) hns_nic_ring_close(ndev, j); @@ -1426,7 +1441,6 @@ static int hns_nic_set_features(struct net_device *netdev, netdev_features_t features) { struct hns_nic_priv *priv = netdev_priv(netdev); - struct hnae_handle *h = priv->ae_handle; switch (priv->enet_ver) { case AE_VERSION_1: @@ -1439,11 +1453,9 @@ static int hns_nic_set_features(struct net_device *netdev, priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso; /* The chip only support 7*4096 */ netif_set_gso_max_size(netdev, 7 * 4096); - h->dev->ops->set_tso_stats(h, 1); } else { priv->ops.fill_desc = fill_v2_desc; priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx; - h->dev->ops->set_tso_stats(h, 0); } break; } @@ -1576,27 +1588,14 @@ static void hns_nic_update_link_status(struct net_device *netdev) struct hns_nic_priv *priv = netdev_priv(netdev); struct hnae_handle *h = priv->ae_handle; - int state = 1; - if (priv->phy) { - if (!genphy_update_link(priv->phy)) - state = priv->phy->link; - else - state = 0; - } - state = state && h->dev->ops->get_status(h); + if (h->phy_dev) { + if (h->phy_if != PHY_INTERFACE_MODE_XGMII) + return; - if (state != priv->link) { - if (state) { - netif_carrier_on(netdev); - netif_tx_wake_all_queues(netdev); - netdev_info(netdev, "link up\n"); - } else { - netif_carrier_off(netdev); - netdev_info(netdev, "link down\n"); - } - priv->link = state; + (void)genphy_read_status(h->phy_dev); } + hns_nic_adjust_link(netdev); } /* for dumping key regs*/ @@ -1632,7 +1631,7 @@ static void hns_nic_dump(struct hns_nic_priv *priv) } } -/* for resetting suntask*/ +/* for resetting subtask */ static void hns_nic_reset_subtask(struct hns_nic_priv *priv) { enum hnae_port_type type = priv->ae_handle->port_type; @@ -1802,11 +1801,14 @@ static void hns_nic_set_priv_ops(struct net_device *netdev) priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tso; /* This chip only support 7*4096 */ netif_set_gso_max_size(netdev, 7 * 4096); - h->dev->ops->set_tso_stats(h, 1); } else { priv->ops.fill_desc = fill_v2_desc; priv->ops.maybe_stop_tx = hns_nic_maybe_stop_tx; } + /* enable tso when init + * control tso on/off through TSE bit in bd + */ + h->dev->ops->set_tso_stats(h, 1); } } @@ -1971,7 +1973,7 @@ static int hns_nic_dev_probe(struct platform_device *pdev) if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64))) dev_dbg(dev, "set mask to 64bit\n"); else - dev_err(dev, "set mask to 32bit fail!\n"); + dev_err(dev, "set mask to 64bit fail!\n"); /* carrier off reporting is important to ethtool even BEFORE open */ netif_carrier_off(ndev); diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c index a809f52f6c16..a395ca1405c3 100644 --- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c +++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c @@ -49,7 +49,7 @@ static u32 hns_nic_get_link(struct net_device *net_dev) h = priv->ae_handle; if (priv->phy) { - if (!genphy_update_link(priv->phy)) + if (!genphy_read_status(priv->phy)) link_stat = priv->phy->link; else link_stat = 0; @@ -242,6 +242,7 @@ static const char hns_nic_test_strs[][ETH_GSTRING_LEN] = { static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en) { #define COPPER_CONTROL_REG 0 +#define PHY_POWER_DOWN BIT(11) #define PHY_LOOP_BACK BIT(14) u16 val = 0; @@ -252,33 +253,40 @@ static int hns_nic_config_phy_loopback(struct phy_device *phy_dev, u8 en) /* speed : 1000M */ phy_write(phy_dev, HNS_PHY_PAGE_REG, 2); phy_write(phy_dev, 21, 0x1046); + + phy_write(phy_dev, HNS_PHY_PAGE_REG, 0); /* Force Master */ phy_write(phy_dev, 9, 0x1F00); + /* Soft-reset */ phy_write(phy_dev, 0, 0x9140); /* If autoneg disabled,two soft-reset operations */ phy_write(phy_dev, 0, 0x9140); - phy_write(phy_dev, 22, 0xFA); + + phy_write(phy_dev, HNS_PHY_PAGE_REG, 0xFA); /* Default is 0x0400 */ phy_write(phy_dev, 1, 0x418); /* Force 1000M Link, Default is 0x0200 */ phy_write(phy_dev, 7, 0x20C); - phy_write(phy_dev, 22, 0); + phy_write(phy_dev, HNS_PHY_PAGE_REG, 0); - /* Enable MAC loop-back */ + /* Enable PHY loop-back */ val = phy_read(phy_dev, COPPER_CONTROL_REG); val |= PHY_LOOP_BACK; + val &= ~PHY_POWER_DOWN; phy_write(phy_dev, COPPER_CONTROL_REG, val); } else { - phy_write(phy_dev, 22, 0xFA); + phy_write(phy_dev, HNS_PHY_PAGE_REG, 0xFA); phy_write(phy_dev, 1, 0x400); phy_write(phy_dev, 7, 0x200); - phy_write(phy_dev, 22, 0); + phy_write(phy_dev, HNS_PHY_PAGE_REG, 0); + phy_write(phy_dev, 9, 0xF00); val = phy_read(phy_dev, COPPER_CONTROL_REG); val &= ~PHY_LOOP_BACK; + val |= PHY_POWER_DOWN; phy_write(phy_dev, COPPER_CONTROL_REG, val); } return 0; @@ -339,28 +347,16 @@ static int __lb_up(struct net_device *ndev, hns_nic_net_reset(ndev); - if (priv->phy) { - phy_disconnect(priv->phy); - msleep(100); - - ret = hns_nic_init_phy(ndev, h); - if (ret) - return ret; - } - ret = __lb_setup(ndev, loop_mode); if (ret) return ret; - msleep(100); + msleep(200); ret = h->dev->ops->start ? h->dev->ops->start(h) : 0; if (ret) return ret; - if (priv->phy) - phy_start(priv->phy); - /* link adjust duplex*/ if (priv->ae_handle->phy_if != PHY_INTERFACE_MODE_XGMII) speed = 1000; @@ -561,9 +557,6 @@ static int __lb_down(struct net_device *ndev) __func__, ret); - if (priv->phy) - phy_stop(priv->phy); - if (h->dev->ops->stop) h->dev->ops->stop(h); @@ -758,6 +751,16 @@ static int hns_get_coalesce(struct net_device *net_dev, &ec->tx_max_coalesced_frames, &ec->rx_max_coalesced_frames); + ops->get_coalesce_range(priv->ae_handle, + &ec->tx_max_coalesced_frames_low, + &ec->rx_max_coalesced_frames_low, + &ec->tx_max_coalesced_frames_high, + &ec->rx_max_coalesced_frames_high, + &ec->tx_coalesce_usecs_low, + &ec->rx_coalesce_usecs_low, + &ec->tx_coalesce_usecs_high, + &ec->rx_coalesce_usecs_high); + return 0; }