Hello,<br><br><div class="gmail_quote">2011/4/10 Jean-Christophe PLAGNIOL-VILLARD <span dir="ltr"><<a href="mailto:plagnioj@jcrosoft.com">plagnioj@jcrosoft.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><div></div><div class="h5">On 16:08 Sat 09 Apr , <a href="mailto:franck.jullien@gmail.com">franck.jullien@gmail.com</a> wrote:<br>
> From: Franck JULLIEN <<a href="mailto:franck.jullien@gmail.com">franck.jullien@gmail.com</a>><br>
><br>
> Add Altera Triple Speed Ethernet driver<br>
><br>
> Signed-off-by: Franck JULLIEN <<a href="mailto:franck.jullien@gmail.com">franck.jullien@gmail.com</a>><br>
> ---<br>
> drivers/net/Kconfig | 16 ++<br>
> drivers/net/Makefile | 5 +-<br>
> drivers/net/altera_tse.c | 620 ++++++++++++++++++++++++++++++++++++++++++++++<br>
> drivers/net/altera_tse.h | 313 +++++++++++++++++++++++<br>
> 4 files changed, 952 insertions(+), 2 deletions(-)<br>
> create mode 100644 drivers/net/altera_tse.c<br>
> create mode 100644 drivers/net/altera_tse.h<br>
><br>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig<br>
> index 6479417..19e35db 100644<br>
> --- a/drivers/net/Kconfig<br>
> +++ b/drivers/net/Kconfig<br>
> @@ -84,6 +84,22 @@ config DRIVER_NET_TAP<br>
> bool "tap Ethernet driver"<br>
> depends on LINUX<br>
><br>
> +config DRIVER_NET_TSE<br>
> + depends on NIOS2<br>
> + bool "Altera TSE ethernet driver"<br>
> + select MIIDEV<br>
> + help<br>
> + This option enables support for the Altera TSE MAC.<br>
> +<br>
> +config TSE_USE_DEDICATED_DESC_MEM<br>
> + depends on DRIVER_NET_TSE<br>
> + bool "Altera TSE uses dedicated descriptor memory"<br>
> + help<br>
> + This option tells the TSE driver to use an onchip memory<br>
> + to store SGDMA descriptors. Descriptor memory is not<br>
> + reserved with a malloc but directly mapped to the memory<br>
> + address (defined in config.h)<br>
> +<br>
> source "drivers/net/usb/Kconfig"<br>
><br>
> endmenu<br>
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile<br>
> index 96d3d32..f02618b 100644<br>
> --- a/drivers/net/Makefile<br>
> +++ b/drivers/net/Makefile<br>
> @@ -1,7 +1,7 @@<br>
> -obj-$(CONFIG_DRIVER_NET_CS8900) += cs8900.o<br>
> +obj-$(CONFIG_DRIVER_NET_CS8900) += cs8900.o<br>
> obj-$(CONFIG_DRIVER_NET_SMC911X) += smc911x.o<br>
> obj-$(CONFIG_DRIVER_NET_SMC91111) += smc91111.o<br>
> -obj-$(CONFIG_DRIVER_NET_DM9000) += dm9000.o<br>
> +obj-$(CONFIG_DRIVER_NET_DM9000) += dm9000.o<br>
</div></div>why do you touch this two?<br>
<br>
if you want to fix the whitespace please do it in an other commit<br></blockquote><div><br></div><div>OK, I'll correct this.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div class="im">> obj-$(CONFIG_DRIVER_NET_NETX) += netx_eth.o<br>
> obj-$(CONFIG_DRIVER_NET_AT91_ETHER) += at91_ether.o<br>
> obj-$(CONFIG_DRIVER_NET_MPC5200) += fec_mpc5200.o<br>
> @@ -11,3 +11,4 @@ obj-$(CONFIG_DRIVER_NET_MACB) += macb.o<br>
> obj-$(CONFIG_DRIVER_NET_TAP) += tap.o<br>
> obj-$(CONFIG_MIIDEV) += miidev.o<br>
> obj-$(CONFIG_NET_USB) += usb/<br>
> +obj-$(CONFIG_DRIVER_NET_TSE) += altera_tse.o<br>
> diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c<br>
> new file mode 100644<br>
> index 0000000..2687377<br>
> --- /dev/null<br>
> +<br>
</div><div class="im">> +static int tse_get_ethaddr(struct eth_device *edev, unsigned char *m)<br>
> +{<br>
> + /* There is no eeprom */<br>
</div>so return the content of the register no?<br></blockquote><div><br></div><div>Well, the register is reseted to 0 when the MAC starts so there is no Ethernet address</div><div>to get.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
> + return -1;<br>
> +}<br>
> +<br>
<div class="im"><br>
> +static int tse_eth_send(struct eth_device *edev, void *packet, int length)<br>
> +{<br>
> +<br>
> + struct altera_tse_priv *priv = edev->priv;<br>
> + struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx;<br>
> + struct alt_sgdma_descriptor *tx_desc = (struct alt_sgdma_descriptor *)priv->tx_desc;<br>
> +<br>
> + struct alt_sgdma_descriptor *tx_desc_cur = (struct alt_sgdma_descriptor *)&tx_desc[0];<br>
> +<br>
> + flush_dcache_range((uint32_t)packet, (uint32_t)packet + length);<br>
> + alt_sgdma_construct_descriptor_burst(<br>
> + (struct alt_sgdma_descriptor *)&tx_desc[0],<br>
> + (struct alt_sgdma_descriptor *)&tx_desc[1],<br>
> + (uint32_t *)packet, /* read addr */<br>
> + (uint32_t *)0, /* */<br>
> + length, /* length or EOP ,will change for each tx */<br>
> + 0x1, /* gen eop */<br>
> + 0x0, /* read fixed */<br>
> + 0x1, /* write fixed or sop */<br>
> + 0x0, /* read burst */<br>
> + 0x0, /* write burst */<br>
> + 0x0 /* channel */<br>
</div>please use tab for indent I see other in the patch please check<br></blockquote><div><br></div><div>I use tab for indent, spaces for alignment. I checked the patch with checkpatch and it</div><div>didn't find errors.....</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><div></div><div class="h5">> + );<br>
> +<br>
> + alt_sgdma_do_sync_transfer(tx_sgdma, tx_desc_cur);<br>
> +<br>
> + return 0;;<br>
> +}<br>
> +<br>
> +static void tse_eth_halt(struct eth_device *edev)<br>
> +{<br>
> + struct altera_tse_priv *priv = edev->priv;<br>
> + struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx;<br>
> + struct alt_sgdma_registers *tx_sgdma = priv->sgdma_tx;<br>
> +<br>
> + writel(0, &rx_sgdma->control); /* Stop the controller and reset settings */<br>
> + writel(0, &tx_sgdma->control); /* Stop the controller and reset settings */<br>
> +}<br>
> +<br>
> +static int tse_eth_rx(struct eth_device *edev)<br>
> +{<br>
> + uint16_t packet_length = 0;<br>
> +<br>
> + struct altera_tse_priv *priv = edev->priv;<br>
> + struct alt_sgdma_descriptor *rx_desc = (struct alt_sgdma_descriptor *)priv->rx_desc;<br>
> + struct alt_sgdma_descriptor *rx_desc_cur = &rx_desc[0];<br>
> + struct alt_sgdma_registers *rx_sgdma = priv->sgdma_rx;<br>
> +<br>
> + if (rx_desc_cur->descriptor_status &<br>
> + ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) {<br>
> +<br>
> + packet_length = rx_desc->actual_bytes_transferred;<br>
> + net_receive(NetRxPackets[0], packet_length);<br>
> +<br>
> + /* Clear Run */<br>
> + rx_sgdma->control = (rx_sgdma->control & (~ALT_SGDMA_CONTROL_RUN_MSK));<br>
> +<br>
> + /* start descriptor again */<br>
> + flush_dcache_range((uint32_t)(NetRxPackets[0]), (uint32_t)(NetRxPackets[0]) + PKTSIZE);<br>
> + alt_sgdma_construct_descriptor_burst(<br>
> + (struct alt_sgdma_descriptor *)&rx_desc[0],<br>
> + (struct alt_sgdma_descriptor *)&rx_desc[1],<br>
> + (uint32_t)0x0, /* read addr */<br>
> + (uint32_t *)NetRxPackets[0], /* */<br>
> + 0x0, /* length or EOP */<br>
> + 0x0, /* gen eop */<br>
> + 0x0, /* read fixed */<br>
> + 0x0, /* write fixed or sop */<br>
> + 0x0, /* read burst */<br>
> + 0x0, /* write burst */<br>
> + 0x0 /* channel */<br>
</div></div>please use tab for indent<br>
<div class="im">> + );<br>
> +<br>
> + /* setup the sgdma */<br>
> + alt_sgdma_do_async_transfer(priv->sgdma_rx, &rx_desc[0]);<br>
> + }<br>
> +<br>
> + return 0;<br>
> +}<br>
> +<br>
> +static char *get_phy_name(uint32_t phy_ID)<br>
> +{<br>
> + uint8_t i = 0;<br>
> +<br>
> + while (phy_name_table[i].phy_ID != 0) {<br>
> + if (phy_name_table[i].phy_ID == phy_ID)<br>
> + return phy_name_table[i].name;<br>
> + i++;<br>
> + }<br>
> +<br>
> + return "unknown";<br>
> +}<br>
</div>why this?<br>
<div class="im">> +<br>
> +static int check_phy_address(struct eth_device *edev)<br>
> +{<br>
> + struct altera_tse_priv *priv = edev->priv;<br>
> + uint8_t mii_bus_scan = 0;<br>
> + uint8_t current_mii_address = 1;<br>
> + uint32_t phy_reg;<br>
> + uint32_t phy_ID;<br>
> +<br>
> + if ((priv->miidev)->address < 0)<br>
> + mii_bus_scan = 1;<br>
> + else<br>
> + current_mii_address = (priv->miidev)->address;<br>
> +<br>
> + do {<br>
> + /* Grab the bits from PHYIR1, and put them in the upper half */<br>
> + phy_reg = tse_phy_read(priv->miidev, current_mii_address, MII_PHYSID1);<br>
> + phy_ID = (phy_reg & 0xffff) << 16;<br>
> +<br>
> + /* Grab the bits from PHYIR2, and put them in the lower half */<br>
> + phy_reg = tse_phy_read(priv->miidev, current_mii_address, MII_PHYSID2);<br>
> + phy_ID |= (phy_reg & 0xffff);<br>
> +<br>
> + if (phy_ID != 0xffffffff) {<br>
> + printf("PHY (%s) found at address %d\n", get_phy_name(phy_ID), current_mii_address);<br>
> + (priv->miidev)->address = current_mii_address;<br>
> + return 0;<br>
> + }<br>
> +<br>
> + current_mii_address++;<br>
> +<br>
> + } while (current_mii_address < 32 && mii_bus_scan);<br>
> +<br>
> + return -1;<br>
> +}<br>
> +<br>
</div>why this?<br></blockquote><div><br></div><div>Because sometimes (often ?), hardware doesn't run first time. So I like to</div><div>have some information on MII bus running correctly....One day I had a PHY</div>
<div>getting the address 1 and sometimes this f***ing PHY got 31 and this</div><div>kind of auto scan helped me to immediately find the problem......</div><div><br></div><div>I could remove those function if it is a problem.... </div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
Best Regards,<br>
<font color="#888888">J.<br>
</font></blockquote></div><br><div>Regards,</div><div>Franck.</div>