-static void qede_init_fp_queue(struct rte_eth_dev *eth_dev)
-{
- struct qede_dev *qdev = eth_dev->data->dev_private;
- struct qede_fastpath *fp;
- uint8_t i, rss_id, txq_index, tc;
- int rxq = 0, txq = 0;
-
- for_each_queue(i) {
- fp = &qdev->fp_array[i];
- if (fp->type & QEDE_FASTPATH_RX) {
- fp->rxq = eth_dev->data->rx_queues[i];
- fp->rxq->queue_id = rxq++;
- }
-
- if (fp->type & QEDE_FASTPATH_TX) {
- for (tc = 0; tc < qdev->num_tc; tc++) {
- txq_index = tc * QEDE_TSS_COUNT(qdev) + txq;
- fp->txqs[tc] =
- eth_dev->data->tx_queues[txq_index];
- fp->txqs[tc]->queue_id = txq_index;
- if (qdev->dev_info.is_legacy)
- fp->txqs[tc]->is_legacy = true;
- }
- txq++;
- }
- }
-}
-
-int qede_dev_start(struct rte_eth_dev *eth_dev)
-{
- struct qede_dev *qdev = eth_dev->data->dev_private;
- struct ecore_dev *edev = &qdev->edev;
- struct qed_link_output link_output;
- struct qede_fastpath *fp;
- int rc;
-
- DP_INFO(edev, "Device state is %d\n", qdev->state);
-
- if (qdev->state == QEDE_DEV_START) {
- DP_INFO(edev, "Port is already started\n");
- return 0;
- }
-
- if (qdev->state == QEDE_DEV_CONFIG)
- qede_init_fp_queue(eth_dev);
-
- rc = qede_start_queues(eth_dev, true);
- if (rc) {
- DP_ERR(edev, "Failed to start queues\n");
- /* TBD: free */
- return rc;
- }
-
- /* Newer SR-IOV PF driver expects RX/TX queues to be started before
- * enabling RSS. Hence RSS configuration is deferred upto this point.
- * Also, we would like to retain similar behavior in PF case, so we
- * don't do PF/VF specific check here.
- */
- if (eth_dev->data->dev_conf.rxmode.mq_mode == ETH_MQ_RX_RSS)
- if (qede_config_rss(eth_dev))
- return -1;
-
- /* Bring-up the link */
- qede_dev_set_link_state(eth_dev, true);
-
- /* Start/resume traffic */
- qdev->ops->fastpath_start(edev);
-
- qdev->state = QEDE_DEV_START;
-
- DP_INFO(edev, "dev_state is QEDE_DEV_START\n");
-
- return 0;
-}
-
-static int qede_drain_txq(struct qede_dev *qdev,
- struct qede_tx_queue *txq, bool allow_drain)
-{
- struct ecore_dev *edev = &qdev->edev;
- int rc, cnt = 1000;
-
- while (txq->sw_tx_cons != txq->sw_tx_prod) {
- qede_process_tx_compl(edev, txq);
- if (!cnt) {
- if (allow_drain) {
- DP_ERR(edev, "Tx queue[%u] is stuck,"
- "requesting MCP to drain\n",
- txq->queue_id);
- rc = qdev->ops->common->drain(edev);
- if (rc)
- return rc;
- return qede_drain_txq(qdev, txq, false);
- }
- DP_ERR(edev, "Timeout waiting for tx queue[%d]:"
- "PROD=%d, CONS=%d\n",
- txq->queue_id, txq->sw_tx_prod,
- txq->sw_tx_cons);
- return -1;
- }
- cnt--;
- DELAY(1000);
- rte_compiler_barrier();
- }
-
- /* FW finished processing, wait for HW to transmit all tx packets */
- DELAY(2000);
-
- return 0;
-}
-
-static int qede_stop_queues(struct qede_dev *qdev)
-{
- struct qed_update_vport_params vport_update_params;
- struct ecore_dev *edev = &qdev->edev;
- struct ecore_sge_tpa_params tpa_params;
- struct qede_fastpath *fp;
- int rc, tc, i;
-
- /* Disable the vport */
- memset(&vport_update_params, 0, sizeof(vport_update_params));
- vport_update_params.vport_id = 0;
- vport_update_params.update_vport_active_flg = 1;
- vport_update_params.vport_active_flg = 0;
- vport_update_params.update_rss_flg = 0;
- /* Disable TPA */
- if (qdev->enable_lro) {
- DP_INFO(edev, "Disabling LRO\n");
- memset(&tpa_params, 0, sizeof(struct ecore_sge_tpa_params));
- qede_update_sge_tpa_params(&tpa_params, qdev->mtu, false);
- vport_update_params.sge_tpa_params = &tpa_params;
- }
-
- DP_INFO(edev, "Deactivate vport\n");
- rc = qdev->ops->vport_update(edev, &vport_update_params);
- if (rc) {
- DP_ERR(edev, "Failed to update vport\n");
- return rc;
- }
-
- DP_INFO(edev, "Flushing tx queues\n");
-
- /* Flush Tx queues. If needed, request drain from MCP */
- for_each_queue(i) {
- fp = &qdev->fp_array[i];
-
- if (fp->type & QEDE_FASTPATH_TX) {
- for (tc = 0; tc < qdev->num_tc; tc++) {
- struct qede_tx_queue *txq = fp->txqs[tc];
-
- rc = qede_drain_txq(qdev, txq, true);
- if (rc)
- return rc;
- }
- }
- }
-
- /* Stop all Queues in reverse order */
- for (i = QEDE_QUEUE_CNT(qdev) - 1; i >= 0; i--) {
- fp = &qdev->fp_array[i];
-
- /* Stop the Tx Queue(s) */
- if (qdev->fp_array[i].type & QEDE_FASTPATH_TX) {
- for (tc = 0; tc < qdev->num_tc; tc++) {
- struct qede_tx_queue *txq = fp->txqs[tc];
- DP_INFO(edev, "Stopping tx queues\n");
- rc = qdev->ops->q_tx_stop(edev, i, txq->handle);
- if (rc) {
- DP_ERR(edev, "Failed to stop TXQ #%d\n",
- i);
- return rc;
- }
- }
- }
-
- /* Stop the Rx Queue */
- if (qdev->fp_array[i].type & QEDE_FASTPATH_RX) {
- DP_INFO(edev, "Stopping rx queues\n");
- rc = qdev->ops->q_rx_stop(edev, i, fp->rxq->handle);
- if (rc) {
- DP_ERR(edev, "Failed to stop RXQ #%d\n", i);
- return rc;
- }
- }
- }
- qede_reset_fp_rings(qdev);
-
- return 0;
-}
-
-int qede_reset_fp_rings(struct qede_dev *qdev)
-{
- struct qede_fastpath *fp;
- struct qede_tx_queue *txq;
- uint8_t tc;
- uint16_t id, i;
-
- for_each_queue(id) {
- fp = &qdev->fp_array[id];
-
- if (fp->type & QEDE_FASTPATH_RX) {
- DP_INFO(&qdev->edev,
- "Reset FP chain for RSS %u\n", id);
- qede_rx_queue_release_mbufs(fp->rxq);
- ecore_chain_reset(&fp->rxq->rx_bd_ring);
- ecore_chain_reset(&fp->rxq->rx_comp_ring);
- fp->rxq->sw_rx_prod = 0;
- fp->rxq->sw_rx_cons = 0;
- *fp->rxq->hw_cons_ptr = 0;
- for (i = 0; i < fp->rxq->nb_rx_desc; i++) {
- if (qede_alloc_rx_buffer(fp->rxq)) {
- DP_ERR(&qdev->edev,
- "RX buffer allocation failed\n");
- return -ENOMEM;
- }
- }
- }
- if (fp->type & QEDE_FASTPATH_TX) {
- for (tc = 0; tc < qdev->num_tc; tc++) {
- txq = fp->txqs[tc];
- qede_tx_queue_release_mbufs(txq);
- ecore_chain_reset(&txq->tx_pbl);
- txq->sw_tx_cons = 0;
- txq->sw_tx_prod = 0;
- *txq->hw_cons_ptr = 0;
- }
- }
- }
-
- return 0;
-}
-
-/* This function frees all memory of a single fp */
-void qede_free_mem_load(struct rte_eth_dev *eth_dev)
-{
- struct qede_dev *qdev = QEDE_INIT_QDEV(eth_dev);
- struct qede_fastpath *fp;
- uint16_t txq_idx;
- uint8_t id;
- uint8_t tc;
-
- for_each_queue(id) {
- fp = &qdev->fp_array[id];
- if (fp->type & QEDE_FASTPATH_RX) {
- if (!fp->rxq)
- continue;
- qede_rx_queue_release(fp->rxq);
- eth_dev->data->rx_queues[id] = NULL;
- } else {
- for (tc = 0; tc < qdev->num_tc; tc++) {
- if (!fp->txqs[tc])
- continue;
- txq_idx = fp->txqs[tc]->queue_id;
- qede_tx_queue_release(fp->txqs[tc]);
- eth_dev->data->tx_queues[txq_idx] = NULL;
- }
- }
- }
-}
-
-void qede_dev_stop(struct rte_eth_dev *eth_dev)
-{
- struct qede_dev *qdev = eth_dev->data->dev_private;
- struct ecore_dev *edev = &qdev->edev;
-
- DP_INFO(edev, "port %u\n", eth_dev->data->port_id);
-
- if (qdev->state != QEDE_DEV_START) {
- DP_INFO(edev, "Device not yet started\n");
- return;
- }
-
- if (qede_stop_queues(qdev))
- DP_ERR(edev, "Didn't succeed to close queues\n");
-
- DP_INFO(edev, "Stopped queues\n");
-
- qdev->ops->fastpath_stop(edev);
-
- /* Bring the link down */
- qede_dev_set_link_state(eth_dev, false);
-
- qdev->state = QEDE_DEV_STOP;
-
- DP_INFO(edev, "dev_state is QEDE_DEV_STOP\n");
-}
-