[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