brintos

brintos / linux-shallow public Read only

0
0
Text · 5.5 KiB · ac1efd0 Raw
197 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Altera TSE SGDMA and MSGDMA Linux driver3 * Copyright (C) 2014 Altera Corporation. All rights reserved4 */5 6#include <linux/netdevice.h>7#include "altera_utils.h"8#include "altera_tse.h"9#include "altera_msgdmahw.h"10#include "altera_msgdma.h"11 12/* No initialization work to do for MSGDMA */13int msgdma_initialize(struct altera_tse_private *priv)14{15	return 0;16}17 18void msgdma_uninitialize(struct altera_tse_private *priv)19{20}21 22void msgdma_start_rxdma(struct altera_tse_private *priv)23{24}25 26void msgdma_reset(struct altera_tse_private *priv)27{28	int counter;29 30	/* Reset Rx mSGDMA */31	csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr,32		msgdma_csroffs(status));33	csrwr32(MSGDMA_CSR_CTL_RESET, priv->rx_dma_csr,34		msgdma_csroffs(control));35 36	counter = 0;37	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {38		if (tse_bit_is_clear(priv->rx_dma_csr, msgdma_csroffs(status),39				     MSGDMA_CSR_STAT_RESETTING))40			break;41		udelay(1);42	}43 44	if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)45		netif_warn(priv, drv, priv->dev,46			   "TSE Rx mSGDMA resetting bit never cleared!\n");47 48	/* clear all status bits */49	csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr, msgdma_csroffs(status));50 51	/* Reset Tx mSGDMA */52	csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr,53		msgdma_csroffs(status));54 55	csrwr32(MSGDMA_CSR_CTL_RESET, priv->tx_dma_csr,56		msgdma_csroffs(control));57 58	counter = 0;59	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {60		if (tse_bit_is_clear(priv->tx_dma_csr, msgdma_csroffs(status),61				     MSGDMA_CSR_STAT_RESETTING))62			break;63		udelay(1);64	}65 66	if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR)67		netif_warn(priv, drv, priv->dev,68			   "TSE Tx mSGDMA resetting bit never cleared!\n");69 70	/* clear all status bits */71	csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr, msgdma_csroffs(status));72}73 74void msgdma_disable_rxirq(struct altera_tse_private *priv)75{76	tse_clear_bit(priv->rx_dma_csr, msgdma_csroffs(control),77		      MSGDMA_CSR_CTL_GLOBAL_INTR);78}79 80void msgdma_enable_rxirq(struct altera_tse_private *priv)81{82	tse_set_bit(priv->rx_dma_csr, msgdma_csroffs(control),83		    MSGDMA_CSR_CTL_GLOBAL_INTR);84}85 86void msgdma_disable_txirq(struct altera_tse_private *priv)87{88	tse_clear_bit(priv->tx_dma_csr, msgdma_csroffs(control),89		      MSGDMA_CSR_CTL_GLOBAL_INTR);90}91 92void msgdma_enable_txirq(struct altera_tse_private *priv)93{94	tse_set_bit(priv->tx_dma_csr, msgdma_csroffs(control),95		    MSGDMA_CSR_CTL_GLOBAL_INTR);96}97 98void msgdma_clear_rxirq(struct altera_tse_private *priv)99{100	csrwr32(MSGDMA_CSR_STAT_IRQ, priv->rx_dma_csr, msgdma_csroffs(status));101}102 103void msgdma_clear_txirq(struct altera_tse_private *priv)104{105	csrwr32(MSGDMA_CSR_STAT_IRQ, priv->tx_dma_csr, msgdma_csroffs(status));106}107 108/* return 0 to indicate transmit is pending */109int msgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)110{111	csrwr32(lower_32_bits(buffer->dma_addr), priv->tx_dma_desc,112		msgdma_descroffs(read_addr_lo));113	csrwr32(upper_32_bits(buffer->dma_addr), priv->tx_dma_desc,114		msgdma_descroffs(read_addr_hi));115	csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_lo));116	csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_hi));117	csrwr32(buffer->len, priv->tx_dma_desc, msgdma_descroffs(len));118	csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(burst_seq_num));119	csrwr32(MSGDMA_DESC_TX_STRIDE, priv->tx_dma_desc,120		msgdma_descroffs(stride));121	csrwr32(MSGDMA_DESC_CTL_TX_SINGLE, priv->tx_dma_desc,122		msgdma_descroffs(control));123	return 0;124}125 126u32 msgdma_tx_completions(struct altera_tse_private *priv)127{128	u32 ready = 0;129	u32 inuse;130	u32 status;131 132	/* Get number of sent descriptors */133	inuse = csrrd32(priv->tx_dma_csr, msgdma_csroffs(rw_fill_level))134			& 0xffff;135 136	if (inuse) { /* Tx FIFO is not empty */137		ready = max_t(int,138			      priv->tx_prod - priv->tx_cons - inuse - 1, 0);139	} else {140		/* Check for buffered last packet */141		status = csrrd32(priv->tx_dma_csr, msgdma_csroffs(status));142		if (status & MSGDMA_CSR_STAT_BUSY)143			ready = priv->tx_prod - priv->tx_cons - 1;144		else145			ready = priv->tx_prod - priv->tx_cons;146	}147	return ready;148}149 150/* Put buffer to the mSGDMA RX FIFO151 */152void msgdma_add_rx_desc(struct altera_tse_private *priv,153			struct tse_buffer *rxbuffer)154{155	u32 len = priv->rx_dma_buf_sz;156	dma_addr_t dma_addr = rxbuffer->dma_addr;157	u32 control = (MSGDMA_DESC_CTL_END_ON_EOP158			| MSGDMA_DESC_CTL_END_ON_LEN159			| MSGDMA_DESC_CTL_TR_COMP_IRQ160			| MSGDMA_DESC_CTL_EARLY_IRQ161			| MSGDMA_DESC_CTL_TR_ERR_IRQ162			| MSGDMA_DESC_CTL_GO);163 164	csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_lo));165	csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_hi));166	csrwr32(lower_32_bits(dma_addr), priv->rx_dma_desc,167		msgdma_descroffs(write_addr_lo));168	csrwr32(upper_32_bits(dma_addr), priv->rx_dma_desc,169		msgdma_descroffs(write_addr_hi));170	csrwr32(len, priv->rx_dma_desc, msgdma_descroffs(len));171	csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(burst_seq_num));172	csrwr32(0x00010001, priv->rx_dma_desc, msgdma_descroffs(stride));173	csrwr32(control, priv->rx_dma_desc, msgdma_descroffs(control));174}175 176/* status is returned on upper 16 bits,177 * length is returned in lower 16 bits178 */179u32 msgdma_rx_status(struct altera_tse_private *priv)180{181	u32 rxstatus = 0;182	u32 pktlength;183	u32 pktstatus;184 185	if (csrrd32(priv->rx_dma_csr, msgdma_csroffs(resp_fill_level))186	    & 0xffff) {187		pktlength = csrrd32(priv->rx_dma_resp,188				    msgdma_respoffs(bytes_transferred));189		pktstatus = csrrd32(priv->rx_dma_resp,190				    msgdma_respoffs(status));191		rxstatus = pktstatus;192		rxstatus = rxstatus << 16;193		rxstatus |= (pktlength & 0xffff);194	}195	return rxstatus;196}197