/* * 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; }