Skip to content

Commit 3569399

Browse files
Furong Xukuba-moo
authored andcommitted
net: stmmac: TSO: Simplify the code flow of DMA descriptor allocations
The TCP Segmentation Offload (TSO) engine is an optional function in DWMAC cores, it is implemented for dwmac4 and dwxgmac2 only, ancient dwmac100 and dwmac1000 are not supported by hardware. Current driver code checks priv->dma_cap.tsoen which is read from MAC_HW_Feature1 register to determine if TSO is enabled in hardware configurations, if (!priv->dma_cap.tsoen) driver never sets NETIF_F_TSO for net_device. This patch never affects dwmac100/dwmac1000 and their stmmac_desc_ops: ndesc_ops/enh_desc_ops, since TSO is never supported by them two. The DMA AXI address width of DWMAC cores can be configured to 32-bit/40-bit/48-bit, then the format of DMA transmit descriptors get a little different between 32-bit and 40-bit/48-bit. Current driver code checks priv->dma_cap.addr64 to use certain format with certain configuration. This patch converts the format of DMA transmit descriptors on dwmac4 and dwxgmac2 that the DMA AXI address width is configured to 32-bit (as described by function comments of stmmac_tso_xmit() in current code) to a more generic format (see updated function comments after this patch) which is actually already used on 40-bit/48-bit platforms to provide better compatibility and make code flow cleaner in TSO TX routine. Another interesting finding, struct stmmac_desc_ops is a common abstract interface to maintain descriptors, we should avoid the direct assignment of descriptor members (e.g. desc->des0), stmmac_set_desc_addr() is the proper method yet. This patch tries to improve this by the way. Tested and verified on: DWMAC CORE 5.00a with 32-bit DMA AXI address width DWMAC CORE 5.10a with 32-bit DMA AXI address width DWXGMAC CORE 3.20a with 40-bit DMA AXI address width Signed-off-by: Furong Xu <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent a003c38 commit 3569399

File tree

1 file changed

+24
-36
lines changed

1 file changed

+24
-36
lines changed

drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

Lines changed: 24 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -4116,11 +4116,7 @@ static void stmmac_tso_allocator(struct stmmac_priv *priv, dma_addr_t des,
41164116
desc = &tx_q->dma_tx[tx_q->cur_tx];
41174117

41184118
curr_addr = des + (total_len - tmp_len);
4119-
if (priv->dma_cap.addr64 <= 32)
4120-
desc->des0 = cpu_to_le32(curr_addr);
4121-
else
4122-
stmmac_set_desc_addr(priv, desc, curr_addr);
4123-
4119+
stmmac_set_desc_addr(priv, desc, curr_addr);
41244120
buff_size = tmp_len >= TSO_MAX_BUFF_SIZE ?
41254121
TSO_MAX_BUFF_SIZE : tmp_len;
41264122

@@ -4166,17 +4162,27 @@ static void stmmac_flush_tx_descriptors(struct stmmac_priv *priv, int queue)
41664162
* First Descriptor
41674163
* --------
41684164
* | DES0 |---> buffer1 = L2/L3/L4 header
4169-
* | DES1 |---> TCP Payload (can continue on next descr...)
4170-
* | DES2 |---> buffer 1 and 2 len
4165+
* | DES1 |---> can be used as buffer2 for TCP Payload if the DMA AXI address
4166+
* | | width is 32-bit, but we never use it.
4167+
* | | Also can be used as the most-significant 8-bits or 16-bits of
4168+
* | | buffer1 address pointer if the DMA AXI address width is 40-bit
4169+
* | | or 48-bit, and we always use it.
4170+
* | DES2 |---> buffer1 len
41714171
* | DES3 |---> must set TSE, TCP hdr len-> [22:19]. TCP payload len [17:0]
41724172
* --------
4173+
* --------
4174+
* | DES0 |---> buffer1 = TCP Payload (can continue on next descr...)
4175+
* | DES1 |---> same as the First Descriptor
4176+
* | DES2 |---> buffer1 len
4177+
* | DES3 |
4178+
* --------
41734179
* |
41744180
* ...
41754181
* |
41764182
* --------
4177-
* | DES0 | --| Split TCP Payload on Buffers 1 and 2
4178-
* | DES1 | --|
4179-
* | DES2 | --> buffer 1 and 2 len
4183+
* | DES0 |---> buffer1 = Split TCP Payload
4184+
* | DES1 |---> same as the First Descriptor
4185+
* | DES2 |---> buffer1 len
41804186
* | DES3 |
41814187
* --------
41824188
*
@@ -4186,15 +4192,14 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
41864192
{
41874193
struct dma_desc *desc, *first, *mss_desc = NULL;
41884194
struct stmmac_priv *priv = netdev_priv(dev);
4189-
int tmp_pay_len = 0, first_tx, nfrags;
41904195
unsigned int first_entry, tx_packets;
41914196
struct stmmac_txq_stats *txq_stats;
41924197
struct stmmac_tx_queue *tx_q;
41934198
u32 pay_len, mss, queue;
4194-
dma_addr_t tso_des, des;
4199+
int i, first_tx, nfrags;
41954200
u8 proto_hdr_len, hdr;
4201+
dma_addr_t des;
41964202
bool set_ic;
4197-
int i;
41984203

41994204
/* Always insert VLAN tag to SKB payload for TSO frames.
42004205
*
@@ -4279,24 +4284,9 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
42794284
if (dma_mapping_error(priv->device, des))
42804285
goto dma_map_err;
42814286

4282-
if (priv->dma_cap.addr64 <= 32) {
4283-
first->des0 = cpu_to_le32(des);
4284-
4285-
/* Fill start of payload in buff2 of first descriptor */
4286-
if (pay_len)
4287-
first->des1 = cpu_to_le32(des + proto_hdr_len);
4288-
4289-
/* If needed take extra descriptors to fill the remaining payload */
4290-
tmp_pay_len = pay_len - TSO_MAX_BUFF_SIZE;
4291-
tso_des = des;
4292-
} else {
4293-
stmmac_set_desc_addr(priv, first, des);
4294-
tmp_pay_len = pay_len;
4295-
tso_des = des + proto_hdr_len;
4296-
pay_len = 0;
4297-
}
4298-
4299-
stmmac_tso_allocator(priv, tso_des, tmp_pay_len, (nfrags == 0), queue);
4287+
stmmac_set_desc_addr(priv, first, des);
4288+
stmmac_tso_allocator(priv, des + proto_hdr_len, pay_len,
4289+
(nfrags == 0), queue);
43004290

43014291
/* In case two or more DMA transmit descriptors are allocated for this
43024292
* non-paged SKB data, the DMA buffer address should be saved to
@@ -4400,11 +4390,9 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
44004390
}
44014391

44024392
/* Complete the first descriptor before granting the DMA */
4403-
stmmac_prepare_tso_tx_desc(priv, first, 1,
4404-
proto_hdr_len,
4405-
pay_len,
4406-
1, tx_q->tx_skbuff_dma[first_entry].last_segment,
4407-
hdr / 4, (skb->len - proto_hdr_len));
4393+
stmmac_prepare_tso_tx_desc(priv, first, 1, proto_hdr_len, 0, 1,
4394+
tx_q->tx_skbuff_dma[first_entry].last_segment,
4395+
hdr / 4, (skb->len - proto_hdr_len));
44084396

44094397
/* If context desc is used to change MSS */
44104398
if (mss_desc) {

0 commit comments

Comments
 (0)