blob: 31213e64513dba604eb9ead1f052a1d7289cb223 [file] [log] [blame]
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +00001/*******************************************************************************
2 Specialised functions for managing Ring mode
3
4 Copyright(C) 2011 STMicroelectronics Ltd
5
6 It defines all the functions used to handle the normal/enhanced
7 descriptors in case of the DMA is configured to work in chained or
8 in ring mode.
9
10 This program is free software; you can redistribute it and/or modify it
11 under the terms and conditions of the GNU General Public License,
12 version 2, as published by the Free Software Foundation.
13
14 This program is distributed in the hope it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
18
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000019 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25#include "stmmac.h"
26
Giuseppe CAVALLARO362b37b2014-08-27 11:27:00 +020027static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000028{
Joao Pintoce736782017-04-06 09:49:10 +010029 struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)p;
LABBE Corentin5bacd772017-03-29 07:05:40 +020030 unsigned int nopaged_len = skb_headlen(skb);
Joao Pintoce736782017-04-06 09:49:10 +010031 struct stmmac_priv *priv = tx_q->priv_data;
32 unsigned int entry = tx_q->cur_tx;
LABBE Corentin5bacd772017-03-29 07:05:40 +020033 unsigned int bmax, len, des2;
Joao Pintoce736782017-04-06 09:49:10 +010034 struct dma_desc *desc;
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000035
Byungho An21ff0192013-08-08 15:30:26 +090036 if (priv->extend_desc)
Joao Pintoce736782017-04-06 09:49:10 +010037 desc = (struct dma_desc *)(tx_q->dma_etx + entry);
Byungho An21ff0192013-08-08 15:30:26 +090038 else
Joao Pintoce736782017-04-06 09:49:10 +010039 desc = tx_q->dma_tx + entry;
Byungho An21ff0192013-08-08 15:30:26 +090040
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000041 if (priv->plat->enh_desc)
42 bmax = BUF_SIZE_8KiB;
43 else
44 bmax = BUF_SIZE_2KiB;
45
46 len = nopaged_len - bmax;
47
48 if (nopaged_len > BUF_SIZE_8KiB) {
49
Michael Weiserf8be0d72016-11-14 18:58:05 +010050 des2 = dma_map_single(priv->device, skb->data, bmax,
51 DMA_TO_DEVICE);
52 desc->des2 = cpu_to_le32(des2);
53 if (dma_mapping_error(priv->device, des2))
Giuseppe CAVALLARO362b37b2014-08-27 11:27:00 +020054 return -1;
55
Joao Pintoce736782017-04-06 09:49:10 +010056 tx_q->tx_skbuff_dma[entry].buf = des2;
57 tx_q->tx_skbuff_dma[entry].len = bmax;
58 tx_q->tx_skbuff_dma[entry].is_jumbo = true;
Giuseppe Cavallaro553e2ab2016-02-29 14:27:31 +010059
Michael Weiserf8be0d72016-11-14 18:58:05 +010060 desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
Giuseppe CAVALLARO4a7d6662013-03-26 04:43:05 +000061 priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum,
Giuseppe Cavallarobe434d52016-02-29 14:27:35 +010062 STMMAC_RING_MODE, 0, false);
Joao Pintoce736782017-04-06 09:49:10 +010063 tx_q->tx_skbuff[entry] = NULL;
Giuseppe Cavallaroe3ad57c2016-02-29 14:27:30 +010064 entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
Byungho An21ff0192013-08-08 15:30:26 +090065
66 if (priv->extend_desc)
Joao Pintoce736782017-04-06 09:49:10 +010067 desc = (struct dma_desc *)(tx_q->dma_etx + entry);
Byungho An21ff0192013-08-08 15:30:26 +090068 else
Joao Pintoce736782017-04-06 09:49:10 +010069 desc = tx_q->dma_tx + entry;
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000070
Michael Weiserf8be0d72016-11-14 18:58:05 +010071 des2 = dma_map_single(priv->device, skb->data + bmax, len,
72 DMA_TO_DEVICE);
73 desc->des2 = cpu_to_le32(des2);
74 if (dma_mapping_error(priv->device, des2))
Giuseppe CAVALLARO362b37b2014-08-27 11:27:00 +020075 return -1;
Joao Pintoce736782017-04-06 09:49:10 +010076 tx_q->tx_skbuff_dma[entry].buf = des2;
77 tx_q->tx_skbuff_dma[entry].len = len;
78 tx_q->tx_skbuff_dma[entry].is_jumbo = true;
Giuseppe Cavallaro553e2ab2016-02-29 14:27:31 +010079
Michael Weiserf8be0d72016-11-14 18:58:05 +010080 desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
Giuseppe CAVALLARO4a7d6662013-03-26 04:43:05 +000081 priv->hw->desc->prepare_tx_desc(desc, 0, len, csum,
Giuseppe Cavallarobe434d52016-02-29 14:27:35 +010082 STMMAC_RING_MODE, 1, true);
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000083 } else {
Michael Weiserf8be0d72016-11-14 18:58:05 +010084 des2 = dma_map_single(priv->device, skb->data,
85 nopaged_len, DMA_TO_DEVICE);
86 desc->des2 = cpu_to_le32(des2);
87 if (dma_mapping_error(priv->device, des2))
Giuseppe CAVALLARO362b37b2014-08-27 11:27:00 +020088 return -1;
Joao Pintoce736782017-04-06 09:49:10 +010089 tx_q->tx_skbuff_dma[entry].buf = des2;
90 tx_q->tx_skbuff_dma[entry].len = nopaged_len;
91 tx_q->tx_skbuff_dma[entry].is_jumbo = true;
Michael Weiserf8be0d72016-11-14 18:58:05 +010092 desc->des3 = cpu_to_le32(des2 + BUF_SIZE_4KiB);
Giuseppe CAVALLARO4a7d6662013-03-26 04:43:05 +000093 priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum,
Giuseppe Cavallarobe434d52016-02-29 14:27:35 +010094 STMMAC_RING_MODE, 0, true);
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000095 }
96
Joao Pintoce736782017-04-06 09:49:10 +010097 tx_q->cur_tx = entry;
Giuseppe Cavallaroe3ad57c2016-02-29 14:27:30 +010098
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000099 return entry;
100}
101
102static unsigned int stmmac_is_jumbo_frm(int len, int enh_desc)
103{
104 unsigned int ret = 0;
105
106 if (len >= BUF_SIZE_4KiB)
107 ret = 1;
108
109 return ret;
110}
111
Rayagond Kokatanur891434b2013-03-26 04:43:10 +0000112static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p)
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +0000113{
Rayagond Kokatanur891434b2013-03-26 04:43:10 +0000114 struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr;
115
Giuseppe CAVALLARO29896a62014-03-10 13:40:33 +0100116 /* Fill DES3 in case of RING mode */
117 if (priv->dma_buf_sz >= BUF_SIZE_8KiB)
Michael Weiserf8be0d72016-11-14 18:58:05 +0100118 p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB);
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +0000119}
120
Giuseppe CAVALLARO4a7d6662013-03-26 04:43:05 +0000121/* In ring mode we need to fill the desc3 because it is used as buffer */
122static void stmmac_init_desc3(struct dma_desc *p)
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +0000123{
Michael Weiserf8be0d72016-11-14 18:58:05 +0100124 p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB);
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +0000125}
126
Rayagond Kokatanur891434b2013-03-26 04:43:10 +0000127static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p)
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +0000128{
Joao Pintoce736782017-04-06 09:49:10 +0100129 struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)priv_ptr;
130 struct stmmac_priv *priv = tx_q->priv_data;
131 unsigned int entry = tx_q->dirty_tx;
Giuseppe Cavallaro96951362016-02-29 14:27:33 +0100132
133 /* des3 is only used for jumbo frames tx or time stamping */
Joao Pintoce736782017-04-06 09:49:10 +0100134 if (unlikely(tx_q->tx_skbuff_dma[entry].is_jumbo ||
135 (tx_q->tx_skbuff_dma[entry].last_segment &&
Giuseppe Cavallaro96951362016-02-29 14:27:33 +0100136 !priv->extend_desc && priv->hwts_tx_en)))
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +0000137 p->des3 = 0;
138}
139
140static int stmmac_set_16kib_bfsize(int mtu)
141{
142 int ret = 0;
143 if (unlikely(mtu >= BUF_SIZE_8KiB))
144 ret = BUF_SIZE_16KiB;
145 return ret;
146}
147
Giuseppe CAVALLARO29896a62014-03-10 13:40:33 +0100148const struct stmmac_mode_ops ring_mode_ops = {
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +0000149 .is_jumbo_frm = stmmac_is_jumbo_frm,
150 .jumbo_frm = stmmac_jumbo_frm,
151 .refill_desc3 = stmmac_refill_desc3,
152 .init_desc3 = stmmac_init_desc3,
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +0000153 .clean_desc3 = stmmac_clean_desc3,
154 .set_16kib_bfsize = stmmac_set_16kib_bfsize,
155};