X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fhinic%2Fhinic_pmd_ethdev.c;h=cd4dad8588f3b348a61ef792371846429f25ce79;hb=39e4a2577fd05199f53182b7c8509aeed40dc07f;hp=8493f6e42c6e2ad5e21d5bafb65973b8a3bef49f;hpb=1b7b9f170fcebbbd0708fab554dcb5a7badef8cf;p=dpdk.git diff --git a/drivers/net/hinic/hinic_pmd_ethdev.c b/drivers/net/hinic/hinic_pmd_ethdev.c index 8493f6e42c..cd4dad8588 100644 --- a/drivers/net/hinic/hinic_pmd_ethdev.c +++ b/drivers/net/hinic/hinic_pmd_ethdev.c @@ -4,7 +4,7 @@ #include #include -#include +#include #include #include #include @@ -36,7 +36,6 @@ /* Mezz card for Blade Server */ #define HINIC_DEV_ID_MEZZ_25GE 0x0210 -#define HINIC_DEV_ID_MEZZ_40GE 0x020D #define HINIC_DEV_ID_MEZZ_100GE 0x0205 /* 2*25G and 2*100G card */ @@ -70,18 +69,9 @@ #define HINIC_VLAN_FILTER_EN (1U << 0) -#define HINIC_MTU_TO_PKTLEN(mtu) \ - ((mtu) + ETH_HLEN + ETH_CRC_LEN) - -#define HINIC_PKTLEN_TO_MTU(pktlen) \ - ((pktlen) - (ETH_HLEN + ETH_CRC_LEN)) - /* lro numer limit for one packet */ #define HINIC_LRO_WQE_NUM_DEFAULT 8 -/* Driver-specific log messages type */ -int hinic_logtype; - struct hinic_xstats_name_off { char name[RTE_ETH_XSTATS_NAME_SIZE]; u32 offset; @@ -226,6 +216,8 @@ static const struct hinic_xstats_name_off hinic_txq_stats_strings[] = { {"copy_pkts", offsetof(struct hinic_txq_stats, cpy_pkts)}, {"rl_drop", offsetof(struct hinic_txq_stats, rl_drop)}, {"burst_pkts", offsetof(struct hinic_txq_stats, burst_pkts)}, + {"sge_len0", offsetof(struct hinic_txq_stats, sge_len0)}, + {"mbuf_null", offsetof(struct hinic_txq_stats, mbuf_null)}, }; #define HINIC_TXQ_XSTATS_NUM (sizeof(hinic_txq_stats_strings) / \ @@ -270,7 +262,7 @@ static void hinic_dev_interrupt_handler(void *param) struct rte_eth_dev *dev = param; struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); - if (!hinic_test_bit(HINIC_DEV_INTR_EN, &nic_dev->dev_status)) { + if (!rte_bit_relaxed_get32(HINIC_DEV_INTR_EN, &nic_dev->dev_status)) { PMD_DRV_LOG(WARNING, "Device's interrupt is disabled, ignore interrupt event, dev_name: %s, port_id: %d", nic_dev->proc_dev_name, dev->data->port_id); return; @@ -348,12 +340,12 @@ static int hinic_dev_configure(struct rte_eth_dev *dev) err = hinic_vlan_offload_set(dev, ETH_VLAN_STRIP_MASK | ETH_VLAN_FILTER_MASK); if (err) { - PMD_DRV_LOG(ERR, "Initialize vlan filter and strip failed\n"); + PMD_DRV_LOG(ERR, "Initialize vlan filter and strip failed"); (void)hinic_config_mq_mode(dev, FALSE); return err; } - /*clear fdir filter flag in function table*/ + /* clear fdir filter flag in function table */ hinic_free_fdir_filter(nic_dev); return HINIC_OK; @@ -439,7 +431,7 @@ static int hinic_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, } nic_dev->rxqs[queue_idx] = rxq; - /* alloc rx sq hw wqepage*/ + /* alloc rx sq hw wqe page */ rc = hinic_create_rq(hwdev, queue_idx, rq_depth, socket_id); if (rc) { PMD_DRV_LOG(ERR, "Create rxq[%d] failed, dev_name: %s, rq_depth: %d", @@ -478,7 +470,7 @@ static int hinic_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_idx, /* alloc rx_cqe and prepare rq_wqe */ rc = hinic_setup_rx_resources(rxq); if (rc) { - PMD_DRV_LOG(ERR, "Setup rxq[%d] rx_resources failed, dev_name:%s", + PMD_DRV_LOG(ERR, "Setup rxq[%d] rx_resources failed, dev_name: %s", queue_idx, dev->data->name); goto setup_rx_res_err; } @@ -736,6 +728,7 @@ hinic_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info) info->max_mac_addrs = HINIC_MAX_UC_MAC_ADDRS; info->min_mtu = HINIC_MIN_MTU_SIZE; info->max_mtu = HINIC_MAX_MTU_SIZE; + info->max_lro_pkt_size = HINIC_MAX_LRO_SIZE; hinic_get_speed_capa(dev, &info->speed_capa); info->rx_queue_offload_capa = 0; @@ -785,7 +778,7 @@ static int hinic_fw_version_get(struct rte_eth_dev *dev, char *fw_version, err = hinic_get_mgmt_version(nic_dev->hwdev, fw_ver); if (err) { - PMD_DRV_LOG(ERR, "Failed to get fw version\n"); + PMD_DRV_LOG(ERR, "Failed to get fw version"); return -EINVAL; } @@ -811,12 +804,10 @@ static int hinic_config_rx_mode(struct hinic_nic_dev *nic_dev, u32 rx_mode_ctrl) return 0; } - static int hinic_rxtx_configure(struct rte_eth_dev *dev) { - int err; struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); - bool lro_en; + int err; /* rx configure, if rss enable, need to init default configuration */ err = hinic_rx_configure(dev); @@ -833,18 +824,6 @@ static int hinic_rxtx_configure(struct rte_eth_dev *dev) goto set_rx_mode_fail; } - /* config lro */ - lro_en = dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_TCP_LRO ? - true : false; - - err = hinic_set_rx_lro(nic_dev->hwdev, lro_en, lro_en, - HINIC_LRO_WQE_NUM_DEFAULT); - if (err) { - PMD_DRV_LOG(ERR, "%s lro failed, err: %d", - lro_en ? "Enable" : "Disable", err); - goto set_rx_mode_fail; - } - return HINIC_OK; set_rx_mode_fail: @@ -954,13 +933,6 @@ static int hinic_dev_set_link_up(struct rte_eth_dev *dev) struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); int ret; - ret = hinic_set_xsfp_tx_status(nic_dev->hwdev, true); - if (ret) { - PMD_DRV_LOG(ERR, "Enable port tx xsfp failed, dev_name: %s, port_id: %d", - nic_dev->proc_dev_name, dev->data->port_id); - return ret; - } - /* link status follow phy port status, up will open pma */ ret = hinic_set_port_enable(nic_dev->hwdev, true); if (ret) @@ -984,13 +956,6 @@ static int hinic_dev_set_link_down(struct rte_eth_dev *dev) struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); int ret; - ret = hinic_set_xsfp_tx_status(nic_dev->hwdev, false); - if (ret) { - PMD_DRV_LOG(ERR, "Disable port tx xsfp failed, dev_name: %s, port_id: %d", - nic_dev->proc_dev_name, dev->data->port_id); - return ret; - } - /* link status follow phy port status, up will close pma */ ret = hinic_set_port_enable(nic_dev->hwdev, false); if (ret) @@ -1028,7 +993,7 @@ static int hinic_dev_start(struct rte_eth_dev *dev) /* init txq and rxq context */ rc = hinic_init_qp_ctxts(nic_dev->hwdev); if (rc) { - PMD_DRV_LOG(ERR, "Initialize qp context failed, dev_name:%s", + PMD_DRV_LOG(ERR, "Initialize qp context failed, dev_name: %s", name); goto init_qp_fail; } @@ -1070,7 +1035,7 @@ static int hinic_dev_start(struct rte_eth_dev *dev) /* open physical port and start packet receiving */ rc = hinic_set_port_enable(nic_dev->hwdev, true); if (rc) { - PMD_DRV_LOG(ERR, "Enable physical port failed, dev_name:%s", + PMD_DRV_LOG(ERR, "Enable physical port failed, dev_name: %s", name); goto en_port_fail; } @@ -1079,7 +1044,7 @@ static int hinic_dev_start(struct rte_eth_dev *dev) if (dev->data->dev_conf.intr_conf.lsc != 0) (void)hinic_link_update(dev, 0); - hinic_set_bit(HINIC_DEV_START, &nic_dev->dev_status); + rte_bit_relaxed_set32(HINIC_DEV_START, &nic_dev->dev_status); return 0; @@ -1110,12 +1075,14 @@ init_qp_fail: /** * DPDK callback to release the receive queue. * - * @param queue - * Generic receive queue pointer. + * @param dev + * Pointer to Ethernet device structure. + * @param qid + * Receive queue index. */ -static void hinic_rx_queue_release(void *queue) +static void hinic_rx_queue_release(struct rte_eth_dev *dev, uint16_t qid) { - struct hinic_rxq *rxq = queue; + struct hinic_rxq *rxq = dev->data->rx_queues[qid]; struct hinic_nic_dev *nic_dev; if (!rxq) { @@ -1142,12 +1109,14 @@ static void hinic_rx_queue_release(void *queue) /** * DPDK callback to release the transmit queue. * - * @param queue - * Generic transmit queue pointer. + * @param dev + * Pointer to Ethernet device structure. + * @param qid + * Transmit queue index. */ -static void hinic_tx_queue_release(void *queue) +static void hinic_tx_queue_release(struct rte_eth_dev *dev, uint16_t qid) { - struct hinic_txq *txq = queue; + struct hinic_txq *txq = dev->data->tx_queues[qid]; struct hinic_nic_dev *nic_dev; if (!txq) { @@ -1192,7 +1161,7 @@ static void hinic_free_all_sq(struct hinic_nic_dev *nic_dev) * @param dev * Pointer to Ethernet device structure. */ -static void hinic_dev_stop(struct rte_eth_dev *dev) +static int hinic_dev_stop(struct rte_eth_dev *dev) { int rc; char *name; @@ -1204,20 +1173,23 @@ static void hinic_dev_stop(struct rte_eth_dev *dev) name = dev->data->name; port_id = dev->data->port_id; - if (!hinic_test_and_clear_bit(HINIC_DEV_START, &nic_dev->dev_status)) { + dev->data->dev_started = 0; + + if (!rte_bit_relaxed_test_and_clear32(HINIC_DEV_START, + &nic_dev->dev_status)) { PMD_DRV_LOG(INFO, "Device %s already stopped", name); - return; + return 0; } /* just stop phy port and vport */ rc = hinic_set_port_enable(nic_dev->hwdev, false); if (rc) - PMD_DRV_LOG(WARNING, "Disable phy port failed, error: %d, dev_name:%s, port_id:%d", + PMD_DRV_LOG(WARNING, "Disable phy port failed, error: %d, dev_name: %s, port_id: %d", rc, name, port_id); rc = hinic_set_vport_enable(nic_dev->hwdev, false); if (rc) - PMD_DRV_LOG(WARNING, "Disable vport failed, error: %d, dev_name:%s, port_id:%d", + PMD_DRV_LOG(WARNING, "Disable vport failed, error: %d, dev_name: %s, port_id: %d", rc, name, port_id); /* Clear recorded link status */ @@ -1236,11 +1208,13 @@ static void hinic_dev_stop(struct rte_eth_dev *dev) /* clean root context */ hinic_free_qp_ctxts(nic_dev->hwdev); - hinic_free_fdir_filter(nic_dev); + hinic_destroy_fdir_filter(dev); /* free mbuf */ hinic_free_all_rx_mbuf(dev); hinic_free_all_tx_mbuf(dev); + + return 0; } static void hinic_disable_interrupt(struct rte_eth_dev *dev) @@ -1249,7 +1223,7 @@ static void hinic_disable_interrupt(struct rte_eth_dev *dev) struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); int ret, retries = 0; - hinic_clear_bit(HINIC_DEV_INTR_EN, &nic_dev->dev_status); + rte_bit_relaxed_clear32(HINIC_DEV_INTR_EN, &nic_dev->dev_status); /* disable msix interrupt in hardware */ hinic_set_msix_state(nic_dev->hwdev, 0, HINIC_MSIX_DISABLE); @@ -1278,18 +1252,31 @@ static void hinic_disable_interrupt(struct rte_eth_dev *dev) if (retries == HINIC_INTR_CB_UNREG_MAX_RETRIES) PMD_DRV_LOG(ERR, "Unregister intr callback failed after %d retries", retries); + + rte_bit_relaxed_clear32(HINIC_DEV_INIT, &nic_dev->dev_status); } static int hinic_set_dev_promiscuous(struct hinic_nic_dev *nic_dev, bool enable) { - u32 rx_mode_ctrl = nic_dev->rx_mode_status; + u32 rx_mode_ctrl; + int err; + + err = hinic_mutex_lock(&nic_dev->rx_mode_mutex); + if (err) + return err; + + rx_mode_ctrl = nic_dev->rx_mode_status; if (enable) rx_mode_ctrl |= HINIC_RX_MODE_PROMISC; else rx_mode_ctrl &= (~HINIC_RX_MODE_PROMISC); - return hinic_config_rx_mode(nic_dev, rx_mode_ctrl); + err = hinic_config_rx_mode(nic_dev, rx_mode_ctrl); + + (void)hinic_mutex_unlock(&nic_dev->rx_mode_mutex); + + return err; } /** @@ -1323,6 +1310,8 @@ hinic_dev_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats) return err; } + dev->data->rx_mbuf_alloc_failed = 0; + /* rx queue stats */ q_num = (nic_dev->num_rq < RTE_ETHDEV_QUEUE_STAT_CNTRS) ? nic_dev->num_rq : RTE_ETHDEV_QUEUE_STAT_CNTRS; @@ -1537,12 +1526,16 @@ static void hinic_deinit_mac_addr(struct rte_eth_dev *eth_dev) /* delete multicast mac addrs */ hinic_delete_mc_addr_list(nic_dev); + + rte_free(nic_dev->mc_list); + } static int hinic_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) { - int ret = 0; struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + uint32_t frame_size; + int ret = 0; PMD_DRV_LOG(INFO, "Set port mtu, port_id: %d, mtu: %d, max_pkt_len: %d", dev->data->port_id, mtu, HINIC_MTU_TO_PKTLEN(mtu)); @@ -1560,7 +1553,15 @@ static int hinic_dev_set_mtu(struct rte_eth_dev *dev, uint16_t mtu) } /* update max frame size */ - dev->data->dev_conf.rxmode.max_rx_pkt_len = HINIC_MTU_TO_PKTLEN(mtu); + frame_size = HINIC_MTU_TO_PKTLEN(mtu); + if (frame_size > HINIC_ETH_MAX_LEN) + dev->data->dev_conf.rxmode.offloads |= + DEV_RX_OFFLOAD_JUMBO_FRAME; + else + dev->data->dev_conf.rxmode.offloads &= + ~DEV_RX_OFFLOAD_JUMBO_FRAME; + + dev->data->dev_conf.rxmode.max_rx_pkt_len = frame_size; nic_dev->mtu_size = mtu; return ret; @@ -1611,6 +1612,9 @@ static int hinic_vlan_filter_set(struct rte_eth_dev *dev, if (vlan_id > RTE_ETHER_MAX_VLAN_ID) return -EINVAL; + if (vlan_id == 0) + return 0; + func_id = hinic_global_func_id(nic_dev->hwdev); if (enable) { @@ -1703,12 +1707,6 @@ static int hinic_vlan_offload_set(struct rte_eth_dev *dev, int mask) nic_dev->proc_dev_name, dev->data->port_id); } - if (mask & ETH_VLAN_EXTEND_MASK) { - PMD_DRV_LOG(ERR, "Don't support vlan qinq, device: %s, port_id: %d", - nic_dev->proc_dev_name, dev->data->port_id); - return -ENOTSUP; - } - return 0; } @@ -1733,14 +1731,25 @@ static void hinic_remove_all_vlanid(struct rte_eth_dev *eth_dev) static int hinic_set_dev_allmulticast(struct hinic_nic_dev *nic_dev, bool enable) { - u32 rx_mode_ctrl = nic_dev->rx_mode_status; + u32 rx_mode_ctrl; + int err; + + err = hinic_mutex_lock(&nic_dev->rx_mode_mutex); + if (err) + return err; + + rx_mode_ctrl = nic_dev->rx_mode_status; if (enable) rx_mode_ctrl |= HINIC_RX_MODE_MC_ALL; else rx_mode_ctrl &= (~HINIC_RX_MODE_MC_ALL); - return hinic_config_rx_mode(nic_dev, rx_mode_ctrl); + err = hinic_config_rx_mode(nic_dev, rx_mode_ctrl); + + (void)hinic_mutex_unlock(&nic_dev->rx_mode_mutex); + + return err; } /** @@ -1847,6 +1856,76 @@ static int hinic_dev_promiscuous_disable(struct rte_eth_dev *dev) return rc; } +static int hinic_flow_ctrl_get(struct rte_eth_dev *dev, + struct rte_eth_fc_conf *fc_conf) +{ + struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + struct nic_pause_config nic_pause; + int err; + + memset(&nic_pause, 0, sizeof(nic_pause)); + + err = hinic_get_pause_info(nic_dev->hwdev, &nic_pause); + if (err) + return err; + + if (nic_dev->pause_set || !nic_pause.auto_neg) { + nic_pause.rx_pause = nic_dev->nic_pause.rx_pause; + nic_pause.tx_pause = nic_dev->nic_pause.tx_pause; + } + + fc_conf->autoneg = nic_pause.auto_neg; + + if (nic_pause.tx_pause && nic_pause.rx_pause) + fc_conf->mode = RTE_FC_FULL; + else if (nic_pause.tx_pause) + fc_conf->mode = RTE_FC_TX_PAUSE; + else if (nic_pause.rx_pause) + fc_conf->mode = RTE_FC_RX_PAUSE; + else + fc_conf->mode = RTE_FC_NONE; + + return 0; +} + +static int hinic_flow_ctrl_set(struct rte_eth_dev *dev, + struct rte_eth_fc_conf *fc_conf) +{ + struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + struct nic_pause_config nic_pause; + int err; + + nic_pause.auto_neg = fc_conf->autoneg; + + if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) || + (fc_conf->mode & RTE_FC_TX_PAUSE)) + nic_pause.tx_pause = true; + else + nic_pause.tx_pause = false; + + if (((fc_conf->mode & RTE_FC_FULL) == RTE_FC_FULL) || + (fc_conf->mode & RTE_FC_RX_PAUSE)) + nic_pause.rx_pause = true; + else + nic_pause.rx_pause = false; + + err = hinic_set_pause_config(nic_dev->hwdev, nic_pause); + if (err) + return err; + + nic_dev->pause_set = true; + nic_dev->nic_pause.auto_neg = nic_pause.auto_neg; + nic_dev->nic_pause.rx_pause = nic_pause.rx_pause; + nic_dev->nic_pause.tx_pause = nic_pause.tx_pause; + + PMD_DRV_LOG(INFO, "Set pause options, tx: %s, rx: %s, auto: %s\n", + nic_pause.tx_pause ? "on" : "off", + nic_pause.rx_pause ? "on" : "off", + nic_pause.auto_neg ? "on" : "off"); + + return 0; +} + /** * DPDK callback to update the RSS hash key and RSS hash type. * @@ -1875,7 +1954,7 @@ static int hinic_rss_hash_update(struct rte_eth_dev *dev, } if (rss_conf->rss_key_len > HINIC_RSS_KEY_SIZE) { - PMD_DRV_LOG(ERR, "Invalid rss key, rss_key_len:%d", + PMD_DRV_LOG(ERR, "Invalid rss key, rss_key_len: %d", rss_conf->rss_key_len); return HINIC_ERROR; } @@ -1968,12 +2047,12 @@ static int hinic_rss_conf_get(struct rte_eth_dev *dev, } /** - * DPDK callback to update the RETA indirection table. + * DPDK callback to update the RSS redirection table. * * @param dev * Pointer to Ethernet device structure. * @param reta_conf - * Pointer to RETA configuration structure array. + * Pointer to RSS reta configuration data. * @param reta_size * Size of the RETA table. * @@ -1996,7 +2075,7 @@ static int hinic_rss_indirtbl_update(struct rte_eth_dev *dev, return HINIC_OK; if (reta_size != NIC_RSS_INDIR_SIZE) { - PMD_DRV_LOG(ERR, "Invalid reta size, reta_size:%d", reta_size); + PMD_DRV_LOG(ERR, "Invalid reta size, reta_size: %d", reta_size); return HINIC_ERROR; } @@ -2008,16 +2087,16 @@ static int hinic_rss_indirtbl_update(struct rte_eth_dev *dev, for (i = 0; i < reta_size; i++) { idx = i / RTE_RETA_GROUP_SIZE; shift = i % RTE_RETA_GROUP_SIZE; - if (reta_conf[idx].mask & (1ULL << shift)) - indirtbl[i] = reta_conf[idx].reta[shift]; - } - for (i = 0 ; i < reta_size; i++) { - if (indirtbl[i] >= nic_dev->num_rq) { - PMD_DRV_LOG(ERR, "Invalid reta entry, index:%d, num_rq:%d", - i, nic_dev->num_rq); - goto disable_rss; + if (reta_conf[idx].reta[shift] >= nic_dev->num_rq) { + PMD_DRV_LOG(ERR, "Invalid reta entry, indirtbl[%d]: %d " + "exceeds the maximum rxq num: %d", i, + reta_conf[idx].reta[shift], nic_dev->num_rq); + return -EINVAL; } + + if (reta_conf[idx].mask & (1ULL << shift)) + indirtbl[i] = reta_conf[idx].reta[shift]; } err = hinic_rss_set_indir_tbl(nic_dev->hwdev, tmpl_idx, indirtbl); @@ -2035,14 +2114,13 @@ disable_rss: return HINIC_ERROR; } - /** - * DPDK callback to get the RETA indirection table. + * DPDK callback to get the RSS indirection table. * * @param dev * Pointer to Ethernet device structure. * @param reta_conf - * Pointer to RETA configuration structure array. + * Pointer to RSS reta configuration data. * @param reta_size * Size of the RETA table. * @@ -2061,13 +2139,13 @@ static int hinic_rss_indirtbl_query(struct rte_eth_dev *dev, u16 i = 0; if (reta_size != NIC_RSS_INDIR_SIZE) { - PMD_DRV_LOG(ERR, "Invalid reta size, reta_size:%d", reta_size); + PMD_DRV_LOG(ERR, "Invalid reta size, reta_size: %d", reta_size); return HINIC_ERROR; } err = hinic_rss_get_indir_tbl(nic_dev->hwdev, tmpl_idx, indirtbl); if (err) { - PMD_DRV_LOG(ERR, "Get rss indirect table failed, error:%d", + PMD_DRV_LOG(ERR, "Get rss indirect table failed, error: %d", err); return err; } @@ -2242,8 +2320,7 @@ static int hinic_dev_xstats_get_names(struct rte_eth_dev *dev, for (i = 0; i < HINIC_VPORT_XSTATS_NUM; i++) { snprintf(xstats_names[count].name, sizeof(xstats_names[count].name), - "%s", - hinic_vport_stats_strings[i].name); + "%s", hinic_vport_stats_strings[i].name); count++; } @@ -2254,13 +2331,13 @@ static int hinic_dev_xstats_get_names(struct rte_eth_dev *dev, for (i = 0; i < HINIC_PHYPORT_XSTATS_NUM; i++) { snprintf(xstats_names[count].name, sizeof(xstats_names[count].name), - "%s", - hinic_phyport_stats_strings[i].name); + "%s", hinic_phyport_stats_strings[i].name); count++; } return count; } + /** * DPDK callback to set mac address * @@ -2286,10 +2363,8 @@ static int hinic_set_mac_addr(struct rte_eth_dev *dev, rte_ether_addr_copy(addr, &nic_dev->default_addr); - PMD_DRV_LOG(INFO, "Set new mac address %02x:%02x:%02x:%02x:%02x:%02x\n", - addr->addr_bytes[0], addr->addr_bytes[1], - addr->addr_bytes[2], addr->addr_bytes[3], - addr->addr_bytes[4], addr->addr_bytes[5]); + PMD_DRV_LOG(INFO, "Set new mac address " RTE_ETHER_ADDR_PRT_FMT, + RTE_ETHER_ADDR_BYTES(addr)); return 0; } @@ -2300,7 +2375,7 @@ static int hinic_set_mac_addr(struct rte_eth_dev *dev, * @param dev * Pointer to Ethernet device structure. * @param index - * MAC address index. + * MAC address index, should less than 128. */ static void hinic_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index) { @@ -2329,16 +2404,15 @@ static void hinic_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index) * @param dev * Pointer to Ethernet device structure. * @param mac_addr - * MAC address to register. + * Pointer to MAC address * @param index - * MAC address index. + * MAC address index, should less than 128. * @param vmdq - * VMDq pool index to associate address with (ignored). + * VMDq pool index(not used). * * @return - * 0 on success, a negative errno value otherwise and rte_errno is set. + * 0 on success, negative error value otherwise. */ - static int hinic_mac_addr_add(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr, uint32_t index, __rte_unused uint32_t vmdq) @@ -2349,7 +2423,7 @@ static int hinic_mac_addr_add(struct rte_eth_dev *dev, int ret; if (index >= HINIC_MAX_UC_MAC_ADDRS) { - PMD_DRV_LOG(INFO, "Add mac index(%u) is out of range,", index); + PMD_DRV_LOG(INFO, "Add mac index(%u) is out of range", index); return -EINVAL; } @@ -2426,54 +2500,42 @@ allmulti: } /** - * DPDK callback to manage filter operations + * DPDK callback to get flow operations * * @param dev * Pointer to Ethernet device structure. - * @param filter_type - * Filter type. - * @param filter_op - * Operation to perform. - * @param arg + * @param ops * Pointer to operation-specific structure. * * @return - * 0 on success, negative errno value on failure. + * 0 on success, negative error value otherwise. */ -static int hinic_dev_filter_ctrl(struct rte_eth_dev *dev, - enum rte_filter_type filter_type, - enum rte_filter_op filter_op, - void *arg) +static int hinic_dev_flow_ops_get(struct rte_eth_dev *dev __rte_unused, + const struct rte_flow_ops **ops) { - struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); - int func_id = hinic_global_func_id(nic_dev->hwdev); - - switch (filter_type) { - case RTE_ETH_FILTER_GENERIC: - if (filter_op != RTE_ETH_FILTER_GET) - return -EINVAL; - *(const void **)arg = &hinic_flow_ops; - break; - default: - PMD_DRV_LOG(INFO, "Filter type (%d) not supported", - filter_type); - return -EINVAL; - } - - PMD_DRV_LOG(INFO, "Set filter_ctrl succeed, func_id: 0x%x, filter_type: 0x%x," - "filter_op: 0x%x.", func_id, filter_type, filter_op); + *ops = &hinic_flow_ops; return 0; } static int hinic_set_default_pause_feature(struct hinic_nic_dev *nic_dev) { struct nic_pause_config pause_config = {0}; + int err; pause_config.auto_neg = 0; pause_config.rx_pause = HINIC_DEFAUT_PAUSE_CONFIG; pause_config.tx_pause = HINIC_DEFAUT_PAUSE_CONFIG; - return hinic_set_pause_config(nic_dev->hwdev, pause_config); + err = hinic_set_pause_config(nic_dev->hwdev, pause_config); + if (err) + return err; + + nic_dev->pause_set = true; + nic_dev->nic_pause.auto_neg = pause_config.auto_neg; + nic_dev->nic_pause.rx_pause = pause_config.rx_pause; + nic_dev->nic_pause.tx_pause = pause_config.tx_pause; + + return 0; } static int hinic_set_default_dcb_feature(struct hinic_nic_dev *nic_dev) @@ -2493,26 +2555,53 @@ static int hinic_set_default_dcb_feature(struct hinic_nic_dev *nic_dev) up_pgid, up_bw, up_strict); } +static int hinic_pf_get_default_cos(struct hinic_hwdev *hwdev, u8 *cos_id) +{ + u8 default_cos = 0; + u8 valid_cos_bitmap; + u8 i; + + valid_cos_bitmap = hwdev->cfg_mgmt->svc_cap.valid_cos_bitmap; + if (!valid_cos_bitmap) { + PMD_DRV_LOG(ERR, "PF has none cos to support\n"); + return -EFAULT; + } + + for (i = 0; i < NR_MAX_COS; i++) { + if (valid_cos_bitmap & BIT(i)) + default_cos = i; /* Find max cos id as default cos */ + } + + *cos_id = default_cos; + + return 0; +} + static int hinic_init_default_cos(struct hinic_nic_dev *nic_dev) { u8 cos_id = 0; int err; if (!HINIC_IS_VF(nic_dev->hwdev)) { - nic_dev->default_cos = - (hinic_global_func_id(nic_dev->hwdev) + - DEFAULT_BASE_COS) % NR_MAX_COS; + err = hinic_pf_get_default_cos(nic_dev->hwdev, &cos_id); + if (err) { + PMD_DRV_LOG(ERR, "Get PF default cos failed, err: %d", + err); + return HINIC_ERROR; + } } else { err = hinic_vf_get_default_cos(nic_dev->hwdev, &cos_id); if (err) { PMD_DRV_LOG(ERR, "Get VF default cos failed, err: %d", - err); + err); return HINIC_ERROR; } - - nic_dev->default_cos = cos_id; } + nic_dev->default_cos = cos_id; + + PMD_DRV_LOG(INFO, "Default cos %d", nic_dev->default_cos); + return 0; } @@ -2736,8 +2825,12 @@ static int hinic_nic_dev_create(struct rte_eth_dev *eth_dev) } /* get nic capability */ - if (!hinic_support_nic(nic_dev->hwdev, &nic_dev->nic_cap)) + if (!hinic_support_nic(nic_dev->hwdev, &nic_dev->nic_cap)) { + PMD_DRV_LOG(ERR, "Hw doesn't support nic, dev_name: %s", + eth_dev->data->name); + rc = -EINVAL; goto nic_check_fail; + } /* init root cla and function table */ rc = hinic_init_nicio(nic_dev->hwdev); @@ -2844,18 +2937,23 @@ static void hinic_nic_dev_destroy(struct rte_eth_dev *eth_dev) * @param dev * Pointer to Ethernet device structure. */ -static void hinic_dev_close(struct rte_eth_dev *dev) +static int hinic_dev_close(struct rte_eth_dev *dev) { struct hinic_nic_dev *nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); + int ret; + + if (rte_eal_process_type() != RTE_PROC_PRIMARY) + return 0; - if (hinic_test_and_set_bit(HINIC_DEV_CLOSE, &nic_dev->dev_status)) { + if (rte_bit_relaxed_test_and_set32(HINIC_DEV_CLOSE, + &nic_dev->dev_status)) { PMD_DRV_LOG(WARNING, "Device %s already closed", dev->data->name); - return; + return 0; } /* stop device first */ - hinic_dev_stop(dev); + ret = hinic_dev_stop(dev); /* rx_cqe, rx_info */ hinic_free_all_rx_resources(dev); @@ -2876,8 +2974,13 @@ static void hinic_dev_close(struct rte_eth_dev *dev) /* disable hardware and uio interrupt */ hinic_disable_interrupt(dev); + /* destroy rx mode mutex */ + hinic_mutex_destroy(&nic_dev->rx_mode_mutex); + /* deinit nic hardware device */ hinic_nic_dev_destroy(dev); + + return ret; } static const struct eth_dev_ops hinic_pmd_ops = { @@ -2901,6 +3004,8 @@ static const struct eth_dev_ops hinic_pmd_ops = { .allmulticast_disable = hinic_dev_allmulticast_disable, .promiscuous_enable = hinic_dev_promiscuous_enable, .promiscuous_disable = hinic_dev_promiscuous_disable, + .flow_ctrl_get = hinic_flow_ctrl_get, + .flow_ctrl_set = hinic_flow_ctrl_set, .rss_hash_update = hinic_rss_hash_update, .rss_hash_conf_get = hinic_rss_conf_get, .reta_update = hinic_rss_indirtbl_update, @@ -2916,7 +3021,7 @@ static const struct eth_dev_ops hinic_pmd_ops = { .mac_addr_remove = hinic_mac_addr_remove, .mac_addr_add = hinic_mac_addr_add, .set_mc_addr_list = hinic_set_mc_addr_list, - .filter_ctrl = hinic_dev_filter_ctrl, + .flow_ops_get = hinic_dev_flow_ops_get, }; static const struct eth_dev_ops hinic_pmd_vf_ops = { @@ -2951,7 +3056,11 @@ static const struct eth_dev_ops hinic_pmd_vf_ops = { .mac_addr_remove = hinic_mac_addr_remove, .mac_addr_add = hinic_mac_addr_add, .set_mc_addr_list = hinic_set_mc_addr_list, - .filter_ctrl = hinic_dev_filter_ctrl, + .flow_ops_get = hinic_dev_flow_ops_get, +}; + +static const struct eth_dev_ops hinic_dev_sec_ops = { + .dev_infos_get = hinic_dev_infos_get, }; static int hinic_func_init(struct rte_eth_dev *eth_dev) @@ -2960,6 +3069,7 @@ static int hinic_func_init(struct rte_eth_dev *eth_dev) struct rte_ether_addr *eth_addr; struct hinic_nic_dev *nic_dev; struct hinic_filter_info *filter_info; + struct hinic_tcam_info *tcam_info; u32 mac_size; int rc; @@ -2967,12 +3077,15 @@ static int hinic_func_init(struct rte_eth_dev *eth_dev) /* EAL is SECONDARY and eth_dev is already created */ if (rte_eal_process_type() != RTE_PROC_PRIMARY) { + eth_dev->dev_ops = &hinic_dev_sec_ops; PMD_DRV_LOG(INFO, "Initialize %s in secondary process", eth_dev->data->name); return 0; } + eth_dev->data->dev_flags |= RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS; + nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev); memset(nic_dev, 0, sizeof(*nic_dev)); @@ -3002,12 +3115,6 @@ static int hinic_func_init(struct rte_eth_dev *eth_dev) goto mc_addr_fail; } - /* - * Pass the information to the rte_eth_dev_close() that it should also - * release the private port resources. - */ - eth_dev->data->dev_flags |= RTE_ETH_DEV_CLOSE_REMOVE; - /* create hardware nic_device */ rc = hinic_nic_dev_create(eth_dev); if (rc) { @@ -3045,19 +3152,24 @@ static int hinic_func_init(struct rte_eth_dev *eth_dev) eth_dev->data->name); goto enable_intr_fail; } - hinic_set_bit(HINIC_DEV_INTR_EN, &nic_dev->dev_status); + rte_bit_relaxed_set32(HINIC_DEV_INTR_EN, &nic_dev->dev_status); + + hinic_mutex_init(&nic_dev->rx_mode_mutex, NULL); /* initialize filter info */ filter_info = &nic_dev->filter; + tcam_info = &nic_dev->tcam; memset(filter_info, 0, sizeof(struct hinic_filter_info)); + memset(tcam_info, 0, sizeof(struct hinic_tcam_info)); /* initialize 5tuple filter list */ TAILQ_INIT(&filter_info->fivetuple_list); + TAILQ_INIT(&tcam_info->tcam_list); TAILQ_INIT(&nic_dev->filter_ntuple_list); TAILQ_INIT(&nic_dev->filter_ethertype_list); TAILQ_INIT(&nic_dev->filter_fdir_rule_list); TAILQ_INIT(&nic_dev->hinic_flow_list); - hinic_set_bit(HINIC_DEV_INIT, &nic_dev->dev_status); + rte_bit_relaxed_set32(HINIC_DEV_INIT, &nic_dev->dev_status); PMD_DRV_LOG(INFO, "Initialize %s in primary successfully", eth_dev->data->name); @@ -3110,32 +3222,17 @@ static int hinic_dev_init(struct rte_eth_dev *eth_dev) static int hinic_dev_uninit(struct rte_eth_dev *dev) { - struct hinic_nic_dev *nic_dev; - - nic_dev = HINIC_ETH_DEV_TO_PRIVATE_NIC_DEV(dev); - hinic_clear_bit(HINIC_DEV_INIT, &nic_dev->dev_status); - if (rte_eal_process_type() != RTE_PROC_PRIMARY) return 0; hinic_dev_close(dev); - dev->dev_ops = NULL; - dev->rx_pkt_burst = NULL; - dev->tx_pkt_burst = NULL; - - rte_free(nic_dev->mc_list); - - rte_free(dev->data->mac_addrs); - dev->data->mac_addrs = NULL; - return HINIC_OK; } static struct rte_pci_id pci_id_hinic_map[] = { { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_PRD) }, { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_MEZZ_25GE) }, - { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_MEZZ_40GE) }, { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_MEZZ_100GE) }, { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_VF) }, { RTE_PCI_DEVICE(HINIC_HUAWEI_VENDOR_ID, HINIC_DEV_ID_VF_HV) }, @@ -3165,10 +3262,4 @@ static struct rte_pci_driver rte_hinic_pmd = { RTE_PMD_REGISTER_PCI(net_hinic, rte_hinic_pmd); RTE_PMD_REGISTER_PCI_TABLE(net_hinic, pci_id_hinic_map); - -RTE_INIT(hinic_init_log) -{ - hinic_logtype = rte_log_register("pmd.net.hinic"); - if (hinic_logtype >= 0) - rte_log_set_level(hinic_logtype, RTE_LOG_INFO); -} +RTE_LOG_REGISTER_DEFAULT(hinic_logtype, INFO);