ns9750_eth.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. /***********************************************************************
  2. *
  3. * Copyright (C) 2004 by FS Forth-Systeme GmbH.
  4. * All rights reserved.
  5. *
  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
  13. * error occurs.
  14. * @References: [1] NS9750 Hardware Reference, December 2003
  15. * [2] Intel LXT971 Datasheet #249414 Rev. 02
  16. * [3] NS7520 Linux Ethernet Driver
  17. *
  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.
  22. *
  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.
  27. *
  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,
  31. * MA 02111-1307 USA
  32. *
  33. ***********************************************************************/
  34. #include <common.h>
  35. #include <net.h> /* NetSendPacket */
  36. #include "ns9750_eth.h" /* for Ethernet and PHY */
  37. /* some definition to make transition to linux easier */
  38. #define NS9750_DRIVER_NAME "eth"
  39. #define KERN_WARNING "Warning:"
  40. #define KERN_ERR "Error:"
  41. #define KERN_INFO "Info:"
  42. #if 0
  43. # define DEBUG
  44. #endif
  45. #ifdef DEBUG
  46. # define printk printf
  47. # define DEBUG_INIT 0x0001
  48. # define DEBUG_MINOR 0x0002
  49. # define DEBUG_RX 0x0004
  50. # define DEBUG_TX 0x0008
  51. # define DEBUG_INT 0x0010
  52. # define DEBUG_POLL 0x0020
  53. # define DEBUG_LINK 0x0040
  54. # define DEBUG_MII 0x0100
  55. # define DEBUG_MII_LOW 0x0200
  56. # define DEBUG_MEM 0x0400
  57. # define DEBUG_ERROR 0x4000
  58. # define DEBUG_ERROR_CRIT 0x8000
  59. static int nDebugLvl = DEBUG_ERROR_CRIT;
  60. # define DEBUG_ARGS0( FLG, a0 ) if( ( nDebugLvl & (FLG) ) == (FLG) ) \
  61. printf("%s: " a0, __FUNCTION__, 0, 0, 0, 0, 0, 0 )
  62. # define DEBUG_ARGS1( FLG, a0, a1 ) if( ( nDebugLvl & (FLG) ) == (FLG)) \
  63. printf("%s: " a0, __FUNCTION__, (int)(a1), 0, 0, 0, 0, 0 )
  64. # define DEBUG_ARGS2( FLG, a0, a1, a2 ) if( (nDebugLvl & (FLG)) ==(FLG))\
  65. printf("%s: " a0, __FUNCTION__, (int)(a1), (int)(a2), 0, 0,0,0 )
  66. # define DEBUG_ARGS3( FLG, a0, a1, a2, a3 ) if((nDebugLvl &(FLG))==(FLG))\
  67. printf("%s: "a0,__FUNCTION__,(int)(a1),(int)(a2),(int)(a3),0,0,0)
  68. # define DEBUG_FN( FLG ) if( (nDebugLvl & (FLG)) == (FLG) ) \
  69. printf("\r%s:line %d\n", (int)__FUNCTION__, __LINE__, 0,0,0,0);
  70. # define ASSERT( expr, func ) if( !( expr ) ) { \
  71. printf( "Assertion failed! %s:line %d %s\n", \
  72. (int)__FUNCTION__,__LINE__,(int)(#expr),0,0,0); \
  73. func }
  74. #else /* DEBUG */
  75. # define printk(...)
  76. # define DEBUG_ARGS0( FLG, a0 )
  77. # define DEBUG_ARGS1( FLG, a0, a1 )
  78. # define DEBUG_ARGS2( FLG, a0, a1, a2 )
  79. # define DEBUG_ARGS3( FLG, a0, a1, a2, a3 )
  80. # define DEBUG_FN( n )
  81. # define ASSERT(expr, func)
  82. #endif /* DEBUG */
  83. #define NS9750_MII_NEG_DELAY (5*CONFIG_SYS_HZ) /* in s */
  84. #define TX_TIMEOUT (5*CONFIG_SYS_HZ) /* in s */
  85. /* @TODO move it to eeprom.h */
  86. #define FS_EEPROM_AUTONEG_MASK 0x7
  87. #define FS_EEPROM_AUTONEG_SPEED_MASK 0x1
  88. #define FS_EEPROM_AUTONEG_SPEED_10 0x0
  89. #define FS_EEPROM_AUTONEG_SPEED_100 0x1
  90. #define FS_EEPROM_AUTONEG_DUPLEX_MASK 0x2
  91. #define FS_EEPROM_AUTONEG_DUPLEX_HALF 0x0
  92. #define FS_EEPROM_AUTONEG_DUPLEX_FULL 0x2
  93. #define FS_EEPROM_AUTONEG_ENABLE_MASK 0x4
  94. #define FS_EEPROM_AUTONEG_DISABLE 0x0
  95. #define FS_EEPROM_AUTONEG_ENABLE 0x4
  96. /* buffer descriptors taken from [1] p.306 */
  97. typedef struct
  98. {
  99. unsigned int* punSrc;
  100. unsigned int unLen; /* 11 bits */
  101. unsigned int* punDest; /* unused */
  102. union {
  103. unsigned int unReg;
  104. struct {
  105. unsigned uStatus : 16;
  106. unsigned uRes : 12;
  107. unsigned uFull : 1;
  108. unsigned uEnable : 1;
  109. unsigned uInt : 1;
  110. unsigned uWrap : 1;
  111. } bits;
  112. } s;
  113. } rx_buffer_desc_t;
  114. typedef struct
  115. {
  116. unsigned int* punSrc;
  117. unsigned int unLen; /* 10 bits */
  118. unsigned int* punDest; /* unused */
  119. union {
  120. unsigned int unReg; /* only 32bit accesses may done to NS9750
  121. * eth engine */
  122. struct {
  123. unsigned uStatus : 16;
  124. unsigned uRes : 12;
  125. unsigned uFull : 1;
  126. unsigned uLast : 1;
  127. unsigned uInt : 1;
  128. unsigned uWrap : 1;
  129. } bits;
  130. } s;
  131. } tx_buffer_desc_t;
  132. static int ns9750_eth_reset( void );
  133. static void ns9750_link_force( void );
  134. static void ns9750_link_auto_negotiate( void );
  135. static void ns9750_link_update_egcr( void );
  136. static void ns9750_link_print_changed( void );
  137. /* the PHY stuff */
  138. static char ns9750_mii_identify_phy( void );
  139. static unsigned short ns9750_mii_read( unsigned short uiRegister );
  140. static void ns9750_mii_write( unsigned short uiRegister, unsigned short uiData );
  141. static unsigned int ns9750_mii_get_clock_divisor( unsigned int unMaxMDIOClk );
  142. static unsigned int ns9750_mii_poll_busy( void );
  143. static unsigned int nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
  144. static unsigned char ucLinkMode = FS_EEPROM_AUTONEG_ENABLE;
  145. static unsigned int uiLastLinkStatus;
  146. static PhyType phyDetected = PHY_NONE;
  147. /* we use only one tx buffer descriptor */
  148. static tx_buffer_desc_t* pTxBufferDesc =
  149. (tx_buffer_desc_t*) get_eth_reg_addr( NS9750_ETH_TXBD );
  150. /* we use only one rx buffer descriptor of the 4 */
  151. static rx_buffer_desc_t aRxBufferDesc[ 4 ];
  152. /***********************************************************************
  153. * @Function: eth_init
  154. * @Return: -1 on failure otherwise 0
  155. * @Descr: Initializes the ethernet engine and uses either FS Forth's default
  156. * MAC addr or the one in environment
  157. ***********************************************************************/
  158. int eth_init (bd_t * pbis)
  159. {
  160. /* This default MAC Addr is reserved by FS Forth-Systeme for the case of
  161. EEPROM failures */
  162. unsigned char aucMACAddr[6] = { 0x00, 0x04, 0xf3, 0x00, 0x06, 0x35 };
  163. char *pcTmp = getenv ("ethaddr");
  164. char *pcEnd;
  165. int i;
  166. DEBUG_FN (DEBUG_INIT);
  167. /* no need to check for hardware */
  168. if (!ns9750_eth_reset ())
  169. return -1;
  170. if (pcTmp != NULL)
  171. for (i = 0; i < 6; i++) {
  172. aucMACAddr[i] =
  173. pcTmp ? simple_strtoul (pcTmp, &pcEnd,
  174. 16) : 0;
  175. pcTmp = (*pcTmp) ? pcEnd + 1 : pcEnd;
  176. }
  177. /* configure ethernet address */
  178. *get_eth_reg_addr (NS9750_ETH_SA1) =
  179. aucMACAddr[5] << 8 | aucMACAddr[4];
  180. *get_eth_reg_addr (NS9750_ETH_SA2) =
  181. aucMACAddr[3] << 8 | aucMACAddr[2];
  182. *get_eth_reg_addr (NS9750_ETH_SA3) =
  183. aucMACAddr[1] << 8 | aucMACAddr[0];
  184. /* enable hardware */
  185. *get_eth_reg_addr (NS9750_ETH_MAC1) = NS9750_ETH_MAC1_RXEN;
  186. /* the linux kernel may give packets < 60 bytes, for example arp */
  187. *get_eth_reg_addr (NS9750_ETH_MAC2) = NS9750_ETH_MAC2_CRCEN |
  188. NS9750_ETH_MAC2_PADEN | NS9750_ETH_MAC2_HUGE;
  189. /* enable receive and transmit FIFO, use 10/100 Mbps MII */
  190. *get_eth_reg_addr (NS9750_ETH_EGCR1) =
  191. NS9750_ETH_EGCR1_ETXWM |
  192. NS9750_ETH_EGCR1_ERX |
  193. NS9750_ETH_EGCR1_ERXDMA |
  194. NS9750_ETH_EGCR1_ETX |
  195. NS9750_ETH_EGCR1_ETXDMA | NS9750_ETH_EGCR1_ITXA;
  196. /* prepare DMA descriptors */
  197. for (i = 0; i < 4; i++) {
  198. aRxBufferDesc[i].punSrc = 0;
  199. aRxBufferDesc[i].unLen = 0;
  200. aRxBufferDesc[i].s.bits.uWrap = 1;
  201. aRxBufferDesc[i].s.bits.uInt = 1;
  202. aRxBufferDesc[i].s.bits.uEnable = 0;
  203. aRxBufferDesc[i].s.bits.uFull = 0;
  204. }
  205. /* NetRxPackets[ 0 ] is initialized before eth_init is called and never
  206. changes. NetRxPackets is 32bit aligned */
  207. aRxBufferDesc[0].punSrc = (unsigned int *) NetRxPackets[0];
  208. aRxBufferDesc[0].s.bits.uEnable = 1;
  209. aRxBufferDesc[0].unLen = 1522; /* as stated in [1] p.307 */
  210. *get_eth_reg_addr (NS9750_ETH_RXAPTR) =
  211. (unsigned int) &aRxBufferDesc[0];
  212. /* [1] Tab. 221 states less than 5us */
  213. *get_eth_reg_addr (NS9750_ETH_EGCR1) |= NS9750_ETH_EGCR1_ERXINIT;
  214. while (!
  215. (*get_eth_reg_addr (NS9750_ETH_EGSR) & NS9750_ETH_EGSR_RXINIT))
  216. /* wait for finish */
  217. udelay (1);
  218. /* @TODO do we need to clear RXINIT? */
  219. *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~NS9750_ETH_EGCR1_ERXINIT;
  220. *get_eth_reg_addr (NS9750_ETH_RXFREE) = 0x1;
  221. return 0;
  222. }
  223. /***********************************************************************
  224. * @Function: eth_send
  225. * @Return: -1 on timeout otherwise 1
  226. * @Descr: sends one frame by DMA
  227. ***********************************************************************/
  228. int eth_send (volatile void *pPacket, int nLen)
  229. {
  230. ulong ulTimeout;
  231. DEBUG_FN (DEBUG_TX);
  232. /* clear old status values */
  233. *get_eth_reg_addr (NS9750_ETH_EINTR) &=
  234. *get_eth_reg_addr (NS9750_ETH_EINTR) & NS9750_ETH_EINTR_TX_MA;
  235. /* prepare Tx Descriptors */
  236. pTxBufferDesc->punSrc = (unsigned int *) pPacket; /* pPacket is 32bit
  237. * aligned */
  238. pTxBufferDesc->unLen = nLen;
  239. /* only 32bit accesses allowed. wrap, full, interrupt and enabled to 1 */
  240. pTxBufferDesc->s.unReg = 0xf0000000;
  241. /* pTxBufferDesc is the first possible buffer descriptor */
  242. *get_eth_reg_addr (NS9750_ETH_TXPTR) = 0x0;
  243. /* enable processor for next frame */
  244. *get_eth_reg_addr (NS9750_ETH_EGCR2) &= ~NS9750_ETH_EGCR2_TCLER;
  245. *get_eth_reg_addr (NS9750_ETH_EGCR2) |= NS9750_ETH_EGCR2_TCLER;
  246. ulTimeout = get_timer (0);
  247. DEBUG_ARGS0 (DEBUG_TX | DEBUG_MINOR,
  248. "Waiting for transmission to finish\n");
  249. while (!
  250. (*get_eth_reg_addr (NS9750_ETH_EINTR) &
  251. (NS9750_ETH_EINTR_TXDONE | NS9750_ETH_EINTR_TXERR))) {
  252. /* do nothing, wait for completion */
  253. if (get_timer (0) - ulTimeout > TX_TIMEOUT) {
  254. DEBUG_ARGS0 (DEBUG_TX, "Transmit Timed out\n");
  255. return -1;
  256. }
  257. }
  258. DEBUG_ARGS0 (DEBUG_TX | DEBUG_MINOR, "transmitted...\n");
  259. return 0;
  260. }
  261. /***********************************************************************
  262. * @Function: eth_rx
  263. * @Return: size of last frame in bytes or 0 if no frame available
  264. * @Descr: gives one frame to U-Boot which has been copied by DMA engine already
  265. * to NetRxPackets[ 0 ].
  266. ***********************************************************************/
  267. int eth_rx (void)
  268. {
  269. int nLen = 0;
  270. unsigned int unStatus;
  271. unStatus =
  272. *get_eth_reg_addr (NS9750_ETH_EINTR) & NS9750_ETH_EINTR_RX_MA;
  273. if (!unStatus)
  274. /* no packet available, return immediately */
  275. return 0;
  276. DEBUG_FN (DEBUG_RX);
  277. /* unLen always < max(nLen) and discard checksum */
  278. nLen = (int) aRxBufferDesc[0].unLen - 4;
  279. /* acknowledge status register */
  280. *get_eth_reg_addr (NS9750_ETH_EINTR) = unStatus;
  281. aRxBufferDesc[0].unLen = 1522;
  282. aRxBufferDesc[0].s.bits.uFull = 0;
  283. /* Buffer A descriptor available again */
  284. *get_eth_reg_addr (NS9750_ETH_RXFREE) |= 0x1;
  285. /* NetReceive may call eth_send. Due to a possible bug of the NS9750 we
  286. * have to acknowledge the received frame before sending a new one */
  287. if (unStatus & NS9750_ETH_EINTR_RXDONEA)
  288. NetReceive (NetRxPackets[0], nLen);
  289. return nLen;
  290. }
  291. /***********************************************************************
  292. * @Function: eth_halt
  293. * @Return: n/a
  294. * @Descr: stops the ethernet engine
  295. ***********************************************************************/
  296. void eth_halt (void)
  297. {
  298. DEBUG_FN (DEBUG_INIT);
  299. *get_eth_reg_addr (NS9750_ETH_MAC1) &= ~NS9750_ETH_MAC1_RXEN;
  300. *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~(NS9750_ETH_EGCR1_ERX |
  301. NS9750_ETH_EGCR1_ERXDMA |
  302. NS9750_ETH_EGCR1_ETX |
  303. NS9750_ETH_EGCR1_ETXDMA);
  304. }
  305. /***********************************************************************
  306. * @Function: ns9750_eth_reset
  307. * @Return: 0 on failure otherwise 1
  308. * @Descr: resets the ethernet interface and the PHY,
  309. * performs auto negotiation or fixed modes
  310. ***********************************************************************/
  311. static int ns9750_eth_reset (void)
  312. {
  313. DEBUG_FN (DEBUG_MINOR);
  314. /* Reset MAC */
  315. *get_eth_reg_addr (NS9750_ETH_EGCR1) |= NS9750_ETH_EGCR1_MAC_HRST;
  316. udelay (5); /* according to [1], p.322 */
  317. *get_eth_reg_addr (NS9750_ETH_EGCR1) &= ~NS9750_ETH_EGCR1_MAC_HRST;
  318. /* reset and initialize PHY */
  319. *get_eth_reg_addr (NS9750_ETH_MAC1) &= ~NS9750_ETH_MAC1_SRST;
  320. /* we don't support hot plugging of PHY, therefore we don't reset
  321. phyDetected and nPhyMaxMdioClock here. The risk is if the setting is
  322. incorrect the first open
  323. may detect the PHY correctly but succeding will fail
  324. For reseting the PHY and identifying we have to use the standard
  325. MDIO CLOCK value 2.5 MHz only after hardware reset
  326. After having identified the PHY we will do faster */
  327. *get_eth_reg_addr (NS9750_ETH_MCFG) =
  328. ns9750_mii_get_clock_divisor (nPhyMaxMdioClock);
  329. /* reset PHY */
  330. ns9750_mii_write(PHY_BMCR, PHY_BMCR_RESET);
  331. ns9750_mii_write(PHY_BMCR, 0);
  332. /* @TODO check time */
  333. udelay (3000); /* [2] p.70 says at least 300us reset recovery time. But
  334. go sure, it didn't worked stable at higher timer
  335. frequencies under LxNETES-2.x */
  336. /* MII clock has been setup to default, ns9750_mii_identify_phy should
  337. work for all */
  338. if (!ns9750_mii_identify_phy ()) {
  339. printk (KERN_ERR NS9750_DRIVER_NAME
  340. ": Unsupported PHY, aborting\n");
  341. return 0;
  342. }
  343. /* now take the highest MDIO clock possible after detection */
  344. *get_eth_reg_addr (NS9750_ETH_MCFG) =
  345. ns9750_mii_get_clock_divisor (nPhyMaxMdioClock);
  346. /* PHY has been detected, so there can be no abort reason and we can
  347. finish initializing ethernet */
  348. uiLastLinkStatus = 0xff; /* undefined */
  349. if ((ucLinkMode & FS_EEPROM_AUTONEG_ENABLE_MASK) ==
  350. FS_EEPROM_AUTONEG_DISABLE)
  351. /* use parameters defined */
  352. ns9750_link_force ();
  353. else
  354. ns9750_link_auto_negotiate ();
  355. if (phyDetected == PHY_LXT971A)
  356. /* set LED2 to link mode */
  357. ns9750_mii_write (PHY_LXT971_LED_CFG,
  358. PHY_LXT971_LED_CFG_LINK_ACT <<
  359. PHY_LXT971_LED_CFG_SHIFT_LED2);
  360. return 1;
  361. }
  362. /***********************************************************************
  363. * @Function: ns9750_link_force
  364. * @Return: void
  365. * @Descr: configures eth and MII to use the link mode defined in
  366. * ucLinkMode
  367. ***********************************************************************/
  368. static void ns9750_link_force (void)
  369. {
  370. unsigned short uiControl;
  371. DEBUG_FN (DEBUG_LINK);
  372. uiControl = ns9750_mii_read(PHY_BMCR);
  373. uiControl &= ~(PHY_BMCR_SPEED_MASK |
  374. PHY_BMCR_AUTON | PHY_BMCR_DPLX);
  375. uiLastLinkStatus = 0;
  376. if ((ucLinkMode & FS_EEPROM_AUTONEG_SPEED_MASK) ==
  377. FS_EEPROM_AUTONEG_SPEED_100) {
  378. uiControl |= PHY_BMCR_100MB;
  379. uiLastLinkStatus |= PHY_LXT971_STAT2_100BTX;
  380. } else
  381. uiControl |= PHY_BMCR_10_MBPS;
  382. if ((ucLinkMode & FS_EEPROM_AUTONEG_DUPLEX_MASK) ==
  383. FS_EEPROM_AUTONEG_DUPLEX_FULL) {
  384. uiControl |= PHY_BMCR_DPLX;
  385. uiLastLinkStatus |= PHY_LXT971_STAT2_DUPLEX_MODE;
  386. }
  387. ns9750_mii_write(PHY_BMCR, uiControl);
  388. ns9750_link_print_changed ();
  389. ns9750_link_update_egcr ();
  390. }
  391. /***********************************************************************
  392. * @Function: ns9750_link_auto_negotiate
  393. * @Return: void
  394. * @Descr: performs auto-negotation of link.
  395. ***********************************************************************/
  396. static void ns9750_link_auto_negotiate (void)
  397. {
  398. unsigned long ulStartJiffies;
  399. unsigned short uiStatus;
  400. DEBUG_FN (DEBUG_LINK);
  401. /* run auto-negotation */
  402. /* define what we are capable of */
  403. ns9750_mii_write(PHY_ANAR,
  404. PHY_ANLPAR_TXFD |
  405. PHY_ANLPAR_TX |
  406. PHY_ANLPAR_10FD |
  407. PHY_ANLPAR_10 |
  408. PHY_ANLPAR_PSB_802_3);
  409. /* start auto-negotiation */
  410. ns9750_mii_write(PHY_BMCR, PHY_BMCR_AUTON | PHY_BMCR_RST_NEG);
  411. /* wait for completion */
  412. ulStartJiffies = get_ticks ();
  413. while (get_ticks () < ulStartJiffies + NS9750_MII_NEG_DELAY) {
  414. uiStatus = ns9750_mii_read(PHY_BMSR);
  415. if ((uiStatus &
  416. (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS)) ==
  417. (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS)) {
  418. /* lucky we are, auto-negotiation succeeded */
  419. ns9750_link_print_changed ();
  420. ns9750_link_update_egcr ();
  421. return;
  422. }
  423. }
  424. DEBUG_ARGS0 (DEBUG_LINK, "auto-negotiation timed out\n");
  425. /* ignore invalid link settings */
  426. }
  427. /***********************************************************************
  428. * @Function: ns9750_link_update_egcr
  429. * @Return: void
  430. * @Descr: updates the EGCR and MAC2 link status after mode change or
  431. * auto-negotation
  432. ***********************************************************************/
  433. static void ns9750_link_update_egcr (void)
  434. {
  435. unsigned int unEGCR;
  436. unsigned int unMAC2;
  437. unsigned int unIPGT;
  438. DEBUG_FN (DEBUG_LINK);
  439. unEGCR = *get_eth_reg_addr (NS9750_ETH_EGCR1);
  440. unMAC2 = *get_eth_reg_addr (NS9750_ETH_MAC2);
  441. unIPGT = *get_eth_reg_addr (NS9750_ETH_IPGT) & ~NS9750_ETH_IPGT_MA;
  442. unMAC2 &= ~NS9750_ETH_MAC2_FULLD;
  443. if ((uiLastLinkStatus & PHY_LXT971_STAT2_DUPLEX_MODE)
  444. == PHY_LXT971_STAT2_DUPLEX_MODE) {
  445. unMAC2 |= NS9750_ETH_MAC2_FULLD;
  446. unIPGT |= 0x15; /* see [1] p. 339 */
  447. } else
  448. unIPGT |= 0x12; /* see [1] p. 339 */
  449. *get_eth_reg_addr (NS9750_ETH_MAC2) = unMAC2;
  450. *get_eth_reg_addr (NS9750_ETH_EGCR1) = unEGCR;
  451. *get_eth_reg_addr (NS9750_ETH_IPGT) = unIPGT;
  452. }
  453. /***********************************************************************
  454. * @Function: ns9750_link_print_changed
  455. * @Return: void
  456. * @Descr: checks whether the link status has changed and if so prints
  457. * the new mode
  458. ***********************************************************************/
  459. static void ns9750_link_print_changed (void)
  460. {
  461. unsigned short uiStatus;
  462. unsigned short uiControl;
  463. DEBUG_FN (DEBUG_LINK);
  464. uiControl = ns9750_mii_read(PHY_BMCR);
  465. if ((uiControl & PHY_BMCR_AUTON) == PHY_BMCR_AUTON) {
  466. /* PHY_BMSR_LS is only set on autonegotiation */
  467. uiStatus = ns9750_mii_read(PHY_BMSR);
  468. if (!(uiStatus & PHY_BMSR_LS)) {
  469. printk (KERN_WARNING NS9750_DRIVER_NAME
  470. ": link down\n");
  471. /* @TODO Linux: carrier_off */
  472. } else {
  473. /* @TODO Linux: carrier_on */
  474. if (phyDetected == PHY_LXT971A) {
  475. uiStatus = ns9750_mii_read (PHY_LXT971_STAT2);
  476. uiStatus &= (PHY_LXT971_STAT2_100BTX |
  477. PHY_LXT971_STAT2_DUPLEX_MODE |
  478. PHY_LXT971_STAT2_AUTO_NEG);
  479. /* mask out all uninteresting parts */
  480. }
  481. /* other PHYs must store their link information in
  482. uiStatus as PHY_LXT971 */
  483. }
  484. } else {
  485. /* mode has been forced, so uiStatus should be the same as the
  486. last link status, enforce printing */
  487. uiStatus = uiLastLinkStatus;
  488. uiLastLinkStatus = 0xff;
  489. }
  490. if (uiStatus != uiLastLinkStatus) {
  491. /* save current link status */
  492. uiLastLinkStatus = uiStatus;
  493. /* print new link status */
  494. printk (KERN_INFO NS9750_DRIVER_NAME
  495. ": link mode %i Mbps %s duplex %s\n",
  496. (uiStatus & PHY_LXT971_STAT2_100BTX) ? 100 : 10,
  497. (uiStatus & PHY_LXT971_STAT2_DUPLEX_MODE) ? "full" :
  498. "half",
  499. (uiStatus & PHY_LXT971_STAT2_AUTO_NEG) ? "(auto)" :
  500. "");
  501. }
  502. }
  503. /***********************************************************************
  504. * the MII low level stuff
  505. ***********************************************************************/
  506. /***********************************************************************
  507. * @Function: ns9750_mii_identify_phy
  508. * @Return: 1 if supported PHY has been detected otherwise 0
  509. * @Descr: checks for supported PHY and prints the IDs.
  510. ***********************************************************************/
  511. static char ns9750_mii_identify_phy (void)
  512. {
  513. unsigned short uiID1;
  514. unsigned short uiID2;
  515. unsigned char *szName;
  516. char cRes = 0;
  517. DEBUG_FN (DEBUG_MII);
  518. phyDetected = (PhyType) uiID1 = ns9750_mii_read(PHY_PHYIDR1);
  519. switch (phyDetected) {
  520. case PHY_LXT971A:
  521. szName = "LXT971A";
  522. uiID2 = ns9750_mii_read(PHY_PHYIDR2);
  523. nPhyMaxMdioClock = PHY_LXT971_MDIO_MAX_CLK;
  524. cRes = 1;
  525. break;
  526. case PHY_NONE:
  527. default:
  528. /* in case uiID1 == 0 && uiID2 == 0 we may have the wrong
  529. address or reset sets the wrong NS9750_ETH_MCFG_CLKS */
  530. uiID2 = 0;
  531. szName = "unknown";
  532. nPhyMaxMdioClock = PHY_MDIO_MAX_CLK;
  533. phyDetected = PHY_NONE;
  534. }
  535. printk (KERN_INFO NS9750_DRIVER_NAME
  536. ": PHY (0x%x, 0x%x) = %s detected\n", uiID1, uiID2, szName);
  537. return cRes;
  538. }
  539. /***********************************************************************
  540. * @Function: ns9750_mii_read
  541. * @Return: the data read from PHY register uiRegister
  542. * @Descr: the data read may be invalid if timed out. If so, a message
  543. * is printed but the invalid data is returned.
  544. * The fixed device address is being used.
  545. ***********************************************************************/
  546. static unsigned short ns9750_mii_read (unsigned short uiRegister)
  547. {
  548. DEBUG_FN (DEBUG_MII_LOW);
  549. /* write MII register to be read */
  550. *get_eth_reg_addr (NS9750_ETH_MADR) =
  551. NS9750_ETH_PHY_ADDRESS << 8 | uiRegister;
  552. *get_eth_reg_addr (NS9750_ETH_MCMD) = NS9750_ETH_MCMD_READ;
  553. if (!ns9750_mii_poll_busy ())
  554. printk (KERN_WARNING NS9750_DRIVER_NAME
  555. ": MII still busy in read\n");
  556. /* continue to read */
  557. *get_eth_reg_addr (NS9750_ETH_MCMD) = 0;
  558. return (unsigned short) (*get_eth_reg_addr (NS9750_ETH_MRDD));
  559. }
  560. /***********************************************************************
  561. * @Function: ns9750_mii_write
  562. * @Return: nothing
  563. * @Descr: writes the data to the PHY register. In case of a timeout,
  564. * no special handling is performed but a message printed
  565. * The fixed device address is being used.
  566. ***********************************************************************/
  567. static void ns9750_mii_write (unsigned short uiRegister,
  568. unsigned short uiData)
  569. {
  570. DEBUG_FN (DEBUG_MII_LOW);
  571. /* write MII register to be written */
  572. *get_eth_reg_addr (NS9750_ETH_MADR) =
  573. NS9750_ETH_PHY_ADDRESS << 8 | uiRegister;
  574. *get_eth_reg_addr (NS9750_ETH_MWTD) = uiData;
  575. if (!ns9750_mii_poll_busy ()) {
  576. printf (KERN_WARNING NS9750_DRIVER_NAME
  577. ": MII still busy in write\n");
  578. }
  579. }
  580. /***********************************************************************
  581. * @Function: ns9750_mii_get_clock_divisor
  582. * @Return: the clock divisor that should be used in NS9750_ETH_MCFG_CLKS
  583. * @Descr: if no clock divisor can be calculated for the
  584. * current SYSCLK and the maximum MDIO Clock, a warning is printed
  585. * and the greatest divisor is taken
  586. ***********************************************************************/
  587. static unsigned int ns9750_mii_get_clock_divisor (unsigned int unMaxMDIOClk)
  588. {
  589. struct {
  590. unsigned int unSysClkDivisor;
  591. unsigned int unClks; /* field for NS9750_ETH_MCFG_CLKS */
  592. } PHYClockDivisors[] = {
  593. {
  594. 4, NS9750_ETH_MCFG_CLKS_4}, {
  595. 6, NS9750_ETH_MCFG_CLKS_6}, {
  596. 8, NS9750_ETH_MCFG_CLKS_8}, {
  597. 10, NS9750_ETH_MCFG_CLKS_10}, {
  598. 20, NS9750_ETH_MCFG_CLKS_20}, {
  599. 30, NS9750_ETH_MCFG_CLKS_30}, {
  600. 40, NS9750_ETH_MCFG_CLKS_40}
  601. };
  602. int nIndexSysClkDiv;
  603. int nArraySize =
  604. sizeof (PHYClockDivisors) / sizeof (PHYClockDivisors[0]);
  605. unsigned int unClks = NS9750_ETH_MCFG_CLKS_40; /* defaults to
  606. greatest div */
  607. DEBUG_FN (DEBUG_INIT);
  608. for (nIndexSysClkDiv = 0; nIndexSysClkDiv < nArraySize;
  609. nIndexSysClkDiv++) {
  610. /* find first sysclock divisor that isn't higher than 2.5 MHz
  611. clock */
  612. if (AHB_CLK_FREQ /
  613. PHYClockDivisors[nIndexSysClkDiv].unSysClkDivisor <=
  614. unMaxMDIOClk) {
  615. unClks = PHYClockDivisors[nIndexSysClkDiv].unClks;
  616. break;
  617. }
  618. }
  619. DEBUG_ARGS2 (DEBUG_INIT,
  620. "Taking MDIO Clock bit mask 0x%0x for max clock %i\n",
  621. unClks, unMaxMDIOClk);
  622. /* return greatest divisor */
  623. return unClks;
  624. }
  625. /***********************************************************************
  626. * @Function: ns9750_mii_poll_busy
  627. * @Return: 0 if timed out otherwise the remaing timeout
  628. * @Descr: waits until the MII has completed a command or it times out
  629. * code may be interrupted by hard interrupts.
  630. * It is not checked what happens on multiple actions when
  631. * the first is still being busy and we timeout.
  632. ***********************************************************************/
  633. static unsigned int ns9750_mii_poll_busy (void)
  634. {
  635. unsigned int unTimeout = 10000;
  636. DEBUG_FN (DEBUG_MII_LOW);
  637. while (((*get_eth_reg_addr (NS9750_ETH_MIND) & NS9750_ETH_MIND_BUSY)
  638. == NS9750_ETH_MIND_BUSY) && unTimeout)
  639. unTimeout--;
  640. return unTimeout;
  641. }