Author: gonzo
Date: Wed Feb 22 01:30:25 2012
New Revision: 231987
URL: http://svn.freebsd.org/changeset/base/231987

Log:
  Refctor address assignment for Octeon's ethernet ports:
  
  - Centralize address assignment
  - Make sure managment ports get first MAC address in pool
  - Properly propagate fail if address allocation failed
  
  Submitted by: Andrew Duane <adu...@juniper.net>

Modified:
  head/sys/mips/cavium/files.octeon1
  head/sys/mips/cavium/if_octm.c
  head/sys/mips/cavium/octe/ethernet-common.c
  head/sys/mips/cavium/octe/ethernet-common.h
  head/sys/mips/cavium/octe/ethernet-rgmii.c
  head/sys/mips/cavium/octe/ethernet-sgmii.c
  head/sys/mips/cavium/octe/ethernet-spi.c
  head/sys/mips/cavium/octe/ethernet-xaui.c
  head/sys/mips/cavium/octe/ethernet.c

Modified: head/sys/mips/cavium/files.octeon1
==============================================================================
--- head/sys/mips/cavium/files.octeon1  Wed Feb 22 01:23:14 2012        
(r231986)
+++ head/sys/mips/cavium/files.octeon1  Wed Feb 22 01:30:25 2012        
(r231987)
@@ -24,6 +24,10 @@ mips/cavium/cryptocteon/cryptocteon.c                o
 mips/mips/octeon_cop2_swtch.S                  standard
 mips/mips/octeon_cop2.c                                standard
 
+# octm must be first, so management ports get the first MAC addresses
+mips/cavium/if_octm.c                          optional octm
+contrib/octeon-sdk/cvmx-mgmt-port.c            optional octm
+
 mips/cavium/octe/ethernet.c                    optional octe
 mips/cavium/octe/ethernet-mv88e61xx.c          optional octe 
octeon_vendor_lanner
 mips/cavium/octe/ethernet-common.c             optional octe
@@ -39,10 +43,6 @@ mips/cavium/octe/mv88e61xxphy.c                      option
 mips/cavium/octe/octe.c                                optional octe
 mips/cavium/octe/octebus.c                     optional octe
 
-mips/cavium/if_octm.c                          optional octm
-
-contrib/octeon-sdk/cvmx-mgmt-port.c            optional octm
-
 mips/cavium/octopci.c                          optional pci
 mips/cavium/octopci_bus_space.c                        optional pci
 

Modified: head/sys/mips/cavium/if_octm.c
==============================================================================
--- head/sys/mips/cavium/if_octm.c      Wed Feb 22 01:23:14 2012        
(r231986)
+++ head/sys/mips/cavium/if_octm.c      Wed Feb 22 01:30:25 2012        
(r231987)
@@ -63,6 +63,7 @@
 #include <contrib/octeon-sdk/cvmx.h>
 #include <contrib/octeon-sdk/cvmx-interrupt.h>
 #include <contrib/octeon-sdk/cvmx-mgmt-port.h>
+#include "octe/ethernet-common.h"
 
 struct octm_softc {
        struct ifnet *sc_ifp;
@@ -176,9 +177,10 @@ octm_attach(device_t dev)
        /*
         * Set MAC address for this management port.
         */
-       mac = 0;
-       memcpy((u_int8_t *)&mac + 2, cvmx_sysinfo_get()->mac_addr_base, 6);
-       mac += sc->sc_port;
+       if (cvm_assign_mac_address(&mac, NULL) != 0) {
+               device_printf(dev, "unable to allocate MAC address.\n");
+               return (ENXIO);
+       }
        cvmx_mgmt_port_set_mac(sc->sc_port, mac);
 
        /* No watermark for input ring.  */

Modified: head/sys/mips/cavium/octe/ethernet-common.c
==============================================================================
--- head/sys/mips/cavium/octe/ethernet-common.c Wed Feb 22 01:23:14 2012        
(r231986)
+++ head/sys/mips/cavium/octe/ethernet-common.c Wed Feb 22 01:30:25 2012        
(r231987)
@@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
 
 extern int octeon_is_simulation(void);
 
+static uint64_t mac_addr = 0;
+static uint32_t mac_offset = 0;
 
 /**
  * Set the multicast list. Currently unimplemented.
@@ -90,6 +92,37 @@ void cvm_oct_common_set_multicast_list(s
 
 
 /**
+ * Assign a MAC addres from the pool of available MAC addresses
+ * Can return as either a 64-bit value and/or 6 octets.
+ *
+ * @param macp    Filled in with the assigned address if non-NULL
+ * @param octets  Filled in with the assigned address if non-NULL
+ * @return Zero on success
+ */
+int cvm_assign_mac_address(uint64_t *macp, uint8_t *octets)
+{
+       /* Initialize from global MAC address base; fail if not set */
+       if (mac_addr == 0) {
+               memcpy((uint8_t *)&mac_addr + 2, 
cvmx_sysinfo_get()->mac_addr_base, 6);
+               if (mac_addr == 0)
+                       return ENXIO;
+       }
+
+       if (mac_offset >= cvmx_sysinfo_get()->mac_addr_count)
+               return ENXIO;       /* Out of addresses to assign */
+       
+       if (macp)
+               *macp = mac_addr;
+       if (octets)
+               memcpy(octets, (u_int8_t *)&mac_addr + 2, 6);
+
+       mac_addr++;
+       mac_offset++;
+
+       return 0;
+}
+
+/**
  * Set the hardware MAC address for a device
  *
  * @param dev    Device to change the MAC address for
@@ -268,16 +301,11 @@ void cvm_oct_common_poll(struct ifnet *i
  */
 int cvm_oct_common_init(struct ifnet *ifp)
 {
-       char mac[6] = {
-               cvmx_sysinfo_get()->mac_addr_base[0],
-               cvmx_sysinfo_get()->mac_addr_base[1],
-               cvmx_sysinfo_get()->mac_addr_base[2],
-               cvmx_sysinfo_get()->mac_addr_base[3],
-               cvmx_sysinfo_get()->mac_addr_base[4],
-               cvmx_sysinfo_get()->mac_addr_base[5] };
+       uint8_t mac[6];
        cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
 
-       mac[5] += cvm_oct_mac_addr_offset++;
+       if (cvm_assign_mac_address(NULL, mac) != 0)
+               return ENXIO;
 
        ifp->if_mtu = ETHERMTU;
 

Modified: head/sys/mips/cavium/octe/ethernet-common.h
==============================================================================
--- head/sys/mips/cavium/octe/ethernet-common.h Wed Feb 22 01:23:14 2012        
(r231986)
+++ head/sys/mips/cavium/octe/ethernet-common.h Wed Feb 22 01:30:25 2012        
(r231987)
@@ -37,6 +37,7 @@ void cvm_oct_common_uninit(struct ifnet 
 int cvm_oct_common_change_mtu(struct ifnet *ifp, int new_mtu);
 void cvm_oct_common_set_multicast_list(struct ifnet *ifp);
 void cvm_oct_common_set_mac_address(struct ifnet *ifp, const void *);
+int cvm_assign_mac_address(uint64_t *, uint8_t *);
 
 int cvm_oct_init_module(device_t);
 void cvm_oct_cleanup_module(device_t);
@@ -52,4 +53,3 @@ int cvm_oct_spi_init(struct ifnet *ifp);
 void cvm_oct_spi_uninit(struct ifnet *ifp);
 int cvm_oct_xaui_init(struct ifnet *ifp);
 
-extern unsigned int cvm_oct_mac_addr_offset;

Modified: head/sys/mips/cavium/octe/ethernet-rgmii.c
==============================================================================
--- head/sys/mips/cavium/octe/ethernet-rgmii.c  Wed Feb 22 01:23:14 2012        
(r231986)
+++ head/sys/mips/cavium/octe/ethernet-rgmii.c  Wed Feb 22 01:30:25 2012        
(r231987)
@@ -215,7 +215,9 @@ int cvm_oct_rgmii_init(struct ifnet *ifp
        int error;
        int rid;
 
-       cvm_oct_common_init(ifp);
+       if (cvm_oct_common_init(ifp) != 0)
+           return ENXIO;
+
        priv->open = cvm_oct_common_open;
        priv->stop = cvm_oct_common_stop;
        priv->stop(ifp);

Modified: head/sys/mips/cavium/octe/ethernet-sgmii.c
==============================================================================
--- head/sys/mips/cavium/octe/ethernet-sgmii.c  Wed Feb 22 01:23:14 2012        
(r231986)
+++ head/sys/mips/cavium/octe/ethernet-sgmii.c  Wed Feb 22 01:30:25 2012        
(r231987)
@@ -49,7 +49,10 @@ extern int octeon_is_simulation(void);
 int cvm_oct_sgmii_init(struct ifnet *ifp)
 {
        cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
-       cvm_oct_common_init(ifp);
+
+       if (cvm_oct_common_init(ifp) != 0)
+           return ENXIO;
+
        priv->open = cvm_oct_common_open;
        priv->stop = cvm_oct_common_stop;
        priv->stop(ifp);

Modified: head/sys/mips/cavium/octe/ethernet-spi.c
==============================================================================
--- head/sys/mips/cavium/octe/ethernet-spi.c    Wed Feb 22 01:23:14 2012        
(r231986)
+++ head/sys/mips/cavium/octe/ethernet-spi.c    Wed Feb 22 01:30:25 2012        
(r231987)
@@ -289,7 +289,8 @@ int cvm_oct_spi_init(struct ifnet *ifp)
                cvm_oct_spi_enable_error_reporting(INTERFACE(priv->port));
                priv->poll = cvm_oct_spi_poll;
        }
-       cvm_oct_common_init(ifp);
+       if (cvm_oct_common_init(ifp) != 0)
+           return ENXIO;
        return 0;
 }
 

Modified: head/sys/mips/cavium/octe/ethernet-xaui.c
==============================================================================
--- head/sys/mips/cavium/octe/ethernet-xaui.c   Wed Feb 22 01:23:14 2012        
(r231986)
+++ head/sys/mips/cavium/octe/ethernet-xaui.c   Wed Feb 22 01:30:25 2012        
(r231987)
@@ -49,7 +49,10 @@ extern int octeon_is_simulation(void);
 int cvm_oct_xaui_init(struct ifnet *ifp)
 {
        cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc;
-       cvm_oct_common_init(ifp);
+
+       if (cvm_oct_common_init(ifp) != 0)
+           return ENXIO;
+
        priv->open = cvm_oct_common_open;
        priv->stop = cvm_oct_common_stop;
        priv->stop(ifp);

Modified: head/sys/mips/cavium/octe/ethernet.c
==============================================================================
--- head/sys/mips/cavium/octe/ethernet.c        Wed Feb 22 01:23:14 2012        
(r231986)
+++ head/sys/mips/cavium/octe/ethernet.c        Wed Feb 22 01:30:25 2012        
(r231987)
@@ -97,15 +97,6 @@ static struct taskqueue *cvm_oct_link_ta
  */
 static int cvm_oct_num_output_buffers;
 
-/*
- * The offset from mac_addr_base that should be used for the next port
- * that is configured.  By convention, if any mgmt ports exist on the
- * chip, they get the first mac addresses.  The ports controlled by
- * this driver are numbered sequencially following any mgmt addresses
- * that may exist.
- */
-unsigned int cvm_oct_mac_addr_offset;
-
 /**
  * Function to update link status.
  */
@@ -321,20 +312,6 @@ int cvm_oct_init_module(device_t bus)
 
        printf("cavium-ethernet: %s\n", OCTEON_SDK_VERSION_STRING);
 
-       /*
-        * MAC addresses for this driver start after the management
-        * ports.
-        *
-        * XXX Would be nice if __cvmx_mgmt_port_num_ports() were
-        *     not static to cvmx-mgmt-port.c.
-        */
-       if (OCTEON_IS_MODEL(OCTEON_CN56XX))
-               cvm_oct_mac_addr_offset = 1;
-       else if (OCTEON_IS_MODEL(OCTEON_CN52XX) || 
OCTEON_IS_MODEL(OCTEON_CN63XX))
-               cvm_oct_mac_addr_offset = 2;
-       else
-               cvm_oct_mac_addr_offset = 0;
-
        cvm_oct_rx_initialize();
        cvm_oct_configure_common_hw(bus);
 
@@ -375,15 +352,17 @@ int cvm_oct_init_module(device_t bus)
                int num_ports = cvmx_helper_ports_on_interface(interface);
                int port;
 
-               for (port = cvmx_helper_get_ipd_port(interface, 0); port < 
cvmx_helper_get_ipd_port(interface, num_ports); port++) {
+               for (port = cvmx_helper_get_ipd_port(interface, 0);
+                    port < cvmx_helper_get_ipd_port(interface, num_ports);
+                    ifnum++, port++) {
                        cvm_oct_private_t *priv;
                        struct ifnet *ifp;
                        
-                       dev = BUS_ADD_CHILD(bus, 0, "octe", ifnum++);
+                       dev = BUS_ADD_CHILD(bus, 0, "octe", ifnum);
                        if (dev != NULL)
                                ifp = if_alloc(IFT_ETHER);
                        if (dev == NULL || ifp == NULL) {
-                               printf("\t\tFailed to allocate ethernet device 
for port %d\n", port);
+                               printf("Failed to allocate ethernet device for 
interface %d port %d\n", interface, port);
                                continue;
                        }
 
@@ -454,12 +433,13 @@ int cvm_oct_init_module(device_t bus)
                        ifp->if_softc = priv;
 
                        if (!priv->init) {
-                               panic("%s: unsupported device type, need to 
free ifp.", __func__);
-                       } else
-                       if (priv->init(ifp) < 0) {
-                               printf("\t\tFailed to register ethernet device 
for interface %d, port %d\n",
-                               interface, priv->port);
-                               panic("%s: init failed, need to free ifp.", 
__func__);
+                               printf("octe%d: unsupported device type 
interface %d, port %d\n",
+                                      ifnum, interface, priv->port);
+                               if_free(ifp);
+                       } else if (priv->init(ifp) != 0) {
+                               printf("octe%d: failed to register device for 
interface %d, port %d\n",
+                                      ifnum, interface, priv->port);
+                               if_free(ifp);
                        } else {
                                cvm_oct_device[priv->port] = ifp;
                                fau -= cvmx_pko_get_num_queues(priv->port) * 
sizeof(uint32_t);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to