The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/pc/ethermii.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 7ac7e83db30deec5cb8e896662c910dd


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.