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/mtkswitch/mtkswitch_mt7620.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  * Copyright (c) 2016 Stanislav Galabov.
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  *
   14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   24  * SUCH DAMAGE.
   25  *
   26  * $FreeBSD$
   27  */
   28 
   29 #include <sys/param.h>
   30 #include <sys/bus.h>
   31 #include <sys/errno.h>
   32 #include <sys/kernel.h>
   33 #include <sys/lock.h>
   34 #include <sys/malloc.h>
   35 #include <sys/module.h>
   36 #include <sys/mutex.h>
   37 #include <sys/rman.h>
   38 #include <sys/socket.h>
   39 #include <sys/sockio.h>
   40 #include <sys/sysctl.h>
   41 #include <sys/systm.h>
   42 
   43 #include <net/if.h>
   44 #include <net/if_var.h>
   45 #include <net/ethernet.h>
   46 #include <net/if_media.h>
   47 #include <net/if_types.h>
   48 
   49 #include <machine/bus.h>
   50 #include <dev/mii/mii.h>
   51 #include <dev/mii/miivar.h>
   52 #include <dev/mdio/mdio.h>
   53 
   54 #include <dev/etherswitch/etherswitch.h>
   55 #include <dev/etherswitch/mtkswitch/mtkswitchvar.h>
   56 #include <dev/etherswitch/mtkswitch/mtkswitch_mt7620.h>
   57 
   58 static int
   59 mtkswitch_phy_read_locked(struct mtkswitch_softc *sc, int phy, int reg)
   60 {
   61         uint32_t data;
   62         
   63         MTKSWITCH_WRITE(sc, MTKSWITCH_PIAC, PIAC_PHY_ACS_ST | PIAC_MDIO_ST |
   64             (reg << PIAC_MDIO_REG_ADDR_OFF) | (phy << PIAC_MDIO_PHY_ADDR_OFF) |
   65             PIAC_MDIO_CMD_READ);
   66         while ((data = MTKSWITCH_READ(sc, MTKSWITCH_PIAC)) & PIAC_PHY_ACS_ST);
   67         
   68         return ((int)(data & PIAC_MDIO_RW_DATA_MASK));
   69 }
   70 
   71 static int
   72 mtkswitch_phy_read(device_t dev, int phy, int reg)
   73 {
   74         struct mtkswitch_softc *sc = device_get_softc(dev);
   75         int data;
   76 
   77         if ((phy < 0 || phy >= 32) || (reg < 0 || reg >= 32))
   78                 return (ENXIO);
   79 
   80         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
   81         MTKSWITCH_LOCK(sc);
   82         data = mtkswitch_phy_read_locked(sc, phy, reg);
   83         MTKSWITCH_UNLOCK(sc);
   84 
   85         return (data);
   86 }
   87 
   88 static int
   89 mtkswitch_phy_write_locked(struct mtkswitch_softc *sc, int phy, int reg,
   90     int val)
   91 {
   92 
   93         MTKSWITCH_WRITE(sc, MTKSWITCH_PIAC, PIAC_PHY_ACS_ST | PIAC_MDIO_ST |
   94             (reg << PIAC_MDIO_REG_ADDR_OFF) | (phy << PIAC_MDIO_PHY_ADDR_OFF) |
   95             (val & PIAC_MDIO_RW_DATA_MASK) | PIAC_MDIO_CMD_WRITE);
   96         while (MTKSWITCH_READ(sc, MTKSWITCH_PIAC) & PIAC_PHY_ACS_ST);
   97 
   98         return (0);
   99 }
  100 
  101 static int
  102 mtkswitch_phy_write(device_t dev, int phy, int reg, int val)
  103 {
  104         struct mtkswitch_softc *sc = device_get_softc(dev);
  105         int res;
  106 
  107         if ((phy < 0 || phy >= 32) || (reg < 0 || reg >= 32))
  108                 return (ENXIO);
  109 
  110         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
  111         MTKSWITCH_LOCK(sc);
  112         res = mtkswitch_phy_write_locked(sc, phy, reg, val);
  113         MTKSWITCH_UNLOCK(sc);
  114 
  115         return (res);
  116 }
  117 
  118 static uint32_t
  119 mtkswitch_reg_read32(struct mtkswitch_softc *sc, int reg)
  120 {
  121 
  122         return (MTKSWITCH_READ(sc, reg));
  123 }
  124 
  125 static uint32_t
  126 mtkswitch_reg_write32(struct mtkswitch_softc *sc, int reg, uint32_t val)
  127 {
  128 
  129         MTKSWITCH_WRITE(sc, reg, val);
  130         return (0);
  131 }
  132 
  133 static uint32_t
  134 mtkswitch_reg_read32_mt7621(struct mtkswitch_softc *sc, int reg)
  135 {
  136         uint32_t low, hi;
  137 
  138         mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
  139             MTKSWITCH_GLOBAL_REG, MTKSWITCH_REG_ADDR(reg));
  140         low = mtkswitch_phy_read_locked(sc, MTKSWITCH_GLOBAL_PHY,
  141             MTKSWITCH_REG_LO(reg));
  142         hi = mtkswitch_phy_read_locked(sc, MTKSWITCH_GLOBAL_PHY,
  143             MTKSWITCH_REG_HI(reg));
  144         return (low | (hi << 16));
  145 }
  146 
  147 static uint32_t
  148 mtkswitch_reg_write32_mt7621(struct mtkswitch_softc *sc, int reg, uint32_t val)
  149 {
  150 
  151         mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
  152             MTKSWITCH_GLOBAL_REG, MTKSWITCH_REG_ADDR(reg));
  153         mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
  154             MTKSWITCH_REG_LO(reg), MTKSWITCH_VAL_LO(val));
  155         mtkswitch_phy_write_locked(sc, MTKSWITCH_GLOBAL_PHY,
  156             MTKSWITCH_REG_HI(reg), MTKSWITCH_VAL_HI(val));
  157         return (0);
  158 }
  159 
  160 static int
  161 mtkswitch_reg_read(device_t dev, int reg)
  162 {
  163         struct mtkswitch_softc *sc = device_get_softc(dev);
  164         uint32_t val;
  165 
  166         val = sc->hal.mtkswitch_read(sc, MTKSWITCH_REG32(reg));
  167         if (MTKSWITCH_IS_HI16(reg))
  168                 return (MTKSWITCH_HI16(val));
  169         return (MTKSWITCH_LO16(val));
  170 }
  171 
  172 static int
  173 mtkswitch_reg_write(device_t dev, int reg, int val)
  174 {
  175         struct mtkswitch_softc *sc = device_get_softc(dev);
  176         uint32_t tmp;
  177 
  178         tmp = sc->hal.mtkswitch_read(sc, MTKSWITCH_REG32(reg));
  179         if (MTKSWITCH_IS_HI16(reg)) {
  180                 tmp &= MTKSWITCH_LO16_MSK;
  181                 tmp |= MTKSWITCH_TO_HI16(val);
  182         } else {
  183                 tmp &= MTKSWITCH_HI16_MSK;
  184                 tmp |= MTKSWITCH_TO_LO16(val);
  185         }
  186         sc->hal.mtkswitch_write(sc, MTKSWITCH_REG32(reg), tmp);
  187 
  188         return (0);
  189 }
  190 
  191 static int
  192 mtkswitch_reset(struct mtkswitch_softc *sc)
  193 {
  194 
  195         /* We don't reset the switch for now */
  196         return (0);
  197 }
  198 
  199 static int
  200 mtkswitch_hw_setup(struct mtkswitch_softc *sc)
  201 {
  202 
  203         /*
  204          * TODO: parse the device tree and see if we need to configure
  205          *       ports, etc. differently. For now we fallback to defaults.
  206          */
  207 
  208         /* Called early and hence unlocked */
  209         return (0);
  210 }
  211 
  212 static int
  213 mtkswitch_hw_global_setup(struct mtkswitch_softc *sc)
  214 {
  215         /* Currently does nothing */
  216 
  217         /* Called early and hence unlocked */
  218         return (0);
  219 }
  220 
  221 static void
  222 mtkswitch_port_init(struct mtkswitch_softc *sc, int port)
  223 {
  224         uint32_t val;
  225 
  226         /* Called early and hence unlocked */
  227 
  228         /* Set the port to secure mode */
  229         val = sc->hal.mtkswitch_read(sc, MTKSWITCH_PCR(port));
  230         val |= PCR_PORT_VLAN_SECURE;
  231         sc->hal.mtkswitch_write(sc, MTKSWITCH_PCR(port), val);
  232 
  233         /* Set port's vlan_attr to user port */
  234         val = sc->hal.mtkswitch_read(sc, MTKSWITCH_PVC(port));
  235         val &= ~PVC_VLAN_ATTR_MASK;
  236         sc->hal.mtkswitch_write(sc, MTKSWITCH_PVC(port), val);
  237 
  238         val = PMCR_CFG_DEFAULT;
  239         if (port == sc->cpuport)
  240                 val |= PMCR_FORCE_LINK | PMCR_FORCE_DPX | PMCR_FORCE_SPD_1000 |
  241                     PMCR_FORCE_MODE;
  242         /* Set port's MAC to default settings */
  243         sc->hal.mtkswitch_write(sc, MTKSWITCH_PMCR(port), val);
  244 }
  245 
  246 static uint32_t
  247 mtkswitch_get_port_status(struct mtkswitch_softc *sc, int port)
  248 {
  249         uint32_t val, res, tmp;
  250 
  251         MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
  252         res = 0;
  253         val = sc->hal.mtkswitch_read(sc, MTKSWITCH_PMSR(port));
  254 
  255         if (val & PMSR_MAC_LINK_STS)
  256                 res |= MTKSWITCH_LINK_UP;
  257         if (val & PMSR_MAC_DPX_STS)
  258                 res |= MTKSWITCH_DUPLEX;
  259         tmp = PMSR_MAC_SPD(val);
  260         if (tmp == 0)
  261                 res |= MTKSWITCH_SPEED_10;
  262         else if (tmp == 1)
  263                 res |= MTKSWITCH_SPEED_100;
  264         else if (tmp == 2)
  265                 res |= MTKSWITCH_SPEED_1000;
  266         if (val & PMSR_TX_FC_STS)
  267                 res |= MTKSWITCH_TXFLOW;
  268         if (val & PMSR_RX_FC_STS)
  269                 res |= MTKSWITCH_RXFLOW;
  270 
  271         return (res);
  272 }
  273 
  274 static int
  275 mtkswitch_atu_flush(struct mtkswitch_softc *sc)
  276 {
  277 
  278         MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
  279 
  280         /* Flush all non-static MAC addresses */
  281         while (sc->hal.mtkswitch_read(sc, MTKSWITCH_ATC) & ATC_BUSY);
  282         sc->hal.mtkswitch_write(sc, MTKSWITCH_ATC, ATC_BUSY |
  283             ATC_AC_MAT_NON_STATIC_MACS | ATC_AC_CMD_CLEAN);
  284         while (sc->hal.mtkswitch_read(sc, MTKSWITCH_ATC) & ATC_BUSY);
  285 
  286         return (0);
  287 }
  288 
  289 static int
  290 mtkswitch_port_vlan_setup(struct mtkswitch_softc *sc, etherswitch_port_t *p)
  291 {
  292         int err;
  293 
  294         /*
  295          * Port behaviour wrt tag/untag/stack is currently defined per-VLAN.
  296          * So we say we don't support it here.
  297          */
  298         if ((p->es_flags & (ETHERSWITCH_PORT_DOUBLE_TAG |
  299             ETHERSWITCH_PORT_ADDTAG | ETHERSWITCH_PORT_STRIPTAG)) != 0)
  300                 return (ENOTSUP);
  301 
  302         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
  303         MTKSWITCH_LOCK(sc);
  304 
  305         /* Set the PVID */
  306         if (p->es_pvid != 0) {
  307                 err = sc->hal.mtkswitch_vlan_set_pvid(sc, p->es_port,
  308                     p->es_pvid);
  309                 if (err != 0) {
  310                         MTKSWITCH_UNLOCK(sc);
  311                         return (err);
  312                 }
  313         }
  314 
  315         MTKSWITCH_UNLOCK(sc);
  316 
  317         return (0);
  318 }
  319 
  320 static int
  321 mtkswitch_port_vlan_get(struct mtkswitch_softc *sc, etherswitch_port_t *p)
  322 {
  323 
  324         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
  325         MTKSWITCH_LOCK(sc);
  326 
  327         /* Retrieve the PVID */
  328         sc->hal.mtkswitch_vlan_get_pvid(sc, p->es_port, &p->es_pvid);
  329 
  330         /*
  331          * Port flags are not supported at the moment.
  332          * Port's tag/untag/stack behaviour is defined per-VLAN.
  333          */
  334         p->es_flags = 0;
  335 
  336         MTKSWITCH_UNLOCK(sc);
  337 
  338         return (0);
  339 }
  340 
  341 static void
  342 mtkswitch_invalidate_vlan(struct mtkswitch_softc *sc, uint32_t vid)
  343 {
  344 
  345         while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
  346         sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, VTCR_BUSY |
  347             VTCR_FUNC_VID_INVALID | (vid & VTCR_VID_MASK));
  348         while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
  349 }
  350 
  351 static void
  352 mtkswitch_vlan_init_hw(struct mtkswitch_softc *sc)
  353 {
  354         uint32_t val, vid, i;
  355 
  356         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
  357         MTKSWITCH_LOCK(sc);
  358         /* Reset all VLANs to defaults first */
  359         for (i = 0; i < sc->info.es_nvlangroups; i++) {
  360                 mtkswitch_invalidate_vlan(sc, i);
  361                 if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
  362                         val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VTIM(i));
  363                         val &= ~(VTIM_MASK << VTIM_OFF(i));
  364                         val |= ((i + 1) << VTIM_OFF(i));
  365                         sc->hal.mtkswitch_write(sc, MTKSWITCH_VTIM(i), val);
  366                 }
  367         }
  368 
  369         /* Now, add all ports as untagged members of VLAN 1 */
  370         if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
  371                 /* MT7620 uses vid index instead of actual vid */
  372                 vid = 0;
  373         } else {
  374                 /* MT7621 uses the vid itself */
  375                 vid = 1;
  376         }
  377         val = VAWD1_IVL_MAC | VAWD1_VTAG_EN | VAWD1_VALID;
  378         for (i = 0; i < sc->info.es_nports; i++)
  379                 val |= VAWD1_PORT_MEMBER(i);
  380         sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD1, val);
  381         sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD2, 0);
  382         val = VTCR_BUSY | VTCR_FUNC_VID_WRITE | vid;
  383         sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, val);
  384 
  385         /* Set all port PVIDs to 1 */
  386         for (i = 0; i < sc->info.es_nports; i++) {
  387                 sc->hal.mtkswitch_vlan_set_pvid(sc, i, 1);
  388         }
  389 
  390         MTKSWITCH_UNLOCK(sc);
  391 }
  392 
  393 static int
  394 mtkswitch_vlan_getvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
  395 {
  396         uint32_t val, i;
  397 
  398         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
  399 
  400         if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) ||
  401             (v->es_vlangroup > sc->info.es_nvlangroups))
  402                 return (EINVAL);
  403 
  404         /* Reset the member ports. */
  405         v->es_untagged_ports = 0;
  406         v->es_member_ports = 0;
  407 
  408         /* Not supported for now */
  409         v->es_fid = 0;
  410 
  411         MTKSWITCH_LOCK(sc);
  412         if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
  413                 v->es_vid = (sc->hal.mtkswitch_read(sc,
  414                     MTKSWITCH_VTIM(v->es_vlangroup)) >>
  415                     VTIM_OFF(v->es_vlangroup)) & VTIM_MASK;
  416         } else {
  417                 v->es_vid = v->es_vlangroup;
  418         }
  419 
  420         while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
  421         sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, VTCR_BUSY |
  422             VTCR_FUNC_VID_READ | (v->es_vlangroup & VTCR_VID_MASK));
  423         while ((val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR)) & VTCR_BUSY);
  424         if (val & VTCR_IDX_INVALID) {
  425                 MTKSWITCH_UNLOCK(sc);
  426                 return (0);
  427         }
  428 
  429         val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VAWD1);
  430         if (val & VAWD1_VALID)
  431                 v->es_vid |= ETHERSWITCH_VID_VALID;
  432         else {
  433                 MTKSWITCH_UNLOCK(sc);
  434                 return (0);
  435         }
  436         v->es_member_ports = (val >> VAWD1_MEMBER_OFF) & VAWD1_MEMBER_MASK;
  437 
  438         val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VAWD2);
  439         for (i = 0; i < sc->info.es_nports; i++) {
  440                 if ((val & VAWD2_PORT_MASK(i)) == VAWD2_PORT_UNTAGGED(i))
  441                         v->es_untagged_ports |= (1<<i);
  442         }
  443 
  444         MTKSWITCH_UNLOCK(sc);
  445         return (0);
  446 }
  447 
  448 static int
  449 mtkswitch_vlan_setvgroup(struct mtkswitch_softc *sc, etherswitch_vlangroup_t *v)
  450 {
  451         uint32_t val, i, vid;
  452 
  453         MTKSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
  454 
  455         if ((sc->vlan_mode != ETHERSWITCH_VLAN_DOT1Q) ||
  456             (v->es_vlangroup > sc->info.es_nvlangroups))
  457                 return (EINVAL);
  458 
  459         /* We currently don't support FID */
  460         if (v->es_fid != 0)
  461                 return (EINVAL);
  462 
  463         MTKSWITCH_LOCK(sc);
  464         while (sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR) & VTCR_BUSY);
  465         if (sc->sc_switchtype == MTK_SWITCH_MT7620) {
  466                 val = sc->hal.mtkswitch_read(sc,
  467                     MTKSWITCH_VTIM(v->es_vlangroup));
  468                 val &= ~(VTIM_MASK << VTIM_OFF(v->es_vlangroup));
  469                 val |= ((v->es_vid & VTIM_MASK) << VTIM_OFF(v->es_vlangroup));
  470                 sc->hal.mtkswitch_write(sc, MTKSWITCH_VTIM(v->es_vlangroup),
  471                     val);
  472                 vid = v->es_vlangroup;
  473         } else
  474                 vid = v->es_vid;
  475 
  476         /* We use FID 0 */
  477         val = VAWD1_IVL_MAC | VAWD1_VTAG_EN | VAWD1_VALID;
  478         val |= ((v->es_member_ports & VAWD1_MEMBER_MASK) << VAWD1_MEMBER_OFF);
  479         sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD1, val);
  480 
  481         /* Set tagged ports */
  482         val = 0;
  483         for (i = 0; i < sc->info.es_nports; i++)
  484                 if (((1<<i) & v->es_untagged_ports) == 0)
  485                         val |= VAWD2_PORT_TAGGED(i);
  486         sc->hal.mtkswitch_write(sc, MTKSWITCH_VAWD2, val);
  487 
  488         /* Write the VLAN entry */
  489         sc->hal.mtkswitch_write(sc, MTKSWITCH_VTCR, VTCR_BUSY |
  490             VTCR_FUNC_VID_WRITE | (vid & VTCR_VID_MASK));
  491         while ((val = sc->hal.mtkswitch_read(sc, MTKSWITCH_VTCR)) & VTCR_BUSY);
  492 
  493         MTKSWITCH_UNLOCK(sc);
  494 
  495         if (val & VTCR_IDX_INVALID)
  496                 return (EINVAL);
  497 
  498         return (0);
  499 }
  500 
  501 static int
  502 mtkswitch_vlan_get_pvid(struct mtkswitch_softc *sc, int port, int *pvid)
  503 {
  504 
  505         MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
  506 
  507         *pvid = sc->hal.mtkswitch_read(sc, MTKSWITCH_PPBV1(port));
  508         *pvid = PPBV_VID_FROM_REG(*pvid);
  509 
  510         return (0); 
  511 }
  512 
  513 static int
  514 mtkswitch_vlan_set_pvid(struct mtkswitch_softc *sc, int port, int pvid)
  515 {
  516         uint32_t val;
  517 
  518         MTKSWITCH_LOCK_ASSERT(sc, MA_OWNED);
  519         val = PPBV_VID(pvid & PPBV_VID_MASK);
  520         sc->hal.mtkswitch_write(sc, MTKSWITCH_PPBV1(port), val);
  521         sc->hal.mtkswitch_write(sc, MTKSWITCH_PPBV2(port), val);
  522 
  523         return (0);
  524 }
  525 
  526 extern void
  527 mtk_attach_switch_mt7620(struct mtkswitch_softc *sc)
  528 {
  529 
  530         sc->portmap = 0x7f;
  531         sc->phymap = 0x1f;
  532 
  533         sc->info.es_nports = 7;
  534         sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q;
  535         sc->info.es_nvlangroups = 16;
  536         sprintf(sc->info.es_name, "Mediatek GSW");
  537 
  538         if (sc->sc_switchtype == MTK_SWITCH_MT7621) {
  539                 sc->hal.mtkswitch_read = mtkswitch_reg_read32_mt7621;
  540                 sc->hal.mtkswitch_write = mtkswitch_reg_write32_mt7621;
  541                 sc->info.es_nvlangroups = 4096;
  542         } else {
  543                 sc->hal.mtkswitch_read = mtkswitch_reg_read32;
  544                 sc->hal.mtkswitch_write = mtkswitch_reg_write32;
  545         }
  546 
  547         sc->hal.mtkswitch_reset = mtkswitch_reset;
  548         sc->hal.mtkswitch_hw_setup = mtkswitch_hw_setup;
  549         sc->hal.mtkswitch_hw_global_setup = mtkswitch_hw_global_setup;
  550         sc->hal.mtkswitch_port_init = mtkswitch_port_init;
  551         sc->hal.mtkswitch_get_port_status = mtkswitch_get_port_status;
  552         sc->hal.mtkswitch_atu_flush = mtkswitch_atu_flush;
  553         sc->hal.mtkswitch_port_vlan_setup = mtkswitch_port_vlan_setup;
  554         sc->hal.mtkswitch_port_vlan_get = mtkswitch_port_vlan_get;
  555         sc->hal.mtkswitch_vlan_init_hw = mtkswitch_vlan_init_hw;
  556         sc->hal.mtkswitch_vlan_getvgroup = mtkswitch_vlan_getvgroup;
  557         sc->hal.mtkswitch_vlan_setvgroup = mtkswitch_vlan_setvgroup;
  558         sc->hal.mtkswitch_vlan_get_pvid = mtkswitch_vlan_get_pvid;
  559         sc->hal.mtkswitch_vlan_set_pvid = mtkswitch_vlan_set_pvid;
  560         sc->hal.mtkswitch_phy_read = mtkswitch_phy_read;
  561         sc->hal.mtkswitch_phy_write = mtkswitch_phy_write;
  562         sc->hal.mtkswitch_reg_read = mtkswitch_reg_read;
  563         sc->hal.mtkswitch_reg_write = mtkswitch_reg_write;
  564 }

Cache object: 37ea47a7078c04aef56f5c76909f5631


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