diff options
Diffstat (limited to 'drivers/net/ethernet/cavium/liquidio')
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/lio_core.c | 41 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/lio_main.c | 258 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/lio_vf_main.c | 211 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/liquidio_common.h | 8 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/octeon_network.h | 53 | ||||
-rw-r--r-- | drivers/net/ethernet/cavium/liquidio/request_manager.c | 3 |
6 files changed, 162 insertions, 412 deletions
diff --git a/drivers/net/ethernet/cavium/liquidio/lio_core.c b/drivers/net/ethernet/cavium/liquidio/lio_core.c index 666cf7e9cd09..2a94eee943b2 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_core.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_core.c @@ -377,20 +377,12 @@ static void lio_update_txq_status(struct octeon_device *oct, int iq_num) return; lio = GET_LIO(netdev); - if (netif_is_multiqueue(netdev)) { - if (__netif_subqueue_stopped(netdev, iq->q_index) && - lio->linfo.link.s.link_up && - (!octnet_iq_is_full(oct, iq_num))) { - netif_wake_subqueue(netdev, iq->q_index); - INCR_INSTRQUEUE_PKT_COUNT(lio->oct_dev, iq_num, - tx_restart, 1); - } - } else if (netif_queue_stopped(netdev) && - lio->linfo.link.s.link_up && - (!octnet_iq_is_full(oct, lio->txq))) { - INCR_INSTRQUEUE_PKT_COUNT(lio->oct_dev, lio->txq, + if (__netif_subqueue_stopped(netdev, iq->q_index) && + lio->linfo.link.s.link_up && + (!octnet_iq_is_full(oct, iq_num))) { + netif_wake_subqueue(netdev, iq->q_index); + INCR_INSTRQUEUE_PKT_COUNT(lio->oct_dev, iq_num, tx_restart, 1); - netif_wake_queue(netdev); } } @@ -1154,3 +1146,26 @@ int liquidio_change_mtu(struct net_device *netdev, int new_mtu) octeon_free_soft_command(oct, sc); return 0; } + +int lio_wait_for_clean_oq(struct octeon_device *oct) +{ + int retry = 100, pending_pkts = 0; + int idx; + + do { + pending_pkts = 0; + + for (idx = 0; idx < MAX_OCTEON_OUTPUT_QUEUES(oct); idx++) { + if (!(oct->io_qmask.oq & BIT_ULL(idx))) + continue; + pending_pkts += + atomic_read(&oct->droq[idx]->pkts_pending); + } + + if (pending_pkts > 0) + schedule_timeout_uninterruptible(1); + + } while (retry-- && pending_pkts); + + return pending_pkts; +} diff --git a/drivers/net/ethernet/cavium/liquidio/lio_main.c b/drivers/net/ethernet/cavium/liquidio/lio_main.c index 21280cb66550..603a144d3d9c 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_main.c @@ -514,148 +514,30 @@ static void liquidio_deinit_pci(void) } /** - * \brief Stop Tx queues - * @param netdev network device - */ -static inline void txqs_stop(struct net_device *netdev) -{ - if (netif_is_multiqueue(netdev)) { - int i; - - for (i = 0; i < netdev->num_tx_queues; i++) - netif_stop_subqueue(netdev, i); - } else { - netif_stop_queue(netdev); - } -} - -/** - * \brief Start Tx queues - * @param netdev network device - */ -static inline void txqs_start(struct net_device *netdev) -{ - if (netif_is_multiqueue(netdev)) { - int i; - - for (i = 0; i < netdev->num_tx_queues; i++) - netif_start_subqueue(netdev, i); - } else { - netif_start_queue(netdev); - } -} - -/** - * \brief Wake Tx queues - * @param netdev network device - */ -static inline void txqs_wake(struct net_device *netdev) -{ - struct lio *lio = GET_LIO(netdev); - - if (netif_is_multiqueue(netdev)) { - int i; - - for (i = 0; i < netdev->num_tx_queues; i++) { - int qno = lio->linfo.txpciq[i % - lio->oct_dev->num_iqs].s.q_no; - - if (__netif_subqueue_stopped(netdev, i)) { - INCR_INSTRQUEUE_PKT_COUNT(lio->oct_dev, qno, - tx_restart, 1); - netif_wake_subqueue(netdev, i); - } - } - } else { - INCR_INSTRQUEUE_PKT_COUNT(lio->oct_dev, lio->txq, - tx_restart, 1); - netif_wake_queue(netdev); - } -} - -/** - * \brief Stop Tx queue - * @param netdev network device - */ -static void stop_txq(struct net_device *netdev) -{ - txqs_stop(netdev); -} - -/** - * \brief Start Tx queue - * @param netdev network device - */ -static void start_txq(struct net_device *netdev) -{ - struct lio *lio = GET_LIO(netdev); - - if (lio->linfo.link.s.link_up) { - txqs_start(netdev); - return; - } -} - -/** - * \brief Wake a queue - * @param netdev network device - * @param q which queue to wake - */ -static inline void wake_q(struct net_device *netdev, int q) -{ - if (netif_is_multiqueue(netdev)) - netif_wake_subqueue(netdev, q); - else - netif_wake_queue(netdev); -} - -/** - * \brief Stop a queue - * @param netdev network device - * @param q which queue to stop - */ -static inline void stop_q(struct net_device *netdev, int q) -{ - if (netif_is_multiqueue(netdev)) - netif_stop_subqueue(netdev, q); - else - netif_stop_queue(netdev); -} - -/** * \brief Check Tx queue status, and take appropriate action * @param lio per-network private data * @returns 0 if full, number of queues woken up otherwise */ static inline int check_txq_status(struct lio *lio) { + int numqs = lio->netdev->num_tx_queues; int ret_val = 0; + int q, iq; - if (netif_is_multiqueue(lio->netdev)) { - int numqs = lio->netdev->num_tx_queues; - int q, iq = 0; - - /* check each sub-queue state */ - for (q = 0; q < numqs; q++) { - iq = lio->linfo.txpciq[q % - lio->oct_dev->num_iqs].s.q_no; - if (octnet_iq_is_full(lio->oct_dev, iq)) - continue; - if (__netif_subqueue_stopped(lio->netdev, q)) { - wake_q(lio->netdev, q); - INCR_INSTRQUEUE_PKT_COUNT(lio->oct_dev, iq, - tx_restart, 1); - ret_val++; - } + /* check each sub-queue state */ + for (q = 0; q < numqs; q++) { + iq = lio->linfo.txpciq[q % + lio->oct_dev->num_iqs].s.q_no; + if (octnet_iq_is_full(lio->oct_dev, iq)) + continue; + if (__netif_subqueue_stopped(lio->netdev, q)) { + netif_wake_subqueue(lio->netdev, q); + INCR_INSTRQUEUE_PKT_COUNT(lio->oct_dev, iq, + tx_restart, 1); + ret_val++; } - } else { - if (octnet_iq_is_full(lio->oct_dev, lio->txq)) - return 0; - wake_q(lio->netdev, lio->txq); - INCR_INSTRQUEUE_PKT_COUNT(lio->oct_dev, lio->txq, - tx_restart, 1); - ret_val = 1; } + return ret_val; } @@ -900,11 +782,11 @@ static inline void update_link_status(struct net_device *netdev, if (lio->linfo.link.s.link_up) { dev_dbg(&oct->pci_dev->dev, "%s: link_up", __func__); netif_carrier_on(netdev); - txqs_wake(netdev); + wake_txqs(netdev); } else { dev_dbg(&oct->pci_dev->dev, "%s: link_off", __func__); netif_carrier_off(netdev); - stop_txq(netdev); + stop_txqs(netdev); } if (lio->linfo.link.s.mtu != current_max_mtu) { netif_info(lio, probe, lio->netdev, "Max MTU changed from %d to %d\n", @@ -1752,43 +1634,6 @@ static int octeon_pci_os_setup(struct octeon_device *oct) return 0; } -static inline int skb_iq(struct lio *lio, struct sk_buff *skb) -{ - int q = 0; - - if (netif_is_multiqueue(lio->netdev)) - q = skb->queue_mapping % lio->linfo.num_txpciq; - - return q; -} - -/** - * \brief Check Tx queue state for a given network buffer - * @param lio per-network private data - * @param skb network buffer - */ -static inline int check_txq_state(struct lio *lio, struct sk_buff *skb) -{ - int q = 0, iq = 0; - - if (netif_is_multiqueue(lio->netdev)) { - q = skb->queue_mapping; - iq = lio->linfo.txpciq[(q % lio->oct_dev->num_iqs)].s.q_no; - } else { - iq = lio->txq; - q = iq; - } - - if (octnet_iq_is_full(lio->oct_dev, iq)) - return 0; - - if (__netif_subqueue_stopped(lio->netdev, q)) { - INCR_INSTRQUEUE_PKT_COUNT(lio->oct_dev, iq, tx_restart, 1); - wake_q(lio->netdev, q); - } - return 1; -} - /** * \brief Unmap and free network buffer * @param buf buffer @@ -1806,8 +1651,6 @@ static void free_netbuf(void *buf) dma_unmap_single(&lio->oct_dev->pci_dev->dev, finfo->dptr, skb->len, DMA_TO_DEVICE); - check_txq_state(lio, skb); - tx_buffer_free(skb); } @@ -1848,8 +1691,6 @@ static void free_netsgbuf(void *buf) list_add_tail(&g->list, &lio->glist[iq]); spin_unlock(&lio->glist_lock[iq]); - check_txq_state(lio, skb); /* mq support: sub-queue state check */ - tx_buffer_free(skb); } @@ -1895,8 +1736,6 @@ static void free_netsgbuf_with_resp(void *buf) spin_unlock(&lio->glist_lock[iq]); /* Don't free the skb yet */ - - check_txq_state(lio, skb); } /** @@ -2224,7 +2063,7 @@ static int liquidio_open(struct net_device *netdev) return -1; } - start_txq(netdev); + start_txqs(netdev); /* tell Octeon to start forwarding packets to host */ send_rx_ctrl_cmd(lio, 1); @@ -2245,16 +2084,6 @@ static int liquidio_stop(struct net_device *netdev) struct octeon_device *oct = lio->oct_dev; struct napi_struct *napi, *n; - if (oct->props[lio->ifidx].napi_enabled) { - list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list) - napi_disable(napi); - - oct->props[lio->ifidx].napi_enabled = 0; - - if (OCTEON_CN23XX_PF(oct)) - oct->droq[0]->ops.poll_mode = 0; - } - ifstate_reset(lio, LIO_IFSTATE_RUNNING); netif_tx_disable(netdev); @@ -2280,6 +2109,21 @@ static int liquidio_stop(struct net_device *netdev) lio->ptp_clock = NULL; } + /* Wait for any pending Rx descriptors */ + if (lio_wait_for_clean_oq(oct)) + netif_info(lio, rx_err, lio->netdev, + "Proceeding with stop interface after partial RX desc processing\n"); + + if (oct->props[lio->ifidx].napi_enabled == 1) { + list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list) + napi_disable(napi); + + oct->props[lio->ifidx].napi_enabled = 0; + + if (OCTEON_CN23XX_PF(oct)) + oct->droq[0]->ops.poll_mode = 0; + } + dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name); return 0; @@ -2666,14 +2510,9 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) lio = GET_LIO(netdev); oct = lio->oct_dev; - if (netif_is_multiqueue(netdev)) { - q_idx = skb->queue_mapping; - q_idx = (q_idx % (lio->linfo.num_txpciq)); - tag = q_idx; - iq_no = lio->linfo.txpciq[q_idx].s.q_no; - } else { - iq_no = lio->txq; - } + q_idx = skb_iq(lio, skb); + tag = q_idx; + iq_no = lio->linfo.txpciq[q_idx].s.q_no; stats = &oct->instr_queue[iq_no]->stats; @@ -2704,23 +2543,14 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) ndata.q_no = iq_no; - if (netif_is_multiqueue(netdev)) { - if (octnet_iq_is_full(oct, ndata.q_no)) { - /* defer sending if queue is full */ - netif_info(lio, tx_err, lio->netdev, "Transmit failed iq:%d full\n", - ndata.q_no); - stats->tx_iq_busy++; - return NETDEV_TX_BUSY; - } - } else { - if (octnet_iq_is_full(oct, lio->txq)) { - /* defer sending if queue is full */ - stats->tx_iq_busy++; - netif_info(lio, tx_err, lio->netdev, "Transmit failed iq:%d full\n", - lio->txq); - return NETDEV_TX_BUSY; - } + if (octnet_iq_is_full(oct, ndata.q_no)) { + /* defer sending if queue is full */ + netif_info(lio, tx_err, lio->netdev, "Transmit failed iq:%d full\n", + ndata.q_no); + stats->tx_iq_busy++; + return NETDEV_TX_BUSY; } + /* pr_info(" XMIT - valid Qs: %d, 1st Q no: %d, cpu: %d, q_no:%d\n", * lio->linfo.num_txpciq, lio->txq, cpu, ndata.q_no); */ @@ -2876,7 +2706,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) netif_info(lio, tx_queued, lio->netdev, "Transmit queued successfully\n"); if (status == IQ_SEND_STOP) - stop_q(netdev, q_idx); + netif_stop_subqueue(netdev, q_idx); netif_trans_update(netdev); @@ -2915,7 +2745,7 @@ static void liquidio_tx_timeout(struct net_device *netdev) "Transmit timeout tx_dropped:%ld, waking up queues now!!\n", netdev->stats.tx_dropped); netif_trans_update(netdev); - txqs_wake(netdev); + wake_txqs(netdev); } static int liquidio_vlan_rx_add_vid(struct net_device *netdev, diff --git a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c index 3342d64b7081..f92dfa411de6 100644 --- a/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c +++ b/drivers/net/ethernet/cavium/liquidio/lio_vf_main.c @@ -285,105 +285,6 @@ static struct pci_driver liquidio_vf_pci_driver = { }; /** - * \brief Stop Tx queues - * @param netdev network device - */ -static void txqs_stop(struct net_device *netdev) -{ - if (netif_is_multiqueue(netdev)) { - int i; - - for (i = 0; i < netdev->num_tx_queues; i++) - netif_stop_subqueue(netdev, i); - } else { - netif_stop_queue(netdev); - } -} - -/** - * \brief Start Tx queues - * @param netdev network device - */ -static void txqs_start(struct net_device *netdev) -{ - if (netif_is_multiqueue(netdev)) { - int i; - - for (i = 0; i < netdev->num_tx_queues; i++) - netif_start_subqueue(netdev, i); - } else { - netif_start_queue(netdev); - } -} - -/** - * \brief Wake Tx queues - * @param netdev network device - */ -static void txqs_wake(struct net_device *netdev) -{ - struct lio *lio = GET_LIO(netdev); - - if (netif_is_multiqueue(netdev)) { - int i; - - for (i = 0; i < netdev->num_tx_queues; i++) { - int qno = lio->linfo.txpciq[i % lio->oct_dev->num_iqs] - .s.q_no; - if (__netif_subqueue_stopped(netdev, i)) { - INCR_INSTRQUEUE_PKT_COUNT(lio->oct_dev, qno, - tx_restart, 1); - netif_wake_subqueue(netdev, i); - } - } - } else { - INCR_INSTRQUEUE_PKT_COUNT(lio->oct_dev, lio->txq, - tx_restart, 1); - netif_wake_queue(netdev); - } -} - -/** - * \brief Start Tx queue - * @param netdev network device - */ -static void start_txq(struct net_device *netdev) -{ - struct lio *lio = GET_LIO(netdev); - - if (lio->linfo.link.s.link_up) { - txqs_start(netdev); - return; - } -} - -/** - * \brief Wake a queue - * @param netdev network device - * @param q which queue to wake - */ -static void wake_q(struct net_device *netdev, int q) -{ - if (netif_is_multiqueue(netdev)) - netif_wake_subqueue(netdev, q); - else - netif_wake_queue(netdev); -} - -/** - * \brief Stop a queue - * @param netdev network device - * @param q which queue to stop - */ -static void stop_q(struct net_device *netdev, int q) -{ - if (netif_is_multiqueue(netdev)) - netif_stop_subqueue(netdev, q); - else - netif_stop_queue(netdev); -} - -/** * Remove the node at the head of the list. The list would be empty at * the end of this call if there are no more nodes in the list. */ @@ -614,10 +515,10 @@ static void update_link_status(struct net_device *netdev, if (lio->linfo.link.s.link_up) { netif_carrier_on(netdev); - txqs_wake(netdev); + wake_txqs(netdev); } else { netif_carrier_off(netdev); - txqs_stop(netdev); + stop_txqs(netdev); } if (lio->linfo.link.s.mtu != current_max_mtu) { @@ -1052,44 +953,6 @@ static int octeon_pci_os_setup(struct octeon_device *oct) return 0; } -static int skb_iq(struct lio *lio, struct sk_buff *skb) -{ - int q = 0; - - if (netif_is_multiqueue(lio->netdev)) - q = skb->queue_mapping % lio->linfo.num_txpciq; - - return q; -} - -/** - * \brief Check Tx queue state for a given network buffer - * @param lio per-network private data - * @param skb network buffer - */ -static int check_txq_state(struct lio *lio, struct sk_buff *skb) -{ - int q = 0, iq = 0; - - if (netif_is_multiqueue(lio->netdev)) { - q = skb->queue_mapping; - iq = lio->linfo.txpciq[q % lio->oct_dev->num_iqs].s.q_no; - } else { - iq = lio->txq; - q = iq; - } - - if (octnet_iq_is_full(lio->oct_dev, iq)) - return 0; - - if (__netif_subqueue_stopped(lio->netdev, q)) { - INCR_INSTRQUEUE_PKT_COUNT(lio->oct_dev, iq, tx_restart, 1); - wake_q(lio->netdev, q); - } - - return 1; -} - /** * \brief Unmap and free network buffer * @param buf buffer @@ -1107,8 +970,6 @@ static void free_netbuf(void *buf) dma_unmap_single(&lio->oct_dev->pci_dev->dev, finfo->dptr, skb->len, DMA_TO_DEVICE); - check_txq_state(lio, skb); - tx_buffer_free(skb); } @@ -1150,8 +1011,6 @@ static void free_netsgbuf(void *buf) list_add_tail(&g->list, &lio->glist[iq]); spin_unlock(&lio->glist_lock[iq]); - check_txq_state(lio, skb); /* mq support: sub-queue state check */ - tx_buffer_free(skb); } @@ -1197,8 +1056,6 @@ static void free_netsgbuf_with_resp(void *buf) spin_unlock(&lio->glist_lock[iq]); /* Don't free the skb yet */ - - check_txq_state(lio, skb); } /** @@ -1258,7 +1115,7 @@ static int liquidio_open(struct net_device *netdev) lio->intf_open = 1; netif_info(lio, ifup, lio->netdev, "Interface Open, ready for traffic\n"); - start_txq(netdev); + start_txqs(netdev); /* tell Octeon to start forwarding packets to host */ send_rx_ctrl_cmd(lio, 1); @@ -1281,15 +1138,6 @@ static int liquidio_stop(struct net_device *netdev) /* tell Octeon to stop forwarding packets to host */ send_rx_ctrl_cmd(lio, 0); - if (oct->props[lio->ifidx].napi_enabled) { - list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list) - napi_disable(napi); - - oct->props[lio->ifidx].napi_enabled = 0; - - oct->droq[0]->ops.poll_mode = 0; - } - netif_info(lio, ifdown, lio->netdev, "Stopping interface!\n"); /* Inform that netif carrier is down */ lio->intf_open = 0; @@ -1300,7 +1148,21 @@ static int liquidio_stop(struct net_device *netdev) ifstate_reset(lio, LIO_IFSTATE_RUNNING); - txqs_stop(netdev); + stop_txqs(netdev); + + /* Wait for any pending Rx descriptors */ + if (lio_wait_for_clean_oq(oct)) + netif_info(lio, rx_err, lio->netdev, + "Proceeding with stop interface after partial RX desc processing\n"); + + if (oct->props[lio->ifidx].napi_enabled == 1) { + list_for_each_entry_safe(napi, n, &netdev->napi_list, dev_list) + napi_disable(napi); + + oct->props[lio->ifidx].napi_enabled = 0; + + oct->droq[0]->ops.poll_mode = 0; + } dev_info(&oct->pci_dev->dev, "%s interface is stopped\n", netdev->name); @@ -1718,14 +1580,9 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) lio = GET_LIO(netdev); oct = lio->oct_dev; - if (netif_is_multiqueue(netdev)) { - q_idx = skb->queue_mapping; - q_idx = (q_idx % (lio->linfo.num_txpciq)); - tag = q_idx; - iq_no = lio->linfo.txpciq[q_idx].s.q_no; - } else { - iq_no = lio->txq; - } + q_idx = skb_iq(lio, skb); + tag = q_idx; + iq_no = lio->linfo.txpciq[q_idx].s.q_no; stats = &oct->instr_queue[iq_no]->stats; @@ -1754,22 +1611,12 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) ndata.q_no = iq_no; - if (netif_is_multiqueue(netdev)) { - if (octnet_iq_is_full(oct, ndata.q_no)) { - /* defer sending if queue is full */ - netif_info(lio, tx_err, lio->netdev, "Transmit failed iq:%d full\n", - ndata.q_no); - stats->tx_iq_busy++; - return NETDEV_TX_BUSY; - } - } else { - if (octnet_iq_is_full(oct, lio->txq)) { - /* defer sending if queue is full */ - stats->tx_iq_busy++; - netif_info(lio, tx_err, lio->netdev, "Transmit failed iq:%d full\n", - ndata.q_no); - return NETDEV_TX_BUSY; - } + if (octnet_iq_is_full(oct, ndata.q_no)) { + /* defer sending if queue is full */ + netif_info(lio, tx_err, lio->netdev, "Transmit failed iq:%d full\n", + ndata.q_no); + stats->tx_iq_busy++; + return NETDEV_TX_BUSY; } ndata.datasize = skb->len; @@ -1911,7 +1758,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev) if (status == IQ_SEND_STOP) { dev_err(&oct->pci_dev->dev, "Rcvd IQ_SEND_STOP signal; stopping IQ-%d\n", iq_no); - stop_q(netdev, q_idx); + netif_stop_subqueue(netdev, q_idx); } netif_trans_update(netdev); @@ -1951,7 +1798,7 @@ static void liquidio_tx_timeout(struct net_device *netdev) "Transmit timeout tx_dropped:%ld, waking up queues now!!\n", netdev->stats.tx_dropped); netif_trans_update(netdev); - txqs_wake(netdev); + wake_txqs(netdev); } static int diff --git a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h index 82a783db5baf..75eea83c7cc6 100644 --- a/drivers/net/ethernet/cavium/liquidio/liquidio_common.h +++ b/drivers/net/ethernet/cavium/liquidio/liquidio_common.h @@ -712,9 +712,13 @@ union oct_txpciq { u64 pkind:6; u64 use_qpg:1; u64 qpg:11; - u64 reserved:30; + u64 reserved0:10; + u64 ctrl_qpg:11; + u64 reserved:9; #else - u64 reserved:30; + u64 reserved:9; + u64 ctrl_qpg:11; + u64 reserved0:10; u64 qpg:11; u64 use_qpg:1; u64 pkind:6; diff --git a/drivers/net/ethernet/cavium/liquidio/octeon_network.h b/drivers/net/ethernet/cavium/liquidio/octeon_network.h index 76803a569794..4069710796a8 100644 --- a/drivers/net/ethernet/cavium/liquidio/octeon_network.h +++ b/drivers/net/ethernet/cavium/liquidio/octeon_network.h @@ -190,6 +190,7 @@ irqreturn_t liquidio_msix_intr_handler(int irq __attribute__((unused)), int octeon_setup_interrupt(struct octeon_device *oct, u32 num_ioqs); +int lio_wait_for_clean_oq(struct octeon_device *oct); /** * \brief Register ethtool operations * @param netdev pointer to network device @@ -506,4 +507,56 @@ static inline int wait_for_pending_requests(struct octeon_device *oct) return 0; } +/** + * \brief Stop Tx queues + * @param netdev network device + */ +static inline void stop_txqs(struct net_device *netdev) +{ + int i; + + for (i = 0; i < netdev->num_tx_queues; i++) + netif_stop_subqueue(netdev, i); +} + +/** + * \brief Wake Tx queues + * @param netdev network device + */ +static inline void wake_txqs(struct net_device *netdev) +{ + struct lio *lio = GET_LIO(netdev); + int i, qno; + + for (i = 0; i < netdev->num_tx_queues; i++) { + qno = lio->linfo.txpciq[i % lio->oct_dev->num_iqs].s.q_no; + + if (__netif_subqueue_stopped(netdev, i)) { + INCR_INSTRQUEUE_PKT_COUNT(lio->oct_dev, qno, + tx_restart, 1); + netif_wake_subqueue(netdev, i); + } + } +} + +/** + * \brief Start Tx queues + * @param netdev network device + */ +static inline void start_txqs(struct net_device *netdev) +{ + struct lio *lio = GET_LIO(netdev); + int i; + + if (lio->linfo.link.s.link_up) { + for (i = 0; i < netdev->num_tx_queues; i++) + netif_start_subqueue(netdev, i); + } +} + +static inline int skb_iq(struct lio *lio, struct sk_buff *skb) +{ + return skb->queue_mapping % lio->linfo.num_txpciq; +} + #endif diff --git a/drivers/net/ethernet/cavium/liquidio/request_manager.c b/drivers/net/ethernet/cavium/liquidio/request_manager.c index 2766af05b89e..b1270355b0b1 100644 --- a/drivers/net/ethernet/cavium/liquidio/request_manager.c +++ b/drivers/net/ethernet/cavium/liquidio/request_manager.c @@ -628,7 +628,8 @@ octeon_prepare_soft_command(struct octeon_device *oct, pki_ih3->tag = LIO_CONTROL; pki_ih3->tagtype = ATOMIC_TAG; pki_ih3->qpg = - oct->instr_queue[sc->iq_no]->txpciq.s.qpg; + oct->instr_queue[sc->iq_no]->txpciq.s.ctrl_qpg; + pki_ih3->pm = 0x7; pki_ih3->sl = 8; |