xref: /openbmc/linux/drivers/net/ethernet/altera/altera_msgdma.c (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*9952f691SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
294fb0ef4SVince Bridgers /* Altera TSE SGDMA and MSGDMA Linux driver
394fb0ef4SVince Bridgers  * Copyright (C) 2014 Altera Corporation. All rights reserved
494fb0ef4SVince Bridgers  */
594fb0ef4SVince Bridgers 
694fb0ef4SVince Bridgers #include <linux/netdevice.h>
794fb0ef4SVince Bridgers #include "altera_utils.h"
894fb0ef4SVince Bridgers #include "altera_tse.h"
994fb0ef4SVince Bridgers #include "altera_msgdmahw.h"
10652f99eaSTobias Klauser #include "altera_msgdma.h"
1194fb0ef4SVince Bridgers 
1294fb0ef4SVince Bridgers /* No initialization work to do for MSGDMA */
msgdma_initialize(struct altera_tse_private * priv)1394fb0ef4SVince Bridgers int msgdma_initialize(struct altera_tse_private *priv)
1494fb0ef4SVince Bridgers {
1594fb0ef4SVince Bridgers 	return 0;
1694fb0ef4SVince Bridgers }
1794fb0ef4SVince Bridgers 
msgdma_uninitialize(struct altera_tse_private * priv)1894fb0ef4SVince Bridgers void msgdma_uninitialize(struct altera_tse_private *priv)
1994fb0ef4SVince Bridgers {
2094fb0ef4SVince Bridgers }
2194fb0ef4SVince Bridgers 
msgdma_start_rxdma(struct altera_tse_private * priv)2237c0ffaaSVince Bridgers void msgdma_start_rxdma(struct altera_tse_private *priv)
2337c0ffaaSVince Bridgers {
2437c0ffaaSVince Bridgers }
2537c0ffaaSVince Bridgers 
msgdma_reset(struct altera_tse_private * priv)2694fb0ef4SVince Bridgers void msgdma_reset(struct altera_tse_private *priv)
2794fb0ef4SVince Bridgers {
2894fb0ef4SVince Bridgers 	int counter;
2994fb0ef4SVince Bridgers 
3094fb0ef4SVince Bridgers 	/* Reset Rx mSGDMA */
3189830580SVince Bridgers 	csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr,
3289830580SVince Bridgers 		msgdma_csroffs(status));
3389830580SVince Bridgers 	csrwr32(MSGDMA_CSR_CTL_RESET, priv->rx_dma_csr,
3489830580SVince Bridgers 		msgdma_csroffs(control));
3594fb0ef4SVince Bridgers 
3694fb0ef4SVince Bridgers 	counter = 0;
3794fb0ef4SVince Bridgers 	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
3889830580SVince Bridgers 		if (tse_bit_is_clear(priv->rx_dma_csr, msgdma_csroffs(status),
3994fb0ef4SVince Bridgers 				     MSGDMA_CSR_STAT_RESETTING))
4094fb0ef4SVince Bridgers 			break;
4194fb0ef4SVince Bridgers 		udelay(1);
4294fb0ef4SVince Bridgers 	}
4394fb0ef4SVince Bridgers 
4494fb0ef4SVince Bridgers 	if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)
4594fb0ef4SVince Bridgers 		netif_warn(priv, drv, priv->dev,
4694fb0ef4SVince Bridgers 			   "TSE Rx mSGDMA resetting bit never cleared!\n");
4794fb0ef4SVince Bridgers 
4894fb0ef4SVince Bridgers 	/* clear all status bits */
4989830580SVince Bridgers 	csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr, msgdma_csroffs(status));
5094fb0ef4SVince Bridgers 
5194fb0ef4SVince Bridgers 	/* Reset Tx mSGDMA */
5289830580SVince Bridgers 	csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr,
5389830580SVince Bridgers 		msgdma_csroffs(status));
5489830580SVince Bridgers 
5589830580SVince Bridgers 	csrwr32(MSGDMA_CSR_CTL_RESET, priv->tx_dma_csr,
5689830580SVince Bridgers 		msgdma_csroffs(control));
5794fb0ef4SVince Bridgers 
5894fb0ef4SVince Bridgers 	counter = 0;
5994fb0ef4SVince Bridgers 	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
6089830580SVince Bridgers 		if (tse_bit_is_clear(priv->tx_dma_csr, msgdma_csroffs(status),
6194fb0ef4SVince Bridgers 				     MSGDMA_CSR_STAT_RESETTING))
6294fb0ef4SVince Bridgers 			break;
6394fb0ef4SVince Bridgers 		udelay(1);
6494fb0ef4SVince Bridgers 	}
6594fb0ef4SVince Bridgers 
6694fb0ef4SVince Bridgers 	if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)
6794fb0ef4SVince Bridgers 		netif_warn(priv, drv, priv->dev,
6894fb0ef4SVince Bridgers 			   "TSE Tx mSGDMA resetting bit never cleared!\n");
6994fb0ef4SVince Bridgers 
7094fb0ef4SVince Bridgers 	/* clear all status bits */
7189830580SVince Bridgers 	csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr, msgdma_csroffs(status));
7294fb0ef4SVince Bridgers }
7394fb0ef4SVince Bridgers 
msgdma_disable_rxirq(struct altera_tse_private * priv)7494fb0ef4SVince Bridgers void msgdma_disable_rxirq(struct altera_tse_private *priv)
7594fb0ef4SVince Bridgers {
7689830580SVince Bridgers 	tse_clear_bit(priv->rx_dma_csr, msgdma_csroffs(control),
7789830580SVince Bridgers 		      MSGDMA_CSR_CTL_GLOBAL_INTR);
7894fb0ef4SVince Bridgers }
7994fb0ef4SVince Bridgers 
msgdma_enable_rxirq(struct altera_tse_private * priv)8094fb0ef4SVince Bridgers void msgdma_enable_rxirq(struct altera_tse_private *priv)
8194fb0ef4SVince Bridgers {
8289830580SVince Bridgers 	tse_set_bit(priv->rx_dma_csr, msgdma_csroffs(control),
8389830580SVince Bridgers 		    MSGDMA_CSR_CTL_GLOBAL_INTR);
8494fb0ef4SVince Bridgers }
8594fb0ef4SVince Bridgers 
msgdma_disable_txirq(struct altera_tse_private * priv)8694fb0ef4SVince Bridgers void msgdma_disable_txirq(struct altera_tse_private *priv)
8794fb0ef4SVince Bridgers {
8889830580SVince Bridgers 	tse_clear_bit(priv->tx_dma_csr, msgdma_csroffs(control),
8989830580SVince Bridgers 		      MSGDMA_CSR_CTL_GLOBAL_INTR);
9094fb0ef4SVince Bridgers }
9194fb0ef4SVince Bridgers 
msgdma_enable_txirq(struct altera_tse_private * priv)9294fb0ef4SVince Bridgers void msgdma_enable_txirq(struct altera_tse_private *priv)
9394fb0ef4SVince Bridgers {
9489830580SVince Bridgers 	tse_set_bit(priv->tx_dma_csr, msgdma_csroffs(control),
9589830580SVince Bridgers 		    MSGDMA_CSR_CTL_GLOBAL_INTR);
9694fb0ef4SVince Bridgers }
9794fb0ef4SVince Bridgers 
msgdma_clear_rxirq(struct altera_tse_private * priv)9894fb0ef4SVince Bridgers void msgdma_clear_rxirq(struct altera_tse_private *priv)
9994fb0ef4SVince Bridgers {
10089830580SVince Bridgers 	csrwr32(MSGDMA_CSR_STAT_IRQ, priv->rx_dma_csr, msgdma_csroffs(status));
10194fb0ef4SVince Bridgers }
10294fb0ef4SVince Bridgers 
msgdma_clear_txirq(struct altera_tse_private * priv)10394fb0ef4SVince Bridgers void msgdma_clear_txirq(struct altera_tse_private *priv)
10494fb0ef4SVince Bridgers {
10589830580SVince Bridgers 	csrwr32(MSGDMA_CSR_STAT_IRQ, priv->tx_dma_csr, msgdma_csroffs(status));
10694fb0ef4SVince Bridgers }
10794fb0ef4SVince Bridgers 
10894fb0ef4SVince Bridgers /* return 0 to indicate transmit is pending */
msgdma_tx_buffer(struct altera_tse_private * priv,struct tse_buffer * buffer)10994fb0ef4SVince Bridgers int msgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
11094fb0ef4SVince Bridgers {
11189830580SVince Bridgers 	csrwr32(lower_32_bits(buffer->dma_addr), priv->tx_dma_desc,
11289830580SVince Bridgers 		msgdma_descroffs(read_addr_lo));
11389830580SVince Bridgers 	csrwr32(upper_32_bits(buffer->dma_addr), priv->tx_dma_desc,
11489830580SVince Bridgers 		msgdma_descroffs(read_addr_hi));
11589830580SVince Bridgers 	csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_lo));
11689830580SVince Bridgers 	csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_hi));
11789830580SVince Bridgers 	csrwr32(buffer->len, priv->tx_dma_desc, msgdma_descroffs(len));
11889830580SVince Bridgers 	csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(burst_seq_num));
11989830580SVince Bridgers 	csrwr32(MSGDMA_DESC_TX_STRIDE, priv->tx_dma_desc,
12089830580SVince Bridgers 		msgdma_descroffs(stride));
12189830580SVince Bridgers 	csrwr32(MSGDMA_DESC_CTL_TX_SINGLE, priv->tx_dma_desc,
12289830580SVince Bridgers 		msgdma_descroffs(control));
12394fb0ef4SVince Bridgers 	return 0;
12494fb0ef4SVince Bridgers }
12594fb0ef4SVince Bridgers 
msgdma_tx_completions(struct altera_tse_private * priv)12694fb0ef4SVince Bridgers u32 msgdma_tx_completions(struct altera_tse_private *priv)
12794fb0ef4SVince Bridgers {
12894fb0ef4SVince Bridgers 	u32 ready = 0;
12994fb0ef4SVince Bridgers 	u32 inuse;
13094fb0ef4SVince Bridgers 	u32 status;
13194fb0ef4SVince Bridgers 
13294fb0ef4SVince Bridgers 	/* Get number of sent descriptors */
13389830580SVince Bridgers 	inuse = csrrd32(priv->tx_dma_csr, msgdma_csroffs(rw_fill_level))
13489830580SVince Bridgers 			& 0xffff;
13594fb0ef4SVince Bridgers 
13694fb0ef4SVince Bridgers 	if (inuse) { /* Tx FIFO is not empty */
1376571ebceSTomonori Sakita 		ready = max_t(int,
1386571ebceSTomonori Sakita 			      priv->tx_prod - priv->tx_cons - inuse - 1, 0);
13994fb0ef4SVince Bridgers 	} else {
14094fb0ef4SVince Bridgers 		/* Check for buffered last packet */
14189830580SVince Bridgers 		status = csrrd32(priv->tx_dma_csr, msgdma_csroffs(status));
14294fb0ef4SVince Bridgers 		if (status & MSGDMA_CSR_STAT_BUSY)
14394fb0ef4SVince Bridgers 			ready = priv->tx_prod - priv->tx_cons - 1;
14494fb0ef4SVince Bridgers 		else
14594fb0ef4SVince Bridgers 			ready = priv->tx_prod - priv->tx_cons;
14694fb0ef4SVince Bridgers 	}
14794fb0ef4SVince Bridgers 	return ready;
14894fb0ef4SVince Bridgers }
14994fb0ef4SVince Bridgers 
15094fb0ef4SVince Bridgers /* Put buffer to the mSGDMA RX FIFO
15194fb0ef4SVince Bridgers  */
msgdma_add_rx_desc(struct altera_tse_private * priv,struct tse_buffer * rxbuffer)15237c0ffaaSVince Bridgers void msgdma_add_rx_desc(struct altera_tse_private *priv,
15394fb0ef4SVince Bridgers 			struct tse_buffer *rxbuffer)
15494fb0ef4SVince Bridgers {
15594fb0ef4SVince Bridgers 	u32 len = priv->rx_dma_buf_sz;
15694fb0ef4SVince Bridgers 	dma_addr_t dma_addr = rxbuffer->dma_addr;
15794fb0ef4SVince Bridgers 	u32 control = (MSGDMA_DESC_CTL_END_ON_EOP
15894fb0ef4SVince Bridgers 			| MSGDMA_DESC_CTL_END_ON_LEN
15994fb0ef4SVince Bridgers 			| MSGDMA_DESC_CTL_TR_COMP_IRQ
16094fb0ef4SVince Bridgers 			| MSGDMA_DESC_CTL_EARLY_IRQ
16194fb0ef4SVince Bridgers 			| MSGDMA_DESC_CTL_TR_ERR_IRQ
16294fb0ef4SVince Bridgers 			| MSGDMA_DESC_CTL_GO);
16394fb0ef4SVince Bridgers 
16489830580SVince Bridgers 	csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_lo));
16589830580SVince Bridgers 	csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_hi));
16689830580SVince Bridgers 	csrwr32(lower_32_bits(dma_addr), priv->rx_dma_desc,
16789830580SVince Bridgers 		msgdma_descroffs(write_addr_lo));
16889830580SVince Bridgers 	csrwr32(upper_32_bits(dma_addr), priv->rx_dma_desc,
16989830580SVince Bridgers 		msgdma_descroffs(write_addr_hi));
17089830580SVince Bridgers 	csrwr32(len, priv->rx_dma_desc, msgdma_descroffs(len));
17189830580SVince Bridgers 	csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(burst_seq_num));
17289830580SVince Bridgers 	csrwr32(0x00010001, priv->rx_dma_desc, msgdma_descroffs(stride));
17389830580SVince Bridgers 	csrwr32(control, priv->rx_dma_desc, msgdma_descroffs(control));
17494fb0ef4SVince Bridgers }
17594fb0ef4SVince Bridgers 
17694fb0ef4SVince Bridgers /* status is returned on upper 16 bits,
17794fb0ef4SVince Bridgers  * length is returned in lower 16 bits
17894fb0ef4SVince Bridgers  */
msgdma_rx_status(struct altera_tse_private * priv)17994fb0ef4SVince Bridgers u32 msgdma_rx_status(struct altera_tse_private *priv)
18094fb0ef4SVince Bridgers {
18194fb0ef4SVince Bridgers 	u32 rxstatus = 0;
18294fb0ef4SVince Bridgers 	u32 pktlength;
18394fb0ef4SVince Bridgers 	u32 pktstatus;
18494fb0ef4SVince Bridgers 
18589830580SVince Bridgers 	if (csrrd32(priv->rx_dma_csr, msgdma_csroffs(resp_fill_level))
18689830580SVince Bridgers 	    & 0xffff) {
18789830580SVince Bridgers 		pktlength = csrrd32(priv->rx_dma_resp,
18889830580SVince Bridgers 				    msgdma_respoffs(bytes_transferred));
18989830580SVince Bridgers 		pktstatus = csrrd32(priv->rx_dma_resp,
19089830580SVince Bridgers 				    msgdma_respoffs(status));
19194fb0ef4SVince Bridgers 		rxstatus = pktstatus;
19294fb0ef4SVince Bridgers 		rxstatus = rxstatus << 16;
19394fb0ef4SVince Bridgers 		rxstatus |= (pktlength & 0xffff);
19494fb0ef4SVince Bridgers 	}
19594fb0ef4SVince Bridgers 	return rxstatus;
19694fb0ef4SVince Bridgers }
197