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 Original line Diff line number Diff line
@@ -5,3 +5,4 @@
obj-$(CONFIG_ALTERA_TSE) += altera_tse.o
obj-$(CONFIG_ALTERA_TSE) += altera_tse.o
altera_tse-objs := altera_tse_main.o altera_tse_ethtool.o \
altera_tse-objs := altera_tse_main.o altera_tse_ethtool.o \
altera_msgdma.o altera_sgdma.o altera_utils.o
altera_msgdma.o altera_sgdma.o altera_utils.o
ccflags-y += -D__CHECK_ENDIAN__
+55 −55
Original line number Original line 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)
void msgdma_reset(struct altera_tse_private *priv)
{
{
	int counter;
	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 */
	/* Reset Rx mSGDMA */
	iowrite32(MSGDMA_CSR_STAT_MASK, &rxcsr->status);
	csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr,
	iowrite32(MSGDMA_CSR_CTL_RESET, &rxcsr->control);
		msgdma_csroffs(status));
	csrwr32(MSGDMA_CSR_CTL_RESET, priv->rx_dma_csr,
		msgdma_csroffs(control));


	counter = 0;
	counter = 0;
	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
	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))
				     MSGDMA_CSR_STAT_RESETTING))
			break;
			break;
		udelay(1);
		udelay(1);
@@ -59,15 +57,18 @@ void msgdma_reset(struct altera_tse_private *priv)
			   "TSE Rx mSGDMA resetting bit never cleared!\n");
			   "TSE Rx mSGDMA resetting bit never cleared!\n");


	/* clear all status bits */
	/* 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 */
	/* Reset Tx mSGDMA */
	iowrite32(MSGDMA_CSR_STAT_MASK, &txcsr->status);
	csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr,
	iowrite32(MSGDMA_CSR_CTL_RESET, &txcsr->control);
		msgdma_csroffs(status));

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


	counter = 0;
	counter = 0;
	while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) {
	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))
				     MSGDMA_CSR_STAT_RESETTING))
			break;
			break;
		udelay(1);
		udelay(1);
@@ -78,58 +79,58 @@ void msgdma_reset(struct altera_tse_private *priv)
			   "TSE Tx mSGDMA resetting bit never cleared!\n");
			   "TSE Tx mSGDMA resetting bit never cleared!\n");


	/* clear all status bits */
	/* 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)
void msgdma_disable_rxirq(struct altera_tse_private *priv)
{
{
	struct msgdma_csr *csr = priv->rx_dma_csr;
	tse_clear_bit(priv->rx_dma_csr, msgdma_csroffs(control),
	tse_clear_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR);
		      MSGDMA_CSR_CTL_GLOBAL_INTR);
}
}


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


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


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


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


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


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

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


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


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


	iowrite32(0, &desc->read_addr_lo);
	csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_lo));
	iowrite32(0, &desc->read_addr_hi);
	csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_hi));
	iowrite32(lower_32_bits(dma_addr), &desc->write_addr_lo);
	csrwr32(lower_32_bits(dma_addr), priv->rx_dma_desc,
	iowrite32(upper_32_bits(dma_addr), &desc->write_addr_hi);
		msgdma_descroffs(write_addr_lo));
	iowrite32(len, &desc->len);
	csrwr32(upper_32_bits(dma_addr), priv->rx_dma_desc,
	iowrite32(0, &desc->burst_seq_num);
		msgdma_descroffs(write_addr_hi));
	iowrite32(0x00010001, &desc->stride);
	csrwr32(len, priv->rx_dma_desc, msgdma_descroffs(len));
	iowrite32(control, &desc->control);
	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,
/* status is returned on upper 16 bits,
@@ -190,14 +191,13 @@ u32 msgdma_rx_status(struct altera_tse_private *priv)
	u32 rxstatus = 0;
	u32 rxstatus = 0;
	u32 pktlength;
	u32 pktlength;
	u32 pktstatus;
	u32 pktstatus;
	struct msgdma_csr *rxcsr =

		(struct msgdma_csr *)priv->rx_dma_csr;
	if (csrrd32(priv->rx_dma_csr, msgdma_csroffs(resp_fill_level))
	struct msgdma_response *rxresp =
	    & 0xffff) {
		(struct msgdma_response *)priv->rx_dma_resp;
		pktlength = csrrd32(priv->rx_dma_resp,

				    msgdma_respoffs(bytes_transferred));
	if (ioread32(&rxcsr->resp_fill_level) & 0xffff) {
		pktstatus = csrrd32(priv->rx_dma_resp,
		pktlength = ioread32(&rxresp->bytes_transferred);
				    msgdma_respoffs(status));
		pktstatus = ioread32(&rxresp->status);
		rxstatus = pktstatus;
		rxstatus = pktstatus;
		rxstatus = rxstatus << 16;
		rxstatus = rxstatus << 16;
		rxstatus |= (pktlength & 0xffff);
		rxstatus |= (pktlength & 0xffff);
+4 −9
Original line number Original line Diff line number Diff line
@@ -17,15 +17,6 @@
#ifndef __ALTERA_MSGDMAHW_H__
#ifndef __ALTERA_MSGDMAHW_H__
#define __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
/* mSGDMA extended descriptor format
 */
 */
struct msgdma_extended_desc {
struct msgdma_extended_desc {
@@ -159,6 +150,10 @@ struct msgdma_response {
	u32 status;
	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
/* mSGDMA response register bit definitions
 */
 */
#define MSGDMA_RESP_EARLY_TERM	BIT(8)
#define MSGDMA_RESP_EARLY_TERM	BIT(8)
+90 −91
Original line number Original line Diff line number Diff line
@@ -20,8 +20,8 @@
#include "altera_sgdmahw.h"
#include "altera_sgdmahw.h"
#include "altera_sgdma.h"
#include "altera_sgdma.h"


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


static int sgdma_async_write(struct altera_tse_private *priv,
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 int sgdma_async_read(struct altera_tse_private *priv);


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


static dma_addr_t
static dma_addr_t
sgdma_rxphysaddr(struct altera_tse_private *priv,
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);
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->rxdescphys = (dma_addr_t) 0;
	priv->txdescphys = (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);
					  priv->rxdescmem, DMA_BIDIRECTIONAL);


	if (dma_mapping_error(priv->device, priv->rxdescphys)) {
	if (dma_mapping_error(priv->device, priv->rxdescphys)) {
@@ -88,7 +89,8 @@ int sgdma_initialize(struct altera_tse_private *priv)
		return -EINVAL;
		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);
					  priv->txdescmem, DMA_TO_DEVICE);


	if (dma_mapping_error(priv->device, priv->txdescphys)) {
	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 */
	/* Initialize descriptor memory to all 0's, sync memory to cache */
	memset(priv->tx_dma_desc, 0, priv->txdescmem);
	memset_io(priv->tx_dma_desc, 0, priv->txdescmem);
	memset(priv->rx_dma_desc, 0, priv->rxdescmem);
	memset_io(priv->rx_dma_desc, 0, priv->rxdescmem);


	dma_sync_single_for_device(priv->device, priv->txdescphys,
	dma_sync_single_for_device(priv->device, priv->txdescphys,
				   priv->txdescmem, DMA_TO_DEVICE);
				   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)
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 */
	/* Initialize descriptor memory to 0 */
	memset(ptxdescripmem, 0, txdescriplen);
	memset_io(priv->tx_dma_desc, 0, priv->txdescmem);
	memset(prxdescripmem, 0, rxdescriplen);
	memset_io(priv->rx_dma_desc, 0, priv->rxdescmem);


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


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


/* For SGDMA, interrupts remain enabled after initially enabling,
/* 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)
void sgdma_clear_rxirq(struct altera_tse_private *priv)
{
{
	struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
	tse_set_bit(priv->rx_dma_csr, sgdma_csroffs(control),
	tse_set_bit(&csr->control, SGDMA_CTRLREG_CLRINT);
		    SGDMA_CTRLREG_CLRINT);
}
}


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


/* transmits buffer through SGDMA. Returns number of buffers
/* 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 sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
{
{
	int pktstx = 0;
	struct sgdma_descrip __iomem *descbase =
	struct sgdma_descrip *descbase =
		(struct sgdma_descrip __iomem *)priv->tx_dma_desc;
		(struct sgdma_descrip *)priv->tx_dma_desc;


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


	/* wait 'til the tx sgdma is ready for the next transmit request */
	/* wait 'til the tx sgdma is ready for the next transmit request */
	if (sgdma_txbusy(priv))
	if (sgdma_txbusy(priv))
@@ -205,7 +199,7 @@ int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
			    0,				/* read fixed */
			    0,				/* read fixed */
			    SGDMA_CONTROL_WR_FIXED);	/* Generate SOP */
			    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 */
	/* enqueue the request to the pending transmit queue */
	queue_tx(priv, buffer);
	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 sgdma_tx_completions(struct altera_tse_private *priv)
{
{
	u32 ready = 0;
	u32 ready = 0;
	struct sgdma_descrip *desc = (struct sgdma_descrip *)priv->tx_dma_desc;


	if (!sgdma_txbusy(priv) &&
	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))) {
	    (dequeue_tx(priv))) {
		ready = 1;
		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)
u32 sgdma_rx_status(struct altera_tse_private *priv)
{
{
	struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
	struct sgdma_descrip __iomem *base =
	struct sgdma_descrip *base = (struct sgdma_descrip *)priv->rx_dma_desc;
		(struct sgdma_descrip __iomem *)priv->rx_dma_desc;
	struct sgdma_descrip *desc = NULL;
	struct sgdma_descrip __iomem *desc = NULL;
	int pktsrx;
	unsigned int rxstatus = 0;
	unsigned int pktlength = 0;
	unsigned int pktstatus = 0;
	struct tse_buffer *rxbuffer = 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];
	desc = &base[0];
	if (sts & SGDMA_STSREG_EOP) {
	if (sts & SGDMA_STSREG_EOP) {
		unsigned int pktlength = 0;
		unsigned int pktstatus = 0;
		dma_sync_single_for_cpu(priv->device,
		dma_sync_single_for_cpu(priv->device,
					priv->rxdescphys,
					priv->rxdescphys,
					priv->sgdmadesclen,
					priv->sgdmadesclen,
					DMA_FROM_DEVICE);
					DMA_FROM_DEVICE);


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


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


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


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


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


		} else {
		} else {
			/* If the SGDMA indicated an end of packet on recv,
			/* 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,
			netdev_err(priv->dev,
				   "SGDMA RX Error Info: %x, %x, %x\n",
				   "SGDMA RX Error Info: %x, %x, %x\n",
				   sts, desc->status, rxstatus);
				   sts, csrrd8(desc, sgdma_descroffs(status)),
				   rxstatus);
		}
		}
	} else if (sts == 0) {
	} else if (sts == 0) {
		pktsrx = sgdma_async_read(priv);
		sgdma_async_read(priv);
	}
	}


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




/* Private functions */
/* Private functions */
static void sgdma_setup_descrip(struct sgdma_descrip *desc,
static void sgdma_setup_descrip(struct sgdma_descrip __iomem *desc,
				struct sgdma_descrip *ndesc,
				struct sgdma_descrip __iomem *ndesc,
				dma_addr_t ndesc_phys,
				dma_addr_t ndesc_phys,
				dma_addr_t raddr,
				dma_addr_t raddr,
				dma_addr_t waddr,
				dma_addr_t waddr,
@@ -320,27 +314,30 @@ static void sgdma_setup_descrip(struct sgdma_descrip *desc,
				int wfixed)
				int wfixed)
{
{
	/* Clear the next descriptor as not owned by hardware */
	/* 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;
	ctrl &= ~SGDMA_CONTROL_HW_OWNED;
	ndesc->control = ctrl;
	csrwr8(ctrl, ndesc, sgdma_descroffs(control));


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


	/* Channel is implicitly zero, initialized to 0 by default */
	/* 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;
	csrwr8(ctrl, desc, sgdma_descroffs(control));
	desc->waddr = waddr;
	csrwr8(0, desc, sgdma_descroffs(status));
	desc->next = lower_32_bits(ndesc_phys);
	csrwr8(0, desc, sgdma_descroffs(wburst));
	desc->control = ctrl;
	csrwr8(0, desc, sgdma_descroffs(rburst));
	desc->status = 0;
	csrwr16(length, desc, sgdma_descroffs(bytes));
	desc->rburst = 0;
	csrwr16(0, desc, sgdma_descroffs(bytes_xferred));
	desc->wburst = 0;
	desc->bytes = length;
	desc->bytes_xferred = 0;
}
}


/* If hardware is busy, don't restart async read.
/* 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)
static int sgdma_async_read(struct altera_tse_private *priv)
{
{
	struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
	struct sgdma_descrip __iomem *descbase =
	struct sgdma_descrip *descbase =
		(struct sgdma_descrip __iomem *)priv->rx_dma_desc;
		(struct sgdma_descrip *)priv->rx_dma_desc;


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


	struct tse_buffer *rxbuffer = NULL;
	struct tse_buffer *rxbuffer = NULL;


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


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


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


		return 1;
		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,
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))
	if (sgdma_txbusy(priv))
		return 0;
		return 0;


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


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


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


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


	return 1;
	return 1;
}
}


static dma_addr_t
static dma_addr_t
sgdma_txphysaddr(struct altera_tse_private *priv,
sgdma_txphysaddr(struct altera_tse_private *priv,
		 struct sgdma_descrip *desc)
		 struct sgdma_descrip __iomem *desc)
{
{
	dma_addr_t paddr = priv->txdescmem_busaddr;
	dma_addr_t paddr = priv->txdescmem_busaddr;
	uintptr_t offs = (uintptr_t)desc - (uintptr_t)priv->tx_dma_desc;
	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
static dma_addr_t
sgdma_rxphysaddr(struct altera_tse_private *priv,
sgdma_rxphysaddr(struct altera_tse_private *priv,
		 struct sgdma_descrip *desc)
		 struct sgdma_descrip __iomem *desc)
{
{
	dma_addr_t paddr = priv->rxdescmem_busaddr;
	dma_addr_t paddr = priv->rxdescmem_busaddr;
	uintptr_t offs = (uintptr_t)desc - (uintptr_t)priv->rx_dma_desc;
	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)
static int sgdma_rxbusy(struct altera_tse_private *priv)
{
{
	struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
	return csrrd32(priv->rx_dma_csr, sgdma_csroffs(status))
	return ioread32(&csr->status) & SGDMA_STSREG_BUSY;
		       & SGDMA_STSREG_BUSY;
}
}


/* waits for the tx sgdma to finish it's current operation, returns 0
/* 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)
static int sgdma_txbusy(struct altera_tse_private *priv)
{
{
	int delay = 0;
	int delay = 0;
	struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr;


	/* if DMA is busy, wait for current transactino to finish */
	/* 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);
		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");
		netdev_err(priv->dev, "timeout waiting for tx dma\n");
		return 1;
		return 1;
	}
	}
+14 −12
Original line number Original line Diff line number Diff line
@@ -19,16 +19,16 @@


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


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


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




@@ -101,6 +101,8 @@ struct sgdma_csr {
	u32	pad3[3];
	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_ERR	BIT(0) /* Error */
#define SGDMA_STSREG_EOP	BIT(1) /* EOP */
#define SGDMA_STSREG_EOP	BIT(1) /* EOP */
Loading