Skip to content

Commit

Permalink
ibmvnic: Update TX and TX completion routines
Browse files Browse the repository at this point in the history
Update TX and TX completion routines to account for TX pool
restructuring. TX routine first chooses the pool depending
on whether a packet is GSO or not, then uses it accordingly.

For the completion routine to know which pool it needs to use,
set the most significant bit of the correlator index to one
if the packet uses the TSO pool. On completion, unset the bit
and use the correlator index to release the buffer pool entry.

Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Thomas Falcon authored and David S. Miller committed Mar 18, 2018
1 parent 3205306 commit 06b3e35
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 27 deletions.
55 changes: 28 additions & 27 deletions drivers/net/ethernet/ibm/ibmvnic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1414,29 +1414,22 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
ret = NETDEV_TX_OK;
goto out;
}
if (skb_is_gso(skb))
tx_pool = &adapter->tso_pool[queue_num];
else
tx_pool = &adapter->tx_pool[queue_num];

tx_pool = &adapter->tx_pool[queue_num];
tx_scrq = adapter->tx_scrq[queue_num];
txq = netdev_get_tx_queue(netdev, skb_get_queue_mapping(skb));
handle_array = (u64 *)((u8 *)(adapter->login_rsp_buf) +
be32_to_cpu(adapter->login_rsp_buf->off_txsubm_subcrqs));

index = tx_pool->free_map[tx_pool->consumer_index];

if (skb_is_gso(skb)) {
offset = tx_pool->tso_index * IBMVNIC_TSO_BUF_SZ;
dst = tx_pool->tso_ltb.buff + offset;
memset(dst, 0, IBMVNIC_TSO_BUF_SZ);
data_dma_addr = tx_pool->tso_ltb.addr + offset;
tx_pool->tso_index++;
if (tx_pool->tso_index == IBMVNIC_TSO_BUFS)
tx_pool->tso_index = 0;
} else {
offset = index * (adapter->req_mtu + VLAN_HLEN);
dst = tx_pool->long_term_buff.buff + offset;
memset(dst, 0, adapter->req_mtu + VLAN_HLEN);
data_dma_addr = tx_pool->long_term_buff.addr + offset;
}
offset = index * tx_pool->buf_size;
dst = tx_pool->long_term_buff.buff + offset;
memset(dst, 0, tx_pool->buf_size);
data_dma_addr = tx_pool->long_term_buff.addr + offset;

if (skb_shinfo(skb)->nr_frags) {
int cur, i;
Expand All @@ -1459,8 +1452,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
}

tx_pool->consumer_index =
(tx_pool->consumer_index + 1) %
adapter->req_tx_entries_per_subcrq;
(tx_pool->consumer_index + 1) % tx_pool->num_buffers;

tx_buff = &tx_pool->tx_buff[index];
tx_buff->skb = skb;
Expand All @@ -1476,11 +1468,13 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
tx_crq.v1.n_crq_elem = 1;
tx_crq.v1.n_sge = 1;
tx_crq.v1.flags1 = IBMVNIC_TX_COMP_NEEDED;
tx_crq.v1.correlator = cpu_to_be32(index);

if (skb_is_gso(skb))
tx_crq.v1.dma_reg = cpu_to_be16(tx_pool->tso_ltb.map_id);
tx_crq.v1.correlator =
cpu_to_be32(index | IBMVNIC_TSO_POOL_MASK);
else
tx_crq.v1.dma_reg = cpu_to_be16(tx_pool->long_term_buff.map_id);
tx_crq.v1.correlator = cpu_to_be32(index);
tx_crq.v1.dma_reg = cpu_to_be16(tx_pool->long_term_buff.map_id);
tx_crq.v1.sge_len = cpu_to_be32(skb->len);
tx_crq.v1.ioba = cpu_to_be64(data_dma_addr);

Expand Down Expand Up @@ -1543,7 +1537,7 @@ static int ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)

if (tx_pool->consumer_index == 0)
tx_pool->consumer_index =
adapter->req_tx_entries_per_subcrq - 1;
tx_pool->num_buffers - 1;
else
tx_pool->consumer_index--;

Expand Down Expand Up @@ -2547,6 +2541,7 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
struct ibmvnic_sub_crq_queue *scrq)
{
struct device *dev = &adapter->vdev->dev;
struct ibmvnic_tx_pool *tx_pool;
struct ibmvnic_tx_buff *txbuff;
union sub_crq *next;
int index;
Expand All @@ -2566,7 +2561,14 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,
continue;
}
index = be32_to_cpu(next->tx_comp.correlators[i]);
txbuff = &adapter->tx_pool[pool].tx_buff[index];
if (index & IBMVNIC_TSO_POOL_MASK) {
tx_pool = &adapter->tso_pool[pool];
index &= ~IBMVNIC_TSO_POOL_MASK;
} else {
tx_pool = &adapter->tx_pool[pool];
}

txbuff = &tx_pool->tx_buff[index];

for (j = 0; j < IBMVNIC_MAX_FRAGS_PER_CRQ; j++) {
if (!txbuff->data_dma[j])
Expand All @@ -2589,11 +2591,10 @@ static int ibmvnic_complete_tx(struct ibmvnic_adapter *adapter,

num_entries += txbuff->num_entries;

adapter->tx_pool[pool].free_map[adapter->tx_pool[pool].
producer_index] = index;
adapter->tx_pool[pool].producer_index =
(adapter->tx_pool[pool].producer_index + 1) %
adapter->req_tx_entries_per_subcrq;
tx_pool->free_map[tx_pool->producer_index] = index;
tx_pool->producer_index =
(tx_pool->producer_index + 1) %
tx_pool->num_buffers;
}
/* remove tx_comp scrq*/
next->tx_comp.first = 0;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/ibm/ibmvnic.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@

#define IBMVNIC_TSO_BUF_SZ 65536
#define IBMVNIC_TSO_BUFS 64
#define IBMVNIC_TSO_POOL_MASK 0x80000000

#define IBMVNIC_MAX_LTB_SIZE ((1 << (MAX_ORDER - 1)) * PAGE_SIZE)
#define IBMVNIC_BUFFER_HLEN 500
Expand Down

0 comments on commit 06b3e35

Please sign in to comment.