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/dev/mii/rlswitch.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 /*-
    2  * SPDX-License-Identifier: BSD-4-Clause
    3  *
    4  * Copyright (c) 1997, 1998, 1999
    5  *      Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
    6  * Copyright (c) 2006 Bernd Walter.  All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. All advertising materials mentioning features or use of this software
   17  *    must display the following acknowledgement:
   18  *      This product includes software developed by Bill Paul.
   19  * 4. Neither the name of the author nor the names of any co-contributors
   20  *    may be used to endorse or promote products derived from this software
   21  *    without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
   27  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
   33  * THE POSSIBILITY OF SUCH DAMAGE.
   34  */
   35 
   36 #include <sys/cdefs.h>
   37 __FBSDID("$FreeBSD$");
   38 
   39 /*
   40  * driver for RealTek 8305 pseudo PHYs
   41  */
   42 
   43 #include <sys/param.h>
   44 #include <sys/systm.h>
   45 #include <sys/kernel.h>
   46 #include <sys/module.h>
   47 #include <sys/socket.h>
   48 #include <sys/bus.h>
   49 #include <sys/taskqueue.h>      /* XXXGL: if_rlreg.h contamination */
   50 
   51 #include <net/if.h>
   52 #include <net/if_arp.h>
   53 #include <net/if_media.h>
   54 
   55 #include <dev/mii/mii.h>
   56 #include <dev/mii/miivar.h>
   57 #include "miidevs.h"
   58 
   59 #include <machine/bus.h>
   60 #include <dev/rl/if_rlreg.h>
   61 
   62 #include "miibus_if.h"
   63 
   64 //#define RL_DEBUG
   65 #define RL_VLAN
   66 
   67 static int rlswitch_probe(device_t);
   68 static int rlswitch_attach(device_t);
   69 
   70 static device_method_t rlswitch_methods[] = {
   71         /* device interface */
   72         DEVMETHOD(device_probe,         rlswitch_probe),
   73         DEVMETHOD(device_attach,        rlswitch_attach),
   74         DEVMETHOD(device_detach,        mii_phy_detach),
   75         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
   76         DEVMETHOD_END
   77 };
   78 
   79 static driver_t rlswitch_driver = {
   80         "rlswitch",
   81         rlswitch_methods,
   82         sizeof(struct mii_softc)
   83 };
   84 
   85 DRIVER_MODULE(rlswitch, miibus, rlswitch_driver, 0, 0);
   86 
   87 static int      rlswitch_service(struct mii_softc *, struct mii_data *, int);
   88 static void     rlswitch_status(struct mii_softc *);
   89 
   90 #ifdef RL_DEBUG
   91 static void     rlswitch_phydump(device_t dev);
   92 #endif
   93 
   94 static const struct mii_phydesc rlswitches[] = {
   95         MII_PHY_DESC(REALTEK, RTL8305SC),
   96         MII_PHY_END
   97 };
   98 
   99 static const struct mii_phy_funcs rlswitch_funcs = {
  100         rlswitch_service,
  101         rlswitch_status,
  102         mii_phy_reset
  103 };
  104 
  105 static int
  106 rlswitch_probe(device_t dev)
  107 {
  108         int rv;
  109 
  110         rv = mii_phy_dev_probe(dev, rlswitches, BUS_PROBE_DEFAULT);
  111         if (rv <= 0)
  112                 return (rv);
  113 
  114         return (ENXIO);
  115 }
  116 
  117 static int
  118 rlswitch_attach(device_t dev)
  119 {
  120         struct mii_softc        *sc;
  121 
  122         sc = device_get_softc(dev);
  123 
  124         /*
  125          * We handle all pseudo PHYs in a single instance.
  126          */
  127         mii_phy_dev_attach(dev, MIIF_NOISOLATE | MIIF_NOMANPAUSE,
  128             &rlswitch_funcs, 0);
  129 
  130         sc->mii_capabilities = BMSR_100TXFDX & sc->mii_capmask;
  131         device_printf(dev, " ");
  132         mii_phy_add_media(sc);
  133         printf("\n");
  134 #ifdef RL_DEBUG
  135         rlswitch_phydump(dev);
  136 #endif
  137 
  138 #ifdef RL_VLAN
  139         int val;
  140 
  141         /* Global Control 0 */
  142         val = 0;
  143         val |= 0 << 10;         /* enable 802.1q VLAN Tag support */
  144         val |= 0 << 9;          /* enable VLAN ingress filtering */
  145         val |= 1 << 8;          /* disable VLAN tag admit control */
  146         val |= 1 << 6;          /* internal use */
  147         val |= 1 << 5;          /* internal use */
  148         val |= 1 << 4;          /* internal use */
  149         val |= 1 << 3;          /* internal use */
  150         val |= 1 << 1;          /* reserved */
  151         MIIBUS_WRITEREG(sc->mii_dev, 0, 16, val);
  152 
  153         /* Global Control 2 */
  154         val = 0;
  155         val |= 1 << 15;         /* reserved */
  156         val |= 0 << 14;         /* enable 1552 Bytes support */
  157         val |= 1 << 13;         /* enable broadcast input drop */
  158         val |= 1 << 12;         /* forward reserved control frames */
  159         val |= 1 << 11;         /* disable forwarding unicast frames to other VLAN's */
  160         val |= 1 << 10;         /* disable forwarding ARP broadcasts to other VLAN's */
  161         val |= 1 << 9;          /* enable 48 pass 1 */
  162         val |= 0 << 8;          /* enable VLAN */
  163         val |= 1 << 7;          /* reserved */
  164         val |= 1 << 6;          /* enable defer */
  165         val |= 1 << 5;          /* 43ms LED blink time */
  166         val |= 3 << 3;          /* 16:1 queue weight */
  167         val |= 1 << 2;          /* disable broadcast storm control */
  168         val |= 1 << 1;          /* enable power-on LED blinking */
  169         val |= 1 << 0;          /* reserved */
  170         MIIBUS_WRITEREG(sc->mii_dev, 0, 18, val);
  171 
  172         /* Port 0 Control Register 0 */
  173         val = 0;
  174         val |= 1 << 15;         /* reserved */
  175         val |= 1 << 11;         /* drop received packets with wrong VLAN tag */
  176         val |= 1 << 10;         /* disable 802.1p priority classification */
  177         val |= 1 << 9;          /* disable diffserv priority classification */
  178         val |= 1 << 6;          /* internal use */
  179         val |= 3 << 4;          /* internal use */
  180         val |= 1 << 3;          /* internal use */
  181         val |= 1 << 2;          /* internal use */
  182         val |= 1 << 0;          /* remove VLAN tags on output */
  183         MIIBUS_WRITEREG(sc->mii_dev, 0, 22, val);
  184 
  185         /* Port 1 Control Register 0 */
  186         val = 0;
  187         val |= 1 << 15;         /* reserved */
  188         val |= 1 << 11;         /* drop received packets with wrong VLAN tag */
  189         val |= 1 << 10;         /* disable 802.1p priority classification */
  190         val |= 1 << 9;          /* disable diffserv priority classification */
  191         val |= 1 << 6;          /* internal use */
  192         val |= 3 << 4;          /* internal use */
  193         val |= 1 << 3;          /* internal use */
  194         val |= 1 << 2;          /* internal use */
  195         val |= 1 << 0;          /* remove VLAN tags on output */
  196         MIIBUS_WRITEREG(sc->mii_dev, 1, 22, val);
  197 
  198         /* Port 2 Control Register 0 */
  199         val = 0;
  200         val |= 1 << 15;         /* reserved */
  201         val |= 1 << 11;         /* drop received packets with wrong VLAN tag */
  202         val |= 1 << 10;         /* disable 802.1p priority classification */
  203         val |= 1 << 9;          /* disable diffserv priority classification */
  204         val |= 1 << 6;          /* internal use */
  205         val |= 3 << 4;          /* internal use */
  206         val |= 1 << 3;          /* internal use */
  207         val |= 1 << 2;          /* internal use */
  208         val |= 1 << 0;          /* remove VLAN tags on output */
  209         MIIBUS_WRITEREG(sc->mii_dev, 2, 22, val);
  210 
  211         /* Port 3 Control Register 0 */
  212         val = 0;
  213         val |= 1 << 15;         /* reserved */
  214         val |= 1 << 11;         /* drop received packets with wrong VLAN tag */
  215         val |= 1 << 10;         /* disable 802.1p priority classification */
  216         val |= 1 << 9;          /* disable diffserv priority classification */
  217         val |= 1 << 6;          /* internal use */
  218         val |= 3 << 4;          /* internal use */
  219         val |= 1 << 3;          /* internal use */
  220         val |= 1 << 2;          /* internal use */
  221         val |= 1 << 0;          /* remove VLAN tags on output */
  222         MIIBUS_WRITEREG(sc->mii_dev, 3, 22, val);
  223 
  224         /* Port 4 (system port) Control Register 0 */
  225         val = 0;
  226         val |= 1 << 15;         /* reserved */
  227         val |= 0 << 11;         /* don't drop received packets with wrong VLAN tag */
  228         val |= 1 << 10;         /* disable 802.1p priority classification */
  229         val |= 1 << 9;          /* disable diffserv priority classification */
  230         val |= 1 << 6;          /* internal use */
  231         val |= 3 << 4;          /* internal use */
  232         val |= 1 << 3;          /* internal use */
  233         val |= 1 << 2;          /* internal use */
  234         val |= 2 << 0;          /* add VLAN tags for untagged packets on output */
  235         MIIBUS_WRITEREG(sc->mii_dev, 4, 22, val);
  236 
  237         /* Port 0 Control Register 1 and VLAN A */
  238         val = 0;
  239         val |= 0x0 << 12;       /* Port 0 VLAN Index */
  240         val |= 1 << 11;         /* internal use */
  241         val |= 1 << 10;         /* internal use */
  242         val |= 1 << 9;          /* internal use */
  243         val |= 1 << 7;          /* internal use */
  244         val |= 1 << 6;          /* internal use */
  245         val |= 0x11 << 0;       /* VLAN A membership */
  246         MIIBUS_WRITEREG(sc->mii_dev, 0, 24, val);
  247 
  248         /* Port 0 Control Register 2 and VLAN A */
  249         val = 0;
  250         val |= 1 << 15;         /* internal use */
  251         val |= 1 << 14;         /* internal use */
  252         val |= 1 << 13;         /* internal use */
  253         val |= 1 << 12;         /* internal use */
  254         val |= 0x100 << 0;      /* VLAN A ID */
  255         MIIBUS_WRITEREG(sc->mii_dev, 0, 25, val);
  256 
  257         /* Port 1 Control Register 1 and VLAN B */
  258         val = 0;
  259         val |= 0x1 << 12;       /* Port 1 VLAN Index */
  260         val |= 1 << 11;         /* internal use */
  261         val |= 1 << 10;         /* internal use */
  262         val |= 1 << 9;          /* internal use */
  263         val |= 1 << 7;          /* internal use */
  264         val |= 1 << 6;          /* internal use */
  265         val |= 0x12 << 0;       /* VLAN B membership */
  266         MIIBUS_WRITEREG(sc->mii_dev, 1, 24, val);
  267 
  268         /* Port 1 Control Register 2 and VLAN B */
  269         val = 0;
  270         val |= 1 << 15;         /* internal use */
  271         val |= 1 << 14;         /* internal use */
  272         val |= 1 << 13;         /* internal use */
  273         val |= 1 << 12;         /* internal use */
  274         val |= 0x101 << 0;      /* VLAN B ID */
  275         MIIBUS_WRITEREG(sc->mii_dev, 1, 25, val);
  276 
  277         /* Port 2 Control Register 1 and VLAN C */
  278         val = 0;
  279         val |= 0x2 << 12;       /* Port 2 VLAN Index */
  280         val |= 1 << 11;         /* internal use */
  281         val |= 1 << 10;         /* internal use */
  282         val |= 1 << 9;          /* internal use */
  283         val |= 1 << 7;          /* internal use */
  284         val |= 1 << 6;          /* internal use */
  285         val |= 0x14 << 0;       /* VLAN C membership */
  286         MIIBUS_WRITEREG(sc->mii_dev, 2, 24, val);
  287 
  288         /* Port 2 Control Register 2 and VLAN C */
  289         val = 0;
  290         val |= 1 << 15;         /* internal use */
  291         val |= 1 << 14;         /* internal use */
  292         val |= 1 << 13;         /* internal use */
  293         val |= 1 << 12;         /* internal use */
  294         val |= 0x102 << 0;      /* VLAN C ID */
  295         MIIBUS_WRITEREG(sc->mii_dev, 2, 25, val);
  296 
  297         /* Port 3 Control Register 1 and VLAN D */
  298         val = 0;
  299         val |= 0x3 << 12;       /* Port 3 VLAN Index */
  300         val |= 1 << 11;         /* internal use */
  301         val |= 1 << 10;         /* internal use */
  302         val |= 1 << 9;          /* internal use */
  303         val |= 1 << 7;          /* internal use */
  304         val |= 1 << 6;          /* internal use */
  305         val |= 0x18 << 0;       /* VLAN D membership */
  306         MIIBUS_WRITEREG(sc->mii_dev, 3, 24, val);
  307 
  308         /* Port 3 Control Register 2 and VLAN D */
  309         val = 0;
  310         val |= 1 << 15;         /* internal use */
  311         val |= 1 << 14;         /* internal use */
  312         val |= 1 << 13;         /* internal use */
  313         val |= 1 << 12;         /* internal use */
  314         val |= 0x103 << 0;      /* VLAN D ID */
  315         MIIBUS_WRITEREG(sc->mii_dev, 3, 25, val);
  316 
  317         /* Port 4 Control Register 1 and VLAN E */
  318         val = 0;
  319         val |= 0x0 << 12;       /* Port 4 VLAN Index */
  320         val |= 1 << 11;         /* internal use */
  321         val |= 1 << 10;         /* internal use */
  322         val |= 1 << 9;          /* internal use */
  323         val |= 1 << 7;          /* internal use */
  324         val |= 1 << 6;          /* internal use */
  325         val |= 0 << 0;          /* VLAN E membership */
  326         MIIBUS_WRITEREG(sc->mii_dev, 4, 24, val);
  327 
  328         /* Port 4 Control Register 2 and VLAN E */
  329         val = 0;
  330         val |= 1 << 15;         /* internal use */
  331         val |= 1 << 14;         /* internal use */
  332         val |= 1 << 13;         /* internal use */
  333         val |= 1 << 12;         /* internal use */
  334         val |= 0x104 << 0;      /* VLAN E ID */
  335         MIIBUS_WRITEREG(sc->mii_dev, 4, 25, val);
  336 #endif
  337 
  338 #ifdef RL_DEBUG
  339         rlswitch_phydump(dev);
  340 #endif
  341         MIIBUS_MEDIAINIT(sc->mii_dev);
  342         return (0);
  343 }
  344 
  345 static int
  346 rlswitch_service(struct mii_softc *sc, struct mii_data *mii, int cmd)
  347 {
  348 
  349         switch (cmd) {
  350         case MII_POLLSTAT:
  351                 break;
  352 
  353         case MII_MEDIACHG:
  354                 break;
  355 
  356         case MII_TICK:
  357                 break;
  358         }
  359 
  360         /* Update the media status. */
  361         PHY_STATUS(sc);
  362 
  363         /* Callback if something changed. */
  364         // mii_phy_update(sc, cmd);
  365         return (0);
  366 }
  367 
  368 static void
  369 rlswitch_status(struct mii_softc *phy)
  370 {
  371         struct mii_data *mii = phy->mii_pdata;
  372 
  373         mii->mii_media_status = IFM_AVALID;
  374         mii->mii_media_active = IFM_ETHER;
  375         mii->mii_media_status |= IFM_ACTIVE;
  376         mii->mii_media_active |=
  377             IFM_100_TX | IFM_FDX | mii_phy_flowstatus(phy);
  378 }
  379 
  380 #ifdef RL_DEBUG
  381 static void
  382 rlswitch_phydump(device_t dev) {
  383         int phy, reg, val;
  384         struct mii_softc *sc;
  385 
  386         sc = device_get_softc(dev);
  387         device_printf(dev, "rlswitchphydump\n");
  388         for (phy = 0; phy <= 5; phy++) {
  389                 printf("PHY%i:", phy);
  390                 for (reg = 0; reg <= 31; reg++) {
  391                         val = MIIBUS_READREG(sc->mii_dev, phy, reg);
  392                         printf(" 0x%x", val);
  393                 }
  394                 printf("\n");
  395         }
  396 }
  397 #endif

Cache object: 8fa1e047965c5646ce5e0da1cc3aed89


[ 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.