Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 48f0459f authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'altera_tse'



Vince Bridgers says:

====================
Altera TSE: Fix Sparse errors and misc issues

This is version 2 of a patch series to correct sparse errors, cppcheck
warnings, and workaound a multicast filtering issue in the Altera TSE
Ethernet driver. Multicast filtering is not working as expected, so if
present in the hardware will not be used and promiscuous mode enabled
instead. This workaround will be replaced with a working solution when
completely debugged, integrated and tested.

Version 2 is different from the first submission by breaking out the
workaround as a seperate patch and addressing a few structure instance
declarations by making them const per review comments.

If you find this patch acceptable, please consider this for inclusion into
the Altera TSE driver source code.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 200b916f d91e5c02
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -5,3 +5,4 @@
obj-$(CONFIG_ALTERA_TSE) += altera_tse.o
altera_tse-objs := altera_tse_main.o altera_tse_ethtool.o \
altera_msgdma.o altera_sgdma.o altera_utils.o
ccflags-y += -D__CHECK_ENDIAN__
+55 −55
Original line number Diff line number Diff line
@@ -37,18 +37,16 @@ void msgdma_start_rxdma(struct altera_tse_private *priv)
void msgdma_reset(struct altera_tse_private *priv)
{
	int counter;
	struct msgdma_csr *txcsr =
		(struct msgdma_csr *)priv->tx_dma_csr;
	struct msgdma_csr *rxcsr =
		(struct msgdma_csr *)priv->rx_dma_csr;

	/* Reset Rx mSGDMA */
	iowrite32(MSGDMA_CSR_STAT_MASK, &rxcsr->status);
	iowrite32(MSGDMA_CSR_CTL_RESET, &rxcsr->control);
	csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr,
		msgdma_csroffs(status));
	csrwr32(MSGDMA_CSR_CTL_RESET, priv->rx_dma_csr,
		msgdma_csroffs(control));

	counter = 0;
	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
		if (tse_bit_is_clear(&rxcsr->status,
		if (tse_bit_is_clear(priv->rx_dma_csr, msgdma_csroffs(status),
				     MSGDMA_CSR_STAT_RESETTING))
			break;
		udelay(1);
@@ -59,15 +57,18 @@ void msgdma_reset(struct altera_tse_private *priv)
			   "TSE Rx mSGDMA resetting bit never cleared!\n");

	/* clear all status bits */
	iowrite32(MSGDMA_CSR_STAT_MASK, &rxcsr->status);
	csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr, msgdma_csroffs(status));

	/* Reset Tx mSGDMA */
	iowrite32(MSGDMA_CSR_STAT_MASK, &txcsr->status);
	iowrite32(MSGDMA_CSR_CTL_RESET, &txcsr->control);
	csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr,
		msgdma_csroffs(status));

	csrwr32(MSGDMA_CSR_CTL_RESET, priv->tx_dma_csr,
		msgdma_csroffs(control));

	counter = 0;
	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
		if (tse_bit_is_clear(&txcsr->status,
		if (tse_bit_is_clear(priv->tx_dma_csr, msgdma_csroffs(status),
				     MSGDMA_CSR_STAT_RESETTING))
			break;
		udelay(1);
@@ -78,58 +79,58 @@ void msgdma_reset(struct altera_tse_private *priv)
			   "TSE Tx mSGDMA resetting bit never cleared!\n");

	/* clear all status bits */
	iowrite32(MSGDMA_CSR_STAT_MASK, &txcsr->status);
	csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr, msgdma_csroffs(status));
}

void msgdma_disable_rxirq(struct altera_tse_private *priv)
{
	struct msgdma_csr *csr = priv->rx_dma_csr;
	tse_clear_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR);
	tse_clear_bit(priv->rx_dma_csr, msgdma_csroffs(control),
		      MSGDMA_CSR_CTL_GLOBAL_INTR);
}

void msgdma_enable_rxirq(struct altera_tse_private *priv)
{
	struct msgdma_csr *csr = priv->rx_dma_csr;
	tse_set_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR);
	tse_set_bit(priv->rx_dma_csr, msgdma_csroffs(control),
		    MSGDMA_CSR_CTL_GLOBAL_INTR);
}

void msgdma_disable_txirq(struct altera_tse_private *priv)
{
	struct msgdma_csr *csr = priv->tx_dma_csr;
	tse_clear_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR);
	tse_clear_bit(priv->tx_dma_csr, msgdma_csroffs(control),
		      MSGDMA_CSR_CTL_GLOBAL_INTR);
}

void msgdma_enable_txirq(struct altera_tse_private *priv)
{
	struct msgdma_csr *csr = priv->tx_dma_csr;
	tse_set_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR);
	tse_set_bit(priv->tx_dma_csr, msgdma_csroffs(control),
		    MSGDMA_CSR_CTL_GLOBAL_INTR);
}

void msgdma_clear_rxirq(struct altera_tse_private *priv)
{
	struct msgdma_csr *csr = priv->rx_dma_csr;
	iowrite32(MSGDMA_CSR_STAT_IRQ, &csr->status);
	csrwr32(MSGDMA_CSR_STAT_IRQ, priv->rx_dma_csr, msgdma_csroffs(status));
}

void msgdma_clear_txirq(struct altera_tse_private *priv)
{
	struct msgdma_csr *csr = priv->tx_dma_csr;
	iowrite32(MSGDMA_CSR_STAT_IRQ, &csr->status);
	csrwr32(MSGDMA_CSR_STAT_IRQ, priv->tx_dma_csr, msgdma_csroffs(status));
}

/* return 0 to indicate transmit is pending */
int msgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
{
	struct msgdma_extended_desc *desc = priv->tx_dma_desc;

	iowrite32(lower_32_bits(buffer->dma_addr), &desc->read_addr_lo);
	iowrite32(upper_32_bits(buffer->dma_addr), &desc->read_addr_hi);
	iowrite32(0, &desc->write_addr_lo);
	iowrite32(0, &desc->write_addr_hi);
	iowrite32(buffer->len, &desc->len);
	iowrite32(0, &desc->burst_seq_num);
	iowrite32(MSGDMA_DESC_TX_STRIDE, &desc->stride);
	iowrite32(MSGDMA_DESC_CTL_TX_SINGLE, &desc->control);
	csrwr32(lower_32_bits(buffer->dma_addr), priv->tx_dma_desc,
		msgdma_descroffs(read_addr_lo));
	csrwr32(upper_32_bits(buffer->dma_addr), priv->tx_dma_desc,
		msgdma_descroffs(read_addr_hi));
	csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_lo));
	csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_hi));
	csrwr32(buffer->len, priv->tx_dma_desc, msgdma_descroffs(len));
	csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(burst_seq_num));
	csrwr32(MSGDMA_DESC_TX_STRIDE, priv->tx_dma_desc,
		msgdma_descroffs(stride));
	csrwr32(MSGDMA_DESC_CTL_TX_SINGLE, priv->tx_dma_desc,
		msgdma_descroffs(control));
	return 0;
}

@@ -138,17 +139,16 @@ u32 msgdma_tx_completions(struct altera_tse_private *priv)
	u32 ready = 0;
	u32 inuse;
	u32 status;
	struct msgdma_csr *txcsr =
		(struct msgdma_csr *)priv->tx_dma_csr;

	/* Get number of sent descriptors */
	inuse = ioread32(&txcsr->rw_fill_level) & 0xffff;
	inuse = csrrd32(priv->tx_dma_csr, msgdma_csroffs(rw_fill_level))
			& 0xffff;

	if (inuse) { /* Tx FIFO is not empty */
		ready = priv->tx_prod - priv->tx_cons - inuse - 1;
	} else {
		/* Check for buffered last packet */
		status = ioread32(&txcsr->status);
		status = csrrd32(priv->tx_dma_csr, msgdma_csroffs(status));
		if (status & MSGDMA_CSR_STAT_BUSY)
			ready = priv->tx_prod - priv->tx_cons - 1;
		else
@@ -162,7 +162,6 @@ u32 msgdma_tx_completions(struct altera_tse_private *priv)
void msgdma_add_rx_desc(struct altera_tse_private *priv,
			struct tse_buffer *rxbuffer)
{
	struct msgdma_extended_desc *desc = priv->rx_dma_desc;
	u32 len = priv->rx_dma_buf_sz;
	dma_addr_t dma_addr = rxbuffer->dma_addr;
	u32 control = (MSGDMA_DESC_CTL_END_ON_EOP
@@ -172,14 +171,16 @@ void msgdma_add_rx_desc(struct altera_tse_private *priv,
			| MSGDMA_DESC_CTL_TR_ERR_IRQ
			| MSGDMA_DESC_CTL_GO);

	iowrite32(0, &desc->read_addr_lo);
	iowrite32(0, &desc->read_addr_hi);
	iowrite32(lower_32_bits(dma_addr), &desc->write_addr_lo);
	iowrite32(upper_32_bits(dma_addr), &desc->write_addr_hi);
	iowrite32(len, &desc->len);
	iowrite32(0, &desc->burst_seq_num);
	iowrite32(0x00010001, &desc->stride);
	iowrite32(control, &desc->control);
	csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_lo));
	csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_hi));
	csrwr32(lower_32_bits(dma_addr), priv->rx_dma_desc,
		msgdma_descroffs(write_addr_lo));
	csrwr32(upper_32_bits(dma_addr), priv->rx_dma_desc,
		msgdma_descroffs(write_addr_hi));
	csrwr32(len, priv->rx_dma_desc, msgdma_descroffs(len));
	csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(burst_seq_num));
	csrwr32(0x00010001, priv->rx_dma_desc, msgdma_descroffs(stride));
	csrwr32(control, priv->rx_dma_desc, msgdma_descroffs(control));
}

/* status is returned on upper 16 bits,
@@ -190,14 +191,13 @@ u32 msgdma_rx_status(struct altera_tse_private *priv)
	u32 rxstatus = 0;
	u32 pktlength;
	u32 pktstatus;
	struct msgdma_csr *rxcsr =
		(struct msgdma_csr *)priv->rx_dma_csr;
	struct msgdma_response *rxresp =
		(struct msgdma_response *)priv->rx_dma_resp;

	if (ioread32(&rxcsr->resp_fill_level) & 0xffff) {
		pktlength = ioread32(&rxresp->bytes_transferred);
		pktstatus = ioread32(&rxresp->status);

	if (csrrd32(priv->rx_dma_csr, msgdma_csroffs(resp_fill_level))
	    & 0xffff) {
		pktlength = csrrd32(priv->rx_dma_resp,
				    msgdma_respoffs(bytes_transferred));
		pktstatus = csrrd32(priv->rx_dma_resp,
				    msgdma_respoffs(status));
		rxstatus = pktstatus;
		rxstatus = rxstatus << 16;
		rxstatus |= (pktlength & 0xffff);
+4 −9
Original line number Diff line number Diff line
@@ -17,15 +17,6 @@
#ifndef __ALTERA_MSGDMAHW_H__
#define __ALTERA_MSGDMAHW_H__

/* mSGDMA standard descriptor format
 */
struct msgdma_desc {
	u32 read_addr;	/* data buffer source address */
	u32 write_addr;	/* data buffer destination address */
	u32 len;	/* the number of bytes to transfer per descriptor */
	u32 control;	/* characteristics of the transfer */
};

/* mSGDMA extended descriptor format
 */
struct msgdma_extended_desc {
@@ -159,6 +150,10 @@ struct msgdma_response {
	u32 status;
};

#define msgdma_respoffs(a) (offsetof(struct msgdma_response, a))
#define msgdma_csroffs(a) (offsetof(struct msgdma_csr, a))
#define msgdma_descroffs(a) (offsetof(struct msgdma_extended_desc, a))

/* mSGDMA response register bit definitions
 */
#define MSGDMA_RESP_EARLY_TERM	BIT(8)
+90 −91
Original line number Diff line number Diff line
@@ -20,8 +20,8 @@
#include "altera_sgdmahw.h"
#include "altera_sgdma.h"

static void sgdma_setup_descrip(struct sgdma_descrip *desc,
				struct sgdma_descrip *ndesc,
static void sgdma_setup_descrip(struct sgdma_descrip __iomem *desc,
				struct sgdma_descrip __iomem *ndesc,
				dma_addr_t ndesc_phys,
				dma_addr_t raddr,
				dma_addr_t waddr,
@@ -31,17 +31,17 @@ static void sgdma_setup_descrip(struct sgdma_descrip *desc,
				int wfixed);

static int sgdma_async_write(struct altera_tse_private *priv,
			      struct sgdma_descrip *desc);
			      struct sgdma_descrip __iomem *desc);

static int sgdma_async_read(struct altera_tse_private *priv);

static dma_addr_t
sgdma_txphysaddr(struct altera_tse_private *priv,
		 struct sgdma_descrip *desc);
		 struct sgdma_descrip __iomem *desc);

static dma_addr_t
sgdma_rxphysaddr(struct altera_tse_private *priv,
		 struct sgdma_descrip *desc);
		 struct sgdma_descrip __iomem *desc);

static int sgdma_txbusy(struct altera_tse_private *priv);

@@ -79,7 +79,8 @@ int sgdma_initialize(struct altera_tse_private *priv)
	priv->rxdescphys = (dma_addr_t) 0;
	priv->txdescphys = (dma_addr_t) 0;

	priv->rxdescphys = dma_map_single(priv->device, priv->rx_dma_desc,
	priv->rxdescphys = dma_map_single(priv->device,
					  (void __force *)priv->rx_dma_desc,
					  priv->rxdescmem, DMA_BIDIRECTIONAL);

	if (dma_mapping_error(priv->device, priv->rxdescphys)) {
@@ -88,7 +89,8 @@ int sgdma_initialize(struct altera_tse_private *priv)
		return -EINVAL;
	}

	priv->txdescphys = dma_map_single(priv->device, priv->tx_dma_desc,
	priv->txdescphys = dma_map_single(priv->device,
					  (void __force *)priv->tx_dma_desc,
					  priv->txdescmem, DMA_TO_DEVICE);

	if (dma_mapping_error(priv->device, priv->txdescphys)) {
@@ -98,8 +100,8 @@ int sgdma_initialize(struct altera_tse_private *priv)
	}

	/* Initialize descriptor memory to all 0's, sync memory to cache */
	memset(priv->tx_dma_desc, 0, priv->txdescmem);
	memset(priv->rx_dma_desc, 0, priv->rxdescmem);
	memset_io(priv->tx_dma_desc, 0, priv->txdescmem);
	memset_io(priv->rx_dma_desc, 0, priv->rxdescmem);

	dma_sync_single_for_device(priv->device, priv->txdescphys,
				   priv->txdescmem, DMA_TO_DEVICE);
@@ -126,22 +128,15 @@ void sgdma_uninitialize(struct altera_tse_private *priv)
 */
void sgdma_reset(struct altera_tse_private *priv)
{
	u32 *ptxdescripmem = (u32 *)priv->tx_dma_desc;
	u32 txdescriplen   = priv->txdescmem;
	u32 *prxdescripmem = (u32 *)priv->rx_dma_desc;
	u32 rxdescriplen   = priv->rxdescmem;
	struct sgdma_csr *ptxsgdma = (struct sgdma_csr *)priv->tx_dma_csr;
	struct sgdma_csr *prxsgdma = (struct sgdma_csr *)priv->rx_dma_csr;

	/* Initialize descriptor memory to 0 */
	memset(ptxdescripmem, 0, txdescriplen);
	memset(prxdescripmem, 0, rxdescriplen);
	memset_io(priv->tx_dma_desc, 0, priv->txdescmem);
	memset_io(priv->rx_dma_desc, 0, priv->rxdescmem);

	iowrite32(SGDMA_CTRLREG_RESET, &ptxsgdma->control);
	iowrite32(0, &ptxsgdma->control);
	csrwr32(SGDMA_CTRLREG_RESET, priv->tx_dma_csr, sgdma_csroffs(control));
	csrwr32(0, priv->tx_dma_csr, sgdma_csroffs(control));

	iowrite32(SGDMA_CTRLREG_RESET, &prxsgdma->control);
	iowrite32(0, &prxsgdma->control);
	csrwr32(SGDMA_CTRLREG_RESET, priv->rx_dma_csr, sgdma_csroffs(control));
	csrwr32(0, priv->rx_dma_csr, sgdma_csroffs(control));
}

/* For SGDMA, interrupts remain enabled after initially enabling,
@@ -167,14 +162,14 @@ void sgdma_disable_txirq(struct altera_tse_private *priv)

void sgdma_clear_rxirq(struct altera_tse_private *priv)
{
	struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
	tse_set_bit(&csr->control, SGDMA_CTRLREG_CLRINT);
	tse_set_bit(priv->rx_dma_csr, sgdma_csroffs(control),
		    SGDMA_CTRLREG_CLRINT);
}

void sgdma_clear_txirq(struct altera_tse_private *priv)
{
	struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr;
	tse_set_bit(&csr->control, SGDMA_CTRLREG_CLRINT);
	tse_set_bit(priv->tx_dma_csr, sgdma_csroffs(control),
		    SGDMA_CTRLREG_CLRINT);
}

/* transmits buffer through SGDMA. Returns number of buffers
@@ -184,12 +179,11 @@ void sgdma_clear_txirq(struct altera_tse_private *priv)
 */
int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
{
	int pktstx = 0;
	struct sgdma_descrip *descbase =
		(struct sgdma_descrip *)priv->tx_dma_desc;
	struct sgdma_descrip __iomem *descbase =
		(struct sgdma_descrip __iomem *)priv->tx_dma_desc;

	struct sgdma_descrip *cdesc = &descbase[0];
	struct sgdma_descrip *ndesc = &descbase[1];
	struct sgdma_descrip __iomem *cdesc = &descbase[0];
	struct sgdma_descrip __iomem *ndesc = &descbase[1];

	/* wait 'til the tx sgdma is ready for the next transmit request */
	if (sgdma_txbusy(priv))
@@ -205,7 +199,7 @@ int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
			    0,				/* read fixed */
			    SGDMA_CONTROL_WR_FIXED);	/* Generate SOP */

	pktstx = sgdma_async_write(priv, cdesc);
	sgdma_async_write(priv, cdesc);

	/* enqueue the request to the pending transmit queue */
	queue_tx(priv, buffer);
@@ -219,10 +213,10 @@ int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
u32 sgdma_tx_completions(struct altera_tse_private *priv)
{
	u32 ready = 0;
	struct sgdma_descrip *desc = (struct sgdma_descrip *)priv->tx_dma_desc;

	if (!sgdma_txbusy(priv) &&
	    ((desc->control & SGDMA_CONTROL_HW_OWNED) == 0) &&
	    ((csrrd8(priv->tx_dma_desc, sgdma_descroffs(control))
	     & SGDMA_CONTROL_HW_OWNED) == 0) &&
	    (dequeue_tx(priv))) {
		ready = 1;
	}
@@ -246,32 +240,31 @@ void sgdma_add_rx_desc(struct altera_tse_private *priv,
 */
u32 sgdma_rx_status(struct altera_tse_private *priv)
{
	struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
	struct sgdma_descrip *base = (struct sgdma_descrip *)priv->rx_dma_desc;
	struct sgdma_descrip *desc = NULL;
	int pktsrx;
	unsigned int rxstatus = 0;
	unsigned int pktlength = 0;
	unsigned int pktstatus = 0;
	struct sgdma_descrip __iomem *base =
		(struct sgdma_descrip __iomem *)priv->rx_dma_desc;
	struct sgdma_descrip __iomem *desc = NULL;
	struct tse_buffer *rxbuffer = NULL;
	unsigned int rxstatus = 0;

	u32 sts = ioread32(&csr->status);
	u32 sts = csrrd32(priv->rx_dma_csr, sgdma_csroffs(status));

	desc = &base[0];
	if (sts & SGDMA_STSREG_EOP) {
		unsigned int pktlength = 0;
		unsigned int pktstatus = 0;
		dma_sync_single_for_cpu(priv->device,
					priv->rxdescphys,
					priv->sgdmadesclen,
					DMA_FROM_DEVICE);

		pktlength = desc->bytes_xferred;
		pktstatus = desc->status & 0x3f;
		rxstatus = pktstatus;
		pktlength = csrrd16(desc, sgdma_descroffs(bytes_xferred));
		pktstatus = csrrd8(desc, sgdma_descroffs(status));
		rxstatus = pktstatus & ~SGDMA_STATUS_EOP;
		rxstatus = rxstatus << 16;
		rxstatus |= (pktlength & 0xffff);

		if (rxstatus) {
			desc->status = 0;
			csrwr8(0, desc, sgdma_descroffs(status));

			rxbuffer = dequeue_rx(priv);
			if (rxbuffer == NULL)
@@ -279,12 +272,12 @@ u32 sgdma_rx_status(struct altera_tse_private *priv)
					    "sgdma rx and rx queue empty!\n");

			/* Clear control */
			iowrite32(0, &csr->control);
			csrwr32(0, priv->rx_dma_csr, sgdma_csroffs(control));
			/* clear status */
			iowrite32(0xf, &csr->status);
			csrwr32(0xf, priv->rx_dma_csr, sgdma_csroffs(status));

			/* kick the rx sgdma after reaping this descriptor */
			pktsrx = sgdma_async_read(priv);
			sgdma_async_read(priv);

		} else {
			/* If the SGDMA indicated an end of packet on recv,
@@ -298,10 +291,11 @@ u32 sgdma_rx_status(struct altera_tse_private *priv)
			 */
			netdev_err(priv->dev,
				   "SGDMA RX Error Info: %x, %x, %x\n",
				   sts, desc->status, rxstatus);
				   sts, csrrd8(desc, sgdma_descroffs(status)),
				   rxstatus);
		}
	} else if (sts == 0) {
		pktsrx = sgdma_async_read(priv);
		sgdma_async_read(priv);
	}

	return rxstatus;
@@ -309,8 +303,8 @@ u32 sgdma_rx_status(struct altera_tse_private *priv)


/* Private functions */
static void sgdma_setup_descrip(struct sgdma_descrip *desc,
				struct sgdma_descrip *ndesc,
static void sgdma_setup_descrip(struct sgdma_descrip __iomem *desc,
				struct sgdma_descrip __iomem *ndesc,
				dma_addr_t ndesc_phys,
				dma_addr_t raddr,
				dma_addr_t waddr,
@@ -320,27 +314,30 @@ static void sgdma_setup_descrip(struct sgdma_descrip *desc,
				int wfixed)
{
	/* Clear the next descriptor as not owned by hardware */
	u32 ctrl = ndesc->control;

	u32 ctrl = csrrd8(ndesc, sgdma_descroffs(control));
	ctrl &= ~SGDMA_CONTROL_HW_OWNED;
	ndesc->control = ctrl;
	csrwr8(ctrl, ndesc, sgdma_descroffs(control));

	ctrl = 0;
	ctrl = SGDMA_CONTROL_HW_OWNED;
	ctrl |= generate_eop;
	ctrl |= rfixed;
	ctrl |= wfixed;

	/* Channel is implicitly zero, initialized to 0 by default */
	csrwr32(lower_32_bits(raddr), desc, sgdma_descroffs(raddr));
	csrwr32(lower_32_bits(waddr), desc, sgdma_descroffs(waddr));

	csrwr32(0, desc, sgdma_descroffs(pad1));
	csrwr32(0, desc, sgdma_descroffs(pad2));
	csrwr32(lower_32_bits(ndesc_phys), desc, sgdma_descroffs(next));

	desc->raddr = raddr;
	desc->waddr = waddr;
	desc->next = lower_32_bits(ndesc_phys);
	desc->control = ctrl;
	desc->status = 0;
	desc->rburst = 0;
	desc->wburst = 0;
	desc->bytes = length;
	desc->bytes_xferred = 0;
	csrwr8(ctrl, desc, sgdma_descroffs(control));
	csrwr8(0, desc, sgdma_descroffs(status));
	csrwr8(0, desc, sgdma_descroffs(wburst));
	csrwr8(0, desc, sgdma_descroffs(rburst));
	csrwr16(length, desc, sgdma_descroffs(bytes));
	csrwr16(0, desc, sgdma_descroffs(bytes_xferred));
}

/* If hardware is busy, don't restart async read.
@@ -351,12 +348,11 @@ static void sgdma_setup_descrip(struct sgdma_descrip *desc,
 */
static int sgdma_async_read(struct altera_tse_private *priv)
{
	struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
	struct sgdma_descrip *descbase =
		(struct sgdma_descrip *)priv->rx_dma_desc;
	struct sgdma_descrip __iomem *descbase =
		(struct sgdma_descrip __iomem *)priv->rx_dma_desc;

	struct sgdma_descrip *cdesc = &descbase[0];
	struct sgdma_descrip *ndesc = &descbase[1];
	struct sgdma_descrip __iomem *cdesc = &descbase[0];
	struct sgdma_descrip __iomem *ndesc = &descbase[1];

	struct tse_buffer *rxbuffer = NULL;

@@ -382,11 +378,13 @@ static int sgdma_async_read(struct altera_tse_private *priv)
					   priv->sgdmadesclen,
					   DMA_TO_DEVICE);

		iowrite32(lower_32_bits(sgdma_rxphysaddr(priv, cdesc)),
			  &csr->next_descrip);
		csrwr32(lower_32_bits(sgdma_rxphysaddr(priv, cdesc)),
			priv->rx_dma_csr,
			sgdma_csroffs(next_descrip));

		iowrite32((priv->rxctrlreg | SGDMA_CTRLREG_START),
			  &csr->control);
		csrwr32((priv->rxctrlreg | SGDMA_CTRLREG_START),
			priv->rx_dma_csr,
			sgdma_csroffs(control));

		return 1;
	}
@@ -395,32 +393,32 @@ static int sgdma_async_read(struct altera_tse_private *priv)
}

static int sgdma_async_write(struct altera_tse_private *priv,
			     struct sgdma_descrip *desc)
			     struct sgdma_descrip __iomem *desc)
{
	struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr;

	if (sgdma_txbusy(priv))
		return 0;

	/* clear control and status */
	iowrite32(0, &csr->control);
	iowrite32(0x1f, &csr->status);
	csrwr32(0, priv->tx_dma_csr, sgdma_csroffs(control));
	csrwr32(0x1f, priv->tx_dma_csr, sgdma_csroffs(status));

	dma_sync_single_for_device(priv->device, priv->txdescphys,
				   priv->sgdmadesclen, DMA_TO_DEVICE);

	iowrite32(lower_32_bits(sgdma_txphysaddr(priv, desc)),
		  &csr->next_descrip);
	csrwr32(lower_32_bits(sgdma_txphysaddr(priv, desc)),
		priv->tx_dma_csr,
		sgdma_csroffs(next_descrip));

	iowrite32((priv->txctrlreg | SGDMA_CTRLREG_START),
		  &csr->control);
	csrwr32((priv->txctrlreg | SGDMA_CTRLREG_START),
		priv->tx_dma_csr,
		sgdma_csroffs(control));

	return 1;
}

static dma_addr_t
sgdma_txphysaddr(struct altera_tse_private *priv,
		 struct sgdma_descrip *desc)
		 struct sgdma_descrip __iomem *desc)
{
	dma_addr_t paddr = priv->txdescmem_busaddr;
	uintptr_t offs = (uintptr_t)desc - (uintptr_t)priv->tx_dma_desc;
@@ -429,7 +427,7 @@ sgdma_txphysaddr(struct altera_tse_private *priv,

static dma_addr_t
sgdma_rxphysaddr(struct altera_tse_private *priv,
		 struct sgdma_descrip *desc)
		 struct sgdma_descrip __iomem *desc)
{
	dma_addr_t paddr = priv->rxdescmem_busaddr;
	uintptr_t offs = (uintptr_t)desc - (uintptr_t)priv->rx_dma_desc;
@@ -518,8 +516,8 @@ queue_rx_peekhead(struct altera_tse_private *priv)
 */
static int sgdma_rxbusy(struct altera_tse_private *priv)
{
	struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
	return ioread32(&csr->status) & SGDMA_STSREG_BUSY;
	return csrrd32(priv->rx_dma_csr, sgdma_csroffs(status))
		       & SGDMA_STSREG_BUSY;
}

/* waits for the tx sgdma to finish it's current operation, returns 0
@@ -528,13 +526,14 @@ static int sgdma_rxbusy(struct altera_tse_private *priv)
static int sgdma_txbusy(struct altera_tse_private *priv)
{
	int delay = 0;
	struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr;

	/* if DMA is busy, wait for current transactino to finish */
	while ((ioread32(&csr->status) & SGDMA_STSREG_BUSY) && (delay++ < 100))
	while ((csrrd32(priv->tx_dma_csr, sgdma_csroffs(status))
		& SGDMA_STSREG_BUSY) && (delay++ < 100))
		udelay(1);

	if (ioread32(&csr->status) & SGDMA_STSREG_BUSY) {
	if (csrrd32(priv->tx_dma_csr, sgdma_csroffs(status))
	    & SGDMA_STSREG_BUSY) {
		netdev_err(priv->dev, "timeout waiting for tx dma\n");
		return 1;
	}
+14 −12
Original line number Diff line number Diff line
@@ -19,16 +19,16 @@

/* SGDMA descriptor structure */
struct sgdma_descrip {
	unsigned int	raddr; /* address of data to be read */
	unsigned int	pad1;
	unsigned int	waddr;
	unsigned int    pad2;
	unsigned int	next;
	unsigned int	pad3;
	unsigned short  bytes;
	unsigned char   rburst;
	unsigned char	wburst;
	unsigned short	bytes_xferred;	/* 16 bits, bytes xferred */
	u32	raddr; /* address of data to be read */
	u32	pad1;
	u32	waddr;
	u32	pad2;
	u32	next;
	u32	pad3;
	u16	bytes;
	u8	rburst;
	u8	wburst;
	u16	bytes_xferred;	/* 16 bits, bytes xferred */

	/* bit 0: error
	 * bit 1: length error
@@ -39,7 +39,7 @@ struct sgdma_descrip {
	 * bit 6: reserved
	 * bit 7: status eop for recv case
	 */
	unsigned char	status;
	u8	status;

	/* bit 0: eop
	 * bit 1: read_fixed
@@ -47,7 +47,7 @@ struct sgdma_descrip {
	 * bits 3,4,5,6: Channel (always 0)
	 * bit 7: hardware owned
	 */
	unsigned char	control;
	u8	control;
} __packed;


@@ -101,6 +101,8 @@ struct sgdma_csr {
	u32	pad3[3];
};

#define sgdma_csroffs(a) (offsetof(struct sgdma_csr, a))
#define sgdma_descroffs(a) (offsetof(struct sgdma_descrip, a))

#define SGDMA_STSREG_ERR	BIT(0) /* Error */
#define SGDMA_STSREG_EOP	BIT(1) /* EOP */
Loading