Miscellany
public text v1 · immutable/*
* Some platforms expect the MAC addresses in the Flash OTP
* If not or if the OTP is unprogrammed, it uses the defaults
* provided earlier in this file
*/
static int get_otp_MACAddress(struct net_device *ndev, priv_data_t *priv)
{
u32 faddr;
u32 flashbase;
u32 low_mac;
int i;
// We only need 6 bytes but a page is probably the smallest that
// gets mapped.
#define OTP_IOREMAP_SIZE PAGE_SIZE
// flashbase = IXP425_EXP_BUS_CS0_BASE_PHYS;
flashbase = IXP4XX_EXP_BUS_BASE(0);
faddr = (u32)ioremap (flashbase, OTP_IOREMAP_SIZE);
if (!faddr)
{
release_mem_region (flashbase, OTP_IOREMAP_SIZE);
printk (KERN_ERR "%s: unable to ioremap flash\n", __FUNCTION__);
return -1;
}
// Send the query command to the flash.
writew (0x9090, faddr);
for (i = 0; i < 6; i++) {
ndev->dev_addr[i] = readb (faddr + 0x10a + i);
}
// Take flash out of query mode
writew (0xffff, faddr);
if (faddr) iounmap ((void *)faddr);
// Check for a valid OTP
if (ndev->dev_addr[0] != 0xFF)
{
// Valid OTP
// Concatenate the lower 3 bytes of the base MAC address
// to use to calculate the MAC address for the requested port
low_mac = ((0x000000FF & ndev->dev_addr[3]) << 16) + ((0x000000F
F & ndev->dev_addr[4]) << 8) + ndev->dev_addr[5];
// There should never be an overflow here. If there is,
// we would have to violate the OUI domain. So, just
// take what we get (at least keep in the right domain)
low_mac = low_mac + priv->port_id;
ndev->dev_addr[3] = (unsigned char) ((low_mac & 0x00FF0000) >> 1
6);
ndev->dev_addr[4] = (unsigned char) ((low_mac & 0x0000FF00) >> 8
);
ndev->dev_addr[5] = (unsigned char) (low_mac & 0x000000FF);
} else {
// Invalid OTP
// Do it the old fashioned way
memcpy(ndev->dev_addr,
&default_mac_addr[priv->port_id].macAddress,
IX_IEEE803_MAC_ADDRESS_SIZE);
}
return 0;
}