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, des2; 24 struct dma_desc *desc; 25 26 if (priv->extend_desc) 27 desc = (struct dma_desc *)(tx_q->dma_etx + entry); 28 else 29 desc = tx_q->dma_tx + entry; 30 31 if (priv->plat->enh_desc) 32 bmax = BUF_SIZE_8KiB; 33 else 34 bmax = BUF_SIZE_2KiB; 35 36 len = nopaged_len - bmax; 37 38 if (nopaged_len > BUF_SIZE_8KiB) { 39 40 des2 = dma_map_single(priv->device, skb->data, bmax, 41 DMA_TO_DEVICE); 42 desc->des2 = cpu_to_le32(des2); 43 if (dma_mapping_error(priv->device, des2)) 44 return -1; 45 46 tx_q->tx_skbuff_dma[entry].buf = des2; 47 tx_q->tx_skbuff_dma[entry].len = bmax; 48 tx_q->tx_skbuff_dma[entry].is_jumbo = true; 49 50 desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB); 51 stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum, 52 STMMAC_RING_MODE, 0, false, skb->len); 53 tx_q->tx_skbuff[entry] = NULL; 54 entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size); 55 56 if (priv->extend_desc) 57 desc = (struct dma_desc *)(tx_q->dma_etx + entry); 58 else 59 desc = tx_q->dma_tx + entry; 60 61 des2 = dma_map_single(priv->device, skb->data + bmax, len, 62 DMA_TO_DEVICE); 63 desc->des2 = cpu_to_le32(des2); 64 if (dma_mapping_error(priv->device, des2)) 65 return -1; 66 tx_q->tx_skbuff_dma[entry].buf = des2; 67 tx_q->tx_skbuff_dma[entry].len = len; 68 tx_q->tx_skbuff_dma[entry].is_jumbo = true; 69 70 desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB); 71 stmmac_prepare_tx_desc(priv, desc, 0, len, csum, 72 STMMAC_RING_MODE, 1, !skb_is_nonlinear(skb), 73 skb->len); 74 } else { 75 des2 = dma_map_single(priv->device, skb->data, 76 nopaged_len, DMA_TO_DEVICE); 77 desc->des2 = cpu_to_le32(des2); 78 if (dma_mapping_error(priv->device, des2)) 79 return -1; 80 tx_q->tx_skbuff_dma[entry].buf = des2; 81 tx_q->tx_skbuff_dma[entry].len = nopaged_len; 82 tx_q->tx_skbuff_dma[entry].is_jumbo = true; 83 desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB); 84 stmmac_prepare_tx_desc(priv, desc, 1, nopaged_len, csum, 85 STMMAC_RING_MODE, 0, !skb_is_nonlinear(skb), 86 skb->len); 87 } 88 89 tx_q->cur_tx = entry; 90 91 return entry; 92 } 93 94 static unsigned int is_jumbo_frm(int len, int enh_desc) 95 { 96 unsigned int ret = 0; 97 98 if (len >= BUF_SIZE_4KiB) 99 ret = 1; 100 101 return ret; 102 } 103 104 static void refill_desc3(struct stmmac_rx_queue *rx_q, struct dma_desc *p) 105 { 106 struct stmmac_priv *priv = rx_q->priv_data; 107 108 /* Fill DES3 in case of RING mode */ 109 if (priv->dma_conf.dma_buf_sz == BUF_SIZE_16KiB) 110 p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB); 111 } 112 113 /* In ring mode we need to fill the desc3 because it is used as buffer */ 114 static void init_desc3(struct dma_desc *p) 115 { 116 p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB); 117 } 118 119 static void clean_desc3(struct stmmac_tx_queue *tx_q, struct dma_desc *p) 120 { 121 struct stmmac_priv *priv = tx_q->priv_data; 122 unsigned int entry = tx_q->dirty_tx; 123 124 /* des3 is only used for jumbo frames tx or time stamping */ 125 if (unlikely(tx_q->tx_skbuff_dma[entry].is_jumbo || 126 (tx_q->tx_skbuff_dma[entry].last_segment && 127 !priv->extend_desc && priv->hwts_tx_en))) 128 p->des3 = 0; 129 } 130 131 static int set_16kib_bfsize(int mtu) 132 { 133 int ret = 0; 134 if (unlikely(mtu > BUF_SIZE_8KiB)) 135 ret = BUF_SIZE_16KiB; 136 return ret; 137 } 138 139 const struct stmmac_mode_ops ring_mode_ops = { 140 .is_jumbo_frm = is_jumbo_frm, 141 .jumbo_frm = jumbo_frm, 142 .refill_desc3 = refill_desc3, 143 .init_desc3 = init_desc3, 144 .clean_desc3 = clean_desc3, 145 .set_16kib_bfsize = set_16kib_bfsize, 146 }; 147