brintos

brintos / linux-shallow public Read only

0
0
Text · 4.7 KiB · fb55efd Raw
167 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*******************************************************************************3  Specialised functions for managing Chained mode4 5  Copyright(C) 2011  STMicroelectronics Ltd6 7  It defines all the functions used to handle the normal/enhanced8  descriptors in case of the DMA is configured to work in chained or9  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, des2;24	unsigned int i = 1, len;25	struct dma_desc *desc;26 27	desc = tx_q->dma_tx + entry;28 29	if (priv->plat->enh_desc)30		bmax = BUF_SIZE_8KiB;31	else32		bmax = BUF_SIZE_2KiB;33 34	len = nopaged_len - bmax;35 36	des2 = dma_map_single(priv->device, skb->data,37			      bmax, DMA_TO_DEVICE);38	desc->des2 = cpu_to_le32(des2);39	if (dma_mapping_error(priv->device, des2))40		return -1;41	tx_q->tx_skbuff_dma[entry].buf = des2;42	tx_q->tx_skbuff_dma[entry].len = bmax;43	/* do not close the descriptor and do not set own bit */44	stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum, STMMAC_CHAIN_MODE,45			0, false, skb->len);46 47	while (len != 0) {48		tx_q->tx_skbuff[entry] = NULL;49		entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);50		desc = tx_q->dma_tx + entry;51 52		if (len > bmax) {53			des2 = dma_map_single(priv->device,54					      (skb->data + bmax * i),55					      bmax, DMA_TO_DEVICE);56			desc->des2 = cpu_to_le32(des2);57			if (dma_mapping_error(priv->device, des2))58				return -1;59			tx_q->tx_skbuff_dma[entry].buf = des2;60			tx_q->tx_skbuff_dma[entry].len = bmax;61			stmmac_prepare_tx_desc(priv, desc, 0, bmax, csum,62					STMMAC_CHAIN_MODE, 1, false, skb->len);63			len -= bmax;64			i++;65		} else {66			des2 = dma_map_single(priv->device,67					      (skb->data + bmax * i), len,68					      DMA_TO_DEVICE);69			desc->des2 = cpu_to_le32(des2);70			if (dma_mapping_error(priv->device, des2))71				return -1;72			tx_q->tx_skbuff_dma[entry].buf = des2;73			tx_q->tx_skbuff_dma[entry].len = len;74			/* last descriptor can be set now */75			stmmac_prepare_tx_desc(priv, desc, 0, len, csum,76					STMMAC_CHAIN_MODE, 1, true, skb->len);77			len = 0;78		}79	}80 81	tx_q->cur_tx = entry;82 83	return entry;84}85 86static unsigned int is_jumbo_frm(int len, int enh_desc)87{88	unsigned int ret = 0;89 90	if ((enh_desc && (len > BUF_SIZE_8KiB)) ||91	    (!enh_desc && (len > BUF_SIZE_2KiB))) {92		ret = 1;93	}94 95	return ret;96}97 98static void init_dma_chain(void *des, dma_addr_t phy_addr,99				  unsigned int size, unsigned int extend_desc)100{101	/*102	 * In chained mode the des3 points to the next element in the ring.103	 * The latest element has to point to the head.104	 */105	int i;106	dma_addr_t dma_phy = phy_addr;107 108	if (extend_desc) {109		struct dma_extended_desc *p = (struct dma_extended_desc *)des;110		for (i = 0; i < (size - 1); i++) {111			dma_phy += sizeof(struct dma_extended_desc);112			p->basic.des3 = cpu_to_le32((unsigned int)dma_phy);113			p++;114		}115		p->basic.des3 = cpu_to_le32((unsigned int)phy_addr);116 117	} else {118		struct dma_desc *p = (struct dma_desc *)des;119		for (i = 0; i < (size - 1); i++) {120			dma_phy += sizeof(struct dma_desc);121			p->des3 = cpu_to_le32((unsigned int)dma_phy);122			p++;123		}124		p->des3 = cpu_to_le32((unsigned int)phy_addr);125	}126}127 128static void refill_desc3(struct stmmac_rx_queue *rx_q, struct dma_desc *p)129{130	struct stmmac_priv *priv = rx_q->priv_data;131 132	if (priv->hwts_rx_en && !priv->extend_desc)133		/* NOTE: Device will overwrite des3 with timestamp value if134		 * 1588-2002 time stamping is enabled, hence reinitialize it135		 * to keep explicit chaining in the descriptor.136		 */137		p->des3 = cpu_to_le32((unsigned int)(rx_q->dma_rx_phy +138				      (((rx_q->dirty_rx) + 1) %139				       priv->dma_conf.dma_rx_size) *140				      sizeof(struct dma_desc)));141}142 143static void clean_desc3(struct stmmac_tx_queue *tx_q, struct dma_desc *p)144{145	struct stmmac_priv *priv = tx_q->priv_data;146	unsigned int entry = tx_q->dirty_tx;147 148	if (tx_q->tx_skbuff_dma[entry].last_segment && !priv->extend_desc &&149	    priv->hwts_tx_en)150		/* NOTE: Device will overwrite des3 with timestamp value if151		 * 1588-2002 time stamping is enabled, hence reinitialize it152		 * to keep explicit chaining in the descriptor.153		 */154		p->des3 = cpu_to_le32((unsigned int)((tx_q->dma_tx_phy +155				      ((tx_q->dirty_tx + 1) %156				       priv->dma_conf.dma_tx_size))157				      * sizeof(struct dma_desc)));158}159 160const struct stmmac_mode_ops chain_mode_ops = {161	.init = init_dma_chain,162	.is_jumbo_frm = is_jumbo_frm,163	.jumbo_frm = jumbo_frm,164	.refill_desc3 = refill_desc3,165	.clean_desc3 = clean_desc3,166};167