]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - doc/README.drivers.eth
tpm: tpm_tis_i2c: Drop unnecessary methods
[karo-tx-uboot.git] / doc / README.drivers.eth
index e73e462c8c2ae5a1f53a0af419ae25e4d4ad1aab..1a9a23b51b92443e076da9468831ed3352f2b0cf 100644 (file)
@@ -1,3 +1,9 @@
+!!! WARNING !!!
+
+This guide describes to the old way of doing things. No new Ethernet drivers
+should be implemented this way. All new drivers should be written against the
+U-Boot core driver model. See doc/driver-model/README.txt
+
 -----------------------
  Ethernet Driver Guide
 -----------------------
@@ -43,15 +49,16 @@ int ape_register(bd_t *bis, int iobase)
 {
        struct ape_priv *priv;
        struct eth_device *dev;
+       struct mii_dev *bus;
 
        priv = malloc(sizeof(*priv));
        if (priv == NULL)
-               return 1;
+               return -ENOMEM;
 
        dev = malloc(sizeof(*dev));
        if (dev == NULL) {
                free(priv);
-               return 1;
+               return -ENOMEM;
        }
 
        /* setup whatever private state you need */
@@ -59,7 +66,8 @@ int ape_register(bd_t *bis, int iobase)
        memset(dev, 0, sizeof(*dev));
        sprintf(dev->name, "APE");
 
-       /* if your device has dedicated hardware storage for the
+       /*
+        * if your device has dedicated hardware storage for the
         * MAC, read it and initialize dev->enetaddr with it
         */
        ape_mac_read(dev->enetaddr);
@@ -70,11 +78,21 @@ int ape_register(bd_t *bis, int iobase)
        dev->halt = ape_halt;
        dev->send = ape_send;
        dev->recv = ape_recv;
+       dev->write_hwaddr = ape_write_hwaddr;
 
        eth_register(dev);
 
-#ifdef CONFIG_CMD_MII)
-       miiphy_register(dev->name, ape_mii_read, ape_mii_write);
+#ifdef CONFIG_PHYLIB
+       bus = mdio_alloc();
+       if (!bus) {
+               free(priv);
+               free(dev);
+               return -ENOMEM;
+       }
+
+       bus->read = ape_mii_read;
+       bus->write = ape_mii_write;
+       mdio_register(bus);
 #endif
 
        return 1;
@@ -102,11 +120,12 @@ not checking its state or doing random probing.
  -----------
 
 Now that we've registered with the ethernet layer, we can start getting some
-real work done.  You will need four functions:
+real work done.  You will need five functions:
        int ape_init(struct eth_device *dev, bd_t *bis);
        int ape_send(struct eth_device *dev, volatile void *packet, int length);
        int ape_recv(struct eth_device *dev);
        int ape_halt(struct eth_device *dev);
+       int ape_write_hwaddr(struct eth_device *dev);
 
 The init function checks the hardware (probing/identifying) and gets it ready
 for send/recv operations.  You often do things here such as resetting the MAC
@@ -122,19 +141,21 @@ function can be called multiple times in a row.
 
 The recv function should process packets as long as the hardware has them
 readily available before returning.  i.e. you should drain the hardware fifo.
-The common code sets up packet buffers for you already (NetRxPackets), so there
-is no need to allocate your own.  For each packet you receive, you should call
-the NetReceive() function on it with the packet length.  So the pseudo code
-here would look something like:
+For each packet you receive, you should call the net_process_received_packet() function on it
+along with the packet length.  The common code sets up packet buffers for you
+already in the .bss (net_rx_packets), so there should be no need to allocate your
+own.  This doesn't mean you must use the net_rx_packets array however; you're
+free to call the net_process_received_packet() function with any buffer you wish.  So the pseudo
+code here would look something like:
 int ape_recv(struct eth_device *dev)
 {
        int length, i = 0;
        ...
        while (packets_are_available()) {
                ...
-               length = ape_get_packet(&NetRxPackets[i]);
+               length = ape_get_packet(&net_rx_packets[i]);
                ...
-               NetReceive(&NetRxPackets[i], length);
+               net_process_received_packet(&net_rx_packets[i], length);
                ...
                if (++i >= PKTBUFSRX)
                        i = 0;
@@ -145,7 +166,11 @@ int ape_recv(struct eth_device *dev)
 }
 
 The halt function should turn off / disable the hardware and place it back in
-its reset state.
+its reset state.  It can be called at any time (before any call to the related
+init function), so make sure it can handle this sort of thing.
+
+The write_hwaddr function should program the MAC address stored in dev->enetaddr
+into the Ethernet controller.
 
 So the call graph at this stage would look something like:
 some net operation (ping / tftp / whatever...)
@@ -158,25 +183,33 @@ some net operation (ping / tftp / whatever...)
        eth_halt()
                dev->halt()
 
------------------------------
- CONFIG_MII / CONFIG_CMD_MII
------------------------------
+--------------------------------
+ CONFIG_PHYLIB / CONFIG_CMD_MII
+--------------------------------
 
 If your device supports banging arbitrary values on the MII bus (pretty much
 every device does), you should add support for the mii command.  Doing so is
 fairly trivial and makes debugging mii issues a lot easier at runtime.
 
 After you have called eth_register() in your driver's register function, add
-a call to miiphy_register() like so:
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
-       miiphy_register(dev->name, mii_read, mii_write);
-#endif
+a call to mdio_alloc() and mdio_register() like so:
+       bus = mdio_alloc();
+       if (!bus) {
+               free(priv);
+               free(dev);
+               return -ENOMEM;
+       }
+
+       bus->read = ape_mii_read;
+       bus->write = ape_mii_write;
+       mdio_register(bus);
 
 And then define the mii_read and mii_write functions if you haven't already.
 Their syntax is straightforward:
-       int mii_read(char *devname, uchar addr, uchar reg, ushort *val);
-       int mii_write(char *devname, uchar addr, uchar reg, ushort val);
+       int mii_read(struct mii_dev *bus, int addr, int devad, int reg);
+       int mii_write(struct mii_dev *bus, int addr, int devad, int reg,
+                     u16 val);
 
 The read function should read the register 'reg' from the phy at address 'addr'
-and store the result in the pointer 'val'.  The implementation for the write
-function should logically follow.
+and return the result to its caller.  The implementation for the write function
+should logically follow.