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