Linux Audio

Check our new training course

Buildroot integration, development and maintenance

Need a Buildroot system for your embedded project?
Loading...
v6.8
  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
 17static 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
 94static 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
104static 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 */
114static void init_desc3(struct dma_desc *p)
115{
116	p->des3 = cpu_to_le32(le32_to_cpu(p->des2) + BUF_SIZE_8KiB);
117}
118
119static 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
131static 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
139const 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};
v3.15
 
  1/*******************************************************************************
  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
 31static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
 
 32{
 33	struct stmmac_priv *priv = (struct stmmac_priv *)p;
 34	unsigned int txsize = priv->dma_tx_size;
 35	unsigned int entry = priv->cur_tx % txsize;
 
 36	struct dma_desc *desc;
 37	unsigned int nopaged_len = skb_headlen(skb);
 38	unsigned int bmax, len;
 39
 40	if (priv->extend_desc)
 41		desc = (struct dma_desc *)(priv->dma_etx + entry);
 42	else
 43		desc = priv->dma_tx + entry;
 44
 45	if (priv->plat->enh_desc)
 46		bmax = BUF_SIZE_8KiB;
 47	else
 48		bmax = BUF_SIZE_2KiB;
 49
 50	len = nopaged_len - bmax;
 51
 52	if (nopaged_len > BUF_SIZE_8KiB) {
 53
 54		desc->des2 = dma_map_single(priv->device, skb->data,
 55					    bmax, DMA_TO_DEVICE);
 56		priv->tx_skbuff_dma[entry] = desc->des2;
 57		desc->des3 = desc->des2 + BUF_SIZE_4KiB;
 58		priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum,
 59						STMMAC_RING_MODE);
 60		wmb();
 61		priv->tx_skbuff[entry] = NULL;
 62		entry = (++priv->cur_tx) % txsize;
 
 
 
 
 
 
 63
 64		if (priv->extend_desc)
 65			desc = (struct dma_desc *)(priv->dma_etx + entry);
 66		else
 67			desc = priv->dma_tx + entry;
 68
 69		desc->des2 = dma_map_single(priv->device, skb->data + bmax,
 70					    len, DMA_TO_DEVICE);
 71		priv->tx_skbuff_dma[entry] = desc->des2;
 72		desc->des3 = desc->des2 + BUF_SIZE_4KiB;
 73		priv->hw->desc->prepare_tx_desc(desc, 0, len, csum,
 74						STMMAC_RING_MODE);
 75		wmb();
 76		priv->hw->desc->set_tx_owner(desc);
 
 
 
 
 
 77	} else {
 78		desc->des2 = dma_map_single(priv->device, skb->data,
 79					    nopaged_len, DMA_TO_DEVICE);
 80		priv->tx_skbuff_dma[entry] = desc->des2;
 81		desc->des3 = desc->des2 + BUF_SIZE_4KiB;
 82		priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum,
 83						STMMAC_RING_MODE);
 
 
 
 
 
 
 84	}
 85
 
 
 86	return entry;
 87}
 88
 89static unsigned int stmmac_is_jumbo_frm(int len, int enh_desc)
 90{
 91	unsigned int ret = 0;
 92
 93	if (len >= BUF_SIZE_4KiB)
 94		ret = 1;
 95
 96	return ret;
 97}
 98
 99static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p)
100{
101	struct stmmac_priv *priv = (struct stmmac_priv *)priv_ptr;
102
103	/* Fill DES3 in case of RING mode */
104	if (priv->dma_buf_sz >= BUF_SIZE_8KiB)
105		p->des3 = p->des2 + BUF_SIZE_8KiB;
106}
107
108/* In ring mode we need to fill the desc3 because it is used as buffer */
109static void stmmac_init_desc3(struct dma_desc *p)
110{
111	p->des3 = p->des2 + BUF_SIZE_8KiB;
112}
113
114static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p)
115{
116	if (unlikely(p->des3))
 
 
 
 
 
 
117		p->des3 = 0;
118}
119
120static int stmmac_set_16kib_bfsize(int mtu)
121{
122	int ret = 0;
123	if (unlikely(mtu >= BUF_SIZE_8KiB))
124		ret = BUF_SIZE_16KiB;
125	return ret;
126}
127
128const struct stmmac_mode_ops ring_mode_ops = {
129	.is_jumbo_frm = stmmac_is_jumbo_frm,
130	.jumbo_frm = stmmac_jumbo_frm,
131	.refill_desc3 = stmmac_refill_desc3,
132	.init_desc3 = stmmac_init_desc3,
133	.clean_desc3 = stmmac_clean_desc3,
134	.set_16kib_bfsize = stmmac_set_16kib_bfsize,
135};