X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fcnxk%2Fcnxk_ethdev.c;h=7adab4605819b3582970980c0b2b44e911a548e4;hb=99fc1f6eefa7850089d392bc682767e75bc79259;hp=3f92780206ad30157332b6f48590878160f3de87;hpb=8589ec212e80c44e0c9e1410a14ae9b6de077e59;p=dpdk.git diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c index 3f92780206..7adab46058 100644 --- a/drivers/net/cnxk/cnxk_ethdev.c +++ b/drivers/net/cnxk/cnxk_ethdev.c @@ -8,7 +8,8 @@ nix_get_rx_offload_capa(struct cnxk_eth_dev *dev) { uint64_t capa = CNXK_NIX_RX_OFFLOAD_CAPA; - if (roc_nix_is_vf_or_sdp(&dev->nix)) + if (roc_nix_is_vf_or_sdp(&dev->nix) || + dev->npc.switch_header_type == ROC_PRIV_FLAGS_HIGIG) capa &= ~DEV_RX_OFFLOAD_TIMESTAMP; return capa; @@ -58,7 +59,7 @@ nix_enable_mseg_on_jumbo(struct cnxk_eth_rxq_sp *rxq) } } -static int +int nix_recalc_mtu(struct rte_eth_dev *eth_dev) { struct rte_eth_dev_data *data = eth_dev->data; @@ -81,6 +82,56 @@ nix_recalc_mtu(struct rte_eth_dev *eth_dev) return rc; } +static int +nix_init_flow_ctrl_config(struct rte_eth_dev *eth_dev) +{ + struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); + struct cnxk_fc_cfg *fc = &dev->fc_cfg; + struct rte_eth_fc_conf fc_conf = {0}; + int rc; + + /* Both Rx & Tx flow ctrl get enabled(RTE_FC_FULL) in HW + * by AF driver, update those info in PMD structure. + */ + rc = cnxk_nix_flow_ctrl_get(eth_dev, &fc_conf); + if (rc) + goto exit; + + fc->mode = fc_conf.mode; + fc->rx_pause = (fc_conf.mode == RTE_FC_FULL) || + (fc_conf.mode == RTE_FC_RX_PAUSE); + fc->tx_pause = (fc_conf.mode == RTE_FC_FULL) || + (fc_conf.mode == RTE_FC_TX_PAUSE); + +exit: + return rc; +} + +static int +nix_update_flow_ctrl_config(struct rte_eth_dev *eth_dev) +{ + struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); + struct cnxk_fc_cfg *fc = &dev->fc_cfg; + struct rte_eth_fc_conf fc_cfg = {0}; + + if (roc_nix_is_vf_or_sdp(&dev->nix)) + return 0; + + fc_cfg.mode = fc->mode; + + /* To avoid Link credit deadlock on Ax, disable Tx FC if it's enabled */ + if (roc_model_is_cn96_ax() && + dev->npc.switch_header_type != ROC_PRIV_FLAGS_HIGIG && + (fc_cfg.mode == RTE_FC_FULL || fc_cfg.mode == RTE_FC_RX_PAUSE)) { + fc_cfg.mode = + (fc_cfg.mode == RTE_FC_FULL || + fc_cfg.mode == RTE_FC_TX_PAUSE) ? + RTE_FC_TX_PAUSE : RTE_FC_NONE; + } + + return cnxk_nix_flow_ctrl_set(eth_dev, &fc_cfg); +} + uint64_t cnxk_nix_rxq_mbuf_setup(struct cnxk_eth_dev *dev) { @@ -99,7 +150,8 @@ cnxk_nix_rxq_mbuf_setup(struct cnxk_eth_dev *dev) offsetof(struct rte_mbuf, data_off) != 6); mb_def.nb_segs = 1; - mb_def.data_off = RTE_PKTMBUF_HEADROOM; + mb_def.data_off = RTE_PKTMBUF_HEADROOM + + (dev->ptp_en * CNXK_NIX_TIMESYNC_RX_OFFSET); mb_def.port = port_id; rte_mbuf_refcnt_set(&mb_def, 1); @@ -305,6 +357,18 @@ cnxk_nix_rx_queue_setup(struct rte_eth_dev *eth_dev, uint16_t qid, eth_dev->data->rx_queues[qid] = rxq_sp + 1; eth_dev->data->rx_queue_state[qid] = RTE_ETH_QUEUE_STATE_STOPPED; + /* Calculating delta and freq mult between PTP HI clock and tsc. + * These are needed in deriving raw clock value from tsc counter. + * read_clock eth op returns raw clock value. + */ + if ((dev->rx_offloads & DEV_RX_OFFLOAD_TIMESTAMP) || dev->ptp_en) { + rc = cnxk_nix_tsc_convert(dev); + if (rc) { + plt_err("Failed to calculate delta and freq mult"); + goto rq_fini; + } + } + return 0; rq_fini: rc |= roc_nix_rq_fini(rq); @@ -370,8 +434,10 @@ cnxk_rss_ethdev_to_nix(struct cnxk_eth_dev *dev, uint64_t ethdev_rss, dev->ethdev_rss_hf = ethdev_rss; - if (ethdev_rss & ETH_RSS_L2_PAYLOAD) + if (ethdev_rss & ETH_RSS_L2_PAYLOAD && + dev->npc.switch_header_type == ROC_PRIV_FLAGS_LEN_90B) { flowkey_cfg |= FLOW_KEY_TYPE_CH_LEN_90B; + } if (ethdev_rss & ETH_RSS_C_VLAN) flowkey_cfg |= FLOW_KEY_TYPE_VLAN; @@ -686,6 +752,7 @@ cnxk_nix_configure(struct rte_eth_dev *eth_dev) struct rte_eth_rxmode *rxmode = &conf->rxmode; struct rte_eth_txmode *txmode = &conf->txmode; char ea_fmt[RTE_ETHER_ADDR_FMT_SIZE]; + struct roc_nix_fc_cfg fc_cfg = {0}; struct roc_nix *nix = &dev->nix; struct rte_ether_addr *ea; uint8_t nb_rxq, nb_txq; @@ -765,6 +832,8 @@ cnxk_nix_configure(struct rte_eth_dev *eth_dev) goto fail_configure; } + dev->npc.channel = roc_nix_get_base_chan(nix); + nb_rxq = data->nb_rx_queues; nb_txq = data->nb_tx_queues; rc = -ENOMEM; @@ -799,11 +868,18 @@ cnxk_nix_configure(struct rte_eth_dev *eth_dev) roc_nix_err_intr_ena_dis(nix, true); roc_nix_ras_intr_ena_dis(nix, true); - if (nix->rx_ptp_ena) { + if (nix->rx_ptp_ena && + dev->npc.switch_header_type == ROC_PRIV_FLAGS_HIGIG) { plt_err("Both PTP and switch header enabled"); goto free_nix_lf; } + rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type); + if (rc) { + plt_err("Failed to enable switch type nix_lf rc=%d", rc); + goto free_nix_lf; + } + /* Setup LSO if needed */ rc = nix_lso_fmt_setup(dev); if (rc) { @@ -867,6 +943,21 @@ cnxk_nix_configure(struct rte_eth_dev *eth_dev) goto cq_fini; } + /* Init flow control configuration */ + fc_cfg.cq_cfg_valid = false; + fc_cfg.rxchan_cfg.enable = true; + rc = roc_nix_fc_config_set(nix, &fc_cfg); + if (rc) { + plt_err("Failed to initialize flow control rc=%d", rc); + goto cq_fini; + } + + /* Update flow control configuration to PMD */ + rc = nix_init_flow_ctrl_config(eth_dev); + if (rc) { + plt_err("Failed to initialize flow control rc=%d", rc); + goto cq_fini; + } /* * Restore queue config when reconfigure followed by * reconfigure and no queue configure invoked from application case. @@ -910,7 +1001,7 @@ fail_configure: return rc; } -static int +int cnxk_nix_tx_queue_start(struct rte_eth_dev *eth_dev, uint16_t qid) { struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); @@ -1046,7 +1137,7 @@ cnxk_nix_dev_start(struct rte_eth_dev *eth_dev) struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); int rc, i; - if (eth_dev->data->nb_rx_queues != 0) { + if (eth_dev->data->nb_rx_queues != 0 && !dev->ptp_en) { rc = nix_recalc_mtu(eth_dev); if (rc) return rc; @@ -1066,6 +1157,13 @@ cnxk_nix_dev_start(struct rte_eth_dev *eth_dev) return rc; } + /* Update Flow control configuration */ + rc = nix_update_flow_ctrl_config(eth_dev); + if (rc) { + plt_err("Failed to enable flow control. error code(%d)", rc); + return rc; + } + /* Enable Rx in NPC */ rc = roc_nix_npc_rx_ena_dis(&dev->nix, true); if (rc) { @@ -1084,6 +1182,25 @@ cnxk_nix_dev_start(struct rte_eth_dev *eth_dev) } } + /* Enable PTP if it is requested by the user or already + * enabled on PF owning this VF + */ + memset(&dev->tstamp, 0, sizeof(struct cnxk_timesync_info)); + if ((dev->rx_offloads & DEV_RX_OFFLOAD_TIMESTAMP) || dev->ptp_en) + cnxk_eth_dev_ops.timesync_enable(eth_dev); + else + cnxk_eth_dev_ops.timesync_disable(eth_dev); + + if (dev->rx_offloads & DEV_RX_OFFLOAD_TIMESTAMP) { + rc = rte_mbuf_dyn_rx_timestamp_register + (&dev->tstamp.tstamp_dynfield_offset, + &dev->tstamp.rx_tstamp_dynflag); + if (rc != 0) { + plt_err("Failed to register Rx timestamp field/flag"); + goto rx_disable; + } + } + cnxk_nix_toggle_flag_link_cfg(dev, false); return 0; @@ -1094,19 +1211,66 @@ rx_disable: return rc; } +static int cnxk_nix_dev_reset(struct rte_eth_dev *eth_dev); +static int cnxk_nix_dev_close(struct rte_eth_dev *eth_dev); + /* CNXK platform independent eth dev ops */ struct eth_dev_ops cnxk_eth_dev_ops = { .mtu_set = cnxk_nix_mtu_set, + .mac_addr_add = cnxk_nix_mac_addr_add, + .mac_addr_remove = cnxk_nix_mac_addr_del, .mac_addr_set = cnxk_nix_mac_addr_set, .dev_infos_get = cnxk_nix_info_get, .link_update = cnxk_nix_link_update, .tx_queue_release = cnxk_nix_tx_queue_release, .rx_queue_release = cnxk_nix_rx_queue_release, .dev_stop = cnxk_nix_dev_stop, + .dev_close = cnxk_nix_dev_close, + .dev_reset = cnxk_nix_dev_reset, .tx_queue_start = cnxk_nix_tx_queue_start, .rx_queue_start = cnxk_nix_rx_queue_start, .rx_queue_stop = cnxk_nix_rx_queue_stop, .dev_supported_ptypes_get = cnxk_nix_supported_ptypes_get, + .promiscuous_enable = cnxk_nix_promisc_enable, + .promiscuous_disable = cnxk_nix_promisc_disable, + .allmulticast_enable = cnxk_nix_allmulticast_enable, + .allmulticast_disable = cnxk_nix_allmulticast_disable, + .rx_burst_mode_get = cnxk_nix_rx_burst_mode_get, + .tx_burst_mode_get = cnxk_nix_tx_burst_mode_get, + .flow_ctrl_get = cnxk_nix_flow_ctrl_get, + .flow_ctrl_set = cnxk_nix_flow_ctrl_set, + .dev_set_link_up = cnxk_nix_set_link_up, + .dev_set_link_down = cnxk_nix_set_link_down, + .get_module_info = cnxk_nix_get_module_info, + .get_module_eeprom = cnxk_nix_get_module_eeprom, + .rx_queue_intr_enable = cnxk_nix_rx_queue_intr_enable, + .rx_queue_intr_disable = cnxk_nix_rx_queue_intr_disable, + .pool_ops_supported = cnxk_nix_pool_ops_supported, + .queue_stats_mapping_set = cnxk_nix_queue_stats_mapping, + .stats_get = cnxk_nix_stats_get, + .stats_reset = cnxk_nix_stats_reset, + .xstats_get = cnxk_nix_xstats_get, + .xstats_get_names = cnxk_nix_xstats_get_names, + .xstats_reset = cnxk_nix_xstats_reset, + .xstats_get_by_id = cnxk_nix_xstats_get_by_id, + .xstats_get_names_by_id = cnxk_nix_xstats_get_names_by_id, + .fw_version_get = cnxk_nix_fw_version_get, + .rxq_info_get = cnxk_nix_rxq_info_get, + .txq_info_get = cnxk_nix_txq_info_get, + .tx_done_cleanup = cnxk_nix_tx_done_cleanup, + .flow_ops_get = cnxk_nix_flow_ops_get, + .get_reg = cnxk_nix_dev_get_reg, + .timesync_read_rx_timestamp = cnxk_nix_timesync_read_rx_timestamp, + .timesync_read_tx_timestamp = cnxk_nix_timesync_read_tx_timestamp, + .timesync_read_time = cnxk_nix_timesync_read_time, + .timesync_write_time = cnxk_nix_timesync_write_time, + .timesync_adjust_time = cnxk_nix_timesync_adjust_time, + .read_clock = cnxk_nix_read_clock, + .reta_update = cnxk_nix_reta_update, + .reta_query = cnxk_nix_reta_query, + .rss_hash_update = cnxk_nix_rss_hash_update, + .rss_hash_conf_get = cnxk_nix_rss_hash_conf_get, + .set_mc_addr_list = cnxk_nix_mc_addr_list_configure, }; static int @@ -1135,6 +1299,7 @@ cnxk_eth_dev_init(struct rte_eth_dev *eth_dev) /* Initialize base roc nix */ nix->pci_dev = pci_dev; + nix->hw_vlan_ins = true; rc = roc_nix_dev_init(nix); if (rc) { plt_err("Failed to initialize roc nix rc=%d", rc); @@ -1171,6 +1336,7 @@ cnxk_eth_dev_init(struct rte_eth_dev *eth_dev) } dev->max_mac_entries = max_entries; + dev->dmac_filter_count = 1; /* Get mac address */ rc = roc_nix_npc_mac_addr_get(nix, dev->mac_addr); @@ -1200,6 +1366,11 @@ cnxk_eth_dev_init(struct rte_eth_dev *eth_dev) dev->speed_capa = nix_get_speed_capa(dev); /* Initialize roc npc */ + dev->npc.roc_nix = nix; + rc = roc_npc_init(&dev->npc); + if (rc) + goto free_mac_addrs; + plt_nix_dbg("Port=%d pf=%d vf=%d ver=%s hwcap=0x%" PRIx64 " rxoffload_capa=0x%" PRIx64 " txoffload_capa=0x%" PRIx64, eth_dev->data->port_id, roc_nix_get_pf(nix), @@ -1217,7 +1388,7 @@ error: } static int -cnxk_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool mbox_close) +cnxk_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool reset) { struct cnxk_eth_dev *dev = cnxk_eth_pmd_priv(eth_dev); const struct eth_dev_ops *dev_ops = eth_dev->dev_ops; @@ -1233,6 +1404,9 @@ cnxk_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool mbox_close) roc_nix_npc_rx_ena_dis(nix, false); + /* Disable and free rte_flow entries */ + roc_npc_fini(&dev->npc); + /* Disable link status events */ roc_nix_mac_link_event_start_stop(nix, false); @@ -1271,14 +1445,11 @@ cnxk_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool mbox_close) rte_free(eth_dev->data->mac_addrs); eth_dev->data->mac_addrs = NULL; - /* Check if mbox close is needed */ - if (!mbox_close) - return 0; - rc = roc_nix_dev_fini(nix); /* Can be freed later by PMD if NPA LF is in use */ if (rc == -EAGAIN) { - eth_dev->data->dev_private = NULL; + if (!reset) + eth_dev->data->dev_private = NULL; return 0; } else if (rc) { plt_err("Failed in nix dev fini, rc=%d", rc); @@ -1287,6 +1458,25 @@ cnxk_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool mbox_close) return rc; } +static int +cnxk_nix_dev_close(struct rte_eth_dev *eth_dev) +{ + cnxk_eth_dev_uninit(eth_dev, false); + return 0; +} + +static int +cnxk_nix_dev_reset(struct rte_eth_dev *eth_dev) +{ + int rc; + + rc = cnxk_eth_dev_uninit(eth_dev, true); + if (rc) + return rc; + + return cnxk_eth_dev_init(eth_dev); +} + int cnxk_nix_remove(struct rte_pci_device *pci_dev) { @@ -1297,7 +1487,7 @@ cnxk_nix_remove(struct rte_pci_device *pci_dev) eth_dev = rte_eth_dev_allocated(pci_dev->device.name); if (eth_dev) { /* Cleanup eth dev */ - rc = cnxk_eth_dev_uninit(eth_dev, true); + rc = cnxk_eth_dev_uninit(eth_dev, false); if (rc) return rc;