ethermii.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #include "u.h"
  2. #include "lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "io.h"
  7. #include "etherif.h"
  8. #include "ethermii.h"
  9. int
  10. mii(Mii* mii, int mask)
  11. {
  12. MiiPhy *miiphy;
  13. int bit, phyno, r, rmask;
  14. /*
  15. * Probe through mii for PHYs in mask;
  16. * return the mask of those found in the current probe.
  17. * If the PHY has not already been probed, update
  18. * the Mii information.
  19. */
  20. rmask = 0;
  21. for(phyno = 0; phyno < NMiiPhy; phyno++){
  22. bit = 1<<phyno;
  23. if(!(mask & bit))
  24. continue;
  25. if(mii->mask & bit){
  26. rmask |= bit;
  27. continue;
  28. }
  29. if(mii->mir(mii, phyno, Bmsr) == -1)
  30. continue;
  31. if((miiphy = malloc(sizeof(MiiPhy))) == nil)
  32. continue;
  33. miiphy->mii = mii;
  34. r = mii->mir(mii, phyno, Phyidr1);
  35. miiphy->oui = (r & 0x3FFF)<<6;
  36. r = mii->mir(mii, phyno, Phyidr2);
  37. miiphy->oui |= r>>10;
  38. miiphy->phyno = phyno;
  39. miiphy->anar = ~0;
  40. miiphy->fc = ~0;
  41. miiphy->mscr = ~0;
  42. mii->phy[phyno] = miiphy;
  43. if(mii->curphy == nil)
  44. mii->curphy = miiphy;
  45. mii->mask |= bit;
  46. mii->nphy++;
  47. rmask |= bit;
  48. }
  49. return rmask;
  50. }
  51. int
  52. miimir(Mii* mii, int r)
  53. {
  54. if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
  55. return -1;
  56. return mii->mir(mii, mii->curphy->phyno, r);
  57. }
  58. int
  59. miimiw(Mii* mii, int r, int data)
  60. {
  61. if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
  62. return -1;
  63. return mii->miw(mii, mii->curphy->phyno, r, data);
  64. }
  65. int
  66. miireset(Mii* mii)
  67. {
  68. int bmcr;
  69. if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
  70. return -1;
  71. bmcr = mii->mir(mii, mii->curphy->phyno, Bmcr);
  72. bmcr |= BmcrR;
  73. mii->miw(mii, mii->curphy->phyno, Bmcr, bmcr);
  74. microdelay(1);
  75. return 0;
  76. }
  77. int
  78. miiane(Mii* mii, int a, int p, int e)
  79. {
  80. int anar, bmsr, mscr, r, phyno;
  81. if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
  82. return -1;
  83. phyno = mii->curphy->phyno;
  84. bmsr = mii->mir(mii, phyno, Bmsr);
  85. if(!(bmsr & BmsrAna))
  86. return -1;
  87. if(a != ~0)
  88. anar = (AnaTXFD|AnaTXHD|Ana10FD|Ana10HD) & a;
  89. else if(mii->curphy->anar != ~0)
  90. anar = mii->curphy->anar;
  91. else{
  92. anar = mii->mir(mii, phyno, Anar);
  93. anar &= ~(AnaAP|AnaP|AnaT4|AnaTXFD|AnaTXHD|Ana10FD|Ana10HD);
  94. if(bmsr & Bmsr10THD)
  95. anar |= Ana10HD;
  96. if(bmsr & Bmsr10TFD)
  97. anar |= Ana10FD;
  98. if(bmsr & Bmsr100TXHD)
  99. anar |= AnaTXHD;
  100. if(bmsr & Bmsr100TXFD)
  101. anar |= AnaTXFD;
  102. }
  103. mii->curphy->anar = anar;
  104. if(p != ~0)
  105. anar |= (AnaAP|AnaP) & p;
  106. else if(mii->curphy->fc != ~0)
  107. anar |= mii->curphy->fc;
  108. mii->curphy->fc = (AnaAP|AnaP) & anar;
  109. if(bmsr & BmsrEs){
  110. mscr = mii->mir(mii, phyno, Mscr);
  111. mscr &= ~(Mscr1000TFD|Mscr1000THD);
  112. if(e != ~0)
  113. mscr |= (Mscr1000TFD|Mscr1000THD) & e;
  114. else if(mii->curphy->mscr != ~0)
  115. mscr = mii->curphy->mscr;
  116. else{
  117. r = mii->mir(mii, phyno, Esr);
  118. if(r & Esr1000THD)
  119. mscr |= Mscr1000THD;
  120. if(r & Esr1000TFD)
  121. mscr |= Mscr1000TFD;
  122. }
  123. mii->curphy->mscr = mscr;
  124. mii->miw(mii, phyno, Mscr, mscr);
  125. }
  126. mii->miw(mii, phyno, Anar, anar);
  127. r = mii->mir(mii, phyno, Bmcr);
  128. if(!(r & BmcrR)){
  129. r |= BmcrAne|BmcrRan;
  130. mii->miw(mii, phyno, Bmcr, r);
  131. }
  132. return 0;
  133. }
  134. int
  135. miistatus(Mii* mii)
  136. {
  137. MiiPhy *phy;
  138. int anlpar, bmsr, p, r, phyno;
  139. if(mii == nil || mii->ctlr == nil || mii->curphy == nil)
  140. return -1;
  141. phy = mii->curphy;
  142. phyno = phy->phyno;
  143. /*
  144. * Check Auto-Negotiation is complete and link is up.
  145. * (Read status twice as the Ls bit is sticky).
  146. */
  147. bmsr = mii->mir(mii, phyno, Bmsr);
  148. if(!(bmsr & (BmsrAnc|BmsrAna)))
  149. return -1;
  150. bmsr = mii->mir(mii, phyno, Bmsr);
  151. if(!(bmsr & BmsrLs)){
  152. phy->link = 0;
  153. return -1;
  154. }
  155. phy->speed = phy->fd = phy->rfc = phy->tfc = 0;
  156. if(phy->mscr){
  157. r = mii->mir(mii, phyno, Mssr);
  158. if((phy->mscr & Mscr1000TFD) && (r & Mssr1000TFD)){
  159. phy->speed = 1000;
  160. phy->fd = 1;
  161. }
  162. else if((phy->mscr & Mscr1000THD) && (r & Mssr1000THD))
  163. phy->speed = 1000;
  164. }
  165. anlpar = mii->mir(mii, phyno, Anlpar);
  166. if(phy->speed == 0){
  167. r = phy->anar & anlpar;
  168. if(r & AnaTXFD){
  169. phy->speed = 100;
  170. phy->fd = 1;
  171. }
  172. else if(r & AnaTXHD)
  173. phy->speed = 100;
  174. else if(r & Ana10FD){
  175. phy->speed = 10;
  176. phy->fd = 1;
  177. }
  178. else if(r & Ana10HD)
  179. phy->speed = 10;
  180. }
  181. if(phy->speed == 0)
  182. return -1;
  183. if(phy->fd){
  184. p = phy->fc;
  185. r = anlpar & (AnaAP|AnaP);
  186. if(p == AnaAP && r == (AnaAP|AnaP))
  187. phy->tfc = 1;
  188. else if(p == (AnaAP|AnaP) && r == AnaAP)
  189. phy->rfc = 1;
  190. else if((p & AnaP) && (r & AnaP))
  191. phy->rfc = phy->tfc = 1;
  192. }
  193. phy->link = 1;
  194. return 0;
  195. }