[U-Boot] [PATCH 1/2] drivers/net/designware, do an explicit memory access instead of implicit, re-written assignments to use readl() and writel(), all of this as preperation for making the driver able to work in a cached environment (I$D$ support).

Vipin Kumar vipin.kumar at st.com
Wed Jan 23 06:29:21 CET 2013


Provide a short patch title and a longer description in the patch 
itself. that would be much more readable

On 1/22/2013 7:40 PM, Frank Dols wrote:
> Signed-off-by: Frank Dols<frank.dols at synopsys.com>
> ---
>   drivers/net/designware.c |  108 +++++++++++++++++++++++++++-------------------
>   drivers/net/designware.h |    4 +-
>   2 files changed, 66 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/net/designware.c b/drivers/net/designware.c
> index bf21a08..2f235d5 100644
> --- a/drivers/net/designware.c
> +++ b/drivers/net/designware.c
> @@ -44,29 +44,36 @@ static void tx_descs_init(struct eth_device *dev)
>   	struct dmamacdescr *desc_p;
>   	u32 idx;
>
> +	txbuffs = (char *) ((((unsigned long) txbuffs) +
> +		CONFIG_SYS_CACHELINE_SIZE)&
> +		(~(CONFIG_SYS_CACHELINE_SIZE - 1)));
> +
>   	for (idx = 0; idx<  CONFIG_TX_DESCR_NUM; idx++) {
>   		desc_p =&desc_table_p[idx];
> -		desc_p->dmamac_addr =&txbuffs[idx * CONFIG_ETH_BUFSIZE];
> -		desc_p->dmamac_next =&desc_table_p[idx + 1];
> +
> +		writel((ulong)&txbuffs[(idx * CONFIG_ETH_BUFSIZE)],
> +			&desc_p->dmamac_addr);
> +		writel((ulong)&desc_table_p[idx + 1],&desc_p->dmamac_next);
>

My first feeling is that the descriptors are allocated as Normal 
Cachabale memory and it would not help to access them using readl/writel

Should the desciptors be allocated as non-cachable memory. If yes then 
how to do that in u-boot

I suppose the rest of the code would be better reviewed if we know about 
this

Vipin

>   #if defined(CONFIG_DW_ALTDESCRIPTOR)
> -		desc_p->txrx_status&= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
> -				DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \
> -				DESC_TXSTS_TXCHECKINSCTRL | \
> -				DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
> -
> -		desc_p->txrx_status |= DESC_TXSTS_TXCHAIN;
> -		desc_p->dmamac_cntl = 0;
> -		desc_p->txrx_status&= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
> +		writel(readl(&desc_p->txrx_status)&  ~(DESC_TXSTS_TXINT |
> +			DESC_TXSTS_TXLAST | DESC_TXSTS_TXFIRST |
> +			DESC_TXSTS_TXCRCDIS | DESC_TXSTS_TXCHECKINSCTRL |
> +			DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS),
> +			&desc_p->txrx_status);
> +		writel(readl(&desc_p->txrx_status) | DESC_TXSTS_TXCHAIN,
> +			&desc_p->txrx_status);
> +		writel(0,&desc_p->dmamac_cntl);
> +		writel(readl(&desc_p->txrx_status)&  ~(DESC_TXSTS_MSK |
> +			DESC_TXSTS_OWNBYDMA),&desc_p->txrx_status);
>   #else
> -		desc_p->dmamac_cntl = DESC_TXCTRL_TXCHAIN;
> -		desc_p->txrx_status = 0;
> +		writel(DESC_TXCTRL_TXCHAIN,&desc_p->dmamac_cntl);
> +		writel(0,&desc_p->txrx_status);
>   #endif
>   	}
>
>   	/* Correcting the last pointer of the chain */
> -	desc_p->dmamac_next =&desc_table_p[0];
> -
> +	writel((ulong)&desc_table_p[0],&desc_p->dmamac_next);
>   	writel((ulong)&desc_table_p[0],&dma_p->txdesclistaddr);
>   }
>
> @@ -79,21 +86,23 @@ static void rx_descs_init(struct eth_device *dev)
>   	struct dmamacdescr *desc_p;
>   	u32 idx;
>
> +	rxbuffs = (char *) ((((unsigned long) rxbuffs) +
> +		CONFIG_SYS_CACHELINE_SIZE)&
> +		(~(CONFIG_SYS_CACHELINE_SIZE - 1)));
> +
>   	for (idx = 0; idx<  CONFIG_RX_DESCR_NUM; idx++) {
>   		desc_p =&desc_table_p[idx];
> -		desc_p->dmamac_addr =&rxbuffs[idx * CONFIG_ETH_BUFSIZE];
> -		desc_p->dmamac_next =&desc_table_p[idx + 1];
>
> -		desc_p->dmamac_cntl =
> -			(MAC_MAX_FRAME_SZ&  DESC_RXCTRL_SIZE1MASK) | \
> -				      DESC_RXCTRL_RXCHAIN;
> -
> -		desc_p->txrx_status = DESC_RXSTS_OWNBYDMA;
> +		writel((ulong)&rxbuffs[idx * CONFIG_ETH_BUFSIZE],
> +			&desc_p->dmamac_addr);
> +		writel((ulong)&desc_table_p[idx + 1],&desc_p->dmamac_next);
> +		writel((MAC_MAX_FRAME_SZ&  DESC_RXCTRL_SIZE1MASK) |
> +			DESC_RXCTRL_RXCHAIN,&desc_p->dmamac_cntl);
> +		writel(DESC_RXSTS_OWNBYDMA,&desc_p->txrx_status);
>   	}
>
>   	/* Correcting the last pointer of the chain */
> -	desc_p->dmamac_next =&desc_table_p[0];
> -
> +	writel((ulong)&desc_table_p[0],&desc_p->dmamac_next);
>   	writel((ulong)&desc_table_p[0],&dma_p->rxdesclistaddr);
>   }
>
> @@ -134,7 +143,7 @@ static int dw_write_hwaddr(struct eth_device *dev)
>   	u32 macid_lo, macid_hi;
>   	u8 *mac_id =&dev->enetaddr[0];
>
> -	macid_lo = mac_id[0] + (mac_id[1]<<  8) + \
> +	macid_lo = mac_id[0] + (mac_id[1]<<  8) +
>   		   (mac_id[2]<<  16) + (mac_id[3]<<  24);
>   	macid_hi = mac_id[4] + (mac_id[5]<<  8);
>
> @@ -198,7 +207,6 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis)
>   	 */
>   	writel(readl(&dma_p->opmode) | RXSTART,&dma_p->opmode);
>   	writel(readl(&dma_p->opmode) | TXSTART,&dma_p->opmode);
> -
>   	writel(readl(&mac_p->conf) | RXENABLE | TXENABLE,&mac_p->conf);
>
>   	return 0;
> @@ -212,26 +220,27 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
>   	struct dmamacdescr *desc_p =&priv->tx_mac_descrtable[desc_num];
>
>   	/* Check if the descriptor is owned by CPU */
> -	if (desc_p->txrx_status&  DESC_TXSTS_OWNBYDMA) {
> +	if (readl(&desc_p->txrx_status)&  DESC_TXSTS_OWNBYDMA) {
>   		printf("CPU not owner of tx frame\n");
>   		return -1;
>   	}
>
> -	memcpy((void *)desc_p->dmamac_addr, packet, length);
> +	memcpy((void *)readl(&desc_p->dmamac_addr), packet, length);
>
>   #if defined(CONFIG_DW_ALTDESCRIPTOR)
> -	desc_p->txrx_status |= DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST;
> -	desc_p->dmamac_cntl |= (length<<  DESC_TXCTRL_SIZE1SHFT)&  \
> -			       DESC_TXCTRL_SIZE1MASK;
> -
> -	desc_p->txrx_status&= ~(DESC_TXSTS_MSK);
> -	desc_p->txrx_status |= DESC_TXSTS_OWNBYDMA;
> +	writel(readl(&desc_p->txrx_status) | DESC_TXSTS_TXFIRST |
> +		DESC_TXSTS_TXLAST,&desc_p->txrx_status);
> +	writel(readl(&desc_p->dmamac_cntl) | (length<<  DESC_TXCTRL_SIZE1SHFT)
> +		&  DESC_TXCTRL_SIZE1MASK,&desc_p->dmamac_cntl);
> +	writel(readl(&desc_p->txrx_status)&  ~(DESC_TXSTS_MSK),
> +		&desc_p->txrx_status);
> +	writel(readl(&desc_p->txrx_status) | DESC_TXSTS_OWNBYDMA,
> +		&desc_p->txrx_status);
>   #else
> -	desc_p->dmamac_cntl |= ((length<<  DESC_TXCTRL_SIZE1SHFT)&  \
> -			       DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST | \
> -			       DESC_TXCTRL_TXFIRST;
> -
> -	desc_p->txrx_status = DESC_TXSTS_OWNBYDMA;
> +	writel(readl(&desc_p->dmamac_cntl) | ((length<<  DESC_TXCTRL_SIZE1SHFT)
> +		&  DESC_TXCTRL_SIZE1MASK) | DESC_TXCTRL_TXLAST |
> +		DESC_TXCTRL_TXFIRST,&desc_p->dmamac_cntl);
> +	writel(DESC_TXSTS_OWNBYDMA,&desc_p->txrx_status);
>   #endif
>
>   	/* Test the wrap-around condition. */
> @@ -240,6 +249,8 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
>
>   	priv->tx_currdescnum = desc_num;
>
> +	wmb(); /* write memory barrier */
> +
>   	/* Start the transmission */
>   	writel(POLL_DATA,&dma_p->txpolldemand);
>
> @@ -252,22 +263,28 @@ static int dw_eth_recv(struct eth_device *dev)
>   	u32 desc_num = priv->rx_currdescnum;
>   	struct dmamacdescr *desc_p =&priv->rx_mac_descrtable[desc_num];
>
> -	u32 status = desc_p->txrx_status;
> +	u32 status;
>   	int length = 0;
> +	int timeout = 30;
> +
> +	do {
> +		status = readl(&desc_p->txrx_status);
> +	} while ((status&  DESC_RXSTS_OWNBYDMA)&&  (timeout-->  0));
>
>   	/* Check  if the owner is the CPU */
>   	if (!(status&  DESC_RXSTS_OWNBYDMA)) {
>
> -		length = (status&  DESC_RXSTS_FRMLENMSK)>>  \
> +		length = (status&  DESC_RXSTS_FRMLENMSK)>>
>   			DESC_RXSTS_FRMLENSHFT;
>
> -		NetReceive(desc_p->dmamac_addr, length);
> +		NetReceive(readl(&desc_p->dmamac_addr), length);
>
>   		/*
>   		 * Make the current descriptor valid again and go to
>   		 * the next one
>   		 */
> -		desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
> +		writel(readl(&desc_p->txrx_status) | DESC_RXSTS_OWNBYDMA,
> +			&desc_p->txrx_status);
>
>   		/* Test the wrap-around condition. */
>   		if (++desc_num>= CONFIG_RX_DESCR_NUM)
> @@ -295,12 +312,13 @@ static int eth_mdio_read(struct eth_device *dev, u8 addr, u8 reg, u16 *val)
>   	u32 miiaddr;
>   	int timeout = CONFIG_MDIO_TIMEOUT;
>
> -	miiaddr = ((addr<<  MIIADDRSHIFT)&  MII_ADDRMSK) | \
> +	miiaddr = ((addr<<  MIIADDRSHIFT)&  MII_ADDRMSK) |
>   		  ((reg<<  MIIREGSHIFT)&  MII_REGMSK);
>
>   	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY,&mac_p->miiaddr);
>
>   	start = get_timer(0);
> +
>   	while (get_timer(start)<  timeout) {
>   		if (!(readl(&mac_p->miiaddr)&  MII_BUSY)) {
>   			*val = readl(&mac_p->miidata);
> @@ -324,7 +342,7 @@ static int eth_mdio_write(struct eth_device *dev, u8 addr, u8 reg, u16 val)
>   	u16 value;
>
>   	writel(val,&mac_p->miidata);
> -	miiaddr = ((addr<<  MIIADDRSHIFT)&  MII_ADDRMSK) | \
> +	miiaddr = ((addr<<  MIIADDRSHIFT)&  MII_ADDRMSK) |
>   		  ((reg<<  MIIREGSHIFT)&  MII_REGMSK) | MII_WRITE;
>
>   	writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY,&mac_p->miiaddr);
> @@ -469,6 +487,7 @@ static int configure_phy(struct eth_device *dev)
>   #if defined(CONFIG_DW_AUTONEG)
>   	timeout = CONFIG_AUTONEG_TIMEOUT;
>   	start = get_timer(0);
> +
>   	puts("Waiting for PHY auto negotiation to complete");
>   	while (get_timer(start)<  timeout) {
>   		eth_mdio_read(dev, phy_addr, MII_BMSR,&bmsr);
> @@ -570,5 +589,6 @@ int designware_initialize(u32 id, ulong base_addr, u32 phy_addr, u32 interface)
>   #if defined(CONFIG_MII)
>   	miiphy_register(dev->name, dw_mii_read, dw_mii_write);
>   #endif
> +
>   	return 1;
>   }
> diff --git a/drivers/net/designware.h b/drivers/net/designware.h
> index d668f8f..2eeb52f 100644
> --- a/drivers/net/designware.h
> +++ b/drivers/net/designware.h
> @@ -246,8 +246,8 @@ struct dw_eth_dev {
>   	struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM];
>   	struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM];
>
> -	char txbuffs[TX_TOTAL_BUFSIZE];
> -	char rxbuffs[RX_TOTAL_BUFSIZE];
> +	char txbuffs[TX_TOTAL_BUFSIZE + CONFIG_SYS_CACHELINE_SIZE];
> +	char rxbuffs[RX_TOTAL_BUFSIZE + CONFIG_SYS_CACHELINE_SIZE];
>
>   	struct eth_mac_regs *mac_regs_p;
>   	struct eth_dma_regs *dma_regs_p;



More information about the U-Boot mailing list