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:23 -0500
committerDavid S. Miller <davem@davemloft.net>2012-11-13 14:18:14 -0500
commit1d9daf45b474a7db7a2f850ab03def2d0721095d (patch)
treec09b82a5fa792a0f2db1c9ccaaf39591bf36aef9 /drivers/net/ethernet/intel/igb/igb_main.c
parented6aa10580b852e29acd48b686438fac8605a97b (diff)
igb: Update igb Tx flags to improve code efficiency
This change is meant to improve the efficiency of the Tx flags in igb by aligning them with the values that will later be written into either the cmd_type or olinfo. By doing this we are able to reduce most of these functions to either just a simple shift followed by an or in the case of cmd_type, or an and followed by an or in the case of olinfo. In order to avoid type conversion errors I also adjusted the locations where we were switching between CPU and little endian. 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.c61
1 files changed, 33 insertions, 28 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index b0730e9c7766..0a0bd819d95b 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -4121,24 +4121,32 @@ static void igb_tx_csum(struct igb_ring *tx_ring, struct igb_tx_buffer *first)
4121 igb_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, mss_l4len_idx); 4121 igb_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, mss_l4len_idx);
4122} 4122}
4123 4123
4124static __le32 igb_tx_cmd_type(u32 tx_flags) 4124#define IGB_SET_FLAG(_input, _flag, _result) \
4125 ((_flag <= _result) ? \
4126 ((u32)(_input & _flag) * (_result / _flag)) : \
4127 ((u32)(_input & _flag) / (_flag / _result)))
4128
4129static u32 igb_tx_cmd_type(struct sk_buff *skb, u32 tx_flags)
4125{ 4130{
4126 /* set type for advanced descriptor with frame checksum insertion */ 4131 /* set type for advanced descriptor with frame checksum insertion */
4127 __le32 cmd_type = cpu_to_le32(E1000_ADVTXD_DTYP_DATA | 4132 u32 cmd_type = E1000_ADVTXD_DTYP_DATA |
4128 E1000_ADVTXD_DCMD_IFCS | 4133 E1000_ADVTXD_DCMD_DEXT |
4129 E1000_ADVTXD_DCMD_DEXT); 4134 E1000_ADVTXD_DCMD_IFCS;
4130 4135
4131 /* set HW vlan bit if vlan is present */ 4136 /* set HW vlan bit if vlan is present */
4132 if (tx_flags & IGB_TX_FLAGS_VLAN) 4137 cmd_type |= IGB_SET_FLAG(tx_flags, IGB_TX_FLAGS_VLAN,
4133 cmd_type |= cpu_to_le32(E1000_ADVTXD_DCMD_VLE); 4138 (E1000_ADVTXD_DCMD_VLE));
4139
4140 /* set segmentation bits for TSO */
4141 cmd_type |= IGB_SET_FLAG(tx_flags, IGB_TX_FLAGS_TSO,
4142 (E1000_ADVTXD_DCMD_TSE));
4134 4143
4135 /* set timestamp bit if present */ 4144 /* set timestamp bit if present */
4136 if (unlikely(tx_flags & IGB_TX_FLAGS_TSTAMP)) 4145 cmd_type |= IGB_SET_FLAG(tx_flags, IGB_TX_FLAGS_TSTAMP,
4137 cmd_type |= cpu_to_le32(E1000_ADVTXD_MAC_TSTAMP); 4146 (E1000_ADVTXD_MAC_TSTAMP));
4138 4147
4139 /* set segmentation bits for TSO */ 4148 /* insert frame checksum */
4140 if (tx_flags & IGB_TX_FLAGS_TSO) 4149 cmd_type ^= IGB_SET_FLAG(skb->no_fcs, 1, E1000_ADVTXD_DCMD_IFCS);
4141 cmd_type |= cpu_to_le32(E1000_ADVTXD_DCMD_TSE);
4142 4150
4143 return cmd_type; 4151 return cmd_type;
4144} 4152}
@@ -4149,19 +4157,19 @@ static void igb_tx_olinfo_status(struct igb_ring *tx_ring,
4149{ 4157{
4150 u32 olinfo_status = paylen << E1000_ADVTXD_PAYLEN_SHIFT; 4158 u32 olinfo_status = paylen << E1000_ADVTXD_PAYLEN_SHIFT;
4151 4159
4152 /* 82575 requires a unique index per ring if any offload is enabled */ 4160 /* 82575 requires a unique index per ring */
4153 if ((tx_flags & (IGB_TX_FLAGS_CSUM | IGB_TX_FLAGS_VLAN)) && 4161 if (test_bit(IGB_RING_FLAG_TX_CTX_IDX, &tx_ring->flags))
4154 test_bit(IGB_RING_FLAG_TX_CTX_IDX, &tx_ring->flags))
4155 olinfo_status |= tx_ring->reg_idx << 4; 4162 olinfo_status |= tx_ring->reg_idx << 4;
4156 4163
4157 /* insert L4 checksum */ 4164 /* insert L4 checksum */
4158 if (tx_flags & IGB_TX_FLAGS_CSUM) { 4165 olinfo_status |= IGB_SET_FLAG(tx_flags,
4159 olinfo_status |= E1000_TXD_POPTS_TXSM << 8; 4166 IGB_TX_FLAGS_CSUM,
4167 (E1000_TXD_POPTS_TXSM << 8));
4160 4168
4161 /* insert IPv4 checksum */ 4169 /* insert IPv4 checksum */
4162 if (tx_flags & IGB_TX_FLAGS_IPV4) 4170 olinfo_status |= IGB_SET_FLAG(tx_flags,
4163 olinfo_status |= E1000_TXD_POPTS_IXSM << 8; 4171 IGB_TX_FLAGS_IPV4,
4164 } 4172 (E1000_TXD_POPTS_IXSM << 8));
4165 4173
4166 tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status); 4174 tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status);
4167} 4175}
@@ -4185,14 +4193,13 @@ static void igb_tx_map(struct igb_ring *tx_ring,
4185 unsigned int data_len = skb->data_len; 4193 unsigned int data_len = skb->data_len;
4186 unsigned int size = skb_headlen(skb); 4194 unsigned int size = skb_headlen(skb);
4187 unsigned int paylen = skb->len - hdr_len; 4195 unsigned int paylen = skb->len - hdr_len;
4188 __le32 cmd_type;
4189 u32 tx_flags = first->tx_flags; 4196 u32 tx_flags = first->tx_flags;
4197 u32 cmd_type = igb_tx_cmd_type(skb, tx_flags);
4190 u16 i = tx_ring->next_to_use; 4198 u16 i = tx_ring->next_to_use;
4191 4199
4192 tx_desc = IGB_TX_DESC(tx_ring, i); 4200 tx_desc = IGB_TX_DESC(tx_ring, i);
4193 4201
4194 igb_tx_olinfo_status(tx_ring, tx_desc, tx_flags, paylen); 4202 igb_tx_olinfo_status(tx_ring, tx_desc, tx_flags, paylen);
4195 cmd_type = igb_tx_cmd_type(tx_flags);
4196 4203
4197 dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE); 4204 dma = dma_map_single(tx_ring->dev, skb->data, size, DMA_TO_DEVICE);
4198 if (dma_mapping_error(tx_ring->dev, dma)) 4205 if (dma_mapping_error(tx_ring->dev, dma))
@@ -4206,7 +4213,7 @@ static void igb_tx_map(struct igb_ring *tx_ring,
4206 for (;;) { 4213 for (;;) {
4207 while (unlikely(size > IGB_MAX_DATA_PER_TXD)) { 4214 while (unlikely(size > IGB_MAX_DATA_PER_TXD)) {
4208 tx_desc->read.cmd_type_len = 4215 tx_desc->read.cmd_type_len =
4209 cmd_type | cpu_to_le32(IGB_MAX_DATA_PER_TXD); 4216 cpu_to_le32(cmd_type ^ IGB_MAX_DATA_PER_TXD);
4210 4217
4211 i++; 4218 i++;
4212 tx_desc++; 4219 tx_desc++;
@@ -4225,7 +4232,7 @@ static void igb_tx_map(struct igb_ring *tx_ring,
4225 if (likely(!data_len)) 4232 if (likely(!data_len))
4226 break; 4233 break;
4227 4234
4228 tx_desc->read.cmd_type_len = cmd_type | cpu_to_le32(size); 4235 tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type ^ size);
4229 4236
4230 i++; 4237 i++;
4231 tx_desc++; 4238 tx_desc++;
@@ -4255,10 +4262,8 @@ static void igb_tx_map(struct igb_ring *tx_ring,
4255 netdev_tx_sent_queue(txring_txq(tx_ring), first->bytecount); 4262 netdev_tx_sent_queue(txring_txq(tx_ring), first->bytecount);
4256 4263
4257 /* write last descriptor with RS and EOP bits */ 4264 /* write last descriptor with RS and EOP bits */
4258 cmd_type |= cpu_to_le32(size) | cpu_to_le32(IGB_TXD_DCMD); 4265 cmd_type |= size | IGB_TXD_DCMD;
4259 if (unlikely(skb->no_fcs)) 4266 tx_desc->read.cmd_type_len = cpu_to_le32(cmd_type);
4260 cmd_type &= ~(cpu_to_le32(E1000_ADVTXD_DCMD_IFCS));
4261 tx_desc->read.cmd_type_len = cmd_type;
4262 4267
4263 /* set the timestamp */ 4268 /* set the timestamp */
4264 first->time_stamp = jiffies; 4269 first->time_stamp = jiffies;