| 166 | } |
| 167 | |
| 168 | static void |
| 169 | emac_get_hwaddr(struct emac_softc *sc, uint8_t *hwaddr) |
| 170 | { |
| 171 | uint32_t val0, val1, rnd; |
| 172 | u_char rootkey[16]; |
| 173 | size_t rootkey_size; |
| 174 | |
| 175 | /* |
| 176 | * Try to get MAC address from running hardware. |
| 177 | * If there is something non-zero there just use it. |
| 178 | * |
| 179 | * Otherwise set the address to a convenient locally assigned address, |
| 180 | * using the SID rootkey. |
| 181 | * This is was uboot does so we end up with the same mac as if uboot |
| 182 | * did set it. |
| 183 | * If we can't get the root key, generate a random one, |
| 184 | * 'bsd' + random 24 low-order bits. 'b' is 0x62, which has the locally |
| 185 | * assigned bit set, and the broadcast/multicast bit clear. |
| 186 | */ |
| 187 | val0 = EMAC_READ_REG(sc, EMAC_MAC_A0); |
| 188 | val1 = EMAC_READ_REG(sc, EMAC_MAC_A1); |
| 189 | if ((val0 | val1) != 0 && (val0 | val1) != 0xffffff) { |
| 190 | hwaddr[0] = (val1 >> 16) & 0xff; |
| 191 | hwaddr[1] = (val1 >> 8) & 0xff; |
| 192 | hwaddr[2] = (val1 >> 0) & 0xff; |
| 193 | hwaddr[3] = (val0 >> 16) & 0xff; |
| 194 | hwaddr[4] = (val0 >> 8) & 0xff; |
| 195 | hwaddr[5] = (val0 >> 0) & 0xff; |
| 196 | } else { |
| 197 | rootkey_size = sizeof(rootkey); |
| 198 | if (aw_sid_get_fuse(AW_SID_FUSE_ROOTKEY, rootkey, |
| 199 | &rootkey_size) == 0) { |
| 200 | hwaddr[0] = 0x2; |
| 201 | hwaddr[1] = rootkey[3]; |
| 202 | hwaddr[2] = rootkey[12]; |
| 203 | hwaddr[3] = rootkey[13]; |
| 204 | hwaddr[4] = rootkey[14]; |
| 205 | hwaddr[5] = rootkey[15]; |
| 206 | } |
| 207 | else { |
| 208 | rnd = arc4random() & 0x00ffffff; |
| 209 | hwaddr[0] = 'b'; |
| 210 | hwaddr[1] = 's'; |
| 211 | hwaddr[2] = 'd'; |
| 212 | hwaddr[3] = (rnd >> 16) & 0xff; |
| 213 | hwaddr[4] = (rnd >> 8) & 0xff; |
| 214 | hwaddr[5] = (rnd >> 0) & 0xff; |
| 215 | } |
| 216 | } |
| 217 | if (bootverbose) |
| 218 | printf("MAC address: %s\n", ether_sprintf(hwaddr)); |
| 219 | } |
| 220 | |
| 221 | static u_int |
| 222 | emac_hash_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt) |
no test coverage detected