Commit 373d9a55 authored by Shinas Rasheed's avatar Shinas Rasheed Committed by David S. Miller

octeon_ep: implement xmit_more in transmit

Add xmit_more handling in tx datapath for octeon_ep pf.
Signed-off-by: default avatarShinas Rasheed <srasheed@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2fba5069
......@@ -15,7 +15,7 @@
/* Tx Queue: maximum descriptors per ring */
#define OCTEP_IQ_MAX_DESCRIPTORS 1024
/* Minimum input (Tx) requests to be enqueued to ring doorbell */
#define OCTEP_DB_MIN 1
#define OCTEP_DB_MIN 8
/* Packet threshold for Tx queue interrupt */
#define OCTEP_IQ_INTR_THRESHOLD 0x0
......
......@@ -784,6 +784,13 @@ static inline int octep_iq_full_check(struct octep_iq *iq)
/* Stop the queue if unable to send */
netif_stop_subqueue(iq->netdev, iq->q_no);
/* Allow for pending updates in write index
* from iq_process_completion in other cpus
* to reflect, in case queue gets free
* entries.
*/
smp_mb();
/* check again and restart the queue, in case NAPI has just freed
* enough Tx ring entries.
*/
......@@ -818,6 +825,7 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb,
struct octep_iq *iq;
skb_frag_t *frag;
u16 nr_frags, si;
int xmit_more;
u16 q_no, wi;
if (skb_put_padto(skb, ETH_ZLEN))
......@@ -830,10 +838,6 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb,
}
iq = oct->iq[q_no];
if (octep_iq_full_check(iq)) {
iq->stats.tx_busy++;
return NETDEV_TX_BUSY;
}
shinfo = skb_shinfo(skb);
nr_frags = shinfo->nr_frags;
......@@ -894,19 +898,33 @@ static netdev_tx_t octep_start_xmit(struct sk_buff *skb,
hw_desc->dptr = tx_buffer->sglist_dma;
}
netdev_tx_sent_queue(iq->netdev_q, skb->len);
xmit_more = netdev_xmit_more();
__netdev_tx_sent_queue(iq->netdev_q, skb->len, xmit_more);
skb_tx_timestamp(skb);
atomic_inc(&iq->instr_pending);
iq->fill_cnt++;
wi++;
if (wi == iq->max_count)
wi = 0;
iq->host_write_index = wi;
/* octep_iq_full_check stops the queue and returns
* true if so, in case the queue has become full
* by inserting current packet. If so, we can
* go ahead and ring doorbell.
*/
if (!octep_iq_full_check(iq) && xmit_more &&
iq->fill_cnt < iq->fill_threshold)
return NETDEV_TX_OK;
/* Flush the hw descriptor before writing to doorbell */
wmb();
/* Ring Doorbell to notify the NIC there is a new packet */
writel(1, iq->doorbell_reg);
iq->stats.instr_posted++;
/* Ring Doorbell to notify the NIC of new packets */
writel(iq->fill_cnt, iq->doorbell_reg);
iq->stats.instr_posted += iq->fill_cnt;
iq->fill_cnt = 0;
return NETDEV_TX_OK;
dma_map_sg_err:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment