smc91111.c 39.4 KB
Newer Older
W
wdenk 已提交
1 2 3 4 5 6 7 8 9
/*------------------------------------------------------------------------
 . smc91111.c
 . This is a driver for SMSC's 91C111 single-chip Ethernet device.
 .
 . (C) Copyright 2002
 . Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 . Rolf Offermanns <rof@sysgo.de>
 .
 . Copyright (C) 2001 Standard Microsystems Corporation (SMSC)
10
 .	 Developed by Simple Network Magic Corporation (SNMC)
W
wdenk 已提交
11 12 13 14 15 16 17 18 19
 . Copyright (C) 1996 by Erik Stahlman (ES)
 .
 . This program is free software; you can redistribute it and/or modify
 . it under the terms of the GNU General Public License as published by
 . the Free Software Foundation; either version 2 of the License, or
 . (at your option) any later version.
 .
 . This program is distributed in the hope that it will be useful,
 . but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
W
wdenk 已提交
21 22 23 24
 . GNU General Public License for more details.
 .
 . You should have received a copy of the GNU General Public License
 . along with this program; if not, write to the Free Software
25
 . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307	 USA
W
wdenk 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38
 .
 . Information contained in this file was obtained from the LAN91C111
 . manual from SMC.  To get a copy, if you really want one, you can find
 . information under www.smsc.com.
 .
 .
 . "Features" of the SMC chip:
 .   Integrated PHY/MAC for 10/100BaseT Operation
 .   Supports internal and external MII
 .   Integrated 8K packet memory
 .   EEPROM interface for configuration
 .
 . Arguments:
39
 .	io	= for the base address
W
wdenk 已提交
40 41 42
 .	irq	= for the IRQ
 .
 . author:
43 44
 .	Erik Stahlman				( erik@vt.edu )
 .	Daris A Nevil				( dnevil@snmc.com )
W
wdenk 已提交
45 46 47 48 49
 .
 .
 . Hardware multicast code from Peter Cammaert ( pc@denkart.be )
 .
 . Sources:
50 51 52
 .    o	  SMSC LAN91C111 databook (www.smsc.com)
 .    o	  smc9194.c by Erik Stahlman
 .    o	  skeleton.c by Donald Becker ( becker@cesdis.gsfc.nasa.gov )
W
wdenk 已提交
53 54
 .
 . History:
55
 .	06/19/03  Richard Woodruff Made u-boot environment aware and added mac addr checks.
W
wdenk 已提交
56
 .	10/17/01  Marco Hasewinkel Modify for DNP/1110
57 58 59
 .	07/25/01  Woojung Huh	   Modify for ADS Bitsy
 .	04/25/01  Daris A Nevil	   Initial public release through SMSC
 .	03/16/01  Daris A Nevil	   Modified smc9194.c for use with LAN91C111
W
wdenk 已提交
60 61 62 63
 ----------------------------------------------------------------------------*/

#include <common.h>
#include <command.h>
W
wdenk 已提交
64
#include <config.h>
W
wdenk 已提交
65 66 67 68 69 70 71 72 73 74
#include "smc91111.h"
#include <net.h>

#ifdef CONFIG_DRIVER_SMC91111

/* Use power-down feature of the chip */
#define POWER_DOWN	0

#define NO_AUTOPROBE

W
wdenk 已提交
75 76 77
#define SMC_DEBUG 0

#if SMC_DEBUG > 1
W
wdenk 已提交
78 79
static const char version[] =
	"smc91111.c:v1.0 04/25/01 by Daris A Nevil (dnevil@snmc.com)\n";
W
wdenk 已提交
80
#endif
W
wdenk 已提交
81

W
wdenk 已提交
82 83 84 85 86
/* Autonegotiation timeout in seconds */
#ifndef CONFIG_SMC_AUTONEG_TIMEOUT
#define CONFIG_SMC_AUTONEG_TIMEOUT 10
#endif

W
wdenk 已提交
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
/*------------------------------------------------------------------------
 .
 . Configuration options, for the experienced user to change.
 .
 -------------------------------------------------------------------------*/

/*
 . Wait time for memory to be free.  This probably shouldn't be
 . tuned that much, as waiting for this means nothing else happens
 . in the system
*/
#define MEMORY_WAIT_TIME 16


#if (SMC_DEBUG > 2 )
#define PRINTK3(args...) printf(args)
#else
#define PRINTK3(args...)
#endif

#if SMC_DEBUG > 1
#define PRINTK2(args...) printf(args)
#else
#define PRINTK2(args...)
#endif

#ifdef SMC_DEBUG
#define PRINTK(args...) printf(args)
#else
#define PRINTK(args...)
#endif


/*------------------------------------------------------------------------
 .
122
 . The internal workings of the driver.	 If you are changing anything
W
wdenk 已提交
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
 . here with the SMC stuff, you should have the datasheet and know
 . what you are doing.
 .
 -------------------------------------------------------------------------*/
#define CARDNAME "LAN91C111"

/* Memory sizing constant */
#define LAN91C111_MEMORY_MULTIPLIER	(1024*2)

#ifndef CONFIG_SMC91111_BASE
#define CONFIG_SMC91111_BASE 0x20000300
#endif

#define SMC_BASE_ADDRESS CONFIG_SMC91111_BASE

#define SMC_DEV_NAME "SMC91111"
#define SMC_PHY_ADDR 0x0000
#define SMC_ALLOC_MAX_TRY 5
#define SMC_TX_TIMEOUT 30

#define SMC_PHY_CLOCK_DELAY 1000

#define ETH_ZLEN 60

147
#ifdef	CONFIG_SMC_USE_32_BIT
W
wdenk 已提交
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
#define USE_32_BIT  1
#else
#undef USE_32_BIT
#endif
/*-----------------------------------------------------------------
 .
 .  The driver can be entered at any of the following entry points.
 .
 .------------------------------------------------------------------  */

extern int eth_init(bd_t *bd);
extern void eth_halt(void);
extern int eth_rx(void);
extern int eth_send(volatile void *packet, int length);


/*
 . This is called by  register_netdev().  It is responsible for
 . checking the portlist for the SMC9000 series chipset.  If it finds
 . one, then it will initialize the device, find the hardware information,
 . and sets up the appropriate device parameters.
 . NOTE: Interrupts are *OFF* when this procedure is called.
 .
 . NB:This shouldn't be static since it is referred to externally.
*/
int smc_init(void);

/*
 . This is called by  unregister_netdev().  It is responsible for
 . cleaning up before the driver is finally unregistered and discarded.
*/
void smc_destructor(void);

/*
 . The kernel calls this function when someone wants to use the device,
 . typically 'ifconfig ethX up'.
*/
W
wdenk 已提交
185
static int smc_open(bd_t *bd);
W
wdenk 已提交
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207


/*
 . This is called by the kernel in response to 'ifconfig ethX down'.  It
 . is responsible for cleaning up everything that the open routine
 . does, and maybe putting the card into a powerdown state.
*/
static int smc_close(void);

/*
 . Configures the PHY through the MII Management interface
*/
#ifndef CONFIG_SMC91111_EXT_PHY
static void smc_phy_configure(void);
#endif /* !CONFIG_SMC91111_EXT_PHY */

/*
 . This is a separate procedure to handle the receipt of a packet, to
 . leave the interrupt code looking slightly cleaner
*/
static int smc_rcv(void);

W
wdenk 已提交
208
/* See if a MAC address is defined in the current environment. If so use it. If not
W
wdenk 已提交
209
 . print a warning and set the environment and other globals with the default.
W
wdenk 已提交
210 211 212 213
 . If an EEPROM is present it really should be consulted.
*/
int smc_get_ethaddr(bd_t *bd);
int get_rom_mac(char *v_rom_mac);
W
wdenk 已提交
214 215 216 217 218 219 220 221 222

/*
 ------------------------------------------------------------
 .
 . Internal routines
 .
 ------------------------------------------------------------
*/

W
wdenk 已提交
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
#ifdef CONFIG_SMC_USE_IOFUNCS
/*
 * input and output functions
 *
 * Implemented due to inx,outx macros accessing the device improperly
 * and putting the device into an unkown state.
 *
 * For instance, on Sharp LPD7A400 SDK, affects were chip memory
 * could not be free'd (hence the alloc failures), duplicate packets,
 * packets being corrupt (shifted) on the wire, etc.  Switching to the
 * inx,outx functions fixed this problem.
 */
static inline word SMC_inw(dword offset);
static inline void SMC_outw(word value, dword offset);
static inline byte SMC_inb(dword offset);
static inline void SMC_outb(byte value, dword offset);
static inline void SMC_insw(dword offset, volatile uchar* buf, dword len);
static inline void SMC_outsw(dword offset, uchar* buf, dword len);

#define barrier() __asm__ __volatile__("": : :"memory")

static inline word SMC_inw(dword offset)
{
	word v;
	v = *((volatile word*)(SMC_BASE_ADDRESS+offset));
	barrier(); *(volatile u32*)(0xc0000000);
	return v;
}

static inline void SMC_outw(word value, dword offset)
{
	*((volatile word*)(SMC_BASE_ADDRESS+offset)) = value;
	barrier(); *(volatile u32*)(0xc0000000);
}

static inline byte SMC_inb(dword offset)
{
	word  _w;

	_w = SMC_inw(offset & ~((dword)1));
	return (offset & 1) ? (byte)(_w >> 8) : (byte)(_w);
}

static inline void SMC_outb(byte value, dword offset)
{
	word  _w;

	_w = SMC_inw(offset & ~((dword)1));
	if (offset & 1)
			*((volatile word*)(SMC_BASE_ADDRESS+(offset & ~((dword)1)))) = (value<<8) | (_w & 0x00ff);
	else
			*((volatile word*)(SMC_BASE_ADDRESS+offset)) = value | (_w & 0xff00);
}

static inline void SMC_insw(dword offset, volatile uchar* buf, dword len)
{
	while (len-- > 0) {
		*((word*)buf)++ = SMC_inw(offset);
		barrier(); *((volatile u32*)(0xc0000000));
	}
}

static inline void SMC_outsw(dword offset, uchar* buf, dword len)
{
	while (len-- > 0) {
		SMC_outw(*((word*)buf)++, offset);
		barrier(); *(volatile u32*)(0xc0000000);
	}
}
#endif  /* CONFIG_SMC_USE_IOFUNCS */

W
wdenk 已提交
294
static char unsigned smc_mac_addr[6] = {0x02, 0x80, 0xad, 0x20, 0x31, 0xb8};
W
wdenk 已提交
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310

/*
 * This function must be called before smc_open() if you want to override
 * the default mac address.
 */

void smc_set_mac_addr(const char *addr) {
	int i;

	for (i=0; i < sizeof(smc_mac_addr); i++){
		smc_mac_addr[i] = addr[i];
	}
}

/*
 * smc_get_macaddr is no longer used. If you want to override the default
W
wdenk 已提交
311
 * mac address, call smc_get_mac_addr as a part of the board initialization.
W
wdenk 已提交
312 313 314 315 316
 */

#if 0
void smc_get_macaddr( byte *addr ) {
	/* MAC ADDRESS AT FLASHBLOCK 1 / OFFSET 0x10 */
W
wdenk 已提交
317
	unsigned char *dnp1110_mac = (unsigned char *) (0xE8000000 + 0x20010);
W
wdenk 已提交
318 319 320
	int i;


W
wdenk 已提交
321 322 323 324 325 326 327 328
	for (i=0; i<6; i++) {
	    addr[0] = *(dnp1110_mac+0);
	    addr[1] = *(dnp1110_mac+1);
	    addr[2] = *(dnp1110_mac+2);
	    addr[3] = *(dnp1110_mac+3);
	    addr[4] = *(dnp1110_mac+4);
	    addr[5] = *(dnp1110_mac+5);
	}
W
wdenk 已提交
329 330 331 332
}
#endif /* 0 */

/***********************************************
333
 * Show available memory		       *
W
wdenk 已提交
334 335 336
 ***********************************************/
void dump_memory_info(void)
{
W
wdenk 已提交
337 338
	word mem_info;
	word old_bank;
W
wdenk 已提交
339

W
wdenk 已提交
340
	old_bank = SMC_inw(BANK_SELECT)&0xF;
W
wdenk 已提交
341

W
wdenk 已提交
342 343 344
	SMC_SELECT_BANK(0);
	mem_info = SMC_inw( MIR_REG );
	PRINTK2("Memory: %4d available\n", (mem_info >> 8)*2048);
W
wdenk 已提交
345

W
wdenk 已提交
346
	SMC_SELECT_BANK(old_bank);
W
wdenk 已提交
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
}
/*
 . A rather simple routine to print out a packet for debugging purposes.
*/
#if SMC_DEBUG > 2
static void print_packet( byte *, int );
#endif

#define tx_done(dev) 1


/* this does a soft reset on the device */
static void smc_reset( void );

/* Enable Interrupts, Receive, and Transmit */
static void smc_enable( void );

/* this puts the device in an inactive state */
static void smc_shutdown( void );

/* Routines to Read and Write the PHY Registers across the
   MII Management Interface
*/

#ifndef CONFIG_SMC91111_EXT_PHY
static word smc_read_phy_register(byte phyreg);
static void smc_write_phy_register(byte phyreg, word phydata);
#endif /* !CONFIG_SMC91111_EXT_PHY */


377 378 379 380 381 382 383 384 385 386 387 388 389
static int poll4int (byte mask, int timeout)
{
	int tmo = get_timer (0) + timeout * CFG_HZ;
	int is_timeout = 0;
	word old_bank = SMC_inw (BSR_REG);

	PRINTK2 ("Polling...\n");
	SMC_SELECT_BANK (2);
	while ((SMC_inw (SMC91111_INT_REG) & mask) == 0) {
		if (get_timer (0) >= tmo) {
			is_timeout = 1;
			break;
		}
W
wdenk 已提交
390 391
	}

392 393
	/* restore old bank selection */
	SMC_SELECT_BANK (old_bank);
W
wdenk 已提交
394

395 396 397 398
	if (is_timeout)
		return 1;
	else
		return 0;
W
wdenk 已提交
399 400
}

401
/* Only one release command at a time, please */
402
static inline void smc_wait_mmu_release_complete (void)
403 404
{
	int count = 0;
405

406
	/* assume bank 2 selected */
407 408 409 410
	while (SMC_inw (MMU_CMD_REG) & MC_BUSY) {
		udelay (1);	/* Wait until not busy */
		if (++count > 200)
			break;
411 412 413
	}
}

W
wdenk 已提交
414 415 416
/*
 . Function: smc_reset( void )
 . Purpose:
417 418
 .	This sets the SMC91111 chip to its normal state, hopefully from whatever
 .	mess that any other DOS driver has put it in.
W
wdenk 已提交
419 420 421 422 423 424 425 426 427 428 429 430
 .
 . Maybe I should reset more registers to defaults in here?  SOFTRST  should
 . do that for me.
 .
 . Method:
 .	1.  send a SOFT RESET
 .	2.  wait for it to finish
 .	3.  enable autorelease mode
 .	4.  reset the memory management unit
 .	5.  clear all interrupts
 .
*/
431
static void smc_reset (void)
W
wdenk 已提交
432
{
W
wdenk 已提交
433
	PRINTK2 ("%s: smc_reset\n", SMC_DEV_NAME);
W
wdenk 已提交
434 435 436

	/* This resets the registers mostly to defaults, but doesn't
	   affect EEPROM.  That seems unnecessary */
437 438
	SMC_SELECT_BANK (0);
	SMC_outw (RCR_SOFTRST, RCR_REG);
W
wdenk 已提交
439 440 441 442 443

	/* Setup the Configuration Register */
	/* This is necessary because the CONFIG_REG is not affected */
	/* by a soft reset */

444
	SMC_SELECT_BANK (1);
W
wdenk 已提交
445
#if defined(CONFIG_SMC91111_EXT_PHY)
446
	SMC_outw (CONFIG_DEFAULT | CONFIG_EXT_PHY, CONFIG_REG);
W
wdenk 已提交
447
#else
448
	SMC_outw (CONFIG_DEFAULT, CONFIG_REG);
W
wdenk 已提交
449 450 451 452 453
#endif


	/* Release from possible power-down state */
	/* Configuration register is not affected by Soft Reset */
454
	SMC_outw (SMC_inw (CONFIG_REG) | CONFIG_EPH_POWER_EN, CONFIG_REG);
W
wdenk 已提交
455

456
	SMC_SELECT_BANK (0);
W
wdenk 已提交
457 458

	/* this should pause enough for the chip to be happy */
459
	udelay (10);
W
wdenk 已提交
460 461

	/* Disable transmit and receive functionality */
462 463
	SMC_outw (RCR_CLEAR, RCR_REG);
	SMC_outw (TCR_CLEAR, TCR_REG);
W
wdenk 已提交
464 465

	/* set the control register */
466 467
	SMC_SELECT_BANK (1);
	SMC_outw (CTL_DEFAULT, CTL_REG);
W
wdenk 已提交
468 469

	/* Reset the MMU */
470 471 472 473 474
	SMC_SELECT_BANK (2);
	smc_wait_mmu_release_complete ();
	SMC_outw (MC_RESET, MMU_CMD_REG);
	while (SMC_inw (MMU_CMD_REG) & MC_BUSY)
		udelay (1);	/* Wait until not busy */
W
wdenk 已提交
475 476 477

	/* Note:  It doesn't seem that waiting for the MMU busy is needed here,
	   but this is a place where future chipsets _COULD_ break.  Be wary
W
wdenk 已提交
478
	   of issuing another MMU command right after this */
W
wdenk 已提交
479 480

	/* Disable all interrupts */
481
	SMC_outb (0, IM_REG);
W
wdenk 已提交
482 483 484 485 486 487 488 489 490 491 492 493
}

/*
 . Function: smc_enable
 . Purpose: let the chip talk to the outside work
 . Method:
 .	1.  Enable the transmitter
 .	2.  Enable the receiver
 .	3.  Enable interrupts
*/
static void smc_enable()
{
W
wdenk 已提交
494
	PRINTK2("%s: smc_enable\n", SMC_DEV_NAME);
W
wdenk 已提交
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
	SMC_SELECT_BANK( 0 );
	/* see the header file for options in TCR/RCR DEFAULT*/
	SMC_outw( TCR_DEFAULT, TCR_REG );
	SMC_outw( RCR_DEFAULT, RCR_REG );

	/* clear MII_DIS */
/*	smc_write_phy_register(PHY_CNTL_REG, 0x0000); */
}

/*
 . Function: smc_shutdown
 . Purpose:  closes down the SMC91xxx chip.
 . Method:
 .	1. zero the interrupt mask
 .	2. clear the enable receive flag
 .	3. clear the enable xmit flags
 .
 . TODO:
 .   (1) maybe utilize power down mode.
 .	Why not yet?  Because while the chip will go into power down mode,
 .	the manual says that it will wake up in response to any I/O requests
516
 .	in the register space.	 Empirical results do not show this working.
W
wdenk 已提交
517 518 519
*/
static void smc_shutdown()
{
W
wdenk 已提交
520
	PRINTK2(CARDNAME ": smc_shutdown\n");
W
wdenk 已提交
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538

	/* no more interrupts for me */
	SMC_SELECT_BANK( 2 );
	SMC_outb( 0, IM_REG );

	/* and tell the card to stay away from that nasty outside world */
	SMC_SELECT_BANK( 0 );
	SMC_outb( RCR_CLEAR, RCR_REG );
	SMC_outb( TCR_CLEAR, TCR_REG );
}


/*
 . Function:  smc_hardware_send_packet(struct net_device * )
 . Purpose:
 .	This sends the actual packet to the SMC9xxx chip.
 .
 . Algorithm:
539
 .	First, see if a saved_skb is available.
W
wdenk 已提交
540 541 542 543 544 545 546
 .		( this should NOT be called if there is no 'saved_skb'
 .	Now, find the packet number that the chip allocated
 .	Point the data pointers at it in memory
 .	Set the length word in the chip's memory
 .	Dump the packet to chip memory
 .	Check if a last byte is needed ( odd length packet )
 .		if so, set the control flag right
547
 .	Tell the card to send it
W
wdenk 已提交
548
 .	Enable the transmit interrupt, so I know if it failed
549
 .	Free the kernel data if I actually sent it.
W
wdenk 已提交
550
*/
551
static int smc_send_packet (volatile void *packet, int packet_length)
W
wdenk 已提交
552
{
553 554 555 556 557 558 559 560
	byte packet_no;
	unsigned long ioaddr;
	byte *buf;
	int length;
	int numPages;
	int try = 0;
	int time_out;
	byte status;
W
wdenk 已提交
561 562
	byte saved_pnr;
	word saved_ptr;
W
wdenk 已提交
563

W
wdenk 已提交
564
	/* save PTR and PNR registers before manipulation */
W
wdenk 已提交
565
	SMC_SELECT_BANK (2);
W
wdenk 已提交
566 567
	saved_pnr = SMC_inb( PN_REG );
	saved_ptr = SMC_inw( PTR_REG );
W
wdenk 已提交
568

W
wdenk 已提交
569
	PRINTK3 ("%s: smc_hardware_send_packet\n", SMC_DEV_NAME);
W
wdenk 已提交
570 571 572 573

	length = ETH_ZLEN < packet_length ? packet_length : ETH_ZLEN;

	/* allocate memory
574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
	 ** The MMU wants the number of pages to be the number of 256 bytes
	 ** 'pages', minus 1 ( since a packet can't ever have 0 pages :) )
	 **
	 ** The 91C111 ignores the size bits, but the code is left intact
	 ** for backwards and future compatibility.
	 **
	 ** Pkt size for allocating is data length +6 (for additional status
	 ** words, length and ctl!)
	 **
	 ** If odd size then last byte is included in this header.
	 */
	numPages = ((length & 0xfffe) + 6);
	numPages >>= 8;		/* Divide by 256 */

	if (numPages > 7) {
		printf ("%s: Far too big packet error. \n", SMC_DEV_NAME);
W
wdenk 已提交
590 591 592 593
		return 0;
	}

	/* now, try to allocate the memory */
594 595
	SMC_SELECT_BANK (2);
	SMC_outw (MC_ALLOC | numPages, MMU_CMD_REG);
W
wdenk 已提交
596

W
wdenk 已提交
597
	/* FIXME: the ALLOC_INT bit never gets set *
598 599 600
	 * so the following will always give a	   *
	 * memory allocation error.		   *
	 * same code works in armboot though	   *
W
wdenk 已提交
601 602 603
	 * -ro
	 */

W
wdenk 已提交
604 605 606 607
again:
	try++;
	time_out = MEMORY_WAIT_TIME;
	do {
608 609
		status = SMC_inb (SMC91111_INT_REG);
		if (status & IM_ALLOC_INT) {
W
wdenk 已提交
610
			/* acknowledge the interrupt */
611
			SMC_outb (IM_ALLOC_INT, SMC91111_INT_REG);
W
wdenk 已提交
612
			break;
W
wdenk 已提交
613
		}
614 615 616 617 618 619 620 621 622
	} while (--time_out);

	if (!time_out) {
		PRINTK2 ("%s: memory allocation, try %d failed ...\n",
			 SMC_DEV_NAME, try);
		if (try < SMC_ALLOC_MAX_TRY)
			goto again;
		else
			return 0;
W
wdenk 已提交
623 624
	}

625 626
	PRINTK2 ("%s: memory allocation, try %d succeeded ...\n",
		 SMC_DEV_NAME, try);
W
wdenk 已提交
627 628 629 630 631

	/* I can send the packet now.. */

	ioaddr = SMC_BASE_ADDRESS;

632
	buf = (byte *) packet;
W
wdenk 已提交
633 634

	/* If I get here, I _know_ there is a packet slot waiting for me */
635 636
	packet_no = SMC_inb (AR_REG);
	if (packet_no & AR_FAILED) {
W
wdenk 已提交
637
		/* or isn't there?  BAD CHIP! */
638
		printf ("%s: Memory allocation failed. \n", SMC_DEV_NAME);
W
wdenk 已提交
639 640 641 642
		return 0;
	}

	/* we have a packet address, so tell the card to use it */
643
#ifndef CONFIG_XAENIAX
644
	SMC_outb (packet_no, PN_REG);
645 646 647 648 649 650 651
#else
	/* On Xaeniax board, we can't use SMC_outb here because that way
	 * the Allocate MMU command will end up written to the command register
	 * as well, which will lead to a problem.
	 */
	SMC_outl (packet_no << 16, 0);
#endif
W
wdenk 已提交
652 653
	/* do not write new ptr value if Write data fifo not empty */
	while ( saved_ptr & PTR_NOTEMPTY )
W
wdenk 已提交
654 655
		printf ("Write data fifo not empty!\n");

W
wdenk 已提交
656
	/* point to the beginning of the packet */
657
	SMC_outw (PTR_AUTOINC, PTR_REG);
W
wdenk 已提交
658

659 660
	PRINTK3 ("%s: Trying to xmit packet of length %x\n",
		 SMC_DEV_NAME, length);
W
wdenk 已提交
661 662

#if SMC_DEBUG > 2
663 664
	printf ("Transmitting Packet\n");
	print_packet (buf, length);
W
wdenk 已提交
665 666 667
#endif

	/* send the packet length ( +6 for status, length and ctl byte )
W
wdenk 已提交
668
	   and the status word ( set to zeros ) */
W
wdenk 已提交
669
#ifdef USE_32_BIT
670
	SMC_outl ((length + 6) << 16, SMC91111_DATA_REG);
W
wdenk 已提交
671
#else
672 673 674
	SMC_outw (0, SMC91111_DATA_REG);
	/* send the packet length ( +6 for status words, length, and ctl */
	SMC_outw ((length + 6), SMC91111_DATA_REG);
W
wdenk 已提交
675 676 677
#endif

	/* send the actual data
678 679
	   . I _think_ it's faster to send the longs first, and then
	   . mop up by sending the last word.  It depends heavily
680
	   . on alignment, at least on the 486.	 Maybe it would be
681 682 683
	   . a good idea to check which is optimal?  But that could take
	   . almost as much time as is saved?
	 */
W
wdenk 已提交
684
#ifdef USE_32_BIT
685 686 687 688
	SMC_outsl (SMC91111_DATA_REG, buf, length >> 2);
	if (length & 0x2)
		SMC_outw (*((word *) (buf + (length & 0xFFFFFFFC))),
			  SMC91111_DATA_REG);
W
wdenk 已提交
689
#else
690
	SMC_outsw (SMC91111_DATA_REG, buf, (length) >> 1);
W
wdenk 已提交
691 692
#endif /* USE_32_BIT */

693
	/* Send the last byte, if there is one.	  */
694 695
	if ((length & 1) == 0) {
		SMC_outw (0, SMC91111_DATA_REG);
W
wdenk 已提交
696
	} else {
697
		SMC_outw (buf[length - 1] | 0x2000, SMC91111_DATA_REG);
W
wdenk 已提交
698 699 700
	}

	/* and let the chipset deal with it */
701
	SMC_outw (MC_ENQUEUE, MMU_CMD_REG);
W
wdenk 已提交
702 703

	/* poll for TX INT */
W
wdenk 已提交
704 705 706
	/* if (poll4int (IM_TX_INT, SMC_TX_TIMEOUT)) { */
	/* poll for TX_EMPTY INT - autorelease enabled */
	if (poll4int(IM_TX_EMPTY_INT, SMC_TX_TIMEOUT)) {
W
wdenk 已提交
707
		/* sending failed */
708
		PRINTK2 ("%s: TX timeout, sending failed...\n", SMC_DEV_NAME);
W
wdenk 已提交
709 710

		/* release packet */
W
wdenk 已提交
711
		/* no need to release, MMU does that now */
712 713 714
#ifdef CONFIG_XAENIAX
		 SMC_outw (MC_FREEPKT, MMU_CMD_REG);
#endif
W
wdenk 已提交
715

W
wdenk 已提交
716
		/* wait for MMU getting ready (low) */
717 718
		while (SMC_inw (MMU_CMD_REG) & MC_BUSY) {
			udelay (10);
W
wdenk 已提交
719
		}
W
wdenk 已提交
720

721
		PRINTK2 ("MMU ready\n");
W
wdenk 已提交
722 723 724 725 726


		return 0;
	} else {
		/* ack. int */
W
wdenk 已提交
727 728
		SMC_outb (IM_TX_EMPTY_INT, SMC91111_INT_REG);
		/* SMC_outb (IM_TX_INT, SMC91111_INT_REG); */
729 730
		PRINTK2 ("%s: Sent packet of length %d \n", SMC_DEV_NAME,
			 length);
W
wdenk 已提交
731 732

		/* release packet */
W
wdenk 已提交
733
		/* no need to release, MMU does that now */
734 735 736
#ifdef CONFIG_XAENIAX
		SMC_outw (MC_FREEPKT, MMU_CMD_REG);
#endif
W
wdenk 已提交
737

W
wdenk 已提交
738
		/* wait for MMU getting ready (low) */
739 740
		while (SMC_inw (MMU_CMD_REG) & MC_BUSY) {
			udelay (10);
W
wdenk 已提交
741
		}
W
wdenk 已提交
742

743
		PRINTK2 ("MMU ready\n");
W
wdenk 已提交
744 745 746 747


	}

W
wdenk 已提交
748
	/* restore previously saved registers */
749
#ifndef CONFIG_XAENIAX
W
wdenk 已提交
750
	SMC_outb( saved_pnr, PN_REG );
751 752 753 754 755 756 757
#else
	/* On Xaeniax board, we can't use SMC_outb here because that way
	 * the Allocate MMU command will end up written to the command register
	 * as well, which will lead to a problem.
	 */
	SMC_outl(saved_pnr << 16, 0);
#endif
W
wdenk 已提交
758 759
	SMC_outw( saved_ptr, PTR_REG );

W
wdenk 已提交
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775
	return length;
}

/*-------------------------------------------------------------------------
 |
 | smc_destructor( struct net_device * dev )
 |   Input parameters:
 |	dev, pointer to the device structure
 |
 |   Output:
 |	None.
 |
 ---------------------------------------------------------------------------
*/
void smc_destructor()
{
W
wdenk 已提交
776
	PRINTK2(CARDNAME ": smc_destructor\n");
W
wdenk 已提交
777 778 779 780 781 782 783 784 785
}


/*
 * Open and Initialize the board
 *
 * Set up everything, reset the card, etc ..
 *
 */
786
static int smc_open (bd_t * bd)
W
wdenk 已提交
787
{
788
	int i, err;
W
wdenk 已提交
789

W
wdenk 已提交
790
	PRINTK2 ("%s: smc_open\n", SMC_DEV_NAME);
W
wdenk 已提交
791 792

	/* reset the hardware */
793 794
	smc_reset ();
	smc_enable ();
W
wdenk 已提交
795 796 797

	/* Configure the PHY */
#ifndef CONFIG_SMC91111_EXT_PHY
798
	smc_phy_configure ();
W
wdenk 已提交
799 800 801 802 803
#endif

	/* conservative setting (10Mbps, HalfDuplex, no AutoNeg.) */
/*	SMC_SELECT_BANK(0); */
/*	SMC_outw(0, RPC_REG); */
804
	SMC_SELECT_BANK (1);
805

806 807
	err = smc_get_ethaddr (bd);	/* set smc_mac_addr, and sync it with u-boot globals */
	if (err < 0) {
808
		memset (bd->bi_enetaddr, 0, 6); /* hack to make error stick! upper code will abort if not set */
809 810
		return (-1);	/* upper code ignores this, but NOT bi_enetaddr */
	}
W
wdenk 已提交
811
#ifdef USE_32_BIT
812
	for (i = 0; i < 6; i += 2) {
W
wdenk 已提交
813 814
		word address;

815 816
		address = smc_mac_addr[i + 1] << 8;
		address |= smc_mac_addr[i];
W
wdenk 已提交
817
		SMC_outw (address, (ADDR0_REG + i));
W
wdenk 已提交
818 819
	}
#else
820
	for (i = 0; i < 6; i++)
W
wdenk 已提交
821
		SMC_outb (smc_mac_addr[i], (ADDR0_REG + i));
W
wdenk 已提交
822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840
#endif

	return 0;
}

/*-------------------------------------------------------------
 .
 . smc_rcv -  receive a packet from the card
 .
 . There is ( at least ) a packet waiting to be read from
 . chip-memory.
 .
 . o Read the status
 . o If an error, record it
 . o otherwise, read in the packet
 --------------------------------------------------------------
*/
static int smc_rcv()
{
841
	int	packet_number;
W
wdenk 已提交
842 843
	word	status;
	word	packet_length;
844
	int	is_error = 0;
W
wdenk 已提交
845 846 847
#ifdef USE_32_BIT
	dword stat_len;
#endif
W
wdenk 已提交
848 849
	byte saved_pnr;
	word saved_ptr;
W
wdenk 已提交
850 851

	SMC_SELECT_BANK(2);
W
wdenk 已提交
852 853 854 855
	/* save PTR and PTR registers */
	saved_pnr = SMC_inb( PN_REG );
	saved_ptr = SMC_inw( PTR_REG );

W
wdenk 已提交
856 857 858 859 860 861 862
	packet_number = SMC_inw( RXFIFO_REG );

	if ( packet_number & RXFIFO_REMPTY ) {

		return 0;
	}

W
wdenk 已提交
863
	PRINTK3("%s: smc_rcv\n", SMC_DEV_NAME);
W
wdenk 已提交
864 865 866 867 868 869 870 871 872
	/*  start reading from the start of the packet */
	SMC_outw( PTR_READ | PTR_RCV | PTR_AUTOINC, PTR_REG );

	/* First two words are status and packet_length */
#ifdef USE_32_BIT
	stat_len = SMC_inl(SMC91111_DATA_REG);
	status = stat_len & 0xffff;
	packet_length = stat_len >> 16;
#else
873 874
	status		= SMC_inw( SMC91111_DATA_REG );
	packet_length	= SMC_inw( SMC91111_DATA_REG );
W
wdenk 已提交
875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896
#endif

	packet_length &= 0x07ff;  /* mask off top bits */

	PRINTK2("RCV: STATUS %4x LENGTH %4x\n", status, packet_length );

	if ( !(status & RS_ERRORS ) ){
		/* Adjust for having already read the first two words */
		packet_length -= 4; /*4; */


		/* set odd length for bug in LAN91C111, */
		/* which never sets RS_ODDFRAME */
		/* TODO ? */


#ifdef USE_32_BIT
		PRINTK3(" Reading %d dwords (and %d bytes) \n",
			packet_length >> 2, packet_length & 3 );
		/* QUESTION:  Like in the TX routine, do I want
		   to send the DWORDs or the bytes first, or some
		   mixture.  A mixture might improve already slow PIO
897
		   performance	*/
W
wdenk 已提交
898 899 900 901 902
		SMC_insl( SMC91111_DATA_REG , NetRxPackets[0], packet_length >> 2 );
		/* read the left over bytes */
		if (packet_length & 3) {
			int i;

903
			byte *tail = (byte *)(NetRxPackets[0] + (packet_length & ~3));
W
wdenk 已提交
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933
			dword leftover = SMC_inl(SMC91111_DATA_REG);
			for (i=0; i<(packet_length & 3); i++)
				*tail++ = (byte) (leftover >> (8*i)) & 0xff;
		}
#else
		PRINTK3(" Reading %d words and %d byte(s) \n",
			(packet_length >> 1 ), packet_length & 1 );
		SMC_insw(SMC91111_DATA_REG , NetRxPackets[0], packet_length >> 1);

#endif /* USE_32_BIT */

#if	SMC_DEBUG > 2
		printf("Receiving Packet\n");
		print_packet( NetRxPackets[0], packet_length );
#endif
	} else {
		/* error ... */
		/* TODO ? */
		is_error = 1;
	}

	while ( SMC_inw( MMU_CMD_REG ) & MC_BUSY )
		udelay(1); /* Wait until not busy */

	/*  error or good, tell the card to get rid of this packet */
	SMC_outw( MC_RELEASE, MMU_CMD_REG );

	while ( SMC_inw( MMU_CMD_REG ) & MC_BUSY )
		udelay(1); /* Wait until not busy */

W
wdenk 已提交
934
	/* restore saved registers */
935
#ifndef CONFIG_XAENIAX
W
wdenk 已提交
936
	SMC_outb( saved_pnr, PN_REG );
937 938 939 940 941 942 943
#else
	/* On Xaeniax board, we can't use SMC_outb here because that way
	 * the Allocate MMU command will end up written to the command register
	 * as well, which will lead to a problem.
	 */
	SMC_outl( saved_pnr << 16, 0);
#endif
W
wdenk 已提交
944 945
	SMC_outw( saved_ptr, PTR_REG );

W
wdenk 已提交
946 947 948 949 950 951 952 953 954 955 956 957 958 959 960
	if (!is_error) {
		/* Pass the packet up to the protocol layers. */
		NetReceive(NetRxPackets[0], packet_length);
		return packet_length;
	} else {
		return 0;
	}

}


/*----------------------------------------------------
 . smc_close
 .
 . this makes the board clean up everything that it can
961
 . and not talk to the outside world.	Caused by
W
wdenk 已提交
962 963 964 965 966
 . an 'ifconfig ethX down'
 .
 -----------------------------------------------------*/
static int smc_close()
{
W
wdenk 已提交
967
	PRINTK2("%s: smc_close\n", SMC_DEV_NAME);
W
wdenk 已提交
968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038

	/* clear everything */
	smc_shutdown();

	return 0;
}


#if 0
/*------------------------------------------------------------
 . Modify a bit in the LAN91C111 register set
 .-------------------------------------------------------------*/
static word smc_modify_regbit(int bank, int ioaddr, int reg,
	unsigned int bit, int val)
{
	word regval;

	SMC_SELECT_BANK( bank );

	regval = SMC_inw( reg );
	if (val)
		regval |= bit;
	else
		regval &= ~bit;

	SMC_outw( regval, 0 );
	return(regval);
}


/*------------------------------------------------------------
 . Retrieve a bit in the LAN91C111 register set
 .-------------------------------------------------------------*/
static int smc_get_regbit(int bank, int ioaddr, int reg, unsigned int bit)
{
	SMC_SELECT_BANK( bank );
	if ( SMC_inw( reg ) & bit)
		return(1);
	else
		return(0);
}


/*------------------------------------------------------------
 . Modify a LAN91C111 register (word access only)
 .-------------------------------------------------------------*/
static void smc_modify_reg(int bank, int ioaddr, int reg, word val)
{
	SMC_SELECT_BANK( bank );
	SMC_outw( val, reg );
}


/*------------------------------------------------------------
 . Retrieve a LAN91C111 register (word access only)
 .-------------------------------------------------------------*/
static int smc_get_reg(int bank, int ioaddr, int reg)
{
	SMC_SELECT_BANK( bank );
	return(SMC_inw( reg ));
}

#endif /* 0 */

/*---PHY CONTROL AND CONFIGURATION----------------------------------------- */

#if (SMC_DEBUG > 2 )

/*------------------------------------------------------------
 . Debugging function for viewing MII Management serial bitstream
 .-------------------------------------------------------------*/
1039
static void smc_dump_mii_stream (byte * bits, int size)
W
wdenk 已提交
1040 1041 1042
{
	int i;

1043 1044 1045 1046
	printf ("BIT#:");
	for (i = 0; i < size; ++i) {
		printf ("%d", i % 10);
	}
W
wdenk 已提交
1047

1048 1049
	printf ("\nMDOE:");
	for (i = 0; i < size; ++i) {
W
wdenk 已提交
1050
		if (bits[i] & MII_MDOE)
1051
			printf ("1");
W
wdenk 已提交
1052
		else
1053 1054
			printf ("0");
	}
W
wdenk 已提交
1055

1056 1057
	printf ("\nMDO :");
	for (i = 0; i < size; ++i) {
W
wdenk 已提交
1058
		if (bits[i] & MII_MDO)
1059
			printf ("1");
W
wdenk 已提交
1060
		else
1061 1062
			printf ("0");
	}
W
wdenk 已提交
1063

1064 1065
	printf ("\nMDI :");
	for (i = 0; i < size; ++i) {
W
wdenk 已提交
1066
		if (bits[i] & MII_MDI)
1067
			printf ("1");
W
wdenk 已提交
1068
		else
1069 1070
			printf ("0");
	}
W
wdenk 已提交
1071

1072
	printf ("\n");
W
wdenk 已提交
1073 1074 1075 1076 1077 1078 1079
}
#endif

/*------------------------------------------------------------
 . Reads a register from the MII Management serial interface
 .-------------------------------------------------------------*/
#ifndef CONFIG_SMC91111_EXT_PHY
1080
static word smc_read_phy_register (byte phyreg)
W
wdenk 已提交
1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104
{
	int oldBank;
	int i;
	byte mask;
	word mii_reg;
	byte bits[64];
	int clk_idx = 0;
	int input_idx;
	word phydata;
	byte phyaddr = SMC_PHY_ADDR;

	/* 32 consecutive ones on MDO to establish sync */
	for (i = 0; i < 32; ++i)
		bits[clk_idx++] = MII_MDOE | MII_MDO;

	/* Start code <01> */
	bits[clk_idx++] = MII_MDOE;
	bits[clk_idx++] = MII_MDOE | MII_MDO;

	/* Read command <10> */
	bits[clk_idx++] = MII_MDOE | MII_MDO;
	bits[clk_idx++] = MII_MDOE;

	/* Output the PHY address, msb first */
1105 1106
	mask = (byte) 0x10;
	for (i = 0; i < 5; ++i) {
W
wdenk 已提交
1107 1108 1109 1110 1111 1112 1113
		if (phyaddr & mask)
			bits[clk_idx++] = MII_MDOE | MII_MDO;
		else
			bits[clk_idx++] = MII_MDOE;

		/* Shift to next lowest bit */
		mask >>= 1;
1114
	}
W
wdenk 已提交
1115 1116

	/* Output the phy register number, msb first */
1117 1118
	mask = (byte) 0x10;
	for (i = 0; i < 5; ++i) {
W
wdenk 已提交
1119 1120 1121 1122 1123 1124 1125
		if (phyreg & mask)
			bits[clk_idx++] = MII_MDOE | MII_MDO;
		else
			bits[clk_idx++] = MII_MDOE;

		/* Shift to next lowest bit */
		mask >>= 1;
1126
	}
W
wdenk 已提交
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142

	/* Tristate and turnaround (2 bit times) */
	bits[clk_idx++] = 0;
	/*bits[clk_idx++] = 0; */

	/* Input starts at this bit time */
	input_idx = clk_idx;

	/* Will input 16 bits */
	for (i = 0; i < 16; ++i)
		bits[clk_idx++] = 0;

	/* Final clock bit */
	bits[clk_idx++] = 0;

	/* Save the current bank */
1143
	oldBank = SMC_inw (BANK_SELECT);
W
wdenk 已提交
1144 1145

	/* Select bank 3 */
1146
	SMC_SELECT_BANK (3);
W
wdenk 已提交
1147 1148

	/* Get the current MII register value */
1149
	mii_reg = SMC_inw (MII_REG);
W
wdenk 已提交
1150 1151

	/* Turn off all MII Interface bits */
1152
	mii_reg &= ~(MII_MDOE | MII_MCLK | MII_MDI | MII_MDO);
W
wdenk 已提交
1153 1154

	/* Clock all 64 cycles */
1155
	for (i = 0; i < sizeof bits; ++i) {
W
wdenk 已提交
1156
		/* Clock Low - output data */
1157 1158
		SMC_outw (mii_reg | bits[i], MII_REG);
		udelay (SMC_PHY_CLOCK_DELAY);
W
wdenk 已提交
1159 1160 1161


		/* Clock Hi - input data */
1162 1163 1164 1165
		SMC_outw (mii_reg | bits[i] | MII_MCLK, MII_REG);
		udelay (SMC_PHY_CLOCK_DELAY);
		bits[i] |= SMC_inw (MII_REG) & MII_MDI;
	}
W
wdenk 已提交
1166 1167 1168

	/* Return to idle state */
	/* Set clock to low, data to low, and output tristated */
1169 1170
	SMC_outw (mii_reg, MII_REG);
	udelay (SMC_PHY_CLOCK_DELAY);
W
wdenk 已提交
1171 1172

	/* Restore original bank select */
1173
	SMC_SELECT_BANK (oldBank);
W
wdenk 已提交
1174 1175 1176

	/* Recover input data */
	phydata = 0;
1177
	for (i = 0; i < 16; ++i) {
W
wdenk 已提交
1178 1179 1180 1181
		phydata <<= 1;

		if (bits[input_idx++] & MII_MDI)
			phydata |= 0x0001;
1182
	}
W
wdenk 已提交
1183 1184

#if (SMC_DEBUG > 2 )
1185
	printf ("smc_read_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
W
wdenk 已提交
1186
		phyaddr, phyreg, phydata);
1187
	smc_dump_mii_stream (bits, sizeof bits);
W
wdenk 已提交
1188 1189
#endif

1190
	return (phydata);
W
wdenk 已提交
1191 1192 1193 1194 1195 1196
}


/*------------------------------------------------------------
 . Writes a register to the MII Management serial interface
 .-------------------------------------------------------------*/
1197
static void smc_write_phy_register (byte phyreg, word phydata)
W
wdenk 已提交
1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219
{
	int oldBank;
	int i;
	word mask;
	word mii_reg;
	byte bits[65];
	int clk_idx = 0;
	byte phyaddr = SMC_PHY_ADDR;

	/* 32 consecutive ones on MDO to establish sync */
	for (i = 0; i < 32; ++i)
		bits[clk_idx++] = MII_MDOE | MII_MDO;

	/* Start code <01> */
	bits[clk_idx++] = MII_MDOE;
	bits[clk_idx++] = MII_MDOE | MII_MDO;

	/* Write command <01> */
	bits[clk_idx++] = MII_MDOE;
	bits[clk_idx++] = MII_MDOE | MII_MDO;

	/* Output the PHY address, msb first */
1220 1221
	mask = (byte) 0x10;
	for (i = 0; i < 5; ++i) {
W
wdenk 已提交
1222 1223 1224 1225 1226 1227 1228
		if (phyaddr & mask)
			bits[clk_idx++] = MII_MDOE | MII_MDO;
		else
			bits[clk_idx++] = MII_MDOE;

		/* Shift to next lowest bit */
		mask >>= 1;
1229
	}
W
wdenk 已提交
1230 1231

	/* Output the phy register number, msb first */
1232 1233
	mask = (byte) 0x10;
	for (i = 0; i < 5; ++i) {
W
wdenk 已提交
1234 1235 1236 1237 1238 1239 1240
		if (phyreg & mask)
			bits[clk_idx++] = MII_MDOE | MII_MDO;
		else
			bits[clk_idx++] = MII_MDOE;

		/* Shift to next lowest bit */
		mask >>= 1;
1241
	}
W
wdenk 已提交
1242 1243 1244 1245 1246 1247 1248

	/* Tristate and turnaround (2 bit times) */
	bits[clk_idx++] = 0;
	bits[clk_idx++] = 0;

	/* Write out 16 bits of data, msb first */
	mask = 0x8000;
1249
	for (i = 0; i < 16; ++i) {
W
wdenk 已提交
1250 1251 1252 1253 1254 1255 1256
		if (phydata & mask)
			bits[clk_idx++] = MII_MDOE | MII_MDO;
		else
			bits[clk_idx++] = MII_MDOE;

		/* Shift to next lowest bit */
		mask >>= 1;
1257
	}
W
wdenk 已提交
1258 1259 1260 1261 1262

	/* Final clock bit (tristate) */
	bits[clk_idx++] = 0;

	/* Save the current bank */
1263
	oldBank = SMC_inw (BANK_SELECT);
W
wdenk 已提交
1264 1265

	/* Select bank 3 */
1266
	SMC_SELECT_BANK (3);
W
wdenk 已提交
1267 1268

	/* Get the current MII register value */
1269
	mii_reg = SMC_inw (MII_REG);
W
wdenk 已提交
1270 1271

	/* Turn off all MII Interface bits */
1272
	mii_reg &= ~(MII_MDOE | MII_MCLK | MII_MDI | MII_MDO);
W
wdenk 已提交
1273 1274

	/* Clock all cycles */
1275
	for (i = 0; i < sizeof bits; ++i) {
W
wdenk 已提交
1276
		/* Clock Low - output data */
1277 1278
		SMC_outw (mii_reg | bits[i], MII_REG);
		udelay (SMC_PHY_CLOCK_DELAY);
W
wdenk 已提交
1279 1280 1281


		/* Clock Hi - input data */
1282 1283 1284 1285
		SMC_outw (mii_reg | bits[i] | MII_MCLK, MII_REG);
		udelay (SMC_PHY_CLOCK_DELAY);
		bits[i] |= SMC_inw (MII_REG) & MII_MDI;
	}
W
wdenk 已提交
1286 1287 1288

	/* Return to idle state */
	/* Set clock to low, data to low, and output tristated */
1289 1290
	SMC_outw (mii_reg, MII_REG);
	udelay (SMC_PHY_CLOCK_DELAY);
W
wdenk 已提交
1291 1292

	/* Restore original bank select */
1293
	SMC_SELECT_BANK (oldBank);
W
wdenk 已提交
1294 1295

#if (SMC_DEBUG > 2 )
1296
	printf ("smc_write_phy_register(): phyaddr=%x,phyreg=%x,phydata=%x\n",
W
wdenk 已提交
1297
		phyaddr, phyreg, phydata);
1298
	smc_dump_mii_stream (bits, sizeof bits);
W
wdenk 已提交
1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319
#endif
}
#endif /* !CONFIG_SMC91111_EXT_PHY */


/*------------------------------------------------------------
 . Waits the specified number of milliseconds - kernel friendly
 .-------------------------------------------------------------*/
#ifndef CONFIG_SMC91111_EXT_PHY
static void smc_wait_ms(unsigned int ms)
{
	udelay(ms*1000);
}
#endif /* !CONFIG_SMC91111_EXT_PHY */


/*------------------------------------------------------------
 . Configures the specified PHY using Autonegotiation. Calls
 . smc_phy_fixed() if the user has requested a certain config.
 .-------------------------------------------------------------*/
#ifndef CONFIG_SMC91111_EXT_PHY
1320
static void smc_phy_configure ()
W
wdenk 已提交
1321 1322 1323
{
	int timeout;
	byte phyaddr;
1324 1325 1326
	word my_phy_caps;	/* My PHY capabilities */
	word my_ad_caps;	/* My Advertised capabilities */
	word status = 0;	/*;my status = 0 */
W
wdenk 已提交
1327 1328
	int failed = 0;

W
wdenk 已提交
1329
	PRINTK3 ("%s: smc_program_phy()\n", SMC_DEV_NAME);
W
wdenk 已提交
1330 1331 1332 1333 1334 1335


	/* Get the detected phy address */
	phyaddr = SMC_PHY_ADDR;

	/* Reset the PHY, setting all other bits to zero */
1336
	smc_write_phy_register (PHY_CNTL_REG, PHY_CNTL_RST);
W
wdenk 已提交
1337 1338

	/* Wait for the reset to complete, or time out */
1339 1340 1341 1342
	timeout = 6;		/* Wait up to 3 seconds */
	while (timeout--) {
		if (!(smc_read_phy_register (PHY_CNTL_REG)
		      & PHY_CNTL_RST)) {
W
wdenk 已提交
1343 1344 1345 1346
			/* reset complete */
			break;
		}

1347 1348 1349 1350 1351
		smc_wait_ms (500);	/* wait 500 millisecs */
	}

	if (timeout < 1) {
		printf ("%s:PHY reset timed out\n", SMC_DEV_NAME);
W
wdenk 已提交
1352
		goto smc_phy_configure_exit;
1353
	}
W
wdenk 已提交
1354 1355 1356 1357 1358 1359

	/* Read PHY Register 18, Status Output */
	/* lp->lastPhy18 = smc_read_phy_register(PHY_INT_REG); */

	/* Enable PHY Interrupts (for register 18) */
	/* Interrupts listed here are disabled */
W
wdenk 已提交
1360
	smc_write_phy_register (PHY_MASK_REG, 0xffff);
W
wdenk 已提交
1361 1362

	/* Configure the Receive/Phy Control register */
1363 1364
	SMC_SELECT_BANK (0);
	SMC_outw (RPC_DEFAULT, RPC_REG);
W
wdenk 已提交
1365 1366

	/* Copy our capabilities from PHY_STAT_REG to PHY_AD_REG */
1367 1368
	my_phy_caps = smc_read_phy_register (PHY_STAT_REG);
	my_ad_caps = PHY_AD_CSMA;	/* I am CSMA capable */
W
wdenk 已提交
1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385

	if (my_phy_caps & PHY_STAT_CAP_T4)
		my_ad_caps |= PHY_AD_T4;

	if (my_phy_caps & PHY_STAT_CAP_TXF)
		my_ad_caps |= PHY_AD_TX_FDX;

	if (my_phy_caps & PHY_STAT_CAP_TXH)
		my_ad_caps |= PHY_AD_TX_HDX;

	if (my_phy_caps & PHY_STAT_CAP_TF)
		my_ad_caps |= PHY_AD_10_FDX;

	if (my_phy_caps & PHY_STAT_CAP_TH)
		my_ad_caps |= PHY_AD_10_HDX;

	/* Update our Auto-Neg Advertisement Register */
1386
	smc_write_phy_register (PHY_AD_REG, my_ad_caps);
W
wdenk 已提交
1387

W
wdenk 已提交
1388 1389 1390 1391 1392
	/* Read the register back.  Without this, it appears that when */
	/* auto-negotiation is restarted, sometimes it isn't ready and */
	/* the link does not come up. */
	smc_read_phy_register(PHY_AD_REG);

W
wdenk 已提交
1393 1394
	PRINTK2 ("%s: phy caps=%x\n", SMC_DEV_NAME, my_phy_caps);
	PRINTK2 ("%s: phy advertised caps=%x\n", SMC_DEV_NAME, my_ad_caps);
W
wdenk 已提交
1395 1396

	/* Restart auto-negotiation process in order to advertise my caps */
1397 1398
	smc_write_phy_register (PHY_CNTL_REG,
				PHY_CNTL_ANEG_EN | PHY_CNTL_ANEG_RST);
W
wdenk 已提交
1399 1400 1401 1402

	/* Wait for the auto-negotiation to complete.  This may take from */
	/* 2 to 3 seconds. */
	/* Wait for the reset to complete, or time out */
W
wdenk 已提交
1403
	timeout = CONFIG_SMC_AUTONEG_TIMEOUT * 2;
1404
	while (timeout--) {
W
wdenk 已提交
1405

1406 1407
		status = smc_read_phy_register (PHY_STAT_REG);
		if (status & PHY_STAT_ANEG_ACK) {
W
wdenk 已提交
1408 1409
			/* auto-negotiate complete */
			break;
1410
		}
W
wdenk 已提交
1411

1412
		smc_wait_ms (500);	/* wait 500 millisecs */
W
wdenk 已提交
1413 1414

		/* Restart auto-negotiation if remote fault */
1415
		if (status & PHY_STAT_REM_FLT) {
W
wdenk 已提交
1416
			printf ("%s: PHY remote fault detected\n",
1417
				SMC_DEV_NAME);
W
wdenk 已提交
1418 1419

			/* Restart auto-negotiation */
W
wdenk 已提交
1420
			printf ("%s: PHY restarting auto-negotiation\n",
W
wdenk 已提交
1421
				SMC_DEV_NAME);
1422 1423 1424 1425 1426
			smc_write_phy_register (PHY_CNTL_REG,
						PHY_CNTL_ANEG_EN |
						PHY_CNTL_ANEG_RST |
						PHY_CNTL_SPEED |
						PHY_CNTL_DPLX);
W
wdenk 已提交
1427
		}
1428
	}
W
wdenk 已提交
1429

1430
	if (timeout < 1) {
W
wdenk 已提交
1431
		printf ("%s: PHY auto-negotiate timed out\n", SMC_DEV_NAME);
W
wdenk 已提交
1432
		failed = 1;
1433
	}
W
wdenk 已提交
1434 1435

	/* Fail if we detected an auto-negotiate remote fault */
1436
	if (status & PHY_STAT_REM_FLT) {
W
wdenk 已提交
1437
		printf ("%s: PHY remote fault detected\n", SMC_DEV_NAME);
W
wdenk 已提交
1438
		failed = 1;
1439
	}
W
wdenk 已提交
1440 1441

	/* Re-Configure the Receive/Phy Control register */
1442
	SMC_outw (RPC_DEFAULT, RPC_REG);
W
wdenk 已提交
1443

W
wdenk 已提交
1444
smc_phy_configure_exit:	;
W
wdenk 已提交
1445 1446 1447 1448 1449 1450 1451 1452

}
#endif /* !CONFIG_SMC91111_EXT_PHY */


#if SMC_DEBUG > 2
static void print_packet( byte * buf, int length )
{
W
wdenk 已提交
1453 1454 1455
	int i;
	int remainder;
	int lines;
W
wdenk 已提交
1456

W
wdenk 已提交
1457
	printf("Packet of length %d \n", length );
W
wdenk 已提交
1458 1459

#if SMC_DEBUG > 3
W
wdenk 已提交
1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482
	lines = length / 16;
	remainder = length % 16;

	for ( i = 0; i < lines ; i ++ ) {
		int cur;

		for ( cur = 0; cur < 8; cur ++ ) {
			byte a, b;

			a = *(buf ++ );
			b = *(buf ++ );
			printf("%02x%02x ", a, b );
		}
		printf("\n");
	}
	for ( i = 0; i < remainder/2 ; i++ ) {
		byte a, b;

		a = *(buf ++ );
		b = *(buf ++ );
		printf("%02x%02x ", a, b );
	}
	printf("\n");
W
wdenk 已提交
1483 1484 1485 1486 1487
#endif
}
#endif

int eth_init(bd_t *bd) {
W
wdenk 已提交
1488
	return (smc_open(bd));
W
wdenk 已提交
1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502
}

void eth_halt() {
	smc_close();
}

int eth_rx() {
	return smc_rcv();
}

int eth_send(volatile void *packet, int length) {
	return smc_send_packet(packet, length);
}

1503
int smc_get_ethaddr (bd_t * bd)
W
wdenk 已提交
1504
{
1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517
	int env_size, rom_valid, env_present = 0, reg;
	char *s = NULL, *e, *v_mac, es[] = "11:22:33:44:55:66";
	uchar s_env_mac[64], v_env_mac[6], v_rom_mac[6];

	env_size = getenv_r ("ethaddr", s_env_mac, sizeof (s_env_mac));
	if ((env_size > 0) && (env_size < sizeof (es))) {	/* exit if env is bad */
		printf ("\n*** ERROR: ethaddr is not set properly!!\n");
		return (-1);
	}

	if (env_size > 0) {
		env_present = 1;
		s = s_env_mac;
W
wdenk 已提交
1518 1519
	}

1520
	for (reg = 0; reg < 6; ++reg) { /* turn string into mac value */
1521 1522 1523
		v_env_mac[reg] = s ? simple_strtoul (s, &e, 16) : 0;
		if (s)
			s = (*e) ? e + 1 : e;
W
wdenk 已提交
1524
	}
1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542

	rom_valid = get_rom_mac (v_rom_mac);	/* get ROM mac value if any */

	if (!env_present) {	/* if NO env */
		if (rom_valid) {	/* but ROM is valid */
			v_mac = v_rom_mac;
			sprintf (s_env_mac, "%02X:%02X:%02X:%02X:%02X:%02X",
				 v_mac[0], v_mac[1], v_mac[2], v_mac[3],
				 v_mac[4], v_mac[5]);
			setenv ("ethaddr", s_env_mac);
		} else {	/* no env, bad ROM */
			printf ("\n*** ERROR: ethaddr is NOT set !!\n");
			return (-1);
		}
	} else {		/* good env, don't care ROM */
		v_mac = v_env_mac;	/* always use a good env over a ROM */
	}

1543
	if (env_present && rom_valid) { /* if both env and ROM are good */
1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560
		if (memcmp (v_env_mac, v_rom_mac, 6) != 0) {
			printf ("\nWarning: MAC addresses don't match:\n");
			printf ("\tHW MAC address:  "
				"%02X:%02X:%02X:%02X:%02X:%02X\n",
				v_rom_mac[0], v_rom_mac[1],
				v_rom_mac[2], v_rom_mac[3],
				v_rom_mac[4], v_rom_mac[5] );
			printf ("\t\"ethaddr\" value: "
				"%02X:%02X:%02X:%02X:%02X:%02X\n",
				v_env_mac[0], v_env_mac[1],
				v_env_mac[2], v_env_mac[3],
				v_env_mac[4], v_env_mac[5]) ;
			debug ("### Set MAC addr from environment\n");
		}
	}
	memcpy (bd->bi_enetaddr, v_mac, 6);	/* update global address to match env (allows env changing) */
	smc_set_mac_addr (v_mac);	/* use old function to update smc default */
W
wdenk 已提交
1561
	PRINTK("Using MAC Address %02X:%02X:%02X:%02X:%02X:%02X\n", v_mac[0], v_mac[1],
1562
		v_mac[2], v_mac[3], v_mac[4], v_mac[5]);
1563
	return (0);
W
wdenk 已提交
1564 1565
}

1566
int get_rom_mac (char *v_rom_mac)
W
wdenk 已提交
1567
{
1568 1569
#ifdef HARDCODE_MAC	/* used for testing or to supress run time warnings */
	char hw_mac_addr[] = { 0x02, 0x80, 0xad, 0x20, 0x31, 0xb8 };
W
wdenk 已提交
1570

1571 1572
	memcpy (v_rom_mac, hw_mac_addr, 6);
	return (1);
W
wdenk 已提交
1573
#else
W
wdenk 已提交
1574
	int i;
W
wdenk 已提交
1575 1576
	int valid_mac = 0;

W
wdenk 已提交
1577 1578 1579
	SMC_SELECT_BANK (1);
	for (i=0; i<6; i++)
	{
W
wdenk 已提交
1580
		v_rom_mac[i] = SMC_inb ((ADDR0_REG + i));
W
wdenk 已提交
1581
		valid_mac |= v_rom_mac[i];
1582
	}
W
wdenk 已提交
1583 1584

	return (valid_mac ? 1 : 0);
W
wdenk 已提交
1585 1586
#endif
}
W
wdenk 已提交
1587
#endif /* CONFIG_DRIVER_SMC91111 */