tsec.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524
  1. /*
  2. * tsec.c
  3. * Motorola Three Speed Ethernet Controller driver
  4. *
  5. * This software may be used and distributed according to the
  6. * terms of the GNU Public License, Version 2, incorporated
  7. * herein by reference.
  8. *
  9. * (C) Copyright 2003, Motorola, Inc.
  10. * maintained by Xianghua Xiao (x.xiao@motorola.com)
  11. * author Andy Fleming
  12. *
  13. */
  14. #include <config.h>
  15. #include <mpc85xx.h>
  16. #include <common.h>
  17. #include <malloc.h>
  18. #include <net.h>
  19. #include <command.h>
  20. #if defined(CONFIG_TSEC_ENET)
  21. #include "tsec.h"
  22. #define TX_BUF_CNT 2
  23. #undef TSEC_DEBUG
  24. #ifdef TSEC_DEBUG
  25. #define DBGPRINT(x) printf(x)
  26. #else
  27. #define DBGPRINT(x)
  28. #endif
  29. static uint rxIdx; /* index of the current RX buffer */
  30. static uint txIdx; /* index of the current TX buffer */
  31. typedef volatile struct rtxbd {
  32. txbd8_t txbd[TX_BUF_CNT];
  33. rxbd8_t rxbd[PKTBUFSRX];
  34. } RTXBD;
  35. #ifdef __GNUC__
  36. static RTXBD rtx __attribute__ ((aligned(8)));
  37. #else
  38. #error "rtx must be 64-bit aligned"
  39. #endif
  40. static int tsec_send(struct eth_device* dev, volatile void *packet, int length);
  41. static int tsec_recv(struct eth_device* dev);
  42. static int tsec_init(struct eth_device* dev, bd_t * bd);
  43. static void tsec_halt(struct eth_device* dev);
  44. static void init_registers(tsec_t *regs);
  45. static void startup_tsec(tsec_t *regs);
  46. static void init_phy(tsec_t *regs);
  47. uint read_phy_reg(tsec_t *regbase, uint phyid, uint offset);
  48. static int phy_id = -1;
  49. /* Initialize device structure. returns 0 on failure, 1 on
  50. * success */
  51. int tsec_initialize(bd_t *bis)
  52. {
  53. struct eth_device* dev;
  54. int i;
  55. tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
  56. dev = (struct eth_device*) malloc(sizeof *dev);
  57. if(dev == NULL)
  58. return 0;
  59. memset(dev, 0, sizeof *dev);
  60. sprintf(dev->name, "MOTO ETHERNET");
  61. dev->iobase = 0;
  62. dev->priv = 0;
  63. dev->init = tsec_init;
  64. dev->halt = tsec_halt;
  65. dev->send = tsec_send;
  66. dev->recv = tsec_recv;
  67. /* Tell u-boot to get the addr from the env */
  68. for(i=0;i<6;i++)
  69. dev->enetaddr[i] = 0;
  70. eth_register(dev);
  71. /* Reconfigure the PHY to advertise everything here
  72. * so that it works with both gigabit and 10/100 */
  73. #ifdef CONFIG_PHY_M88E1011
  74. /* Assign a Physical address to the TBI */
  75. regs->tbipa=TBIPA_VALUE;
  76. /* reset the management interface */
  77. regs->miimcfg=MIIMCFG_RESET;
  78. regs->miimcfg=MIIMCFG_INIT_VALUE;
  79. /* Wait until the bus is free */
  80. while(regs->miimind & MIIMIND_BUSY);
  81. /* Locate PHYs. Skip TBIPA, which we know is 31.
  82. */
  83. for (i=0; i<31; i++) {
  84. if (read_phy_reg(regs, i, 2) == 0x141) {
  85. if (phy_id == -1)
  86. phy_id = i;
  87. #ifdef TSEC_DEBUG
  88. printf("Found Marvell PHY at 0x%02x\n", i);
  89. #endif
  90. }
  91. }
  92. #ifdef TSEC_DEBUG
  93. printf("Using PHY ID 0x%02x\n", phy_id);
  94. #endif
  95. write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_RESET);
  96. RESET_ERRATA(regs, phy_id);
  97. /* Configure the PHY to advertise gbit and 10/100 */
  98. write_phy_reg(regs, phy_id, MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT);
  99. write_phy_reg(regs, phy_id, MIIM_ANAR, MIIM_ANAR_INIT);
  100. /* Reset the PHY so the new settings take effect */
  101. write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_RESET);
  102. #endif
  103. return 1;
  104. }
  105. /* Initializes data structures and registers for the controller,
  106. * and brings the interface up */
  107. int tsec_init(struct eth_device* dev, bd_t * bd)
  108. {
  109. tsec_t *regs;
  110. uint tempval;
  111. char tmpbuf[MAC_ADDR_LEN];
  112. int i;
  113. regs = (tsec_t *)(TSEC_BASE_ADDR);
  114. /* Make sure the controller is stopped */
  115. tsec_halt(dev);
  116. /* Reset the MAC */
  117. regs->maccfg1 |= MACCFG1_SOFT_RESET;
  118. /* Clear MACCFG1[Soft_Reset] */
  119. regs->maccfg1 &= ~(MACCFG1_SOFT_RESET);
  120. /* Init MACCFG2. Defaults to GMII/MII */
  121. regs->maccfg2 = MACCFG2_INIT_SETTINGS;
  122. /* Init ECNTRL */
  123. regs->ecntrl = ECNTRL_INIT_SETTINGS;
  124. /* Copy the station address into the address registers.
  125. * Backwards, because little endian MACS are dumb */
  126. for(i=0;i<MAC_ADDR_LEN;i++) {
  127. tmpbuf[MAC_ADDR_LEN - 1 - i] = bd->bi_enetaddr[i];
  128. }
  129. (uint)(regs->macstnaddr1) = *((uint *)(tmpbuf));
  130. tempval = *((uint *)(tmpbuf +4));
  131. (uint)(regs->macstnaddr2) = tempval;
  132. /* Initialize the PHY */
  133. init_phy(regs);
  134. /* reset the indices to zero */
  135. rxIdx = 0;
  136. txIdx = 0;
  137. /* Clear out (for the most part) the other registers */
  138. init_registers(regs);
  139. /* Ready the device for tx/rx */
  140. startup_tsec(regs);
  141. return 1;
  142. }
  143. /* Reads from the register at offset in the PHY at phyid, */
  144. /* using the register set defined in regbase. It waits until the */
  145. /* bits in the miimstat are valid (miimind notvalid bit cleared), */
  146. /* and then passes those bits on to the variable specified in */
  147. /* value */
  148. /* Before it does the read, it needs to clear the command field */
  149. uint read_phy_reg(tsec_t *regbase, uint phyid, uint offset)
  150. {
  151. uint value;
  152. /* Put the address of the phy, and the register number into
  153. * MIIMADD
  154. */
  155. regbase->miimadd = (phyid << 8) | offset;
  156. /* Clear the command register, and wait */
  157. regbase->miimcom = 0;
  158. asm("msync");
  159. /* Initiate a read command, and wait */
  160. regbase->miimcom = MIIM_READ_COMMAND;
  161. asm("msync");
  162. /* Wait for the the indication that the read is done */
  163. while((regbase->miimind & (MIIMIND_NOTVALID | MIIMIND_BUSY)));
  164. /* Grab the value read from the PHY */
  165. value = regbase->miimstat;
  166. return value;
  167. }
  168. /* Setup the PHY */
  169. static void init_phy(tsec_t *regs)
  170. {
  171. uint testval;
  172. unsigned int timeout = TSEC_TIMEOUT;
  173. /* Assign a Physical address to the TBI */
  174. regs->tbipa=TBIPA_VALUE;
  175. /* reset the management interface */
  176. regs->miimcfg=MIIMCFG_RESET;
  177. regs->miimcfg=MIIMCFG_INIT_VALUE;
  178. /* Wait until the bus is free */
  179. while(regs->miimind & MIIMIND_BUSY);
  180. #ifdef CONFIG_PHY_CIS8201
  181. /* override PHY config settings */
  182. write_phy_reg(regs, 0, MIIM_AUX_CONSTAT, MIIM_AUXCONSTAT_INIT);
  183. /* Set up interface mode */
  184. write_phy_reg(regs, 0, MIIM_EXT_CON1, MIIM_EXTCON1_INIT);
  185. #endif
  186. /* Set the PHY to gigabit, full duplex, Auto-negotiate */
  187. write_phy_reg(regs, phy_id, MIIM_CONTROL, MIIM_CONTROL_INIT);
  188. /* Wait until STATUS indicates Auto-Negotiation is done */
  189. DBGPRINT("Waiting for Auto-negotiation to complete\n");
  190. testval=read_phy_reg(regs, phy_id, MIIM_STATUS);
  191. while((!(testval & MIIM_STATUS_AN_DONE))&& timeout--) {
  192. testval=read_phy_reg(regs, phy_id, MIIM_STATUS);
  193. }
  194. if(testval & MIIM_STATUS_AN_DONE)
  195. DBGPRINT("Auto-negotiation done\n");
  196. else
  197. DBGPRINT("Auto-negotiation timed-out.\n");
  198. #ifdef CONFIG_PHY_CIS8201
  199. /* Find out what duplexity (duplicity?) we have */
  200. /* Read it twice to make sure */
  201. testval=read_phy_reg(regs, phy_id, MIIM_AUX_CONSTAT);
  202. if(testval & MIIM_AUXCONSTAT_DUPLEX) {
  203. DBGPRINT("Enet starting in full duplex\n");
  204. regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
  205. } else {
  206. DBGPRINT("Enet starting in half duplex\n");
  207. regs->maccfg2 &= ~MACCFG2_FULL_DUPLEX;
  208. }
  209. /* Also, we look to see what speed we are at
  210. * if Gigabit, MACCFG2 goes in GMII, otherwise,
  211. * MII mode.
  212. */
  213. if((testval & MIIM_AUXCONSTAT_SPEED) != MIIM_AUXCONSTAT_GBIT) {
  214. if((testval & MIIM_AUXCONSTAT_SPEED) == MIIM_AUXCONSTAT_100)
  215. DBGPRINT("Enet starting in 100BT\n");
  216. else
  217. DBGPRINT("Enet starting in 10BT\n");
  218. /* mark the mode in MACCFG2 */
  219. regs->maccfg2 = ((regs->maccfg2&~(MACCFG2_IF)) | MACCFG2_MII);
  220. } else {
  221. DBGPRINT("Enet starting in 1000BT\n");
  222. }
  223. #endif
  224. #ifdef CONFIG_PHY_M88E1011
  225. /* Read the PHY to see what speed and duplex we are */
  226. testval=read_phy_reg(regs, phy_id, MIIM_PHY_STATUS);
  227. timeout = TSEC_TIMEOUT;
  228. while((!(testval & MIIM_PHYSTAT_SPDDONE)) && timeout--) {
  229. testval = read_phy_reg(regs,phy_id,MIIM_PHY_STATUS);
  230. }
  231. if(!(testval & MIIM_PHYSTAT_SPDDONE))
  232. DBGPRINT("Enet: Speed not resolved\n");
  233. testval=read_phy_reg(regs, phy_id, MIIM_PHY_STATUS);
  234. if(testval & MIIM_PHYSTAT_DUPLEX) {
  235. DBGPRINT("Enet starting in Full Duplex\n");
  236. regs->maccfg2 |= MACCFG2_FULL_DUPLEX;
  237. } else {
  238. DBGPRINT("Enet starting in Half Duplex\n");
  239. regs->maccfg2 &= ~MACCFG2_FULL_DUPLEX;
  240. }
  241. if(!((testval&MIIM_PHYSTAT_SPEED) == MIIM_PHYSTAT_GBIT)) {
  242. if((testval & MIIM_PHYSTAT_SPEED) == MIIM_PHYSTAT_100)
  243. DBGPRINT("Enet starting in 100BT\n");
  244. else
  245. DBGPRINT("Enet starting in 10BT\n");
  246. regs->maccfg2 = ((regs->maccfg2&~(MACCFG2_IF)) | MACCFG2_MII);
  247. } else {
  248. DBGPRINT("Enet starting in 1000BT\n");
  249. }
  250. #endif
  251. }
  252. static void init_registers(tsec_t *regs)
  253. {
  254. /* Clear IEVENT */
  255. regs->ievent = IEVENT_INIT_CLEAR;
  256. regs->imask = IMASK_INIT_CLEAR;
  257. regs->hash.iaddr0 = 0;
  258. regs->hash.iaddr1 = 0;
  259. regs->hash.iaddr2 = 0;
  260. regs->hash.iaddr3 = 0;
  261. regs->hash.iaddr4 = 0;
  262. regs->hash.iaddr5 = 0;
  263. regs->hash.iaddr6 = 0;
  264. regs->hash.iaddr7 = 0;
  265. regs->hash.gaddr0 = 0;
  266. regs->hash.gaddr1 = 0;
  267. regs->hash.gaddr2 = 0;
  268. regs->hash.gaddr3 = 0;
  269. regs->hash.gaddr4 = 0;
  270. regs->hash.gaddr5 = 0;
  271. regs->hash.gaddr6 = 0;
  272. regs->hash.gaddr7 = 0;
  273. regs->rctrl = 0x00000000;
  274. /* Init RMON mib registers */
  275. memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t));
  276. regs->rmon.cam1 = 0xffffffff;
  277. regs->rmon.cam2 = 0xffffffff;
  278. regs->mrblr = MRBLR_INIT_SETTINGS;
  279. regs->minflr = MINFLR_INIT_SETTINGS;
  280. regs->attr = ATTR_INIT_SETTINGS;
  281. regs->attreli = ATTRELI_INIT_SETTINGS;
  282. }
  283. static void startup_tsec(tsec_t *regs)
  284. {
  285. int i;
  286. /* Point to the buffer descriptors */
  287. regs->tbase = (unsigned int)(&rtx.txbd[txIdx]);
  288. regs->rbase = (unsigned int)(&rtx.rxbd[rxIdx]);
  289. /* Initialize the Rx Buffer descriptors */
  290. for (i = 0; i < PKTBUFSRX; i++) {
  291. rtx.rxbd[i].status = RXBD_EMPTY;
  292. rtx.rxbd[i].length = 0;
  293. rtx.rxbd[i].bufPtr = (uint)NetRxPackets[i];
  294. }
  295. rtx.rxbd[PKTBUFSRX -1].status |= RXBD_WRAP;
  296. /* Initialize the TX Buffer Descriptors */
  297. for(i=0; i<TX_BUF_CNT; i++) {
  298. rtx.txbd[i].status = 0;
  299. rtx.txbd[i].length = 0;
  300. rtx.txbd[i].bufPtr = 0;
  301. }
  302. rtx.txbd[TX_BUF_CNT -1].status |= TXBD_WRAP;
  303. /* Enable Transmit and Receive */
  304. regs->maccfg1 |= (MACCFG1_RX_EN | MACCFG1_TX_EN);
  305. /* Tell the DMA it is clear to go */
  306. regs->dmactrl |= DMACTRL_INIT_SETTINGS;
  307. regs->tstat = TSTAT_CLEAR_THALT;
  308. regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
  309. }
  310. /* This returns the status bits of the device. The return value
  311. * is never checked, and this is what the 8260 driver did, so we
  312. * do the same. Presumably, this would be zero if there were no
  313. * errors */
  314. static int tsec_send(struct eth_device* dev, volatile void *packet, int length)
  315. {
  316. int i;
  317. int result = 0;
  318. tsec_t * regs = (tsec_t *)(TSEC_BASE_ADDR);
  319. /* Find an empty buffer descriptor */
  320. for(i=0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
  321. if (i >= TOUT_LOOP) {
  322. DBGPRINT("tsec: tx buffers full\n");
  323. return result;
  324. }
  325. }
  326. rtx.txbd[txIdx].bufPtr = (uint)packet;
  327. rtx.txbd[txIdx].length = length;
  328. rtx.txbd[txIdx].status |= (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT);
  329. /* Tell the DMA to go */
  330. regs->tstat = TSTAT_CLEAR_THALT;
  331. /* Wait for buffer to be transmitted */
  332. for(i=0; rtx.txbd[txIdx].status & TXBD_READY; i++) {
  333. if (i >= TOUT_LOOP) {
  334. DBGPRINT("tsec: tx error\n");
  335. return result;
  336. }
  337. }
  338. txIdx = (txIdx + 1) % TX_BUF_CNT;
  339. result = rtx.txbd[txIdx].status & TXBD_STATS;
  340. return result;
  341. }
  342. static int tsec_recv(struct eth_device* dev)
  343. {
  344. int length;
  345. tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
  346. while(!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) {
  347. length = rtx.rxbd[rxIdx].length;
  348. /* Send the packet up if there were no errors */
  349. if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) {
  350. NetReceive(NetRxPackets[rxIdx], length - 4);
  351. }
  352. rtx.rxbd[rxIdx].length = 0;
  353. /* Set the wrap bit if this is the last element in the list */
  354. rtx.rxbd[rxIdx].status = RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0);
  355. rxIdx = (rxIdx + 1) % PKTBUFSRX;
  356. }
  357. if(regs->ievent&IEVENT_BSY) {
  358. regs->ievent = IEVENT_BSY;
  359. regs->rstat = RSTAT_CLEAR_RHALT;
  360. }
  361. return -1;
  362. }
  363. static void tsec_halt(struct eth_device* dev)
  364. {
  365. tsec_t *regs = (tsec_t *)(TSEC_BASE_ADDR);
  366. regs->dmactrl &= ~(DMACTRL_GRS | DMACTRL_GTS);
  367. regs->dmactrl |= (DMACTRL_GRS | DMACTRL_GTS);
  368. while(!(regs->ievent & (IEVENT_GRSC | IEVENT_GTSC)));
  369. regs->maccfg1 &= ~(MACCFG1_TX_EN | MACCFG1_RX_EN);
  370. }
  371. #ifndef CONFIG_BITBANGMII
  372. /*
  373. * Read a MII PHY register.
  374. *
  375. * Returns:
  376. * 0 on success
  377. */
  378. int miiphy_read(unsigned char addr,
  379. unsigned char reg,
  380. unsigned short *value)
  381. {
  382. tsec_t *regs;
  383. unsigned short rv;
  384. regs = (tsec_t *)(TSEC_BASE_ADDR);
  385. rv = (unsigned short)read_phy_reg(regs, addr, reg);
  386. *value = rv;
  387. return 0;
  388. }
  389. /*
  390. * Write a MII PHY register.
  391. *
  392. * Returns:
  393. * 0 on success
  394. */
  395. int miiphy_write(unsigned char addr,
  396. unsigned char reg,
  397. unsigned short value)
  398. {
  399. tsec_t *regs;
  400. regs = (tsec_t *)(TSEC_BASE_ADDR);
  401. write_phy_reg(regs, addr, reg, value);
  402. return 0;
  403. }
  404. #endif /* CONFIG_BITBANGMII */
  405. #endif /* CONFIG_TSEC_ENET */