aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/igb/igb_main.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2012-11-12 23:03:24 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-13 14:18:15 -0500
commit80d0759e5e714cb738c50d32edf3364b713453ff (patch)
tree82edbde223cbc6b91b93fdc3bd8ada551a90ddb5 /drivers/net/ethernet/intel/igb/igb_main.c
parent1d9daf45b474a7db7a2f850ab03def2d0721095d (diff)
igb: Improve performance and reduce size of igb_tx_map
This change is meant to both improve the performance and reduce the size of igb_tx_map. To do this I have expanded the work done in the main loop by pushing first into tx_buffer. This allows us to pull in the dma_mapping_error check, the tx_buffer value assignment, and the initial DMA value assignment to the Tx descriptor. The net result is that the function reduces in size by a little over a 100 bytes and is about 1% or 2% faster. Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Tested-by: Aaron Brown <aaron.f.brown@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/intel/igb/igb_main.c')
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c47
1 files changed, 22 insertions, 25 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index 0a0bd819d95b..7044aaadeca1 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -4188,29 +4188,34 @@ static void igb_tx_map(struct igb_ring *tx_ring,
4188 struct sk_buff *skb = first->skb; 4188 struct sk_buff *skb = first->skb;
4189 struct igb_tx_buffer *tx_buffer; 4189 struct igb_tx_buffer *tx_buffer;
4190 union e1000_adv_tx_desc *tx_desc; 4190 union e1000_adv_tx_desc *tx_desc;
4191 struct skb_frag_struct *frag;
4191 dma_addr_t dma; 4192 dma_addr_t dma;
4192 struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[0]; 4193 unsigned int data_len, size;
4193 unsigned int data_len = skb->data_len;
4194 unsigned int size = skb_headlen(skb);
4195 unsigned int paylen = skb->len - hdr_len;
4196 u32 tx_flags = first->tx_flags; 4194 u32 tx_flags = first->tx_flags;
4197 u32 cmd_type = igb_tx_cmd_type(skb, tx_flags); 4195 u32 cmd_type = igb_tx_cmd_type(skb, tx_flags);
4198 u16 i = tx_ring->next_to_use; 4196 u16 i = tx_ring->next_to_use;
4199 4197
4200 tx_desc = IGB_TX_DESC(tx_ring, i); 4198 tx_desc = IGB_TX_DESC(tx_ring, i);
4201 4199
4202 igb_tx_olinfo_status(tx_ring, tx_desc, tx_flags, paylen); 4200 igb_tx_olinfo_status(tx_ring, tx_desc, tx_flags, skb->len - hdr_len);
4201
4202 size = skb_headlen(skb);
4203 data_len = skb->data_len;
4203 4204
4204 dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE); 4205 dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE);
4205 if (dma_mapping_error(tx_ring->dev, dma))
4206 goto dma_error;
4207 4206
4208 /* record length, and DMA address */ 4207 tx_buffer = first;
4209 dma_unmap_len_set(first, len, size); 4208
4210 dma_unmap_addr_set(first, dma, dma); 4209 for (frag = &skb_shinfo(skb)->frags[0];; frag++) {
4211 tx_desc->read.buffer_addr = cpu_to_le64(dma); 4210 if (dma_mapping_error(tx_ring->dev, dma))
4211 goto dma_error;
4212
4213 /* record length, and DMA address */
4214 dma_unmap_len_set(tx_buffer, len, size);
4215 dma_unmap_addr_set(tx_buffer, dma, dma);
4216
4217 tx_desc->read.buffer_addr = cpu_to_le64(dma);
4212 4218
4213 for (;;) {
4214 while (unlikely(size > IGB_MAX_DATA_PER_TXD)) { 4219 while (unlikely(size > IGB_MAX_DATA_PER_TXD)) {
4215 tx_desc->read.cmd_type_len = 4220 tx_desc->read.cmd_type_len =
4216 cpu_to_le32(cmd_type ^ IGB_MAX_DATA_PER_TXD); 4221 cpu_to_le32(cmd_type ^ IGB_MAX_DATA_PER_TXD);
@@ -4221,11 +4226,11 @@ static void igb_tx_map(struct igb_ring *tx_ring,
4221 tx_desc = IGB_TX_DESC(tx_ring, 0); 4226 tx_desc = IGB_TX_DESC(tx_ring, 0);
4222 i = 0; 4227 i = 0;
4223 } 4228 }
4229 tx_desc->read.olinfo_status = 0;
4224 4230
4225 dma += IGB_MAX_DATA_PER_TXD; 4231 dma += IGB_MAX_DATA_PER_TXD;
4226 size -= IGB_MAX_DATA_PER_TXD; 4232 size -= IGB_MAX_DATA_PER_TXD;
4227 4233
4228 tx_desc->read.olinfo_status = 0;
4229 tx_desc->read.buffer_addr = cpu_to_le64(dma); 4234 tx_desc->read.buffer_addr = cpu_to_le64(dma);
4230 } 4235 }
4231 4236
@@ -4240,31 +4245,23 @@ static void igb_tx_map(struct igb_ring *tx_ring,
4240 tx_desc = IGB_TX_DESC(tx_ring, 0); 4245 tx_desc = IGB_TX_DESC(tx_ring, 0);
4241 i = 0; 4246 i = 0;
4242 } 4247 }
4248 tx_desc->read.olinfo_status = 0;
4243 4249
4244 size = skb_frag_size(frag); 4250 size = skb_frag_size(frag);
4245 data_len -= size; 4251 data_len -= size;
4246 4252
4247 dma = skb_frag_dma_map(tx_ring->dev, frag, 0, 4253 dma = skb_frag_dma_map(tx_ring->dev, frag, 0,
4248 size, DMA_TO_DEVICE); 4254 size, DMA_TO_DEVICE);
4249 if (dma_mapping_error(tx_ring->dev, dma))
4250 goto dma_error;
4251 4255
4252 tx_buffer = &tx_ring->tx_buffer_info[i]; 4256 tx_buffer = &tx_ring->tx_buffer_info[i];
4253 dma_unmap_len_set(tx_buffer, len, size);
4254 dma_unmap_addr_set(tx_buffer, dma, dma);
4255
4256 tx_desc->read.olinfo_status = 0;
4257 tx_desc->read.buffer_addr = cpu_to_le64(dma);
4258
4259 frag++;
4260 } 4257 }
4261 4258
4262 netdev_tx_sent_queue(txring_txq(tx_ring), first->bytecount);
4263
4264 /* write last descriptor with RS and EOP bits */ 4259 /* write last descriptor with RS and EOP bits */
4265 cmd_type |= size | IGB_TXD_DCMD; 4260 cmd_type |= size | IGB_TXD_DCMD;
4266 tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type); 4261 tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type);
4267 4262
4263 netdev_tx_sent_queue(txring_txq(tx_ring), first->bytecount);
4264
4268 /* set the timestamp */ 4265 /* set the timestamp */
4269 first->time_stamp = jiffies; 4266 first->time_stamp = jiffies;
4270 4267