blob: cfc2f24ba08b8e9443daa0e885d170b0c4071949 [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
19 You should have received a copy of the GNU General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc.,
21 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22
23 The full GNU General Public License is included in this distribution in
24 the file called "COPYING".
25
26 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
27*******************************************************************************/
28
29#include "stmmac.h"
30
Giuseppe CAVALLARO362b37b2014-08-27 11:27:00 +020031static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000032{
Giuseppe CAVALLAROceb694992013-04-08 02:10:01 +000033 struct stmmac_priv *priv = (struct stmmac_priv *)p;
Giuseppe Cavallaroe3ad57c2016-02-29 14:27:30 +010034 unsigned int entry = priv->cur_tx;
Byungho An21ff0192013-08-08 15:30:26 +090035 struct dma_desc *desc;
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000036 unsigned int nopaged_len = skb_headlen(skb);
37 unsigned int bmax, len;
38
Byungho An21ff0192013-08-08 15:30:26 +090039 if (priv->extend_desc)
40 desc = (struct dma_desc *)(priv->dma_etx + entry);
41 else
42 desc = priv->dma_tx + entry;
43
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000044 if (priv->plat->enh_desc)
45 bmax = BUF_SIZE_8KiB;
46 else
47 bmax = BUF_SIZE_2KiB;
48
49 len = nopaged_len - bmax;
50
51 if (nopaged_len > BUF_SIZE_8KiB) {
52
53 desc->des2 = dma_map_single(priv->device, skb->data,
54 bmax, DMA_TO_DEVICE);
Giuseppe CAVALLARO362b37b2014-08-27 11:27:00 +020055 if (dma_mapping_error(priv->device, desc->des2))
56 return -1;
57
58 priv->tx_skbuff_dma[entry].buf = desc->des2;
Giuseppe Cavallaro553e2ab2016-02-29 14:27:31 +010059 priv->tx_skbuff_dma[entry].len = bmax;
60
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000061 desc->des3 = desc->des2 + BUF_SIZE_4KiB;
Giuseppe CAVALLARO4a7d6662013-03-26 04:43:05 +000062 priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum,
63 STMMAC_RING_MODE);
Deepak Sikri684901a2012-07-08 21:14:46 +000064 wmb();
damuzi00075e43642014-01-17 23:47:59 +080065 priv->tx_skbuff[entry] = NULL;
Giuseppe Cavallaroe3ad57c2016-02-29 14:27:30 +010066 entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
Byungho An21ff0192013-08-08 15:30:26 +090067
68 if (priv->extend_desc)
69 desc = (struct dma_desc *)(priv->dma_etx + entry);
70 else
71 desc = priv->dma_tx + entry;
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000072
73 desc->des2 = dma_map_single(priv->device, skb->data + bmax,
74 len, DMA_TO_DEVICE);
Giuseppe CAVALLARO362b37b2014-08-27 11:27:00 +020075 if (dma_mapping_error(priv->device, desc->des2))
76 return -1;
77 priv->tx_skbuff_dma[entry].buf = desc->des2;
Giuseppe Cavallaro553e2ab2016-02-29 14:27:31 +010078 priv->tx_skbuff_dma[entry].len = len;
79
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000080 desc->des3 = desc->des2 + BUF_SIZE_4KiB;
Giuseppe CAVALLARO4a7d6662013-03-26 04:43:05 +000081 priv->hw->desc->prepare_tx_desc(desc, 0, len, csum,
82 STMMAC_RING_MODE);
Deepak Sikri684901a2012-07-08 21:14:46 +000083 wmb();
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000084 priv->hw->desc->set_tx_owner(desc);
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000085 } else {
86 desc->des2 = dma_map_single(priv->device, skb->data,
87 nopaged_len, DMA_TO_DEVICE);
Giuseppe CAVALLARO362b37b2014-08-27 11:27:00 +020088 if (dma_mapping_error(priv->device, desc->des2))
89 return -1;
90 priv->tx_skbuff_dma[entry].buf = desc->des2;
Giuseppe Cavallaro553e2ab2016-02-29 14:27:31 +010091 priv->tx_skbuff_dma[entry].len = nopaged_len;
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000092 desc->des3 = desc->des2 + BUF_SIZE_4KiB;
Giuseppe CAVALLARO4a7d6662013-03-26 04:43:05 +000093 priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum,
94 STMMAC_RING_MODE);
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +000095 }
96
Giuseppe Cavallaroe3ad57c2016-02-29 14:27:30 +010097 priv->cur_tx = entry;
98
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)
118 p->des3 = 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{
Giuseppe CAVALLARO4a7d6662013-03-26 04:43:05 +0000124 p->des3 = 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{
129 if (unlikely(p->des3))
130 p->des3 = 0;
131}
132
133static int stmmac_set_16kib_bfsize(int mtu)
134{
135 int ret = 0;
136 if (unlikely(mtu >= BUF_SIZE_8KiB))
137 ret = BUF_SIZE_16KiB;
138 return ret;
139}
140
Giuseppe CAVALLARO29896a62014-03-10 13:40:33 +0100141const struct stmmac_mode_ops ring_mode_ops = {
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +0000142 .is_jumbo_frm = stmmac_is_jumbo_frm,
143 .jumbo_frm = stmmac_jumbo_frm,
144 .refill_desc3 = stmmac_refill_desc3,
145 .init_desc3 = stmmac_init_desc3,
Giuseppe CAVALLARO286a8372011-10-18 00:01:24 +0000146 .clean_desc3 = stmmac_clean_desc3,
147 .set_16kib_bfsize = stmmac_set_16kib_bfsize,
148};