1 /***********************************************************************
3 * Copyright (C) 2004 by FS Forth-Systeme GmbH.
6 * $Id: ns9750_eth.c,v 1.2 2004/02/24 14:09:39 mpietrek Exp $
7 * @Author: Markus Pietrek
8 * @Descr: Ethernet driver for the NS9750. Uses DMA Engine with polling
9 * interrupt status. But interrupts are not enabled.
10 * Only one tx buffer descriptor and the RXA buffer descriptor are used
11 * Currently no transmit lockup handling is included. eth_send has a 5s
12 * timeout for sending frames. No retransmits are performed when an
14 * @References: [1] NS9750 Hardware Reference, December 2003
15 * [2] Intel LXT971 Datasheet #249414 Rev. 02
16 * [3] NS7520 Linux Ethernet Driver
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License as
20 * published by the Free Software Foundation; either version 2 of
21 * the License, or (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
33 ***********************************************************************/
36 #include <net.h> /* NetSendPacket */
38 #include "ns9750_eth.h" /* for Ethernet and PHY */
40 /* some definition to make transistion to linux easier */
42 #define NS9750_DRIVER_NAME "eth"
43 #define KERN_WARNING "Warning:"
44 #define KERN_ERR "Error:"
45 #define KERN_INFO "Info:"
52 # define printk printf
54 # define DEBUG_INIT 0x0001
55 # define DEBUG_MINOR 0x0002
56 # define DEBUG_RX 0x0004
57 # define DEBUG_TX 0x0008
58 # define DEBUG_INT 0x0010
59 # define DEBUG_POLL 0x0020
60 # define DEBUG_LINK 0x0040
61 # define DEBUG_MII 0x0100
62 # define DEBUG_MII_LOW 0x0200
63 # define DEBUG_MEM 0x0400
64 # define DEBUG_ERROR 0x4000
65 # define DEBUG_ERROR_CRIT 0x8000
67 static int nDebugLvl = DEBUG_ERROR_CRIT;
69 # define DEBUG_ARGS0( FLG, a0 ) if( ( nDebugLvl & (FLG) ) == (FLG) ) \
70 printf("%s: " a0, __FUNCTION__, 0, 0, 0, 0, 0, 0 )
71 # define DEBUG_ARGS1( FLG, a0, a1 ) if( ( nDebugLvl & (FLG) ) == (FLG)) \
72 printf("%s: " a0, __FUNCTION__, (int)(a1), 0, 0, 0, 0, 0 )
73 # define DEBUG_ARGS2( FLG, a0, a1, a2 ) if( (nDebugLvl & (FLG)) ==(FLG))\
74 printf("%s: " a0, __FUNCTION__, (int)(a1), (int)(a2), 0, 0,0,0 )
75 # define DEBUG_ARGS3( FLG, a0, a1, a2, a3 ) if((nDebugLvl &(FLG))==(FLG))\
76 printf("%s: "a0,__FUNCTION__,(int)(a1),(int)(a2),(int)(a3),0,0,0)
77 # define DEBUG_FN( FLG ) if( (nDebugLvl & (FLG)) == (FLG) ) \
78 printf("\r%s:line %d\n", (int)__FUNCTION__, __LINE__, 0,0,0,0);
79 # define ASSERT( expr, func ) if( !( expr ) ) { \
80 printf( "Assertion failed! %s:line %d %s\n", \
81 (int)__FUNCTION__,__LINE__,(int)(#expr),0,0,0); \
85 # define DEBUG_ARGS0( FLG, a0 )
86 # define DEBUG_ARGS1( FLG, a0, a1 )
87 # define DEBUG_ARGS2( FLG, a0, a1, a2 )
88 # define DEBUG_ARGS3( FLG, a0, a1, a2, a3 )
89 # define DEBUG_FN( n )
90 # define ASSERT(expr, func)
93 #define NS9750_MII_NEG_DELAY (5*CFG_HZ) /* in s */
94 #define TX_TIMEOUT (5*CFG_HZ) /* in s */
96 /* @TODO move it to eeprom.h */
97 #define FS_EEPROM_AUTONEG_MASK 0x7
98 #define FS_EEPROM_AUTONEG_SPEED_MASK 0x1
99 #define FS_EEPROM_AUTONEG_SPEED_10 0x0
100 #define FS_EEPROM_AUTONEG_SPEED_100 0x1
101 #define FS_EEPROM_AUTONEG_DUPLEX_MASK 0x2
102 #define FS_EEPROM_AUTONEG_DUPLEX_HALF 0x0
103 #define FS_EEPROM_AUTONEG_DUPLEX_FULL 0x2
104 #define FS_EEPROM_AUTONEG_ENABLE_MASK 0x4
105 #define FS_EEPROM_AUTONEG_DISABLE 0x0
106 #define FS_EEPROM_AUTONEG_ENABLE 0x4
108 /* buffer descriptors taken from [1] p.306 */
111 unsigned int* punSrc;
112 unsigned int unLen; /* 11 bits */
113 unsigned int* punDest; /* unused */
117 unsigned uStatus : 16;
120 unsigned uEnable : 1;
129 unsigned int* punSrc;
130 unsigned int unLen; /* 10 bits */
131 unsigned int* punDest; /* unused */
133 unsigned int unReg; /* only 32bit accesses may done to NS9750
136 unsigned uStatus : 16;
146 static int ns9750_eth_reset( void );
148 static void ns9750_link_force( void );
149 static void ns9750_link_auto_negotiate( void );
150 static void ns9750_link_update_egcr( void );
151 static void ns9750_link_print_changed( void );
155 static char ns9750_mii_identify_phy( void );
156 static unsigned short ns9750_mii_read( unsigned short uiRegister );
157 static void ns9750_mii_write( unsigned short uiRegister, unsigned short uiData );
158 static unsigned int ns9750_mii_get_clock_divisor( unsigned int unMaxMDIOClk );
159 static unsigned int ns9750_mii_poll_busy( void );
161 static unsigned int nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
162 static unsigned char ucLinkMode = FS_EEPROM_AUTONEG_ENABLE;
163 static unsigned int uiLastLinkStatus;
164 static PhyType phyDetected = PHY_NONE;
166 /* we use only one tx buffer descriptor */
167 static tx_buffer_desc_t* pTxBufferDesc =
168 (tx_buffer_desc_t*) get_eth_reg_addr( NS9750_ETH_TXBD );
170 /* we use only one rx buffer descriptor of the 4 */
171 static rx_buffer_desc_t aRxBufferDesc[ 4 ];
173 /***********************************************************************
174 * @Function: eth_init
175 * @Return: -1 on failure otherwise 0
176 * @Descr: Initializes the ethernet engine and uses either FS Forth's default
177 * MAC addr or the one in environment
178 ***********************************************************************/
180 int eth_init (bd_t * pbis)
182 /* This default MAC Addr is reserved by FS Forth-Systeme for the case of
184 unsigned char aucMACAddr[6] = { 0x00, 0x04, 0xf3, 0x00, 0x06, 0x35 };
185 char *pcTmp = getenv ("ethaddr");
189 DEBUG_FN (DEBUG_INIT);
191 /* no need to check for hardware */
193 if (!ns9750_eth_reset ())
197 for (i = 0; i < 6; i++) {
199 pcTmp ? simple_strtoul (pcTmp, &pcEnd,
201 pcTmp = (*pcTmp) ? pcEnd + 1 : pcEnd;
204 /* configure ethernet address */
206 *get_eth_reg_addr (NS9750_ETH_SA1) =
207 aucMACAddr[5] << 8 | aucMACAddr[4];
208 *get_eth_reg_addr (NS9750_ETH_SA2) =
209 aucMACAddr[3] << 8 | aucMACAddr[2];
210 *get_eth_reg_addr (NS9750_ETH_SA3) =
211 aucMACAddr[1] << 8 | aucMACAddr[0];
213 /* enable hardware */
215 *get_eth_reg_addr (NS9750_ETH_MAC1) = NS9750_ETH_MAC1_RXEN;
217 /* the linux kernel may give packets < 60 bytes, for example arp */
218 *get_eth_reg_addr (NS9750_ETH_MAC2) = NS9750_ETH_MAC2_CRCEN |
219 NS9750_ETH_MAC2_PADEN | NS9750_ETH_MAC2_HUGE;
221 /* enable receive and transmit FIFO, use 10/100 Mbps MII */
222 *get_eth_reg_addr (NS9750_ETH_EGCR1) =
223 NS9750_ETH_EGCR1_ETXWM |
224 NS9750_ETH_EGCR1_ERX |
225 NS9750_ETH_EGCR1_ERXDMA |
226 NS9750_ETH_EGCR1_ETX |
227 NS9750_ETH_EGCR1_ETXDMA | NS9750_ETH_EGCR1_ITXA;
229 /* prepare DMA descriptors */
230 for (i = 0; i < 4; i++) {
231 aRxBufferDesc[i].punSrc = 0;
232 aRxBufferDesc[i].unLen = 0;
233 aRxBufferDesc[i].s.bits.uWrap = 1;
234 aRxBufferDesc[i].s.bits.uInt = 1;
235 aRxBufferDesc[i].s.bits.uEnable = 0;
236 aRxBufferDesc[i].s.bits.uFull = 0;
239 /* NetRxPackets[ 0 ] is initialized before eth_init is called and never
240 changes. NetRxPackets is 32bit aligned */
241 aRxBufferDesc[0].punSrc = (unsigned int *) NetRxPackets[0];
242 aRxBufferDesc[0].s.bits.uEnable = 1;
243 aRxBufferDesc[0].unLen = 1522; /* as stated in [1] p.307 */
245 *get_eth_reg_addr (NS9750_ETH_RXAPTR) =
246 (unsigned int) &aRxBufferDesc[0];
248 /* [1] Tab. 221 states less than 5us */
249 *get_eth_reg_addr (NS9750_ETH_EGCR1) |= NS9750_ETH_EGCR1_ERXINIT;
251 (*get_eth_reg_addr (NS9750_ETH_EGSR) & NS9750_ETH_EGSR_RXINIT))
252 /* wait for finish */
255 /* @TODO do we need to clear RXINIT? */
256 *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~NS9750_ETH_EGCR1_ERXINIT;
258 *get_eth_reg_addr (NS9750_ETH_RXFREE) = 0x1;
263 /***********************************************************************
264 * @Function: eth_send
265 * @Return: -1 on timeout otherwise 1
266 * @Descr: sends one frame by DMA
267 ***********************************************************************/
269 int eth_send (volatile void *pPacket, int nLen)
275 /* clear old status values */
276 *get_eth_reg_addr (NS9750_ETH_EINTR) &=
277 *get_eth_reg_addr (NS9750_ETH_EINTR) & NS9750_ETH_EINTR_TX_MA;
279 /* prepare Tx Descriptors */
281 pTxBufferDesc->punSrc = (unsigned int *) pPacket; /* pPacket is 32bit
283 pTxBufferDesc->unLen = nLen;
284 /* only 32bit accesses allowed. wrap, full, interrupt and enabled to 1 */
285 pTxBufferDesc->s.unReg = 0xf0000000;
286 /* pTxBufferDesc is the first possible buffer descriptor */
287 *get_eth_reg_addr (NS9750_ETH_TXPTR) = 0x0;
289 /* enable processor for next frame */
291 *get_eth_reg_addr (NS9750_ETH_EGCR2) &= ~NS9750_ETH_EGCR2_TCLER;
292 *get_eth_reg_addr (NS9750_ETH_EGCR2) |= NS9750_ETH_EGCR2_TCLER;
294 ulTimeout = get_timer (0);
296 DEBUG_ARGS0 (DEBUG_TX | DEBUG_MINOR,
297 "Waiting for transmission to finish\n");
299 (*get_eth_reg_addr (NS9750_ETH_EINTR) &
300 (NS9750_ETH_EINTR_TXDONE | NS9750_ETH_EINTR_TXERR))) {
301 /* do nothing, wait for completion */
302 if (get_timer (0) - ulTimeout > TX_TIMEOUT) {
303 DEBUG_ARGS0 (DEBUG_TX, "Transmit Timed out\n");
307 DEBUG_ARGS0 (DEBUG_TX | DEBUG_MINOR, "transmitted...\n");
312 /***********************************************************************
314 * @Return: size of last frame in bytes or 0 if no frame available
315 * @Descr: gives one frame to U-Boot which has been copied by DMA engine already
316 * to NetRxPackets[ 0 ].
317 ***********************************************************************/
322 unsigned int unStatus;
325 *get_eth_reg_addr (NS9750_ETH_EINTR) & NS9750_ETH_EINTR_RX_MA;
328 /* no packet available, return immediately */
333 /* unLen always < max(nLen) and discard checksum */
334 nLen = (int) aRxBufferDesc[0].unLen - 4;
336 /* acknowledge status register */
337 *get_eth_reg_addr (NS9750_ETH_EINTR) = unStatus;
339 aRxBufferDesc[0].unLen = 1522;
340 aRxBufferDesc[0].s.bits.uFull = 0;
342 /* Buffer A descriptor available again */
343 *get_eth_reg_addr (NS9750_ETH_RXFREE) |= 0x1;
345 /* NetReceive may call eth_send. Due to a possible bug of the NS9750 we
346 * have to acknowledge the received frame before sending a new one */
347 if (unStatus & NS9750_ETH_EINTR_RXDONEA)
348 NetReceive (NetRxPackets[0], nLen);
353 /***********************************************************************
354 * @Function: eth_halt
356 * @Descr: stops the ethernet engine
357 ***********************************************************************/
361 DEBUG_FN (DEBUG_INIT);
363 *get_eth_reg_addr (NS9750_ETH_MAC1) &= ~NS9750_ETH_MAC1_RXEN;
364 *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~(NS9750_ETH_EGCR1_ERX |
365 NS9750_ETH_EGCR1_ERXDMA |
366 NS9750_ETH_EGCR1_ETX |
367 NS9750_ETH_EGCR1_ETXDMA);
370 /***********************************************************************
371 * @Function: ns9750_eth_reset
372 * @Return: 0 on failure otherwise 1
373 * @Descr: resets the ethernet interface and the PHY,
374 * performs auto negotiation or fixed modes
375 ***********************************************************************/
377 static int ns9750_eth_reset (void)
379 DEBUG_FN (DEBUG_MINOR);
382 *get_eth_reg_addr (NS9750_ETH_EGCR1) |= NS9750_ETH_EGCR1_MAC_HRST;
383 udelay (5); /* according to [1], p.322 */
384 *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~NS9750_ETH_EGCR1_MAC_HRST;
386 /* reset and initialize PHY */
388 *get_eth_reg_addr (NS9750_ETH_MAC1) &= ~NS9750_ETH_MAC1_SRST;
390 /* we don't support hot plugging of PHY, therefore we don't reset
391 phyDetected and nPhyMaxMdioClock here. The risk is if the setting is
392 incorrect the first open
393 may detect the PHY correctly but succeding will fail
394 For reseting the PHY and identifying we have to use the standard
395 MDIO CLOCK value 2.5 MHz only after hardware reset
396 After having identified the PHY we will do faster */
398 *get_eth_reg_addr (NS9750_ETH_MCFG) =
399 ns9750_mii_get_clock_divisor (nPhyMaxMdioClock);
402 ns9750_mii_write (PHY_COMMON_CTRL, PHY_COMMON_CTRL_RESET);
403 ns9750_mii_write (PHY_COMMON_CTRL, 0);
405 /* @TODO check time */
406 udelay (3000); /* [2] p.70 says at least 300us reset recovery time. But
407 go sure, it didn't worked stable at higher timer
408 frequencies under LxNETES-2.x */
410 /* MII clock has been setup to default, ns9750_mii_identify_phy should
413 if (!ns9750_mii_identify_phy ()) {
414 printk (KERN_ERR NS9750_DRIVER_NAME
415 ": Unsupported PHY, aborting\n");
419 /* now take the highest MDIO clock possible after detection */
420 *get_eth_reg_addr (NS9750_ETH_MCFG) =
421 ns9750_mii_get_clock_divisor (nPhyMaxMdioClock);
424 /* PHY has been detected, so there can be no abort reason and we can
425 finish initializing ethernet */
427 uiLastLinkStatus = 0xff; /* undefined */
429 if ((ucLinkMode & FS_EEPROM_AUTONEG_ENABLE_MASK) ==
430 FS_EEPROM_AUTONEG_DISABLE)
431 /* use parameters defined */
432 ns9750_link_force ();
434 ns9750_link_auto_negotiate ();
436 if (phyDetected == PHY_LXT971A)
437 /* set LED2 to link mode */
438 ns9750_mii_write (PHY_LXT971_LED_CFG,
439 PHY_LXT971_LED_CFG_LINK_ACT <<
440 PHY_LXT971_LED_CFG_SHIFT_LED2);
445 /***********************************************************************
446 * @Function: ns9750_link_force
448 * @Descr: configures eth and MII to use the link mode defined in
450 ***********************************************************************/
452 static void ns9750_link_force (void)
454 unsigned short uiControl;
456 DEBUG_FN (DEBUG_LINK);
458 uiControl = ns9750_mii_read (PHY_COMMON_CTRL);
459 uiControl &= ~(PHY_COMMON_CTRL_SPD_MA |
460 PHY_COMMON_CTRL_AUTO_NEG | PHY_COMMON_CTRL_DUPLEX);
462 uiLastLinkStatus = 0;
464 if ((ucLinkMode & FS_EEPROM_AUTONEG_SPEED_MASK) ==
465 FS_EEPROM_AUTONEG_SPEED_100) {
466 uiControl |= PHY_COMMON_CTRL_SPD_100;
467 uiLastLinkStatus |= PHY_LXT971_STAT2_100BTX;
469 uiControl |= PHY_COMMON_CTRL_SPD_10;
471 if ((ucLinkMode & FS_EEPROM_AUTONEG_DUPLEX_MASK) ==
472 FS_EEPROM_AUTONEG_DUPLEX_FULL) {
473 uiControl |= PHY_COMMON_CTRL_DUPLEX;
474 uiLastLinkStatus |= PHY_LXT971_STAT2_DUPLEX_MODE;
477 ns9750_mii_write (PHY_COMMON_CTRL, uiControl);
479 ns9750_link_print_changed ();
480 ns9750_link_update_egcr ();
483 /***********************************************************************
484 * @Function: ns9750_link_auto_negotiate
486 * @Descr: performs auto-negotation of link.
487 ***********************************************************************/
489 static void ns9750_link_auto_negotiate (void)
491 unsigned long ulStartJiffies;
492 unsigned short uiStatus;
494 DEBUG_FN (DEBUG_LINK);
496 /* run auto-negotation */
497 /* define what we are capable of */
498 ns9750_mii_write (PHY_COMMON_AUTO_ADV,
499 PHY_COMMON_AUTO_ADV_100BTXFD |
500 PHY_COMMON_AUTO_ADV_100BTX |
501 PHY_COMMON_AUTO_ADV_10BTFD |
502 PHY_COMMON_AUTO_ADV_10BT |
503 PHY_COMMON_AUTO_ADV_802_3);
504 /* start auto-negotiation */
505 ns9750_mii_write (PHY_COMMON_CTRL,
506 PHY_COMMON_CTRL_AUTO_NEG |
507 PHY_COMMON_CTRL_RES_AUTO);
509 /* wait for completion */
511 ulStartJiffies = get_ticks ();
512 while (get_ticks () < ulStartJiffies + NS9750_MII_NEG_DELAY) {
513 uiStatus = ns9750_mii_read (PHY_COMMON_STAT);
515 (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) ==
516 (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) {
517 /* lucky we are, auto-negotiation succeeded */
518 ns9750_link_print_changed ();
519 ns9750_link_update_egcr ();
524 DEBUG_ARGS0 (DEBUG_LINK, "auto-negotiation timed out\n");
525 /* ignore invalid link settings */
528 /***********************************************************************
529 * @Function: ns9750_link_update_egcr
531 * @Descr: updates the EGCR and MAC2 link status after mode change or
533 ***********************************************************************/
535 static void ns9750_link_update_egcr (void)
541 DEBUG_FN (DEBUG_LINK);
543 unEGCR = *get_eth_reg_addr (NS9750_ETH_EGCR1);
544 unMAC2 = *get_eth_reg_addr (NS9750_ETH_MAC2);
545 unIPGT = *get_eth_reg_addr (NS9750_ETH_IPGT) & ~NS9750_ETH_IPGT_MA;
547 unMAC2 &= ~NS9750_ETH_MAC2_FULLD;
548 if ((uiLastLinkStatus & PHY_LXT971_STAT2_DUPLEX_MODE)
549 == PHY_LXT971_STAT2_DUPLEX_MODE) {
550 unMAC2 |= NS9750_ETH_MAC2_FULLD;
551 unIPGT |= 0x15; /* see [1] p. 339 */
553 unIPGT |= 0x12; /* see [1] p. 339 */
555 *get_eth_reg_addr (NS9750_ETH_MAC2) = unMAC2;
556 *get_eth_reg_addr (NS9750_ETH_EGCR1) = unEGCR;
557 *get_eth_reg_addr (NS9750_ETH_IPGT) = unIPGT;
560 /***********************************************************************
561 * @Function: ns9750_link_print_changed
563 * @Descr: checks whether the link status has changed and if so prints
565 ***********************************************************************/
567 static void ns9750_link_print_changed (void)
569 unsigned short uiStatus;
570 unsigned short uiControl;
572 DEBUG_FN (DEBUG_LINK);
574 uiControl = ns9750_mii_read (PHY_COMMON_CTRL);
576 if ((uiControl & PHY_COMMON_CTRL_AUTO_NEG) ==
577 PHY_COMMON_CTRL_AUTO_NEG) {
578 /* PHY_COMMON_STAT_LNK_STAT is only set on autonegotiation */
579 uiStatus = ns9750_mii_read (PHY_COMMON_STAT);
581 if (!(uiStatus & PHY_COMMON_STAT_LNK_STAT)) {
582 printk (KERN_WARNING NS9750_DRIVER_NAME
584 /* @TODO Linux: carrier_off */
586 /* @TODO Linux: carrier_on */
587 if (phyDetected == PHY_LXT971A) {
588 uiStatus = ns9750_mii_read (PHY_LXT971_STAT2);
589 uiStatus &= (PHY_LXT971_STAT2_100BTX |
590 PHY_LXT971_STAT2_DUPLEX_MODE |
591 PHY_LXT971_STAT2_AUTO_NEG);
593 /* mask out all uninteresting parts */
595 /* other PHYs must store there link information in
596 uiStatus as PHY_LXT971 */
599 /* mode has been forced, so uiStatus should be the same as the
600 last link status, enforce printing */
601 uiStatus = uiLastLinkStatus;
602 uiLastLinkStatus = 0xff;
605 if (uiStatus != uiLastLinkStatus) {
606 /* save current link status */
607 uiLastLinkStatus = uiStatus;
609 /* print new link status */
611 printk (KERN_INFO NS9750_DRIVER_NAME
612 ": link mode %i Mbps %s duplex %s\n",
613 (uiStatus & PHY_LXT971_STAT2_100BTX) ? 100 : 10,
614 (uiStatus & PHY_LXT971_STAT2_DUPLEX_MODE) ? "full" :
616 (uiStatus & PHY_LXT971_STAT2_AUTO_NEG) ? "(auto)" :
621 /***********************************************************************
622 * the MII low level stuff
623 ***********************************************************************/
625 /***********************************************************************
626 * @Function: ns9750_mii_identify_phy
627 * @Return: 1 if supported PHY has been detected otherwise 0
628 * @Descr: checks for supported PHY and prints the IDs.
629 ***********************************************************************/
631 static char ns9750_mii_identify_phy (void)
633 unsigned short uiID1;
634 unsigned short uiID2;
635 unsigned char *szName;
638 DEBUG_FN (DEBUG_MII);
640 phyDetected = (PhyType) uiID1 = ns9750_mii_read (PHY_COMMON_ID1);
642 switch (phyDetected) {
645 uiID2 = ns9750_mii_read (PHY_COMMON_ID2);
646 nPhyMaxMdioClock = PHY_LXT971_MDIO_MAX_CLK;
651 /* in case uiID1 == 0 && uiID2 == 0 we may have the wrong
652 address or reset sets the wrong NS9750_ETH_MCFG_CLKS */
656 nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
657 phyDetected = PHY_NONE;
660 printk (KERN_INFO NS9750_DRIVER_NAME
661 ": PHY (0x%x, 0x%x) = %s detected\n", uiID1, uiID2, szName);
666 /***********************************************************************
667 * @Function: ns9750_mii_read
668 * @Return: the data read from PHY register uiRegister
669 * @Descr: the data read may be invalid if timed out. If so, a message
670 * is printed but the invalid data is returned.
671 * The fixed device address is being used.
672 ***********************************************************************/
674 static unsigned short ns9750_mii_read (unsigned short uiRegister)
676 DEBUG_FN (DEBUG_MII_LOW);
678 /* write MII register to be read */
679 *get_eth_reg_addr (NS9750_ETH_MADR) =
680 NS9750_ETH_PHY_ADDRESS << 8 | uiRegister;
682 *get_eth_reg_addr (NS9750_ETH_MCMD) = NS9750_ETH_MCMD_READ;
684 if (!ns9750_mii_poll_busy ())
685 printk (KERN_WARNING NS9750_DRIVER_NAME
686 ": MII still busy in read\n");
687 /* continue to read */
689 *get_eth_reg_addr (NS9750_ETH_MCMD) = 0;
691 return (unsigned short) (*get_eth_reg_addr (NS9750_ETH_MRDD));
695 /***********************************************************************
696 * @Function: ns9750_mii_write
698 * @Descr: writes the data to the PHY register. In case of a timeout,
699 * no special handling is performed but a message printed
700 * The fixed device address is being used.
701 ***********************************************************************/
703 static void ns9750_mii_write (unsigned short uiRegister,
704 unsigned short uiData)
706 DEBUG_FN (DEBUG_MII_LOW);
708 /* write MII register to be written */
709 *get_eth_reg_addr (NS9750_ETH_MADR) =
710 NS9750_ETH_PHY_ADDRESS << 8 | uiRegister;
712 *get_eth_reg_addr (NS9750_ETH_MWTD) = uiData;
714 if (!ns9750_mii_poll_busy ()) {
715 printf (KERN_WARNING NS9750_DRIVER_NAME
716 ": MII still busy in write\n");
721 /***********************************************************************
722 * @Function: ns9750_mii_get_clock_divisor
723 * @Return: the clock divisor that should be used in NS9750_ETH_MCFG_CLKS
724 * @Descr: if no clock divisor can be calculated for the
725 * current SYSCLK and the maximum MDIO Clock, a warning is printed
726 * and the greatest divisor is taken
727 ***********************************************************************/
729 static unsigned int ns9750_mii_get_clock_divisor (unsigned int unMaxMDIOClk)
732 unsigned int unSysClkDivisor;
733 unsigned int unClks; /* field for NS9750_ETH_MCFG_CLKS */
734 } PHYClockDivisors[] = {
736 4, NS9750_ETH_MCFG_CLKS_4}, {
737 6, NS9750_ETH_MCFG_CLKS_6}, {
738 8, NS9750_ETH_MCFG_CLKS_8}, {
739 10, NS9750_ETH_MCFG_CLKS_10}, {
740 20, NS9750_ETH_MCFG_CLKS_20}, {
741 30, NS9750_ETH_MCFG_CLKS_30}, {
742 40, NS9750_ETH_MCFG_CLKS_40}
747 sizeof (PHYClockDivisors) / sizeof (PHYClockDivisors[0]);
748 unsigned int unClks = NS9750_ETH_MCFG_CLKS_40; /* defaults to
751 DEBUG_FN (DEBUG_INIT);
753 for (nIndexSysClkDiv = 0; nIndexSysClkDiv < nArraySize;
755 /* find first sysclock divisor that isn't higher than 2.5 MHz
758 PHYClockDivisors[nIndexSysClkDiv].unSysClkDivisor <=
760 unClks = PHYClockDivisors[nIndexSysClkDiv].unClks;
765 DEBUG_ARGS2 (DEBUG_INIT,
766 "Taking MDIO Clock bit mask 0x%0x for max clock %i\n",
767 unClks, unMaxMDIOClk);
769 /* return greatest divisor */
773 /***********************************************************************
774 * @Function: ns9750_mii_poll_busy
775 * @Return: 0 if timed out otherwise the remaing timeout
776 * @Descr: waits until the MII has completed a command or it times out
777 * code may be interrupted by hard interrupts.
778 * It is not checked what happens on multiple actions when
779 * the first is still being busy and we timeout.
780 ***********************************************************************/
782 static unsigned int ns9750_mii_poll_busy (void)
784 unsigned int unTimeout = 10000;
786 DEBUG_FN (DEBUG_MII_LOW);
788 while (((*get_eth_reg_addr (NS9750_ETH_MIND) & NS9750_ETH_MIND_BUSY)
789 == NS9750_ETH_MIND_BUSY) && unTimeout)