xref: /openbmc/u-boot/board/ti/am335x/board.c (revision c0dcece7d9925506a950e45028cbd25614aad791)
1 /*
2  * board.c
3  *
4  * Board functions for TI AM335X based boards
5  *
6  * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
7  *
8  * SPDX-License-Identifier:	GPL-2.0+
9  */
10 
11 #include <common.h>
12 #include <errno.h>
13 #include <spl.h>
14 #include <asm/arch/cpu.h>
15 #include <asm/arch/hardware.h>
16 #include <asm/arch/omap.h>
17 #include <asm/arch/ddr_defs.h>
18 #include <asm/arch/clock.h>
19 #include <asm/arch/gpio.h>
20 #include <asm/arch/mmc_host_def.h>
21 #include <asm/arch/sys_proto.h>
22 #include <asm/arch/mem.h>
23 #include <asm/io.h>
24 #include <asm/emif.h>
25 #include <asm/gpio.h>
26 #include <i2c.h>
27 #include <miiphy.h>
28 #include <cpsw.h>
29 #include "board.h"
30 
31 DECLARE_GLOBAL_DATA_PTR;
32 
33 /* GPIO that controls power to DDR on EVM-SK */
34 #define GPIO_DDR_VTT_EN		7
35 
36 static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
37 
38 /*
39  * Read header information from EEPROM into global structure.
40  */
41 static int read_eeprom(struct am335x_baseboard_id *header)
42 {
43 	/* Check if baseboard eeprom is available */
44 	if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) {
45 		puts("Could not probe the EEPROM; something fundamentally "
46 			"wrong on the I2C bus.\n");
47 		return -ENODEV;
48 	}
49 
50 	/* read the eeprom using i2c */
51 	if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 2, (uchar *)header,
52 		     sizeof(struct am335x_baseboard_id))) {
53 		puts("Could not read the EEPROM; something fundamentally"
54 			" wrong on the I2C bus.\n");
55 		return -EIO;
56 	}
57 
58 	if (header->magic != 0xEE3355AA) {
59 		/*
60 		 * read the eeprom using i2c again,
61 		 * but use only a 1 byte address
62 		 */
63 		if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0, 1, (uchar *)header,
64 			     sizeof(struct am335x_baseboard_id))) {
65 			puts("Could not read the EEPROM; something "
66 				"fundamentally wrong on the I2C bus.\n");
67 			return -EIO;
68 		}
69 
70 		if (header->magic != 0xEE3355AA) {
71 			printf("Incorrect magic number (0x%x) in EEPROM\n",
72 					header->magic);
73 			return -EINVAL;
74 		}
75 	}
76 
77 	return 0;
78 }
79 
80 #if defined(CONFIG_SPL_BUILD) || defined(CONFIG_NOR_BOOT)
81 static const struct ddr_data ddr2_data = {
82 	.datardsratio0 = ((MT47H128M16RT25E_RD_DQS<<30) |
83 			  (MT47H128M16RT25E_RD_DQS<<20) |
84 			  (MT47H128M16RT25E_RD_DQS<<10) |
85 			  (MT47H128M16RT25E_RD_DQS<<0)),
86 	.datawdsratio0 = ((MT47H128M16RT25E_WR_DQS<<30) |
87 			  (MT47H128M16RT25E_WR_DQS<<20) |
88 			  (MT47H128M16RT25E_WR_DQS<<10) |
89 			  (MT47H128M16RT25E_WR_DQS<<0)),
90 	.datawiratio0 = ((MT47H128M16RT25E_PHY_WRLVL<<30) |
91 			 (MT47H128M16RT25E_PHY_WRLVL<<20) |
92 			 (MT47H128M16RT25E_PHY_WRLVL<<10) |
93 			 (MT47H128M16RT25E_PHY_WRLVL<<0)),
94 	.datagiratio0 = ((MT47H128M16RT25E_PHY_GATELVL<<30) |
95 			 (MT47H128M16RT25E_PHY_GATELVL<<20) |
96 			 (MT47H128M16RT25E_PHY_GATELVL<<10) |
97 			 (MT47H128M16RT25E_PHY_GATELVL<<0)),
98 	.datafwsratio0 = ((MT47H128M16RT25E_PHY_FIFO_WE<<30) |
99 			  (MT47H128M16RT25E_PHY_FIFO_WE<<20) |
100 			  (MT47H128M16RT25E_PHY_FIFO_WE<<10) |
101 			  (MT47H128M16RT25E_PHY_FIFO_WE<<0)),
102 	.datawrsratio0 = ((MT47H128M16RT25E_PHY_WR_DATA<<30) |
103 			  (MT47H128M16RT25E_PHY_WR_DATA<<20) |
104 			  (MT47H128M16RT25E_PHY_WR_DATA<<10) |
105 			  (MT47H128M16RT25E_PHY_WR_DATA<<0)),
106 	.datauserank0delay = MT47H128M16RT25E_PHY_RANK0_DELAY,
107 	.datadldiff0 = PHY_DLL_LOCK_DIFF,
108 };
109 
110 static const struct cmd_control ddr2_cmd_ctrl_data = {
111 	.cmd0csratio = MT47H128M16RT25E_RATIO,
112 	.cmd0dldiff = MT47H128M16RT25E_DLL_LOCK_DIFF,
113 	.cmd0iclkout = MT47H128M16RT25E_INVERT_CLKOUT,
114 
115 	.cmd1csratio = MT47H128M16RT25E_RATIO,
116 	.cmd1dldiff = MT47H128M16RT25E_DLL_LOCK_DIFF,
117 	.cmd1iclkout = MT47H128M16RT25E_INVERT_CLKOUT,
118 
119 	.cmd2csratio = MT47H128M16RT25E_RATIO,
120 	.cmd2dldiff = MT47H128M16RT25E_DLL_LOCK_DIFF,
121 	.cmd2iclkout = MT47H128M16RT25E_INVERT_CLKOUT,
122 };
123 
124 static const struct emif_regs ddr2_emif_reg_data = {
125 	.sdram_config = MT47H128M16RT25E_EMIF_SDCFG,
126 	.ref_ctrl = MT47H128M16RT25E_EMIF_SDREF,
127 	.sdram_tim1 = MT47H128M16RT25E_EMIF_TIM1,
128 	.sdram_tim2 = MT47H128M16RT25E_EMIF_TIM2,
129 	.sdram_tim3 = MT47H128M16RT25E_EMIF_TIM3,
130 	.emif_ddr_phy_ctlr_1 = MT47H128M16RT25E_EMIF_READ_LATENCY,
131 };
132 
133 static const struct ddr_data ddr3_data = {
134 	.datardsratio0 = MT41J128MJT125_RD_DQS,
135 	.datawdsratio0 = MT41J128MJT125_WR_DQS,
136 	.datafwsratio0 = MT41J128MJT125_PHY_FIFO_WE,
137 	.datawrsratio0 = MT41J128MJT125_PHY_WR_DATA,
138 	.datadldiff0 = PHY_DLL_LOCK_DIFF,
139 };
140 
141 static const struct ddr_data ddr3_beagleblack_data = {
142 	.datardsratio0 = MT41K256M16HA125E_RD_DQS,
143 	.datawdsratio0 = MT41K256M16HA125E_WR_DQS,
144 	.datafwsratio0 = MT41K256M16HA125E_PHY_FIFO_WE,
145 	.datawrsratio0 = MT41K256M16HA125E_PHY_WR_DATA,
146 	.datadldiff0 = PHY_DLL_LOCK_DIFF,
147 };
148 
149 static const struct ddr_data ddr3_evm_data = {
150 	.datardsratio0 = MT41J512M8RH125_RD_DQS,
151 	.datawdsratio0 = MT41J512M8RH125_WR_DQS,
152 	.datafwsratio0 = MT41J512M8RH125_PHY_FIFO_WE,
153 	.datawrsratio0 = MT41J512M8RH125_PHY_WR_DATA,
154 	.datadldiff0 = PHY_DLL_LOCK_DIFF,
155 };
156 
157 static const struct cmd_control ddr3_cmd_ctrl_data = {
158 	.cmd0csratio = MT41J128MJT125_RATIO,
159 	.cmd0dldiff = MT41J128MJT125_DLL_LOCK_DIFF,
160 	.cmd0iclkout = MT41J128MJT125_INVERT_CLKOUT,
161 
162 	.cmd1csratio = MT41J128MJT125_RATIO,
163 	.cmd1dldiff = MT41J128MJT125_DLL_LOCK_DIFF,
164 	.cmd1iclkout = MT41J128MJT125_INVERT_CLKOUT,
165 
166 	.cmd2csratio = MT41J128MJT125_RATIO,
167 	.cmd2dldiff = MT41J128MJT125_DLL_LOCK_DIFF,
168 	.cmd2iclkout = MT41J128MJT125_INVERT_CLKOUT,
169 };
170 
171 static const struct cmd_control ddr3_beagleblack_cmd_ctrl_data = {
172 	.cmd0csratio = MT41K256M16HA125E_RATIO,
173 	.cmd0dldiff = MT41K256M16HA125E_DLL_LOCK_DIFF,
174 	.cmd0iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
175 
176 	.cmd1csratio = MT41K256M16HA125E_RATIO,
177 	.cmd1dldiff = MT41K256M16HA125E_DLL_LOCK_DIFF,
178 	.cmd1iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
179 
180 	.cmd2csratio = MT41K256M16HA125E_RATIO,
181 	.cmd2dldiff = MT41K256M16HA125E_DLL_LOCK_DIFF,
182 	.cmd2iclkout = MT41K256M16HA125E_INVERT_CLKOUT,
183 };
184 
185 static const struct cmd_control ddr3_evm_cmd_ctrl_data = {
186 	.cmd0csratio = MT41J512M8RH125_RATIO,
187 	.cmd0dldiff = MT41J512M8RH125_DLL_LOCK_DIFF,
188 	.cmd0iclkout = MT41J512M8RH125_INVERT_CLKOUT,
189 
190 	.cmd1csratio = MT41J512M8RH125_RATIO,
191 	.cmd1dldiff = MT41J512M8RH125_DLL_LOCK_DIFF,
192 	.cmd1iclkout = MT41J512M8RH125_INVERT_CLKOUT,
193 
194 	.cmd2csratio = MT41J512M8RH125_RATIO,
195 	.cmd2dldiff = MT41J512M8RH125_DLL_LOCK_DIFF,
196 	.cmd2iclkout = MT41J512M8RH125_INVERT_CLKOUT,
197 };
198 
199 static struct emif_regs ddr3_emif_reg_data = {
200 	.sdram_config = MT41J128MJT125_EMIF_SDCFG,
201 	.ref_ctrl = MT41J128MJT125_EMIF_SDREF,
202 	.sdram_tim1 = MT41J128MJT125_EMIF_TIM1,
203 	.sdram_tim2 = MT41J128MJT125_EMIF_TIM2,
204 	.sdram_tim3 = MT41J128MJT125_EMIF_TIM3,
205 	.zq_config = MT41J128MJT125_ZQ_CFG,
206 	.emif_ddr_phy_ctlr_1 = MT41J128MJT125_EMIF_READ_LATENCY |
207 				PHY_EN_DYN_PWRDN,
208 };
209 
210 static struct emif_regs ddr3_beagleblack_emif_reg_data = {
211 	.sdram_config = MT41K256M16HA125E_EMIF_SDCFG,
212 	.ref_ctrl = MT41K256M16HA125E_EMIF_SDREF,
213 	.sdram_tim1 = MT41K256M16HA125E_EMIF_TIM1,
214 	.sdram_tim2 = MT41K256M16HA125E_EMIF_TIM2,
215 	.sdram_tim3 = MT41K256M16HA125E_EMIF_TIM3,
216 	.zq_config = MT41K256M16HA125E_ZQ_CFG,
217 	.emif_ddr_phy_ctlr_1 = MT41K256M16HA125E_EMIF_READ_LATENCY,
218 };
219 
220 static struct emif_regs ddr3_evm_emif_reg_data = {
221 	.sdram_config = MT41J512M8RH125_EMIF_SDCFG,
222 	.ref_ctrl = MT41J512M8RH125_EMIF_SDREF,
223 	.sdram_tim1 = MT41J512M8RH125_EMIF_TIM1,
224 	.sdram_tim2 = MT41J512M8RH125_EMIF_TIM2,
225 	.sdram_tim3 = MT41J512M8RH125_EMIF_TIM3,
226 	.zq_config = MT41J512M8RH125_ZQ_CFG,
227 	.emif_ddr_phy_ctlr_1 = MT41J512M8RH125_EMIF_READ_LATENCY |
228 				PHY_EN_DYN_PWRDN,
229 };
230 
231 #ifdef CONFIG_SPL_OS_BOOT
232 int spl_start_uboot(void)
233 {
234 	/* break into full u-boot on 'c' */
235 	return (serial_tstc() && serial_getc() == 'c');
236 }
237 #endif
238 
239 #define OSC	(V_OSCK/1000000)
240 const struct dpll_params dpll_ddr = {
241 		266, OSC-1, 1, -1, -1, -1, -1};
242 const struct dpll_params dpll_ddr_evm_sk = {
243 		303, OSC-1, 1, -1, -1, -1, -1};
244 const struct dpll_params dpll_ddr_bone_black = {
245 		400, OSC-1, 1, -1, -1, -1, -1};
246 
247 const struct dpll_params *get_dpll_ddr_params(void)
248 {
249 	struct am335x_baseboard_id header;
250 
251 	enable_i2c0_pin_mux();
252 	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
253 	if (read_eeprom(&header) < 0)
254 		puts("Could not get board ID.\n");
255 
256 	if (board_is_evm_sk(&header))
257 		return &dpll_ddr_evm_sk;
258 	else if (board_is_bone_lt(&header))
259 		return &dpll_ddr_bone_black;
260 	else if (board_is_evm_15_or_later(&header))
261 		return &dpll_ddr_evm_sk;
262 	else
263 		return &dpll_ddr;
264 }
265 
266 void set_uart_mux_conf(void)
267 {
268 #ifdef CONFIG_SERIAL1
269 	enable_uart0_pin_mux();
270 #endif /* CONFIG_SERIAL1 */
271 #ifdef CONFIG_SERIAL2
272 	enable_uart1_pin_mux();
273 #endif /* CONFIG_SERIAL2 */
274 #ifdef CONFIG_SERIAL3
275 	enable_uart2_pin_mux();
276 #endif /* CONFIG_SERIAL3 */
277 #ifdef CONFIG_SERIAL4
278 	enable_uart3_pin_mux();
279 #endif /* CONFIG_SERIAL4 */
280 #ifdef CONFIG_SERIAL5
281 	enable_uart4_pin_mux();
282 #endif /* CONFIG_SERIAL5 */
283 #ifdef CONFIG_SERIAL6
284 	enable_uart5_pin_mux();
285 #endif /* CONFIG_SERIAL6 */
286 }
287 
288 void set_mux_conf_regs(void)
289 {
290 	__maybe_unused struct am335x_baseboard_id header;
291 
292 	if (read_eeprom(&header) < 0)
293 		puts("Could not get board ID.\n");
294 
295 	enable_board_pin_mux(&header);
296 }
297 
298 void sdram_init(void)
299 {
300 	__maybe_unused struct am335x_baseboard_id header;
301 
302 	if (read_eeprom(&header) < 0)
303 		puts("Could not get board ID.\n");
304 
305 	if (board_is_evm_sk(&header)) {
306 		/*
307 		 * EVM SK 1.2A and later use gpio0_7 to enable DDR3.
308 		 * This is safe enough to do on older revs.
309 		 */
310 		gpio_request(GPIO_DDR_VTT_EN, "ddr_vtt_en");
311 		gpio_direction_output(GPIO_DDR_VTT_EN, 1);
312 	}
313 
314 	if (board_is_evm_sk(&header))
315 		config_ddr(303, MT41J128MJT125_IOCTRL_VALUE, &ddr3_data,
316 			   &ddr3_cmd_ctrl_data, &ddr3_emif_reg_data, 0);
317 	else if (board_is_bone_lt(&header))
318 		config_ddr(400, MT41K256M16HA125E_IOCTRL_VALUE,
319 			   &ddr3_beagleblack_data,
320 			   &ddr3_beagleblack_cmd_ctrl_data,
321 			   &ddr3_beagleblack_emif_reg_data, 0);
322 	else if (board_is_evm_15_or_later(&header))
323 		config_ddr(303, MT41J512M8RH125_IOCTRL_VALUE, &ddr3_evm_data,
324 			   &ddr3_evm_cmd_ctrl_data, &ddr3_evm_emif_reg_data, 0);
325 	else
326 		config_ddr(266, MT47H128M16RT25E_IOCTRL_VALUE, &ddr2_data,
327 			   &ddr2_cmd_ctrl_data, &ddr2_emif_reg_data, 0);
328 }
329 #endif
330 
331 /*
332  * Basic board specific setup.  Pinmux has been handled already.
333  */
334 int board_init(void)
335 {
336 #ifdef CONFIG_NOR
337 	const u32 gpmc_nor[GPMC_MAX_REG] = { STNOR_GPMC_CONFIG1,
338 		STNOR_GPMC_CONFIG2, STNOR_GPMC_CONFIG3, STNOR_GPMC_CONFIG4,
339 		STNOR_GPMC_CONFIG5, STNOR_GPMC_CONFIG6, STNOR_GPMC_CONFIG7 };
340 #endif
341 
342 	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
343 
344 	gpmc_init();
345 
346 #ifdef CONFIG_NOR
347 	/* Reconfigure CS0 for NOR instead of NAND. */
348 	enable_gpmc_cs_config(gpmc_nor, &gpmc_cfg->cs[0],
349 			      CONFIG_SYS_FLASH_BASE, GPMC_SIZE_16M);
350 #endif
351 
352 	return 0;
353 }
354 
355 #ifdef CONFIG_BOARD_LATE_INIT
356 int board_late_init(void)
357 {
358 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
359 	char safe_string[HDR_NAME_LEN + 1];
360 	struct am335x_baseboard_id header;
361 
362 	if (read_eeprom(&header) < 0)
363 		puts("Could not get board ID.\n");
364 
365 	/* Now set variables based on the header. */
366 	strncpy(safe_string, (char *)header.name, sizeof(header.name));
367 	safe_string[sizeof(header.name)] = 0;
368 	setenv("board_name", safe_string);
369 
370 	strncpy(safe_string, (char *)header.version, sizeof(header.version));
371 	safe_string[sizeof(header.version)] = 0;
372 	setenv("board_rev", safe_string);
373 #endif
374 
375 	return 0;
376 }
377 #endif
378 
379 #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
380 	(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
381 static void cpsw_control(int enabled)
382 {
383 	/* VTP can be added here */
384 
385 	return;
386 }
387 
388 static struct cpsw_slave_data cpsw_slaves[] = {
389 	{
390 		.slave_reg_ofs	= 0x208,
391 		.sliver_reg_ofs	= 0xd80,
392 		.phy_id		= 0,
393 	},
394 	{
395 		.slave_reg_ofs	= 0x308,
396 		.sliver_reg_ofs	= 0xdc0,
397 		.phy_id		= 1,
398 	},
399 };
400 
401 static struct cpsw_platform_data cpsw_data = {
402 	.mdio_base		= CPSW_MDIO_BASE,
403 	.cpsw_base		= CPSW_BASE,
404 	.mdio_div		= 0xff,
405 	.channels		= 8,
406 	.cpdma_reg_ofs		= 0x800,
407 	.slaves			= 1,
408 	.slave_data		= cpsw_slaves,
409 	.ale_reg_ofs		= 0xd00,
410 	.ale_entries		= 1024,
411 	.host_port_reg_ofs	= 0x108,
412 	.hw_stats_reg_ofs	= 0x900,
413 	.bd_ram_ofs		= 0x2000,
414 	.mac_control		= (1 << 5),
415 	.control		= cpsw_control,
416 	.host_port_num		= 0,
417 	.version		= CPSW_CTRL_VERSION_2,
418 };
419 #endif
420 
421 #if defined(CONFIG_DRIVER_TI_CPSW) || \
422 	(defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET))
423 int board_eth_init(bd_t *bis)
424 {
425 	int rv, n = 0;
426 	uint8_t mac_addr[6];
427 	uint32_t mac_hi, mac_lo;
428 	__maybe_unused struct am335x_baseboard_id header;
429 
430 	/* try reading mac address from efuse */
431 	mac_lo = readl(&cdev->macid0l);
432 	mac_hi = readl(&cdev->macid0h);
433 	mac_addr[0] = mac_hi & 0xFF;
434 	mac_addr[1] = (mac_hi & 0xFF00) >> 8;
435 	mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
436 	mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
437 	mac_addr[4] = mac_lo & 0xFF;
438 	mac_addr[5] = (mac_lo & 0xFF00) >> 8;
439 
440 #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
441 	(defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
442 	if (!getenv("ethaddr")) {
443 		printf("<ethaddr> not set. Validating first E-fuse MAC\n");
444 
445 		if (is_valid_ether_addr(mac_addr))
446 			eth_setenv_enetaddr("ethaddr", mac_addr);
447 	}
448 
449 #ifdef CONFIG_DRIVER_TI_CPSW
450 	if (read_eeprom(&header) < 0)
451 		puts("Could not get board ID.\n");
452 
453 	if (board_is_bone(&header) || board_is_bone_lt(&header) ||
454 	    board_is_idk(&header)) {
455 		writel(MII_MODE_ENABLE, &cdev->miisel);
456 		cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
457 				PHY_INTERFACE_MODE_MII;
458 	} else {
459 		writel((RGMII_MODE_ENABLE | RGMII_INT_DELAY), &cdev->miisel);
460 		cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
461 				PHY_INTERFACE_MODE_RGMII;
462 	}
463 
464 	rv = cpsw_register(&cpsw_data);
465 	if (rv < 0)
466 		printf("Error %d registering CPSW switch\n", rv);
467 	else
468 		n += rv;
469 #endif
470 
471 	/*
472 	 *
473 	 * CPSW RGMII Internal Delay Mode is not supported in all PVT
474 	 * operating points.  So we must set the TX clock delay feature
475 	 * in the AR8051 PHY.  Since we only support a single ethernet
476 	 * device in U-Boot, we only do this for the first instance.
477 	 */
478 #define AR8051_PHY_DEBUG_ADDR_REG	0x1d
479 #define AR8051_PHY_DEBUG_DATA_REG	0x1e
480 #define AR8051_DEBUG_RGMII_CLK_DLY_REG	0x5
481 #define AR8051_RGMII_TX_CLK_DLY		0x100
482 
483 	if (board_is_evm_sk(&header) || board_is_gp_evm(&header)) {
484 		const char *devname;
485 		devname = miiphy_get_current_dev();
486 
487 		miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_ADDR_REG,
488 				AR8051_DEBUG_RGMII_CLK_DLY_REG);
489 		miiphy_write(devname, 0x0, AR8051_PHY_DEBUG_DATA_REG,
490 				AR8051_RGMII_TX_CLK_DLY);
491 	}
492 #endif
493 #if defined(CONFIG_USB_ETHER) && \
494 	(!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USBETH_SUPPORT))
495 	if (is_valid_ether_addr(mac_addr))
496 		eth_setenv_enetaddr("usbnet_devaddr", mac_addr);
497 
498 	rv = usb_eth_initialize(bis);
499 	if (rv < 0)
500 		printf("Error %d registering USB_ETHER\n", rv);
501 	else
502 		n += rv;
503 #endif
504 	return n;
505 }
506 #endif
507