1 // SPDX-License-Identifier: GPL-2.0-only 2 /******************************************************************************* 3 Specialised functions for managing Ring mode 4 5 Copyright(C) 2011 STMicroelectronics Ltd 6 7 It defines all the functions used to handle the normal/enhanced 8 descriptors in case of the DMA is configured to work in chained or 9 in ring mode. 10 11 12 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 13 *******************************************************************************/ 14 15 #include "stmmac.h" 16 17 static int jumbo_frm(struct stmmac_tx_queue *tx_q, struct sk_buff *skb, 18 int csum) 19 { 20 unsigned int nopaged_len = skb_headlen(skb); 21 struct stmmac_priv *priv = tx_q->priv_data; 22 unsigned int entry = tx_q->cur_tx; 23 unsigned int bmax, len; 24 struct dma_desc *desc; 25 dma_addr_t des2; 26 27 if (priv->extend_desc) 28 desc = (struct dma_desc *)(tx_q->dma_etx + entry); 29 else 30 desc = tx_q->dma_tx + entry; 31 32 if (priv->plat->enh_desc) 33 bmax = BUF_SIZE_8KiB; 34 else 35 bmax = BUF_SIZE_2KiB; 36 37 len = nopaged_len - bmax; 38 39 if (nopaged_len > BUF_SIZE_8KiB) { 40 41 des2 = dma_map_single(priv->device, skb->data, bmax, 42 DMA_TO_DEVICE); 43 desc->des2 = cpu_to_le32(lower_32_bits(des2)); 44 if (dma_mapping_error(priv->device, des2)) 45 return -1; 46 47 tx_q->tx_skbuff_dma[entry].buf = des2; 48 tx_q->tx_skbuff_dma[entry].len = bmax; 49 tx_q->tx_skbuff_dma[entry].is_jumbo = true; 50 51 desc->des3 = cpu_to_le32(lower_32_bits(des2) + BUF_SIZE_4KiB); 52 stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum, 53 STMMAC_RING_MODE, 0, false, skb->len); 54 tx_q->tx_skbuff[entry] = NULL; 55 entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_tx_size); 56 57 if (priv->extend_desc) 58 desc = (struct dma_desc *)(tx_q->dma_etx + entry); 59 else 60 desc = tx_q->dma_tx + entry; 61 62 des2 = dma_map_single(priv->device, skb->data + bmax, len, 63 DMA_TO_DEVICE); 64 desc->des2 = cpu_to_le32(lower_32_bits(des2)); 65 if (dma_mapping_error(priv->device, des2)) 66 return -1; 67 tx_q->tx_skbuff_dma[entry].buf = des2; 68 tx_q->tx_skbuff_dma[entry].len = len; 69 tx_q->tx_skbuff_dma[entry].is_jumbo = true; 70 71 desc->des3 = cpu_to_le32(lower_32_bits(des2) + BUF_SIZE_4KiB); 72 stmmac_prepare_tx_desc(priv, desc, 0, len, csum, 73 STMMAC_RING_MODE, 1, !skb_is_nonlinear(skb), 74 skb->len); 75 } else { 76 des2 = dma_map_single(priv->device, skb->data, 77 nopaged_len, DMA_TO_DEVICE); 78 desc->des2 = cpu_to_le32(lower_32_bits(des2)); 79 if (dma_mapping_error(priv->device, des2)) 80 return -1; 81 tx_q->tx_skbuff_dma[entry].buf = des2; 82 tx_q->tx_skbuff_dma[entry].len = nopaged_len; 83 tx_q->tx_skbuff_dma[entry].is_jumbo = true; 84 desc->des3 = cpu_to_le32(lower_32_bits(des2) + BUF_SIZE_4KiB); 85 stmmac_prepare_tx_desc(priv, desc, 1, nopaged_len, csum, 86 STMMAC_RING_MODE, 0, !skb_is_nonlinear(skb), 87 skb->len); 88 } 89 90 tx_q->cur_tx = entry; 91 92 return entry; 93 } 94 95 static bool is_jumbo_frm(unsigned int len, bool enh_desc) 96 { 97 return len >= BUF_SIZE_4KiB; 98 } 99 100 static void refill_desc3(struct stmmac_rx_queue *rx_q, struct dma_desc *p) 101 { 102 struct stmmac_priv *priv = rx_q->priv_data; 103 104 /* Fill DES3 in case of RING mode */ 105 if (priv->dma_conf.dma_buf_sz == BUF_SIZE_16KiB) 106 p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB); 107 } 108 109 /* In ring mode we need to fill the desc3 because it is used as buffer */ 110 static void init_desc3(struct dma_desc *p) 111 { 112 p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB); 113 } 114 115 static void clean_desc3(struct stmmac_tx_queue *tx_q, struct dma_desc *p) 116 { 117 struct stmmac_priv *priv = tx_q->priv_data; 118 unsigned int entry = tx_q->dirty_tx; 119 120 /* des3 is only used for jumbo frames tx or time stamping */ 121 if (unlikely(tx_q->tx_skbuff_dma[entry].is_jumbo || 122 (tx_q->tx_skbuff_dma[entry].last_segment && 123 !priv->extend_desc && priv->hwts_tx_en))) 124 p->des3 = 0; 125 } 126 127 static int set_16kib_bfsize(int mtu) 128 { 129 int ret = 0; 130 if (unlikely(mtu > BUF_SIZE_8KiB)) 131 ret = BUF_SIZE_16KiB; 132 return ret; 133 } 134 135 const struct stmmac_mode_ops ring_mode_ops = { 136 .is_jumbo_frm = is_jumbo_frm, 137 .jumbo_frm = jumbo_frm, 138 .refill_desc3 = refill_desc3, 139 .init_desc3 = init_desc3, 140 .clean_desc3 = clean_desc3, 141 .set_16kib_bfsize = set_16kib_bfsize, 142 }; 143