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:
parent
19ab58bfe3
commit
57fa7d3101
@ -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
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user