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 <aduane@juniper.net>
This commit is contained in:
Oleksandr Tymoshenko 2012-02-22 01:30:25 +00:00
parent 19ab58bfe3
commit 57fa7d3101
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=231987
9 changed files with 71 additions and 52 deletions

View File

@ -24,6 +24,10 @@ mips/cavium/cryptocteon/cryptocteon.c optional cryptocteon
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 optional octe mv88e61xxphy
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

View File

@ -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. */

View File

@ -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.
@ -89,6 +91,37 @@ void cvm_oct_common_set_multicast_list(struct ifnet *ifp)
}
/**
* 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
*
@ -268,16 +301,11 @@ void cvm_oct_common_poll(struct ifnet *ifp)
*/
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;

View File

@ -37,6 +37,7 @@ void cvm_oct_common_uninit(struct ifnet *ifp);
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;

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -97,15 +97,6 @@ static struct taskqueue *cvm_oct_link_taskq;
*/
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);