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/etherswitch/rtl8366/rtl8366rb.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-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2015-2016 Hiroki Mori.
    5  * Copyright (c) 2011-2012 Stefan Bethke.
    6  * 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  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  *
   29  * $FreeBSD$
   30  */
   31 
   32 #include "opt_etherswitch.h"
   33 
   34 #include <sys/param.h>
   35 #include <sys/bus.h>
   36 #include <sys/errno.h>
   37 #include <sys/kernel.h>
   38 #include <sys/lock.h>
   39 #include <sys/malloc.h>
   40 #include <sys/module.h>
   41 #include <sys/mutex.h>
   42 #include <sys/socket.h>
   43 #include <sys/sockio.h>
   44 #include <sys/sysctl.h>
   45 #include <sys/systm.h>
   46 
   47 #include <net/if.h>
   48 #include <net/if_var.h>
   49 #include <net/ethernet.h>
   50 #include <net/if_media.h>
   51 #include <net/if_types.h>
   52 
   53 #include <machine/bus.h>
   54 #include <dev/iicbus/iic.h>
   55 #include <dev/iicbus/iiconf.h>
   56 #include <dev/iicbus/iicbus.h>
   57 #include <dev/mii/mii.h>
   58 #include <dev/mii/miivar.h>
   59 #include <dev/mdio/mdio.h>
   60 
   61 #include <dev/etherswitch/etherswitch.h>
   62 #include <dev/etherswitch/rtl8366/rtl8366rbvar.h>
   63 
   64 #include "mdio_if.h"
   65 #include "iicbus_if.h"
   66 #include "miibus_if.h"
   67 #include "etherswitch_if.h"
   68 
   69 
   70 struct rtl8366rb_softc {
   71         struct mtx      sc_mtx;         /* serialize access to softc */
   72         int             smi_acquired;   /* serialize access to SMI/I2C bus */
   73         struct mtx      callout_mtx;    /* serialize callout */
   74         device_t        dev;
   75         int             vid[RTL8366_NUM_VLANS];
   76         char            *ifname[RTL8366_NUM_PHYS];
   77         device_t        miibus[RTL8366_NUM_PHYS];
   78         if_t ifp[RTL8366_NUM_PHYS];
   79         struct callout  callout_tick;
   80         etherswitch_info_t      info;
   81         int             chip_type;
   82         int             phy4cpu;
   83         int             numphys;
   84 };
   85 
   86 #define RTL_LOCK(_sc)   mtx_lock(&(_sc)->sc_mtx)
   87 #define RTL_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
   88 #define RTL_LOCK_ASSERT(_sc, _what)     mtx_assert(&(_s)c->sc_mtx, (_what))
   89 #define RTL_TRYLOCK(_sc)        mtx_trylock(&(_sc)->sc_mtx)
   90 
   91 #define RTL_WAITOK      0
   92 #define RTL_NOWAIT      1
   93 
   94 #define RTL_SMI_ACQUIRED        1
   95 #define RTL_SMI_ACQUIRED_ASSERT(_sc) \
   96         KASSERT((_sc)->smi_acquired == RTL_SMI_ACQUIRED, ("smi must be acquired @%s", __FUNCTION__))
   97 
   98 #if defined(DEBUG)
   99 #define DPRINTF(dev, args...) device_printf(dev, args)
  100 #define DEVERR(dev, err, fmt, args...) do { \
  101                 if (err != 0) device_printf(dev, fmt, err, args); \
  102         } while (0)
  103 #define DEBUG_INCRVAR(var)      do { \
  104                 var++; \
  105         } while (0)
  106 
  107 static int callout_blocked = 0;
  108 static int iic_select_retries = 0;
  109 static int phy_access_retries = 0;
  110 static SYSCTL_NODE(_debug, OID_AUTO, rtl8366rb, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
  111     "rtl8366rb");
  112 SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, callout_blocked, CTLFLAG_RW, &callout_blocked, 0,
  113         "number of times the callout couldn't acquire the bus");
  114 SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, iic_select_retries, CTLFLAG_RW, &iic_select_retries, 0,
  115         "number of times the I2C bus selection had to be retried");
  116 SYSCTL_INT(_debug_rtl8366rb, OID_AUTO, phy_access_retries, CTLFLAG_RW, &phy_access_retries, 0,
  117         "number of times PHY register access had to be retried");
  118 #else
  119 #define DPRINTF(dev, args...)
  120 #define DEVERR(dev, err, fmt, args...)
  121 #define DEBUG_INCRVAR(var)
  122 #endif
  123 
  124 static int smi_probe(device_t dev);
  125 static int smi_read(device_t dev, uint16_t addr, uint16_t *data, int sleep);
  126 static int smi_write(device_t dev, uint16_t addr, uint16_t data, int sleep);
  127 static int smi_rmw(device_t dev, uint16_t addr, uint16_t mask, uint16_t data, int sleep);
  128 static void rtl8366rb_tick(void *arg);
  129 static int rtl8366rb_ifmedia_upd(if_t );
  130 static void rtl8366rb_ifmedia_sts(if_t , struct ifmediareq *);
  131 
  132 static void
  133 rtl8366rb_identify(driver_t *driver, device_t parent)
  134 {
  135         device_t child;
  136         struct iicbus_ivar *devi;
  137 
  138         if (device_find_child(parent, "rtl8366rb", -1) == NULL) {
  139                 child = BUS_ADD_CHILD(parent, 0, "rtl8366rb", -1);
  140                 devi = IICBUS_IVAR(child);
  141                 devi->addr = RTL8366_IIC_ADDR;
  142         }
  143 }
  144 
  145 static int
  146 rtl8366rb_probe(device_t dev)
  147 {
  148         struct rtl8366rb_softc *sc;
  149 
  150         sc = device_get_softc(dev);
  151 
  152         bzero(sc, sizeof(*sc));
  153         if (smi_probe(dev) != 0)
  154                 return (ENXIO);
  155         if (sc->chip_type == RTL8366RB)
  156                 device_set_desc(dev, "RTL8366RB Ethernet Switch Controller");
  157         else
  158                 device_set_desc(dev, "RTL8366SR Ethernet Switch Controller");
  159         return (BUS_PROBE_DEFAULT);
  160 }
  161 
  162 static void
  163 rtl8366rb_init(device_t dev)
  164 {
  165         struct rtl8366rb_softc *sc;
  166         int i;
  167 
  168         sc = device_get_softc(dev);
  169 
  170         /* Initialisation for TL-WR1043ND */
  171 #ifdef RTL8366_SOFT_RESET
  172         smi_rmw(dev, RTL8366_RCR,
  173                 RTL8366_RCR_SOFT_RESET,
  174                 RTL8366_RCR_SOFT_RESET, RTL_WAITOK);
  175 #else
  176         smi_rmw(dev, RTL8366_RCR,
  177                 RTL8366_RCR_HARD_RESET,
  178                 RTL8366_RCR_HARD_RESET, RTL_WAITOK);
  179 #endif
  180         /* hard reset not return ack */
  181         DELAY(100000);
  182         /* Enable 16 VLAN mode */
  183         smi_rmw(dev, RTL8366_SGCR,
  184                 RTL8366_SGCR_EN_VLAN | RTL8366_SGCR_EN_VLAN_4KTB,
  185                 RTL8366_SGCR_EN_VLAN, RTL_WAITOK);
  186         /* Initialize our vlan table. */
  187         for (i = 0; i <= 1; i++)
  188                 sc->vid[i] = (i + 1) | ETHERSWITCH_VID_VALID;
  189         /* Remove port 0 from VLAN 1. */
  190         smi_rmw(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, 0),
  191                 (1 << 0), 0, RTL_WAITOK);
  192         /* Add port 0 untagged and port 5 tagged to VLAN 2. */
  193         smi_rmw(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, 1),
  194                 ((1 << 5 | 1 << 0) << RTL8366_VMCR_MU_MEMBER_SHIFT)
  195                         | ((1 << 5 | 1 << 0) << RTL8366_VMCR_MU_UNTAG_SHIFT),
  196                 ((1 << 5 | 1 << 0) << RTL8366_VMCR_MU_MEMBER_SHIFT
  197                         | ((1 << 0) << RTL8366_VMCR_MU_UNTAG_SHIFT)),
  198                 RTL_WAITOK);
  199         /* Set PVID 2 for port 0. */
  200         smi_rmw(dev, RTL8366_PVCR_REG(0),
  201                 RTL8366_PVCR_VAL(0, RTL8366_PVCR_PORT_MASK),
  202                 RTL8366_PVCR_VAL(0, 1), RTL_WAITOK);
  203 }
  204 
  205 static int
  206 rtl8366rb_attach(device_t dev)
  207 {
  208         struct rtl8366rb_softc *sc;
  209         uint16_t rev = 0;
  210         char name[IFNAMSIZ];
  211         int err = 0;
  212         int i;
  213 
  214         sc = device_get_softc(dev);
  215 
  216         sc->dev = dev;
  217         mtx_init(&sc->sc_mtx, "rtl8366rb", NULL, MTX_DEF);
  218         sc->smi_acquired = 0;
  219         mtx_init(&sc->callout_mtx, "rtl8366rbcallout", NULL, MTX_DEF);
  220 
  221         rtl8366rb_init(dev);
  222         smi_read(dev, RTL8366_CVCR, &rev, RTL_WAITOK);
  223         device_printf(dev, "rev. %d\n", rev & 0x000f);
  224 
  225         sc->phy4cpu = 0;
  226         (void) resource_int_value(device_get_name(dev), device_get_unit(dev),
  227             "phy4cpu", &sc->phy4cpu);
  228 
  229         sc->numphys = sc->phy4cpu ? RTL8366_NUM_PHYS - 1 : RTL8366_NUM_PHYS;
  230 
  231         sc->info.es_nports = sc->numphys + 1;
  232         sc->info.es_nvlangroups = RTL8366_NUM_VLANS;
  233         sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q;
  234         if (sc->chip_type == RTL8366RB)
  235                 sprintf(sc->info.es_name, "Realtek RTL8366RB");
  236         else
  237                 sprintf(sc->info.es_name, "Realtek RTL8366SR");
  238 
  239         /* attach miibus and phys */
  240         /* PHYs need an interface, so we generate a dummy one */
  241         for (i = 0; i < sc->numphys; i++) {
  242                 sc->ifp[i] = if_alloc(IFT_ETHER);
  243                 if (sc->ifp[i] == NULL) {
  244                         device_printf(dev, "couldn't allocate ifnet structure\n");
  245                         err = ENOMEM;
  246                         break;
  247                 }
  248 
  249                 if_setsoftc(sc->ifp[i], sc);
  250                 if_setflagbits(sc->ifp[i], IFF_UP | IFF_BROADCAST | IFF_DRV_RUNNING
  251                         | IFF_SIMPLEX, 0);
  252                 snprintf(name, IFNAMSIZ, "%sport", device_get_nameunit(dev));
  253                 sc->ifname[i] = malloc(strlen(name)+1, M_DEVBUF, M_WAITOK);
  254                 bcopy(name, sc->ifname[i], strlen(name)+1);
  255                 if_initname(sc->ifp[i], sc->ifname[i], i);
  256                 err = mii_attach(dev, &sc->miibus[i], sc->ifp[i], rtl8366rb_ifmedia_upd, \
  257                         rtl8366rb_ifmedia_sts, BMSR_DEFCAPMASK, \
  258                         i, MII_OFFSET_ANY, 0);
  259                 if (err != 0) {
  260                         device_printf(dev, "attaching PHY %d failed\n", i);
  261                         return (err);
  262                 }
  263         }
  264 
  265         bus_generic_probe(dev);
  266         bus_enumerate_hinted_children(dev);
  267         err = bus_generic_attach(dev);
  268         if (err != 0)
  269                 return (err);
  270         
  271         callout_init_mtx(&sc->callout_tick, &sc->callout_mtx, 0);
  272         rtl8366rb_tick(sc);
  273         
  274         return (err);
  275 }
  276 
  277 static int
  278 rtl8366rb_detach(device_t dev)
  279 {
  280         struct rtl8366rb_softc *sc;
  281         int i;
  282 
  283         sc = device_get_softc(dev);
  284 
  285         for (i=0; i < sc->numphys; i++) {
  286                 if (sc->miibus[i])
  287                         device_delete_child(dev, sc->miibus[i]);
  288                 if (sc->ifp[i] != NULL)
  289                         if_free(sc->ifp[i]);
  290                 free(sc->ifname[i], M_DEVBUF);
  291         }
  292         bus_generic_detach(dev);
  293         callout_drain(&sc->callout_tick);
  294         mtx_destroy(&sc->callout_mtx);
  295         mtx_destroy(&sc->sc_mtx);
  296 
  297         return (0);
  298 }
  299 
  300 static void
  301 rtl8366rb_update_ifmedia(int portstatus, u_int *media_status, u_int *media_active)
  302 {
  303         *media_active = IFM_ETHER;
  304         *media_status = IFM_AVALID;
  305         if ((portstatus & RTL8366_PLSR_LINK) != 0)
  306                 *media_status |= IFM_ACTIVE;
  307         else {
  308                 *media_active |= IFM_NONE;
  309                 return;
  310         }
  311         switch (portstatus & RTL8366_PLSR_SPEED_MASK) {
  312         case RTL8366_PLSR_SPEED_10:
  313                 *media_active |= IFM_10_T;
  314                 break;
  315         case RTL8366_PLSR_SPEED_100:
  316                 *media_active |= IFM_100_TX;
  317                 break;
  318         case RTL8366_PLSR_SPEED_1000:
  319                 *media_active |= IFM_1000_T;
  320                 break;
  321         }
  322         if ((portstatus & RTL8366_PLSR_FULLDUPLEX) != 0)
  323                 *media_active |= IFM_FDX;
  324         else
  325                 *media_active |= IFM_HDX;
  326         if ((portstatus & RTL8366_PLSR_TXPAUSE) != 0)
  327                 *media_active |= IFM_ETH_TXPAUSE;
  328         if ((portstatus & RTL8366_PLSR_RXPAUSE) != 0)
  329                 *media_active |= IFM_ETH_RXPAUSE;
  330 }
  331 
  332 static void
  333 rtl833rb_miipollstat(struct rtl8366rb_softc *sc)
  334 {
  335         int i;
  336         struct mii_data *mii;
  337         struct mii_softc *miisc;
  338         uint16_t value;
  339         int portstatus;
  340 
  341         for (i = 0; i < sc->numphys; i++) {
  342                 mii = device_get_softc(sc->miibus[i]);
  343                 if ((i % 2) == 0) {
  344                         if (smi_read(sc->dev, RTL8366_PLSR_BASE + i/2, &value, RTL_NOWAIT) != 0) {
  345                                 DEBUG_INCRVAR(callout_blocked);
  346                                 return;
  347                         }
  348                         portstatus = value & 0xff;
  349                 } else {
  350                         portstatus = (value >> 8) & 0xff;
  351                 }
  352                 rtl8366rb_update_ifmedia(portstatus, &mii->mii_media_status, &mii->mii_media_active);
  353                 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) {
  354                         if (IFM_INST(mii->mii_media.ifm_cur->ifm_media) != miisc->mii_inst)
  355                                 continue;
  356                         mii_phy_update(miisc, MII_POLLSTAT);
  357                 }
  358         }       
  359 }
  360 
  361 static void
  362 rtl8366rb_tick(void *arg)
  363 {
  364         struct rtl8366rb_softc *sc;
  365 
  366         sc = arg;
  367 
  368         rtl833rb_miipollstat(sc);
  369         callout_reset(&sc->callout_tick, hz, rtl8366rb_tick, sc);
  370 }
  371 
  372 static int
  373 smi_probe(device_t dev)
  374 {
  375         struct rtl8366rb_softc *sc;
  376         device_t iicbus, iicha;
  377         int err, i, j;
  378         uint16_t chipid;
  379         char bytes[2];
  380         int xferd;
  381 
  382         sc = device_get_softc(dev);
  383 
  384         iicbus = device_get_parent(dev);
  385         iicha = device_get_parent(iicbus);
  386 
  387         for (i = 0; i < 2; ++i) {
  388                 iicbus_reset(iicbus, IIC_FASTEST, RTL8366_IIC_ADDR, NULL);
  389                 for (j=3; j--; ) {
  390                         IICBUS_STOP(iicha);
  391                         /*
  392                          * we go directly to the host adapter because iicbus.c
  393                          * only issues a stop on a bus that was successfully started.
  394                          */
  395                 }
  396                 err = iicbus_request_bus(iicbus, dev, IIC_WAIT);
  397                 if (err != 0)
  398                         goto out;
  399                 err = iicbus_start(iicbus, RTL8366_IIC_ADDR | RTL_IICBUS_READ, RTL_IICBUS_TIMEOUT);
  400                 if (err != 0)
  401                         goto out;
  402                 if (i == 0) {
  403                         bytes[0] = RTL8366RB_CIR & 0xff;
  404                         bytes[1] = (RTL8366RB_CIR >> 8) & 0xff;
  405                 } else {
  406                         bytes[0] = RTL8366SR_CIR & 0xff;
  407                         bytes[1] = (RTL8366SR_CIR >> 8) & 0xff;
  408                 }
  409                 err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT);
  410                 if (err != 0)
  411                         goto out;
  412                 err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0);
  413                 if (err != 0)
  414                         goto out;
  415                 chipid = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
  416                 if (i == 0 && chipid == RTL8366RB_CIR_ID8366RB) {
  417                         DPRINTF(dev, "chip id 0x%04x\n", chipid);
  418                         sc->chip_type = RTL8366RB;
  419                         err = 0;
  420                         break;
  421                 }
  422                 if (i == 1 && chipid == RTL8366SR_CIR_ID8366SR) {
  423                         DPRINTF(dev, "chip id 0x%04x\n", chipid);
  424                         sc->chip_type = RTL8366SR;
  425                         err = 0;
  426                         break;
  427                 }
  428                 if (i == 0) {
  429                         iicbus_stop(iicbus);
  430                         iicbus_release_bus(iicbus, dev);
  431                 }
  432         }
  433         if (i == 2)
  434                 err = ENXIO;
  435 out:
  436         iicbus_stop(iicbus);
  437         iicbus_release_bus(iicbus, dev);
  438         return (err == 0 ? 0 : ENXIO);
  439 }
  440 
  441 static int
  442 smi_acquire(struct rtl8366rb_softc *sc, int sleep)
  443 {
  444         int r = 0;
  445         if (sleep == RTL_WAITOK)
  446                 RTL_LOCK(sc);
  447         else
  448                 if (RTL_TRYLOCK(sc) == 0)
  449                         return (EWOULDBLOCK);
  450         if (sc->smi_acquired == RTL_SMI_ACQUIRED)
  451                 r = EBUSY;
  452         else {
  453                 r = iicbus_request_bus(device_get_parent(sc->dev), sc->dev, \
  454                         sleep == RTL_WAITOK ? IIC_WAIT : IIC_DONTWAIT);
  455                 if (r == 0)
  456                         sc->smi_acquired = RTL_SMI_ACQUIRED;
  457         }
  458         RTL_UNLOCK(sc);
  459         return (r);
  460 }
  461 
  462 static int
  463 smi_release(struct rtl8366rb_softc *sc, int sleep)
  464 {
  465         if (sleep == RTL_WAITOK)
  466                 RTL_LOCK(sc);
  467         else
  468                 if (RTL_TRYLOCK(sc) == 0)
  469                         return (EWOULDBLOCK);
  470         RTL_SMI_ACQUIRED_ASSERT(sc);
  471         iicbus_release_bus(device_get_parent(sc->dev), sc->dev);
  472         sc->smi_acquired = 0;
  473         RTL_UNLOCK(sc);
  474         return (0);
  475 }
  476 
  477 static int
  478 smi_select(device_t dev, int op, int sleep)
  479 {
  480         struct rtl8366rb_softc *sc;
  481         int err, i;
  482         device_t iicbus;
  483         struct iicbus_ivar *devi;
  484         int slave;
  485 
  486         sc = device_get_softc(dev);
  487 
  488         iicbus = device_get_parent(dev);
  489         devi = IICBUS_IVAR(dev);
  490         slave = devi->addr;
  491 
  492         RTL_SMI_ACQUIRED_ASSERT((struct rtl8366rb_softc *)device_get_softc(dev));
  493 
  494         if (sc->chip_type == RTL8366SR) {   // RTL8366SR work around
  495                 // this is same work around at probe
  496                 for (int i=3; i--; )
  497                         IICBUS_STOP(device_get_parent(device_get_parent(dev)));
  498         }
  499         /*
  500          * The chip does not use clock stretching when it is busy,
  501          * instead ignoring the command. Retry a few times.
  502          */
  503         for (i = RTL_IICBUS_RETRIES; i--; ) {
  504                 err = iicbus_start(iicbus, slave | op, RTL_IICBUS_TIMEOUT);
  505                 if (err != IIC_ENOACK)
  506                         break;
  507                 if (sleep == RTL_WAITOK) {
  508                         DEBUG_INCRVAR(iic_select_retries);
  509                         pause("smi_select", RTL_IICBUS_RETRY_SLEEP);
  510                 } else
  511                         break;
  512         }
  513         return (err);
  514 }
  515 
  516 static int
  517 smi_read_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t *data, int sleep)
  518 {
  519         int err;
  520         device_t iicbus;
  521         char bytes[2];
  522         int xferd;
  523 
  524         iicbus = device_get_parent(sc->dev);
  525 
  526         RTL_SMI_ACQUIRED_ASSERT(sc);
  527         bytes[0] = addr & 0xff;
  528         bytes[1] = (addr >> 8) & 0xff;
  529         err = smi_select(sc->dev, RTL_IICBUS_READ, sleep);
  530         if (err != 0)
  531                 goto out;
  532         err = iicbus_write(iicbus, bytes, 2, &xferd, RTL_IICBUS_TIMEOUT);
  533         if (err != 0)
  534                 goto out;
  535         err = iicbus_read(iicbus, bytes, 2, &xferd, IIC_LAST_READ, 0);
  536         if (err != 0)
  537                 goto out;
  538         *data = ((bytes[1] & 0xff) << 8) | (bytes[0] & 0xff);
  539 
  540 out:
  541         iicbus_stop(iicbus);
  542         return (err);
  543 }
  544 
  545 static int
  546 smi_write_locked(struct rtl8366rb_softc *sc, uint16_t addr, uint16_t data, int sleep)
  547 {
  548         int err;
  549         device_t iicbus;
  550         char bytes[4];
  551         int xferd;
  552 
  553         iicbus = device_get_parent(sc->dev);
  554 
  555         RTL_SMI_ACQUIRED_ASSERT(sc);
  556         bytes[0] = addr & 0xff;
  557         bytes[1] = (addr >> 8) & 0xff;
  558         bytes[2] = data & 0xff;
  559         bytes[3] = (data >> 8) & 0xff;
  560 
  561         err = smi_select(sc->dev, RTL_IICBUS_WRITE, sleep);
  562         if (err == 0)
  563                 err = iicbus_write(iicbus, bytes, 4, &xferd, RTL_IICBUS_TIMEOUT);
  564         iicbus_stop(iicbus);
  565 
  566         return (err);
  567 }
  568 
  569 static int
  570 smi_read(device_t dev, uint16_t addr, uint16_t *data, int sleep)
  571 {
  572         struct rtl8366rb_softc *sc;
  573         int err;
  574 
  575         sc = device_get_softc(dev);
  576 
  577         err = smi_acquire(sc, sleep);
  578         if (err != 0)
  579                 return (EBUSY);
  580         err = smi_read_locked(sc, addr, data, sleep);
  581         smi_release(sc, sleep);
  582         DEVERR(dev, err, "smi_read()=%d: addr=%04x\n", addr);
  583         return (err == 0 ? 0 : EIO);
  584 }
  585 
  586 static int
  587 smi_write(device_t dev, uint16_t addr, uint16_t data, int sleep)
  588 {
  589         struct rtl8366rb_softc *sc;
  590         int err;
  591         
  592         sc = device_get_softc(dev);
  593 
  594         err = smi_acquire(sc, sleep);
  595         if (err != 0)
  596                 return (EBUSY);
  597         err = smi_write_locked(sc, addr, data, sleep);
  598         smi_release(sc, sleep);
  599         DEVERR(dev, err, "smi_write()=%d: addr=%04x\n", addr);
  600         return (err == 0 ? 0 : EIO);
  601 }
  602 
  603 static int
  604 smi_rmw(device_t dev, uint16_t addr, uint16_t mask, uint16_t data, int sleep)
  605 {
  606         struct rtl8366rb_softc *sc;
  607         int err;
  608         uint16_t oldv, newv;
  609         
  610         sc = device_get_softc(dev);
  611 
  612         err = smi_acquire(sc, sleep);
  613         if (err != 0)
  614                 return (EBUSY);
  615         if (err == 0) {
  616                 err = smi_read_locked(sc, addr, &oldv, sleep);
  617                 if (err == 0) {
  618                         newv = oldv & ~mask;
  619                         newv |= data & mask;
  620                         if (newv != oldv)
  621                                 err = smi_write_locked(sc, addr, newv, sleep);
  622                 }
  623         }
  624         smi_release(sc, sleep);
  625         DEVERR(dev, err, "smi_rmw()=%d: addr=%04x\n", addr);
  626         return (err == 0 ? 0 : EIO);
  627 }
  628 
  629 static etherswitch_info_t *
  630 rtl_getinfo(device_t dev)
  631 {
  632         struct rtl8366rb_softc *sc;
  633 
  634         sc = device_get_softc(dev);
  635 
  636         return (&sc->info);
  637 }
  638 
  639 static int
  640 rtl_readreg(device_t dev, int reg)
  641 {
  642         uint16_t data;
  643 
  644         data = 0;
  645 
  646         smi_read(dev, reg, &data, RTL_WAITOK);
  647         return (data);
  648 }
  649 
  650 static int
  651 rtl_writereg(device_t dev, int reg, int value)
  652 {
  653         return (smi_write(dev, reg, value, RTL_WAITOK));
  654 }
  655 
  656 static int
  657 rtl_getport(device_t dev, etherswitch_port_t *p)
  658 {
  659         struct rtl8366rb_softc *sc;
  660         struct ifmedia *ifm;
  661         struct mii_data *mii;
  662         struct ifmediareq *ifmr;
  663         uint16_t v;
  664         int err, vlangroup;
  665         
  666         sc = device_get_softc(dev);
  667 
  668         ifmr = &p->es_ifmr;
  669 
  670         if (p->es_port < 0 || p->es_port >= (sc->numphys + 1))
  671                 return (ENXIO);
  672         if (sc->phy4cpu && p->es_port == sc->numphys) {
  673                 vlangroup = RTL8366_PVCR_GET(p->es_port + 1,
  674                     rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port + 1)));
  675         } else {
  676                 vlangroup = RTL8366_PVCR_GET(p->es_port,
  677                     rtl_readreg(dev, RTL8366_PVCR_REG(p->es_port)));
  678         }
  679         p->es_pvid = sc->vid[vlangroup] & ETHERSWITCH_VID_MASK;
  680         
  681         if (p->es_port < sc->numphys) {
  682                 mii = device_get_softc(sc->miibus[p->es_port]);
  683                 ifm = &mii->mii_media;
  684                 err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCGIFMEDIA);
  685                 if (err)
  686                         return (err);
  687         } else {
  688                 /* fill in fixed values for CPU port */
  689                 p->es_flags |= ETHERSWITCH_PORT_CPU;
  690                 smi_read(dev, RTL8366_PLSR_BASE + (RTL8366_NUM_PHYS)/2, &v, RTL_WAITOK);
  691                 v = v >> (8 * ((RTL8366_NUM_PHYS) % 2));
  692                 rtl8366rb_update_ifmedia(v, &ifmr->ifm_status, &ifmr->ifm_active);
  693                 ifmr->ifm_current = ifmr->ifm_active;
  694                 ifmr->ifm_mask = 0;
  695                 ifmr->ifm_status = IFM_ACTIVE | IFM_AVALID;
  696                 /* Return our static media list. */
  697                 if (ifmr->ifm_count > 0) {
  698                         ifmr->ifm_count = 1;
  699                         ifmr->ifm_ulist[0] = IFM_MAKEWORD(IFM_ETHER, IFM_1000_T,
  700                             IFM_FDX, 0);
  701                 } else
  702                         ifmr->ifm_count = 0;
  703         }
  704         return (0);
  705 }
  706 
  707 static int
  708 rtl_setport(device_t dev, etherswitch_port_t *p)
  709 {
  710         struct rtl8366rb_softc *sc;
  711         int i, err, vlangroup;
  712         struct ifmedia *ifm;
  713         struct mii_data *mii;
  714         int port;
  715 
  716         sc = device_get_softc(dev);
  717 
  718         if (p->es_port < 0 || p->es_port >= (sc->numphys + 1))
  719                 return (ENXIO);
  720         vlangroup = -1;
  721         for (i = 0; i < RTL8366_NUM_VLANS; i++) {
  722                 if ((sc->vid[i] & ETHERSWITCH_VID_MASK) == p->es_pvid) {
  723                         vlangroup = i;
  724                         break;
  725                 }
  726         }
  727         if (vlangroup == -1)
  728                 return (ENXIO);
  729         if (sc->phy4cpu && p->es_port == sc->numphys) {
  730                 port = p->es_port + 1;
  731         } else {
  732                 port = p->es_port;
  733         }
  734         err = smi_rmw(dev, RTL8366_PVCR_REG(port),
  735             RTL8366_PVCR_VAL(port, RTL8366_PVCR_PORT_MASK),
  736             RTL8366_PVCR_VAL(port, vlangroup), RTL_WAITOK);
  737         if (err)
  738                 return (err);
  739         /* CPU Port */
  740         if (p->es_port == sc->numphys)
  741                 return (0);
  742         mii = device_get_softc(sc->miibus[p->es_port]);
  743         ifm = &mii->mii_media;
  744         err = ifmedia_ioctl(sc->ifp[p->es_port], &p->es_ifr, ifm, SIOCSIFMEDIA);
  745         return (err);
  746 }
  747 
  748 static int
  749 rtl_getvgroup(device_t dev, etherswitch_vlangroup_t *vg)
  750 {
  751         struct rtl8366rb_softc *sc;
  752         uint16_t vmcr[3];
  753         int i;
  754         int member, untagged;
  755         
  756         sc = device_get_softc(dev);
  757 
  758         for (i=0; i<RTL8366_VMCR_MULT; i++)
  759                 vmcr[i] = rtl_readreg(dev, RTL8366_VMCR(i, vg->es_vlangroup));
  760                 
  761         vg->es_vid = sc->vid[vg->es_vlangroup];
  762         member = RTL8366_VMCR_MEMBER(vmcr);
  763         untagged = RTL8366_VMCR_UNTAG(vmcr);
  764         if (sc->phy4cpu) {
  765                 vg->es_member_ports = ((member & 0x20) >> 1) | (member & 0x0f);
  766                 vg->es_untagged_ports = ((untagged & 0x20) >> 1) | (untagged & 0x0f);
  767         } else {
  768                 vg->es_member_ports = member;
  769                 vg->es_untagged_ports = untagged;
  770         }
  771         vg->es_fid = RTL8366_VMCR_FID(vmcr);
  772         return (0);
  773 }
  774 
  775 static int
  776 rtl_setvgroup(device_t dev, etherswitch_vlangroup_t *vg)
  777 {
  778         struct rtl8366rb_softc *sc;
  779         int g;
  780         int member, untagged;
  781 
  782         sc = device_get_softc(dev);
  783 
  784         g = vg->es_vlangroup;
  785 
  786         sc->vid[g] = vg->es_vid;
  787         /* VLAN group disabled ? */
  788         if (vg->es_member_ports == 0 && vg->es_untagged_ports == 0 && vg->es_vid == 0)
  789                 return (0);
  790         sc->vid[g] |= ETHERSWITCH_VID_VALID;
  791         rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_DOT1Q_REG, g),
  792                 (vg->es_vid << RTL8366_VMCR_DOT1Q_VID_SHIFT) & RTL8366_VMCR_DOT1Q_VID_MASK);
  793         if (sc->phy4cpu) {
  794                 /* add space at phy4 */
  795                 member = (vg->es_member_ports & 0x0f) |
  796                     ((vg->es_member_ports & 0x10) << 1);
  797                 untagged = (vg->es_untagged_ports & 0x0f) |
  798                     ((vg->es_untagged_ports & 0x10) << 1);
  799         } else {
  800                 member = vg->es_member_ports;
  801                 untagged = vg->es_untagged_ports;
  802         }
  803         if (sc->chip_type == RTL8366RB) {
  804                 rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, g),
  805                     ((member << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
  806                     ((untagged << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK));
  807                 rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_FID_REG, g),
  808                     vg->es_fid);
  809         } else {
  810                 rtl_writereg(dev, RTL8366_VMCR(RTL8366_VMCR_MU_REG, g),
  811                     ((member << RTL8366_VMCR_MU_MEMBER_SHIFT) & RTL8366_VMCR_MU_MEMBER_MASK) |
  812                     ((untagged << RTL8366_VMCR_MU_UNTAG_SHIFT) & RTL8366_VMCR_MU_UNTAG_MASK) |
  813                     ((vg->es_fid << RTL8366_VMCR_FID_FID_SHIFT) & RTL8366_VMCR_FID_FID_MASK));
  814         }
  815         return (0);
  816 }
  817 
  818 static int
  819 rtl_getconf(device_t dev, etherswitch_conf_t *conf)
  820 {
  821 
  822         /* Return the VLAN mode. */
  823         conf->cmd = ETHERSWITCH_CONF_VLAN_MODE;
  824         conf->vlan_mode = ETHERSWITCH_VLAN_DOT1Q;
  825 
  826         return (0);
  827 }
  828 
  829 static int
  830 rtl_readphy(device_t dev, int phy, int reg)
  831 {
  832         struct rtl8366rb_softc *sc;
  833         uint16_t data;
  834         int err, i, sleep;
  835 
  836         sc = device_get_softc(dev);
  837 
  838         data = 0;
  839 
  840         if (phy < 0 || phy >= RTL8366_NUM_PHYS)
  841                 return (ENXIO);
  842         if (reg < 0 || reg >= RTL8366_NUM_PHY_REG)
  843                 return (ENXIO);
  844         sleep = RTL_WAITOK;
  845         err = smi_acquire(sc, sleep);
  846         if (err != 0)
  847                 return (EBUSY);
  848         for (i = RTL_IICBUS_RETRIES; i--; ) {
  849                 err = smi_write_locked(sc, RTL8366_PACR, RTL8366_PACR_READ, sleep);
  850                 if (err == 0)
  851                         err = smi_write_locked(sc, RTL8366_PHYREG(phy, 0, reg), 0, sleep);
  852                 if (err == 0) {
  853                         err = smi_read_locked(sc, RTL8366_PADR, &data, sleep);
  854                         break;
  855                 }
  856                 DEBUG_INCRVAR(phy_access_retries);
  857                 DPRINTF(dev, "rtl_readphy(): chip not responsive, retrying %d more times\n", i);
  858                 pause("rtl_readphy", RTL_IICBUS_RETRY_SLEEP);
  859         }
  860         smi_release(sc, sleep);
  861         DEVERR(dev, err, "rtl_readphy()=%d: phy=%d.%02x\n", phy, reg);
  862         return (data);
  863 }
  864 
  865 static int
  866 rtl_writephy(device_t dev, int phy, int reg, int data)
  867 {
  868         struct rtl8366rb_softc *sc;
  869         int err, i, sleep;
  870         
  871         sc = device_get_softc(dev);
  872 
  873         if (phy < 0 || phy >= RTL8366_NUM_PHYS)
  874                 return (ENXIO);
  875         if (reg < 0 || reg >= RTL8366_NUM_PHY_REG)
  876                 return (ENXIO);
  877         sleep = RTL_WAITOK;
  878         err = smi_acquire(sc, sleep);
  879         if (err != 0)
  880                 return (EBUSY);
  881         for (i = RTL_IICBUS_RETRIES; i--; ) {
  882                 err = smi_write_locked(sc, RTL8366_PACR, RTL8366_PACR_WRITE, sleep);
  883                 if (err == 0)
  884                         err = smi_write_locked(sc, RTL8366_PHYREG(phy, 0, reg), data, sleep);
  885                 if (err == 0) {
  886                         break;
  887                 }
  888                 DEBUG_INCRVAR(phy_access_retries);
  889                 DPRINTF(dev, "rtl_writephy(): chip not responsive, retrying %d more tiems\n", i);
  890                 pause("rtl_writephy", RTL_IICBUS_RETRY_SLEEP);
  891         }
  892         smi_release(sc, sleep);
  893         DEVERR(dev, err, "rtl_writephy()=%d: phy=%d.%02x\n", phy, reg);
  894         return (err == 0 ? 0 : EIO);
  895 }
  896 
  897 static int
  898 rtl8366rb_ifmedia_upd(if_t ifp)
  899 {
  900         struct rtl8366rb_softc *sc;
  901         struct mii_data *mii;
  902         
  903         sc = if_getsoftc(ifp);
  904         mii = device_get_softc(sc->miibus[if_getdunit(ifp)]);
  905         
  906         mii_mediachg(mii);
  907         return (0);
  908 }
  909 
  910 static void
  911 rtl8366rb_ifmedia_sts(if_t ifp, struct ifmediareq *ifmr)
  912 {
  913         struct rtl8366rb_softc *sc;
  914         struct mii_data *mii;
  915 
  916         sc = if_getsoftc(ifp);
  917         mii = device_get_softc(sc->miibus[if_getdunit(ifp)]);
  918 
  919         mii_pollstat(mii);
  920         ifmr->ifm_active = mii->mii_media_active;
  921         ifmr->ifm_status = mii->mii_media_status;
  922 }
  923 
  924 
  925 static device_method_t rtl8366rb_methods[] = {
  926         /* Device interface */
  927         DEVMETHOD(device_identify,      rtl8366rb_identify),
  928         DEVMETHOD(device_probe,         rtl8366rb_probe),
  929         DEVMETHOD(device_attach,        rtl8366rb_attach),
  930         DEVMETHOD(device_detach,        rtl8366rb_detach),
  931         
  932         /* bus interface */
  933         DEVMETHOD(bus_add_child,        device_add_child_ordered),
  934         
  935         /* MII interface */
  936         DEVMETHOD(miibus_readreg,       rtl_readphy),
  937         DEVMETHOD(miibus_writereg,      rtl_writephy),
  938 
  939         /* MDIO interface */
  940         DEVMETHOD(mdio_readreg,         rtl_readphy),
  941         DEVMETHOD(mdio_writereg,        rtl_writephy),
  942 
  943         /* etherswitch interface */
  944         DEVMETHOD(etherswitch_getconf,  rtl_getconf),
  945         DEVMETHOD(etherswitch_getinfo,  rtl_getinfo),
  946         DEVMETHOD(etherswitch_readreg,  rtl_readreg),
  947         DEVMETHOD(etherswitch_writereg, rtl_writereg),
  948         DEVMETHOD(etherswitch_readphyreg,       rtl_readphy),
  949         DEVMETHOD(etherswitch_writephyreg,      rtl_writephy),
  950         DEVMETHOD(etherswitch_getport,  rtl_getport),
  951         DEVMETHOD(etherswitch_setport,  rtl_setport),
  952         DEVMETHOD(etherswitch_getvgroup,        rtl_getvgroup),
  953         DEVMETHOD(etherswitch_setvgroup,        rtl_setvgroup),
  954 
  955         DEVMETHOD_END
  956 };
  957 
  958 DEFINE_CLASS_0(rtl8366rb, rtl8366rb_driver, rtl8366rb_methods,
  959     sizeof(struct rtl8366rb_softc));
  960 
  961 DRIVER_MODULE(rtl8366rb, iicbus, rtl8366rb_driver, 0, 0);
  962 DRIVER_MODULE(miibus, rtl8366rb, miibus_driver, 0, 0);
  963 DRIVER_MODULE(mdio, rtl8366rb, mdio_driver, 0, 0);
  964 DRIVER_MODULE(etherswitch, rtl8366rb, etherswitch_driver, 0, 0);
  965 MODULE_VERSION(rtl8366rb, 1);
  966 MODULE_DEPEND(rtl8366rb, iicbus, 1, 1, 1); /* XXX which versions? */
  967 MODULE_DEPEND(rtl8366rb, miibus, 1, 1, 1); /* XXX which versions? */
  968 MODULE_DEPEND(rtl8366rb, etherswitch, 1, 1, 1); /* XXX which versions? */

Cache object: e3e7abc05a40a46e1e82ec9e20f1364c


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