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/arswitch/arswitch_8327.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) 2011-2012 Stefan Bethke.
    5  * Copyright (c) 2014 Adrian Chadd.
    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 <sys/param.h>
   33 #include <sys/bus.h>
   34 #include <sys/errno.h>
   35 #include <sys/kernel.h>
   36 #include <sys/module.h>
   37 #include <sys/socket.h>
   38 #include <sys/sockio.h>
   39 #include <sys/sysctl.h>
   40 #include <sys/systm.h>
   41 
   42 #include <net/if.h>
   43 #include <net/if_arp.h>
   44 #include <net/ethernet.h>
   45 #include <net/if_dl.h>
   46 #include <net/if_media.h>
   47 #include <net/if_types.h>
   48 
   49 #include <machine/bus.h>
   50 #include <dev/iicbus/iic.h>
   51 #include <dev/iicbus/iiconf.h>
   52 #include <dev/iicbus/iicbus.h>
   53 #include <dev/mii/mii.h>
   54 #include <dev/mii/miivar.h>
   55 #include <dev/mdio/mdio.h>
   56 
   57 #include <dev/etherswitch/etherswitch.h>
   58 
   59 #include <dev/etherswitch/arswitch/arswitchreg.h>
   60 #include <dev/etherswitch/arswitch/arswitchvar.h>
   61 #include <dev/etherswitch/arswitch/arswitch_reg.h>
   62 #include <dev/etherswitch/arswitch/arswitch_phy.h>
   63 #include <dev/etherswitch/arswitch/arswitch_vlans.h>
   64 
   65 #include <dev/etherswitch/arswitch/arswitch_8327.h>
   66 
   67 #include "mdio_if.h"
   68 #include "miibus_if.h"
   69 #include "etherswitch_if.h"
   70 
   71 /*
   72  * AR8327 TODO:
   73  *
   74  * There should be a default hardware setup hint set for the default
   75  * switch config.  Otherwise the default is "all ports in one vlangroup",
   76  * which means both CPU ports can see each other and that will quickly
   77  * lead to traffic storms/loops.
   78  */
   79 
   80 /* Map port+led to register+shift */
   81 struct ar8327_led_mapping ar8327_led_mapping[AR8327_NUM_PHYS][ETHERSWITCH_PORT_MAX_LEDS] =
   82 {
   83         {       /* PHY0 */
   84                 {AR8327_REG_LED_CTRL0, 14 },
   85                 {AR8327_REG_LED_CTRL1, 14 },
   86                 {AR8327_REG_LED_CTRL2, 14 }
   87         },
   88         {       /* PHY1 */
   89                 {AR8327_REG_LED_CTRL3, 8  },
   90                 {AR8327_REG_LED_CTRL3, 10 },
   91                 {AR8327_REG_LED_CTRL3, 12 }
   92         },
   93         {       /* PHY2 */
   94                 {AR8327_REG_LED_CTRL3, 14 },
   95                 {AR8327_REG_LED_CTRL3, 16 },
   96                 {AR8327_REG_LED_CTRL3, 18 }
   97         },
   98         {       /* PHY3 */
   99                 {AR8327_REG_LED_CTRL3, 20 },
  100                 {AR8327_REG_LED_CTRL3, 22 },
  101                 {AR8327_REG_LED_CTRL3, 24 }
  102         },
  103         {       /* PHY4 */
  104                 {AR8327_REG_LED_CTRL0, 30 },
  105                 {AR8327_REG_LED_CTRL1, 30 },
  106                 {AR8327_REG_LED_CTRL2, 30 }
  107         }
  108 };
  109 
  110 static int
  111 ar8327_vlan_op(struct arswitch_softc *sc, uint32_t op, uint32_t vid,
  112     uint32_t data)
  113 {
  114         int err;
  115 
  116         /*
  117          * Wait for the "done" bit to finish.
  118          */
  119         if (arswitch_waitreg(sc->sc_dev, AR8327_REG_VTU_FUNC1,
  120             AR8327_VTU_FUNC1_BUSY, 0, 5))
  121                 return (EBUSY);
  122 
  123         /*
  124          * If it's a "load" operation, then ensure 'data' is loaded
  125          * in first.
  126          */
  127         if ((op & AR8327_VTU_FUNC1_OP) == AR8327_VTU_FUNC1_OP_LOAD) {
  128                 err = arswitch_writereg(sc->sc_dev, AR8327_REG_VTU_FUNC0, data);
  129                 if (err)
  130                         return (err);
  131         }
  132 
  133         /*
  134          * Set the VID.
  135          */
  136         op |= ((vid & 0xfff) << AR8327_VTU_FUNC1_VID_S);
  137 
  138         /*
  139          * Set busy bit to start loading in the command.
  140          */
  141         op |= AR8327_VTU_FUNC1_BUSY;
  142         arswitch_writereg(sc->sc_dev, AR8327_REG_VTU_FUNC1, op);
  143 
  144         /*
  145          * Finally - wait for it to load.
  146          */
  147         if (arswitch_waitreg(sc->sc_dev, AR8327_REG_VTU_FUNC1,
  148             AR8327_VTU_FUNC1_BUSY, 0, 5))
  149                 return (EBUSY);
  150 
  151         return (0);
  152 }
  153 
  154 static void
  155 ar8327_phy_fixup(struct arswitch_softc *sc, int phy)
  156 {
  157         if (bootverbose)
  158                 device_printf(sc->sc_dev,
  159                     "%s: called; phy=%d; chiprev=%d\n", __func__,
  160                     phy,
  161                     sc->chip_rev);
  162         switch (sc->chip_rev) {
  163         case 1:
  164                 /* For 100M waveform */
  165                 arswitch_writedbg(sc->sc_dev, phy, 0, 0x02ea);
  166                 /* Turn on Gigabit clock */
  167                 arswitch_writedbg(sc->sc_dev, phy, 0x3d, 0x68a0);
  168                 break;
  169 
  170         case 2:
  171                 arswitch_writemmd(sc->sc_dev, phy, 0x7, 0x3c);
  172                 arswitch_writemmd(sc->sc_dev, phy, 0x4007, 0x0);
  173                 /* fallthrough */
  174         case 4:
  175                 arswitch_writemmd(sc->sc_dev, phy, 0x3, 0x800d);
  176                 arswitch_writemmd(sc->sc_dev, phy, 0x4003, 0x803f);
  177 
  178                 arswitch_writedbg(sc->sc_dev, phy, 0x3d, 0x6860);
  179                 arswitch_writedbg(sc->sc_dev, phy, 0x5, 0x2c46);
  180                 arswitch_writedbg(sc->sc_dev, phy, 0x3c, 0x6000);
  181                 break;
  182         }
  183 }
  184 
  185 static uint32_t
  186 ar8327_get_pad_cfg(struct ar8327_pad_cfg *cfg)
  187 {
  188         uint32_t t;
  189 
  190         if (!cfg)
  191                 return (0);
  192 
  193         t = 0;
  194         switch (cfg->mode) {
  195         case AR8327_PAD_NC:
  196                 break;
  197 
  198         case AR8327_PAD_MAC2MAC_MII:
  199                 t = AR8327_PAD_MAC_MII_EN;
  200                 if (cfg->rxclk_sel)
  201                         t |= AR8327_PAD_MAC_MII_RXCLK_SEL;
  202                 if (cfg->txclk_sel)
  203                         t |= AR8327_PAD_MAC_MII_TXCLK_SEL;
  204                 break;
  205 
  206         case AR8327_PAD_MAC2MAC_GMII:
  207                 t = AR8327_PAD_MAC_GMII_EN;
  208                 if (cfg->rxclk_sel)
  209                         t |= AR8327_PAD_MAC_GMII_RXCLK_SEL;
  210                 if (cfg->txclk_sel)
  211                         t |= AR8327_PAD_MAC_GMII_TXCLK_SEL;
  212                 break;
  213 
  214         case AR8327_PAD_MAC_SGMII:
  215                 t = AR8327_PAD_SGMII_EN;
  216 
  217                 /*
  218                  * WAR for the Qualcomm Atheros AP136 board.
  219                  * It seems that RGMII TX/RX delay settings needs to be
  220                  * applied for SGMII mode as well, The ethernet is not
  221                  * reliable without this.
  222                  */
  223                 t |= cfg->txclk_delay_sel << AR8327_PAD_RGMII_TXCLK_DELAY_SEL_S;
  224                 t |= cfg->rxclk_delay_sel << AR8327_PAD_RGMII_RXCLK_DELAY_SEL_S;
  225                 if (cfg->rxclk_delay_en)
  226                         t |= AR8327_PAD_RGMII_RXCLK_DELAY_EN;
  227                 if (cfg->txclk_delay_en)
  228                         t |= AR8327_PAD_RGMII_TXCLK_DELAY_EN;
  229 
  230                 if (cfg->sgmii_delay_en)
  231                         t |= AR8327_PAD_SGMII_DELAY_EN;
  232 
  233                 break;
  234 
  235         case AR8327_PAD_MAC2PHY_MII:
  236                 t = AR8327_PAD_PHY_MII_EN;
  237                 if (cfg->rxclk_sel)
  238                         t |= AR8327_PAD_PHY_MII_RXCLK_SEL;
  239                 if (cfg->txclk_sel)
  240                         t |= AR8327_PAD_PHY_MII_TXCLK_SEL;
  241                 break;
  242 
  243         case AR8327_PAD_MAC2PHY_GMII:
  244                 t = AR8327_PAD_PHY_GMII_EN;
  245                 if (cfg->pipe_rxclk_sel)
  246                         t |= AR8327_PAD_PHY_GMII_PIPE_RXCLK_SEL;
  247                 if (cfg->rxclk_sel)
  248                         t |= AR8327_PAD_PHY_GMII_RXCLK_SEL;
  249                 if (cfg->txclk_sel)
  250                         t |= AR8327_PAD_PHY_GMII_TXCLK_SEL;
  251                 break;
  252 
  253         case AR8327_PAD_MAC_RGMII:
  254                 t = AR8327_PAD_RGMII_EN;
  255                 t |= cfg->txclk_delay_sel << AR8327_PAD_RGMII_TXCLK_DELAY_SEL_S;
  256                 t |= cfg->rxclk_delay_sel << AR8327_PAD_RGMII_RXCLK_DELAY_SEL_S;
  257                 if (cfg->rxclk_delay_en)
  258                         t |= AR8327_PAD_RGMII_RXCLK_DELAY_EN;
  259                 if (cfg->txclk_delay_en)
  260                         t |= AR8327_PAD_RGMII_TXCLK_DELAY_EN;
  261                 break;
  262 
  263         case AR8327_PAD_PHY_GMII:
  264                 t = AR8327_PAD_PHYX_GMII_EN;
  265                 break;
  266 
  267         case AR8327_PAD_PHY_RGMII:
  268                 t = AR8327_PAD_PHYX_RGMII_EN;
  269                 break;
  270 
  271         case AR8327_PAD_PHY_MII:
  272                 t = AR8327_PAD_PHYX_MII_EN;
  273                 break;
  274         }
  275 
  276         return (t);
  277 }
  278 
  279 /*
  280  * Map the hard-coded port config from the switch setup to
  281  * the chipset port config (status, duplex, flow, etc.)
  282  */
  283 static uint32_t
  284 ar8327_get_port_init_status(struct ar8327_port_cfg *cfg)
  285 {
  286         uint32_t t;
  287 
  288         if (!cfg->force_link)
  289                 return (AR8X16_PORT_STS_LINK_AUTO);
  290 
  291         t = AR8X16_PORT_STS_TXMAC | AR8X16_PORT_STS_RXMAC;
  292         t |= cfg->duplex ? AR8X16_PORT_STS_DUPLEX : 0;
  293         t |= cfg->rxpause ? AR8X16_PORT_STS_RXFLOW : 0;
  294         t |= cfg->txpause ? AR8X16_PORT_STS_TXFLOW : 0;
  295 
  296         switch (cfg->speed) {
  297         case AR8327_PORT_SPEED_10:
  298                 t |= AR8X16_PORT_STS_SPEED_10;
  299                 break;
  300         case AR8327_PORT_SPEED_100:
  301                 t |= AR8X16_PORT_STS_SPEED_100;
  302                 break;
  303         case AR8327_PORT_SPEED_1000:
  304                 t |= AR8X16_PORT_STS_SPEED_1000;
  305                 break;
  306         }
  307 
  308         return (t);
  309 }
  310 
  311 /*
  312  * Fetch the port data for the given port.
  313  *
  314  * This goes and does dirty things with the hints space
  315  * to determine what the configuration parameters should be.
  316  *
  317  * Returns 1 if the structure was successfully parsed and
  318  * the contents are valid; 0 otherwise.
  319  */
  320 static int
  321 ar8327_fetch_pdata_port(struct arswitch_softc *sc,
  322     struct ar8327_port_cfg *pcfg,
  323     int port)
  324 {
  325         int val;
  326         char sbuf[128];
  327 
  328         /* Check if force_link exists */
  329         val = 0;
  330         snprintf(sbuf, 128, "port.%d.force_link", port);
  331         (void) resource_int_value(device_get_name(sc->sc_dev),
  332             device_get_unit(sc->sc_dev),
  333             sbuf, &val);
  334         if (val != 1)
  335                 return (0);
  336         pcfg->force_link = 1;
  337 
  338         /* force_link is set; let's parse the rest of the fields */
  339         snprintf(sbuf, 128, "port.%d.speed", port);
  340         if (resource_int_value(device_get_name(sc->sc_dev),
  341             device_get_unit(sc->sc_dev),
  342             sbuf, &val) == 0) {
  343                 switch (val) {
  344                 case 10:
  345                         pcfg->speed = AR8327_PORT_SPEED_10;
  346                         break;
  347                 case 100:
  348                         pcfg->speed = AR8327_PORT_SPEED_100;
  349                         break;
  350                 case 1000:
  351                         pcfg->speed = AR8327_PORT_SPEED_1000;
  352                         break;
  353                 default:
  354                         device_printf(sc->sc_dev,
  355                             "%s: invalid port %d duplex value (%d)\n",
  356                             __func__,
  357                             port,
  358                             val);
  359                         return (0);
  360                 }
  361         }
  362 
  363         snprintf(sbuf, 128, "port.%d.duplex", port);
  364         if (resource_int_value(device_get_name(sc->sc_dev),
  365             device_get_unit(sc->sc_dev),
  366             sbuf, &val) == 0)
  367                 pcfg->duplex = val;
  368 
  369         snprintf(sbuf, 128, "port.%d.txpause", port);
  370         if (resource_int_value(device_get_name(sc->sc_dev),
  371             device_get_unit(sc->sc_dev),
  372             sbuf, &val) == 0)
  373                 pcfg->txpause = val;
  374 
  375         snprintf(sbuf, 128, "port.%d.rxpause", port);
  376         if (resource_int_value(device_get_name(sc->sc_dev),
  377             device_get_unit(sc->sc_dev),
  378             sbuf, &val) == 0)
  379                 pcfg->rxpause = val;
  380 
  381 #if 1
  382         device_printf(sc->sc_dev,
  383             "%s: port %d: speed=%d, duplex=%d, txpause=%d, rxpause=%d\n",
  384             __func__,
  385             port,
  386             pcfg->speed,
  387             pcfg->duplex,
  388             pcfg->txpause,
  389             pcfg->rxpause);
  390 #endif
  391 
  392         return (1);
  393 }
  394 
  395 /*
  396  * Parse the pad configuration from the boot hints.
  397  *
  398  * The (mostly optional) fields are:
  399  *
  400  * uint32_t mode;
  401  * uint32_t rxclk_sel;
  402  * uint32_t txclk_sel;
  403  * uint32_t txclk_delay_sel;
  404  * uint32_t rxclk_delay_sel;
  405  * uint32_t txclk_delay_en;
  406  * uint32_t rxclk_delay_en;
  407  * uint32_t sgmii_delay_en;
  408  * uint32_t pipe_rxclk_sel;
  409  *
  410  * If mode isn't in the hints, 0 is returned.
  411  * Else the structure is fleshed out and 1 is returned.
  412  */
  413 static int
  414 ar8327_fetch_pdata_pad(struct arswitch_softc *sc,
  415     struct ar8327_pad_cfg *pc,
  416     int pad)
  417 {
  418         int val;
  419         char sbuf[128];
  420 
  421         /* Check if mode exists */
  422         val = 0;
  423         snprintf(sbuf, 128, "pad.%d.mode", pad);
  424         if (resource_int_value(device_get_name(sc->sc_dev),
  425             device_get_unit(sc->sc_dev),
  426             sbuf, &val) != 0)
  427                 return (0);
  428 
  429         /* assume that 'mode' exists and was found */
  430         pc->mode = val;
  431 
  432         snprintf(sbuf, 128, "pad.%d.rxclk_sel", pad);
  433         if (resource_int_value(device_get_name(sc->sc_dev),
  434             device_get_unit(sc->sc_dev),
  435             sbuf, &val) == 0)
  436                 pc->rxclk_sel = val;
  437 
  438         snprintf(sbuf, 128, "pad.%d.txclk_sel", pad);
  439         if (resource_int_value(device_get_name(sc->sc_dev),
  440             device_get_unit(sc->sc_dev),
  441             sbuf, &val) == 0)
  442                 pc->txclk_sel = val;
  443 
  444         snprintf(sbuf, 128, "pad.%d.txclk_delay_sel", pad);
  445         if (resource_int_value(device_get_name(sc->sc_dev),
  446             device_get_unit(sc->sc_dev),
  447             sbuf, &val) == 0)
  448                 pc->txclk_delay_sel = val;
  449 
  450         snprintf(sbuf, 128, "pad.%d.rxclk_delay_sel", pad);
  451         if (resource_int_value(device_get_name(sc->sc_dev),
  452             device_get_unit(sc->sc_dev),
  453             sbuf, &val) == 0)
  454                 pc->rxclk_delay_sel = val;
  455 
  456         snprintf(sbuf, 128, "pad.%d.txclk_delay_en", pad);
  457         if (resource_int_value(device_get_name(sc->sc_dev),
  458             device_get_unit(sc->sc_dev),
  459             sbuf, &val) == 0)
  460                 pc->txclk_delay_en = val;
  461 
  462         snprintf(sbuf, 128, "pad.%d.rxclk_delay_en", pad);
  463         if (resource_int_value(device_get_name(sc->sc_dev),
  464             device_get_unit(sc->sc_dev),
  465             sbuf, &val) == 0)
  466                 pc->rxclk_delay_en = val;
  467 
  468         snprintf(sbuf, 128, "pad.%d.sgmii_delay_en", pad);
  469         if (resource_int_value(device_get_name(sc->sc_dev),
  470             device_get_unit(sc->sc_dev),
  471             sbuf, &val) == 0)
  472                 pc->sgmii_delay_en = val;
  473 
  474         snprintf(sbuf, 128, "pad.%d.pipe_rxclk_sel", pad);
  475         if (resource_int_value(device_get_name(sc->sc_dev),
  476             device_get_unit(sc->sc_dev),
  477             sbuf, &val) == 0)
  478                 pc->pipe_rxclk_sel = val;
  479 
  480         if (bootverbose) {
  481                 device_printf(sc->sc_dev,
  482                     "%s: pad %d: mode=%d, rxclk_sel=%d, txclk_sel=%d, "
  483                     "txclk_delay_sel=%d, rxclk_delay_sel=%d, txclk_delay_en=%d, "
  484                     "rxclk_enable_en=%d, sgmii_delay_en=%d, pipe_rxclk_sel=%d\n",
  485                     __func__,
  486                     pad,
  487                     pc->mode,
  488                     pc->rxclk_sel,
  489                     pc->txclk_sel,
  490                     pc->txclk_delay_sel,
  491                     pc->rxclk_delay_sel,
  492                     pc->txclk_delay_en,
  493                     pc->rxclk_delay_en,
  494                     pc->sgmii_delay_en,
  495                     pc->pipe_rxclk_sel);
  496         }
  497 
  498         return (1);
  499 }
  500 
  501 /*
  502  * Fetch the SGMII configuration block from the boot hints.
  503  */
  504 static int
  505 ar8327_fetch_pdata_sgmii(struct arswitch_softc *sc,
  506     struct ar8327_sgmii_cfg *scfg)
  507 {
  508         int val;
  509 
  510         /* sgmii_ctrl */
  511         val = 0;
  512         if (resource_int_value(device_get_name(sc->sc_dev),
  513             device_get_unit(sc->sc_dev),
  514             "sgmii.ctrl", &val) != 0)
  515                 return (0);
  516         scfg->sgmii_ctrl = val;
  517 
  518         /* serdes_aen */
  519         val = 0;
  520         if (resource_int_value(device_get_name(sc->sc_dev),
  521             device_get_unit(sc->sc_dev),
  522             "sgmii.serdes_aen", &val) != 0)
  523                 return (0);
  524         scfg->serdes_aen = val;
  525 
  526         return (1);
  527 }
  528 
  529 /*
  530  * Fetch the LED configuration from the boot hints.
  531  */
  532 static int
  533 ar8327_fetch_pdata_led(struct arswitch_softc *sc,
  534     struct ar8327_led_cfg *lcfg)
  535 {
  536         int val;
  537 
  538         val = 0;
  539         if (resource_int_value(device_get_name(sc->sc_dev),
  540             device_get_unit(sc->sc_dev),
  541             "led.ctrl0", &val) != 0)
  542                 return (0);
  543         lcfg->led_ctrl0 = val;
  544 
  545         val = 0;
  546         if (resource_int_value(device_get_name(sc->sc_dev),
  547             device_get_unit(sc->sc_dev),
  548             "led.ctrl1", &val) != 0)
  549                 return (0);
  550         lcfg->led_ctrl1 = val;
  551 
  552         val = 0;
  553         if (resource_int_value(device_get_name(sc->sc_dev),
  554             device_get_unit(sc->sc_dev),
  555             "led.ctrl2", &val) != 0)
  556                 return (0);
  557         lcfg->led_ctrl2 = val;
  558 
  559         val = 0;
  560         if (resource_int_value(device_get_name(sc->sc_dev),
  561             device_get_unit(sc->sc_dev),
  562             "led.ctrl3", &val) != 0)
  563                 return (0);
  564         lcfg->led_ctrl3 = val;
  565 
  566         val = 0;
  567         if (resource_int_value(device_get_name(sc->sc_dev),
  568             device_get_unit(sc->sc_dev),
  569             "led.open_drain", &val) != 0)
  570                 return (0);
  571         lcfg->open_drain = val;
  572 
  573         return (1);
  574 }
  575 
  576 /*
  577  * Initialise the ar8327 specific hardware features from
  578  * the hints provided in the boot environment.
  579  */
  580 static int
  581 ar8327_init_pdata(struct arswitch_softc *sc)
  582 {
  583         struct ar8327_pad_cfg pc;
  584         struct ar8327_port_cfg port_cfg;
  585         struct ar8327_sgmii_cfg scfg;
  586         struct ar8327_led_cfg lcfg;
  587         uint32_t t, new_pos, pos;
  588 
  589         /* Port 0 */
  590         bzero(&port_cfg, sizeof(port_cfg));
  591         sc->ar8327.port0_status = 0;
  592         if (ar8327_fetch_pdata_port(sc, &port_cfg, 0))
  593                 sc->ar8327.port0_status = ar8327_get_port_init_status(&port_cfg);
  594 
  595         /* Port 6 */
  596         bzero(&port_cfg, sizeof(port_cfg));
  597         sc->ar8327.port6_status = 0;
  598         if (ar8327_fetch_pdata_port(sc, &port_cfg, 6))
  599                 sc->ar8327.port6_status = ar8327_get_port_init_status(&port_cfg);
  600 
  601         /* Pad 0 */
  602         bzero(&pc, sizeof(pc));
  603         t = 0;
  604         if (ar8327_fetch_pdata_pad(sc, &pc, 0))
  605                 t = ar8327_get_pad_cfg(&pc);
  606 #if 0
  607                 if (AR8X16_IS_SWITCH(sc, AR8337))
  608                         t |= AR8337_PAD_MAC06_EXCHANGE_EN;
  609 #endif
  610         arswitch_writereg(sc->sc_dev, AR8327_REG_PAD0_MODE, t);
  611 
  612         /* Pad 5 */
  613         bzero(&pc, sizeof(pc));
  614         t = 0;
  615         if (ar8327_fetch_pdata_pad(sc, &pc, 5))
  616                 t = ar8327_get_pad_cfg(&pc);
  617         arswitch_writereg(sc->sc_dev, AR8327_REG_PAD5_MODE, t);
  618 
  619         /* Pad 6 */
  620         bzero(&pc, sizeof(pc));
  621         t = 0;
  622         if (ar8327_fetch_pdata_pad(sc, &pc, 6))
  623                 t = ar8327_get_pad_cfg(&pc);
  624         arswitch_writereg(sc->sc_dev, AR8327_REG_PAD6_MODE, t);
  625 
  626         pos = arswitch_readreg(sc->sc_dev, AR8327_REG_POWER_ON_STRIP);
  627         new_pos = pos;
  628 
  629         /* XXX LED config */
  630         bzero(&lcfg, sizeof(lcfg));
  631         if (ar8327_fetch_pdata_led(sc, &lcfg)) {
  632                 if (lcfg.open_drain)
  633                         new_pos |= AR8327_POWER_ON_STRIP_LED_OPEN_EN;
  634                 else
  635                         new_pos &= ~AR8327_POWER_ON_STRIP_LED_OPEN_EN;
  636 
  637                 arswitch_writereg(sc->sc_dev, AR8327_REG_LED_CTRL0,
  638                     lcfg.led_ctrl0);
  639                 arswitch_writereg(sc->sc_dev, AR8327_REG_LED_CTRL1,
  640                     lcfg.led_ctrl1);
  641                 arswitch_writereg(sc->sc_dev, AR8327_REG_LED_CTRL2,
  642                     lcfg.led_ctrl2);
  643                 arswitch_writereg(sc->sc_dev, AR8327_REG_LED_CTRL3,
  644                     lcfg.led_ctrl3);
  645 
  646                 if (new_pos != pos)
  647                         new_pos |= AR8327_POWER_ON_STRIP_POWER_ON_SEL;
  648         }
  649 
  650         /* SGMII config */
  651         bzero(&scfg, sizeof(scfg));
  652         if (ar8327_fetch_pdata_sgmii(sc, &scfg)) {
  653                 device_printf(sc->sc_dev, "%s: SGMII cfg?\n", __func__);
  654                 t = scfg.sgmii_ctrl;
  655                 if (sc->chip_rev == 1)
  656                         t |= AR8327_SGMII_CTRL_EN_PLL |
  657                             AR8327_SGMII_CTRL_EN_RX |
  658                             AR8327_SGMII_CTRL_EN_TX;
  659                 else
  660                         t &= ~(AR8327_SGMII_CTRL_EN_PLL |
  661                             AR8327_SGMII_CTRL_EN_RX |
  662                             AR8327_SGMII_CTRL_EN_TX);
  663 
  664                 arswitch_writereg(sc->sc_dev, AR8327_REG_SGMII_CTRL, t);
  665 
  666                 if (scfg.serdes_aen)
  667                         new_pos &= ~AR8327_POWER_ON_STRIP_SERDES_AEN;
  668                 else
  669                         new_pos |= AR8327_POWER_ON_STRIP_SERDES_AEN;
  670         }
  671 
  672         arswitch_writereg(sc->sc_dev, AR8327_REG_POWER_ON_STRIP, new_pos);
  673 
  674         return (0);
  675 }
  676 
  677 static int
  678 ar8327_hw_setup(struct arswitch_softc *sc)
  679 {
  680         int i;
  681         int err;
  682 
  683         /* pdata fetch and setup */
  684         err = ar8327_init_pdata(sc);
  685         if (err != 0)
  686                 return (err);
  687 
  688         /* XXX init leds */
  689 
  690         for (i = 0; i < AR8327_NUM_PHYS; i++) {
  691                 /* phy fixup */
  692                 ar8327_phy_fixup(sc, i);
  693 
  694                 /* start PHY autonegotiation? */
  695                 /* XXX is this done as part of the normal PHY setup? */
  696 
  697         }
  698 
  699         /* Let things settle */
  700         DELAY(1000);
  701 
  702         return (0);
  703 }
  704 
  705 static int
  706 ar8327_atu_learn_default(struct arswitch_softc *sc)
  707 {
  708 
  709         device_printf(sc->sc_dev, "%s: TODO!\n", __func__);
  710         return (0);
  711 }
  712 
  713 /*
  714  * Initialise other global values, for the AR8327.
  715  */
  716 static int
  717 ar8327_hw_global_setup(struct arswitch_softc *sc)
  718 {
  719         uint32_t t;
  720 
  721         ARSWITCH_LOCK(sc);
  722 
  723         /* enable CPU port and disable mirror port */
  724         t = AR8327_FWD_CTRL0_CPU_PORT_EN |
  725             AR8327_FWD_CTRL0_MIRROR_PORT;
  726         arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL0, t);
  727 
  728         /* forward multicast and broadcast frames to CPU */
  729         t = (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_UC_FLOOD_S) |
  730             (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_MC_FLOOD_S) |
  731             (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_BC_FLOOD_S);
  732         arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL1, t);
  733 
  734         /* enable jumbo frames */
  735         /* XXX need to macro-shift the value! */
  736         arswitch_modifyreg(sc->sc_dev, AR8327_REG_MAX_FRAME_SIZE,
  737             AR8327_MAX_FRAME_SIZE_MTU, 9018 + 8 + 2);
  738 
  739         /* Enable MIB counters */
  740         arswitch_modifyreg(sc->sc_dev, AR8327_REG_MODULE_EN,
  741             AR8327_MODULE_EN_MIB, AR8327_MODULE_EN_MIB);
  742 
  743         /* Disable EEE on all ports due to stability issues */
  744         t = arswitch_readreg(sc->sc_dev, AR8327_REG_EEE_CTRL);
  745         t |= AR8327_EEE_CTRL_DISABLE_PHY(0) |
  746             AR8327_EEE_CTRL_DISABLE_PHY(1) |
  747             AR8327_EEE_CTRL_DISABLE_PHY(2) |
  748             AR8327_EEE_CTRL_DISABLE_PHY(3) |
  749             AR8327_EEE_CTRL_DISABLE_PHY(4);
  750         arswitch_writereg(sc->sc_dev, AR8327_REG_EEE_CTRL, t);
  751 
  752         /* Set the right number of ports */
  753         /* GMAC0 (CPU), GMAC1..5 (PHYs), GMAC6 (CPU) */
  754         sc->info.es_nports = 7;
  755 
  756         ARSWITCH_UNLOCK(sc);
  757         return (0);
  758 }
  759 
  760 /*
  761  * Port setup.  Called at attach time.
  762  */
  763 static void
  764 ar8327_port_init(struct arswitch_softc *sc, int port)
  765 {
  766         uint32_t t;
  767         int ports;
  768 
  769         /* For now, port can see all other ports */
  770         ports = 0x7f;
  771 
  772         if (port == AR8X16_PORT_CPU)
  773                 t = sc->ar8327.port0_status;
  774         else if (port == 6)
  775                 t = sc->ar8327.port6_status;
  776         else
  777                 t = AR8X16_PORT_STS_LINK_AUTO;
  778 
  779         arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_STATUS(port), t);
  780         arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_HEADER(port), 0);
  781 
  782         /*
  783          * Default to 1 port group.
  784          */
  785         t = 1 << AR8327_PORT_VLAN0_DEF_SVID_S;
  786         t |= 1 << AR8327_PORT_VLAN0_DEF_CVID_S;
  787         arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(port), t);
  788 
  789         t = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH << AR8327_PORT_VLAN1_OUT_MODE_S;
  790         arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN1(port), t);
  791 
  792         /*
  793          * This doesn't configure any ports which this port can "see".
  794          * bits 0-6 control which ports a frame coming into this port
  795          * can be sent out to.
  796          *
  797          * So by doing this, we're making it impossible to send frames out
  798          * to that port.
  799          */
  800         t = AR8327_PORT_LOOKUP_LEARN;
  801         t |= AR8X16_PORT_CTRL_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
  802 
  803         /* So this allows traffic to any port except ourselves */
  804         t |= (ports & ~(1 << port));
  805         arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(port), t);
  806 }
  807 
  808 static int
  809 ar8327_port_vlan_setup(struct arswitch_softc *sc, etherswitch_port_t *p)
  810 {
  811 
  812         /* Check: ADDTAG/STRIPTAG - exclusive */
  813 
  814         ARSWITCH_LOCK(sc);
  815 
  816         /* Set the PVID. */
  817         if (p->es_pvid != 0)
  818                 sc->hal.arswitch_vlan_set_pvid(sc, p->es_port, p->es_pvid);
  819 
  820         /*
  821          * DOUBLE_TAG
  822          * VLAN_MODE_ADD
  823          * VLAN_MODE_STRIP
  824          */
  825         ARSWITCH_UNLOCK(sc);
  826         return (0);
  827 }
  828 
  829 /*
  830  * Get the port VLAN configuration.
  831  */
  832 static int
  833 ar8327_port_vlan_get(struct arswitch_softc *sc, etherswitch_port_t *p)
  834 {
  835 
  836         ARSWITCH_LOCK(sc);
  837 
  838         /* Retrieve the PVID */
  839         sc->hal.arswitch_vlan_get_pvid(sc, p->es_port, &p->es_pvid);
  840 
  841         /* Retrieve the current port configuration from the VTU */
  842         /*
  843          * DOUBLE_TAG
  844          * VLAN_MODE_ADD
  845          * VLAN_MODE_STRIP
  846          */
  847 
  848         ARSWITCH_UNLOCK(sc);
  849         return (0);
  850 }
  851 
  852 static void
  853 ar8327_port_disable_mirror(struct arswitch_softc *sc, int port)
  854 {
  855 
  856         arswitch_modifyreg(sc->sc_dev,
  857             AR8327_REG_PORT_LOOKUP(port),
  858             AR8327_PORT_LOOKUP_ING_MIRROR_EN,
  859             0);
  860         arswitch_modifyreg(sc->sc_dev,
  861             AR8327_REG_PORT_HOL_CTRL1(port),
  862             AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN,
  863             0);
  864 }
  865 
  866 static void
  867 ar8327_reset_vlans(struct arswitch_softc *sc)
  868 {
  869         int i;
  870         uint32_t t;
  871         int ports;
  872 
  873         ARSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
  874         ARSWITCH_LOCK(sc);
  875 
  876         /* Clear the existing VLAN configuration */
  877         memset(sc->vid, 0, sizeof(sc->vid));
  878 
  879         /*
  880          * Disable mirroring.
  881          */
  882         arswitch_modifyreg(sc->sc_dev, AR8327_REG_FWD_CTRL0,
  883             AR8327_FWD_CTRL0_MIRROR_PORT,
  884             (0xF << AR8327_FWD_CTRL0_MIRROR_PORT_S));
  885 
  886         /*
  887          * XXX TODO: disable any Q-in-Q port configuration,
  888          * tagging, egress filters, etc.
  889          */
  890 
  891         /*
  892          * For now, let's default to one portgroup, just so traffic
  893          * flows.  All ports can see other ports. There are two CPU GMACs
  894          * (GMAC0, GMAC6), GMAC1..GMAC5 are external PHYs.
  895          *
  896          * (ETHERSWITCH_VLAN_PORT)
  897          */
  898         ports = 0x7f;
  899 
  900         /*
  901          * XXX TODO: set things up correctly for vlans!
  902          */
  903         for (i = 0; i < AR8327_NUM_PORTS; i++) {
  904                 int egress, ingress;
  905 
  906                 if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT) {
  907                         sc->vid[i] = i | ETHERSWITCH_VID_VALID;
  908                         /* set egress == out_keep */
  909                         ingress = AR8X16_PORT_VLAN_MODE_PORT_ONLY;
  910                         /* in_port_only, forward */
  911                         egress = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH;
  912                 } else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) {
  913                         ingress = AR8X16_PORT_VLAN_MODE_SECURE;
  914                         egress = AR8327_PORT_VLAN1_OUT_MODE_UNMOD;
  915                 } else {
  916                         /* set egress == out_keep */
  917                         ingress = AR8X16_PORT_VLAN_MODE_PORT_ONLY;
  918                         /* in_port_only, forward */
  919                         egress = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH;
  920                 }
  921 
  922                 /* set pvid = 1; there's only one vlangroup to start with */
  923                 t = 1 << AR8327_PORT_VLAN0_DEF_SVID_S;
  924                 t |= 1 << AR8327_PORT_VLAN0_DEF_CVID_S;
  925                 arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(i), t);
  926 
  927                 t = AR8327_PORT_VLAN1_PORT_VLAN_PROP;
  928                 t |= egress << AR8327_PORT_VLAN1_OUT_MODE_S;
  929                 arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN1(i), t);
  930 
  931                 /* Ports can see other ports */
  932                 /* XXX not entirely true for dot1q? */
  933                 t = (ports & ~(1 << i));        /* all ports besides us */
  934                 t |= AR8327_PORT_LOOKUP_LEARN;
  935 
  936                 t |= ingress << AR8327_PORT_LOOKUP_IN_MODE_S;
  937                 t |= AR8X16_PORT_CTRL_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
  938                 arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(i), t);
  939         }
  940 
  941         /*
  942          * Disable port mirroring entirely.
  943          */
  944         for (i = 0; i < AR8327_NUM_PORTS; i++) {
  945                 ar8327_port_disable_mirror(sc, i);
  946         }
  947 
  948         /*
  949          * If dot1q - set pvid; dot1q, etc.
  950          */
  951         if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) {
  952                 sc->vid[0] = 1;
  953                 for (i = 0; i < AR8327_NUM_PORTS; i++) {
  954                         /* Each port - pvid 1 */
  955                         sc->hal.arswitch_vlan_set_pvid(sc, i, sc->vid[0]);
  956                 }
  957                 /* Initialise vlan1 - all ports, untagged */
  958                 sc->hal.arswitch_set_dot1q_vlan(sc, ports, ports, sc->vid[0]);
  959                 sc->vid[0] |= ETHERSWITCH_VID_VALID;
  960         }
  961 
  962         ARSWITCH_UNLOCK(sc);
  963 }
  964 
  965 static int
  966 ar8327_vlan_get_port(struct arswitch_softc *sc, uint32_t *ports, int vid)
  967 {
  968         int port;
  969         uint32_t reg;
  970 
  971         ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
  972 
  973         /* For port based vlans the vlanid is the same as the port index. */
  974         port = vid & ETHERSWITCH_VID_MASK;
  975         reg = arswitch_readreg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(port));
  976         *ports = reg & 0x7f;
  977         return (0);
  978 }
  979 
  980 static int
  981 ar8327_vlan_set_port(struct arswitch_softc *sc, uint32_t ports, int vid)
  982 {
  983         int err, port;
  984 
  985         ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
  986 
  987         /* For port based vlans the vlanid is the same as the port index. */
  988         port = vid & ETHERSWITCH_VID_MASK;
  989 
  990         err = arswitch_modifyreg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(port),
  991             0x7f, /* vlan membership mask */
  992             (ports & 0x7f));
  993 
  994         if (err)
  995                 return (err);
  996         return (0);
  997 }
  998 
  999 static int
 1000 ar8327_vlan_getvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
 1001 {
 1002 
 1003         return (ar8xxx_getvgroup(sc, vg));
 1004 }
 1005 
 1006 static int
 1007 ar8327_vlan_setvgroup(struct arswitch_softc *sc, etherswitch_vlangroup_t *vg)
 1008 {
 1009 
 1010         return (ar8xxx_setvgroup(sc, vg));
 1011 }
 1012 
 1013 static int
 1014 ar8327_get_pvid(struct arswitch_softc *sc, int port, int *pvid)
 1015 {
 1016         uint32_t reg;
 1017 
 1018         ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
 1019 
 1020         /*
 1021          * XXX for now, assuming it's CVID; likely very wrong!
 1022          */
 1023         port = port & ETHERSWITCH_VID_MASK;
 1024         reg = arswitch_readreg(sc->sc_dev, AR8327_REG_PORT_VLAN0(port));
 1025         reg = reg >> AR8327_PORT_VLAN0_DEF_CVID_S;
 1026         reg = reg & 0xfff;
 1027 
 1028         *pvid = reg;
 1029         return (0);
 1030 }
 1031 
 1032 static int
 1033 ar8327_set_pvid(struct arswitch_softc *sc, int port, int pvid)
 1034 {
 1035         uint32_t t;
 1036 
 1037         /* Limit pvid to valid values */
 1038         pvid &= 0x7f;
 1039 
 1040         t = pvid << AR8327_PORT_VLAN0_DEF_SVID_S;
 1041         t |= pvid << AR8327_PORT_VLAN0_DEF_CVID_S;
 1042         arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(port), t);
 1043 
 1044         return (0);
 1045 }
 1046 
 1047 static int
 1048 ar8327_atu_wait_ready(struct arswitch_softc *sc)
 1049 {
 1050         int ret;
 1051 
 1052         ret = arswitch_waitreg(sc->sc_dev,
 1053             AR8327_REG_ATU_FUNC,
 1054             AR8327_ATU_FUNC_BUSY,
 1055             0,
 1056             1000);
 1057 
 1058         return (ret);
 1059 }
 1060 
 1061 static int
 1062 ar8327_atu_flush(struct arswitch_softc *sc)
 1063 {
 1064 
 1065         int ret;
 1066 
 1067         ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
 1068 
 1069         ret = ar8327_atu_wait_ready(sc);
 1070         if (ret)
 1071                 device_printf(sc->sc_dev, "%s: waitreg failed\n", __func__);
 1072 
 1073         if (!ret)
 1074                 arswitch_writereg(sc->sc_dev,
 1075                     AR8327_REG_ATU_FUNC,
 1076                     AR8327_ATU_FUNC_OP_FLUSH | AR8327_ATU_FUNC_BUSY);
 1077         return (ret);
 1078 }
 1079 
 1080 static int
 1081 ar8327_atu_flush_port(struct arswitch_softc *sc, int port)
 1082 {
 1083         int ret;
 1084         uint32_t val;
 1085 
 1086         ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
 1087 
 1088         ret = ar8327_atu_wait_ready(sc);
 1089         if (ret)
 1090                 device_printf(sc->sc_dev, "%s: waitreg failed\n", __func__);
 1091 
 1092         val = AR8327_ATU_FUNC_OP_FLUSH_UNICAST;
 1093         val |= SM(port, AR8327_ATU_FUNC_PORT_NUM);
 1094 
 1095         if (!ret)
 1096                 arswitch_writereg(sc->sc_dev,
 1097                     AR8327_REG_ATU_FUNC,
 1098                     val | AR8327_ATU_FUNC_BUSY);
 1099 
 1100         return (ret);
 1101 }
 1102 
 1103 /*
 1104  * Fetch a single entry from the ATU.
 1105  */
 1106 static int
 1107 ar8327_atu_fetch_table(struct arswitch_softc *sc, etherswitch_atu_entry_t *e,
 1108     int atu_fetch_op)
 1109 {
 1110         uint32_t ret0, ret1, ret2, val;
 1111 
 1112         ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);
 1113 
 1114         switch (atu_fetch_op) {
 1115         case 0:
 1116                 /* Initialise things for the first fetch */
 1117 
 1118                 DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: initializing\n", __func__);
 1119                 (void) ar8327_atu_wait_ready(sc);
 1120 
 1121                 arswitch_writereg(sc->sc_dev,
 1122                     AR8327_REG_ATU_FUNC, AR8327_ATU_FUNC_OP_GET_NEXT);
 1123                 arswitch_writereg(sc->sc_dev, AR8327_REG_ATU_DATA0, 0);
 1124                 arswitch_writereg(sc->sc_dev, AR8327_REG_ATU_DATA1, 0);
 1125                 arswitch_writereg(sc->sc_dev, AR8327_REG_ATU_DATA2, 0);
 1126 
 1127                 return (0);
 1128         case 1:
 1129                 DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: reading next\n", __func__);
 1130                 /*
 1131                  * Attempt to read the next address entry; don't modify what
 1132                  * is there in these registers as its used for the next fetch
 1133                  */
 1134                 (void) ar8327_atu_wait_ready(sc);
 1135 
 1136                 /* Begin the next read event; not modifying anything */
 1137                 val = arswitch_readreg(sc->sc_dev, AR8327_REG_ATU_FUNC);
 1138                 val |= AR8327_ATU_FUNC_BUSY;
 1139                 arswitch_writereg(sc->sc_dev, AR8327_REG_ATU_FUNC, val);
 1140 
 1141                 /* Wait for it to complete */
 1142                 (void) ar8327_atu_wait_ready(sc);
 1143 
 1144                 /* Fetch the ethernet address and ATU status */
 1145                 ret0 = arswitch_readreg(sc->sc_dev, AR8327_REG_ATU_DATA0);
 1146                 ret1 = arswitch_readreg(sc->sc_dev, AR8327_REG_ATU_DATA1);
 1147                 ret2 = arswitch_readreg(sc->sc_dev, AR8327_REG_ATU_DATA2);
 1148 
 1149                 /* If the status is zero, then we're done */
 1150                 if (MS(ret2, AR8327_ATU_FUNC_DATA2_STATUS) == 0)
 1151                         return (-1);
 1152 
 1153                 /* MAC address */
 1154                 e->es_macaddr[5] = MS(ret0, AR8327_ATU_DATA0_MAC_ADDR3);
 1155                 e->es_macaddr[4] = MS(ret0, AR8327_ATU_DATA0_MAC_ADDR2);
 1156                 e->es_macaddr[3] = MS(ret0, AR8327_ATU_DATA0_MAC_ADDR1);
 1157                 e->es_macaddr[2] = MS(ret0, AR8327_ATU_DATA0_MAC_ADDR0);
 1158                 e->es_macaddr[0] = MS(ret1, AR8327_ATU_DATA1_MAC_ADDR5);
 1159                 e->es_macaddr[1] = MS(ret1, AR8327_ATU_DATA1_MAC_ADDR4);
 1160 
 1161                 /* Bitmask of ports this entry is for */
 1162                 e->es_portmask = MS(ret1, AR8327_ATU_DATA1_DEST_PORT);
 1163 
 1164                 /* TODO: other flags that are interesting */
 1165 
 1166                 DPRINTF(sc, ARSWITCH_DBG_ATU, "%s: MAC %6D portmask 0x%08x\n",
 1167                     __func__,
 1168                     e->es_macaddr, ":", e->es_portmask);
 1169                 return (0);
 1170         default:
 1171                 return (-1);
 1172         }
 1173         return (-1);
 1174 }
 1175 static int
 1176 ar8327_flush_dot1q_vlan(struct arswitch_softc *sc)
 1177 {
 1178 
 1179         return (ar8327_vlan_op(sc, AR8327_VTU_FUNC1_OP_FLUSH, 0, 0));
 1180 }
 1181 
 1182 static int
 1183 ar8327_purge_dot1q_vlan(struct arswitch_softc *sc, int vid)
 1184 {
 1185 
 1186         return (ar8327_vlan_op(sc, AR8327_VTU_FUNC1_OP_PURGE, vid, 0));
 1187 }
 1188 
 1189 static int
 1190 ar8327_get_dot1q_vlan(struct arswitch_softc *sc, uint32_t *ports,
 1191     uint32_t *untagged_ports, int vid)
 1192 {
 1193         int i, r;
 1194         uint32_t op, reg, val;
 1195 
 1196         op = AR8327_VTU_FUNC1_OP_GET_ONE;
 1197 
 1198         /* Filter out the vid flags; only grab the VLAN ID */
 1199         vid &= 0xfff;
 1200 
 1201         /* XXX TODO: the VTU here stores egress mode - keep, tag, untagged, none */
 1202         r = ar8327_vlan_op(sc, op, vid, 0);
 1203         if (r != 0) {
 1204                 device_printf(sc->sc_dev, "%s: %d: op failed\n", __func__, vid);
 1205         }
 1206 
 1207         reg = arswitch_readreg(sc->sc_dev, AR8327_REG_VTU_FUNC0);
 1208         DPRINTF(sc, ARSWITCH_DBG_REGIO, "%s: %d: reg=0x%08x\n", __func__, vid, reg);
 1209 
 1210         /*
 1211          * If any of the bits are set, update the port mask.
 1212          * Worry about the port config itself when getport() is called.
 1213          */
 1214         *ports = 0;
 1215         for (i = 0; i < AR8327_NUM_PORTS; i++) {
 1216                 val = reg >> AR8327_VTU_FUNC0_EG_MODE_S(i);
 1217                 val = val & 0x3;
 1218                 /* XXX KEEP (unmodified?) */
 1219                 if (val == AR8327_VTU_FUNC0_EG_MODE_TAG) {
 1220                         *ports |= (1 << i);
 1221                 } else if (val == AR8327_VTU_FUNC0_EG_MODE_UNTAG) {
 1222                         *ports |= (1 << i);
 1223                         *untagged_ports |= (1 << i);
 1224                 }
 1225         }
 1226 
 1227         return (0);
 1228 }
 1229 
 1230 static int
 1231 ar8327_set_dot1q_vlan(struct arswitch_softc *sc, uint32_t ports,
 1232     uint32_t untagged_ports, int vid)
 1233 {
 1234         int i;
 1235         uint32_t op, val, mode;
 1236 
 1237         op = AR8327_VTU_FUNC1_OP_LOAD;
 1238         vid &= 0xfff;
 1239 
 1240         DPRINTF(sc, ARSWITCH_DBG_VLAN,
 1241             "%s: vid: %d, ports=0x%08x, untagged_ports=0x%08x\n",
 1242             __func__,
 1243             vid,
 1244             ports,
 1245             untagged_ports);
 1246 
 1247         /*
 1248          * Mark it as valid; and that it should use per-VLAN MAC table,
 1249          * not VID=0 when doing MAC lookups
 1250          */
 1251         val = AR8327_VTU_FUNC0_VALID | AR8327_VTU_FUNC0_IVL;
 1252 
 1253         for (i = 0; i < AR8327_NUM_PORTS; i++) {
 1254                 if ((ports & BIT(i)) == 0)
 1255                         mode = AR8327_VTU_FUNC0_EG_MODE_NOT;
 1256                 else if (untagged_ports & BIT(i))
 1257                         mode = AR8327_VTU_FUNC0_EG_MODE_UNTAG;
 1258                 else
 1259                         mode = AR8327_VTU_FUNC0_EG_MODE_TAG;
 1260 
 1261                 val |= mode << AR8327_VTU_FUNC0_EG_MODE_S(i);
 1262         }
 1263 
 1264         return (ar8327_vlan_op(sc, op, vid, val));
 1265 }
 1266 
 1267 void
 1268 ar8327_attach(struct arswitch_softc *sc)
 1269 {
 1270 
 1271         sc->hal.arswitch_hw_setup = ar8327_hw_setup;
 1272         sc->hal.arswitch_hw_global_setup = ar8327_hw_global_setup;
 1273 
 1274         sc->hal.arswitch_port_init = ar8327_port_init;
 1275 
 1276         sc->hal.arswitch_vlan_getvgroup = ar8327_vlan_getvgroup;
 1277         sc->hal.arswitch_vlan_setvgroup = ar8327_vlan_setvgroup;
 1278         sc->hal.arswitch_port_vlan_setup = ar8327_port_vlan_setup;
 1279         sc->hal.arswitch_port_vlan_get = ar8327_port_vlan_get;
 1280         sc->hal.arswitch_flush_dot1q_vlan = ar8327_flush_dot1q_vlan;
 1281         sc->hal.arswitch_purge_dot1q_vlan = ar8327_purge_dot1q_vlan;
 1282         sc->hal.arswitch_set_dot1q_vlan = ar8327_set_dot1q_vlan;
 1283         sc->hal.arswitch_get_dot1q_vlan = ar8327_get_dot1q_vlan;
 1284 
 1285         sc->hal.arswitch_vlan_init_hw = ar8327_reset_vlans;
 1286         sc->hal.arswitch_vlan_get_pvid = ar8327_get_pvid;
 1287         sc->hal.arswitch_vlan_set_pvid = ar8327_set_pvid;
 1288 
 1289         sc->hal.arswitch_get_port_vlan = ar8327_vlan_get_port;
 1290         sc->hal.arswitch_set_port_vlan = ar8327_vlan_set_port;
 1291 
 1292         sc->hal.arswitch_atu_learn_default = ar8327_atu_learn_default;
 1293         sc->hal.arswitch_atu_flush = ar8327_atu_flush;
 1294         sc->hal.arswitch_atu_flush_port = ar8327_atu_flush_port;
 1295         sc->hal.arswitch_atu_fetch_table = ar8327_atu_fetch_table;
 1296 
 1297         /*
 1298          * Reading the PHY via the MDIO interface currently doesn't
 1299          * work correctly.
 1300          *
 1301          * So for now, just go direct to the PHY registers themselves.
 1302          * This has always worked  on external devices, but not internal
 1303          * devices (AR934x, AR724x, AR933x.)
 1304          */
 1305         sc->hal.arswitch_phy_read = arswitch_readphy_external;
 1306         sc->hal.arswitch_phy_write = arswitch_writephy_external;
 1307 
 1308         /* Set the switch vlan capabilities. */
 1309         sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q |
 1310             ETHERSWITCH_VLAN_PORT | ETHERSWITCH_VLAN_DOUBLE_TAG;
 1311         sc->info.es_nvlangroups = AR8X16_MAX_VLANS;
 1312 }

Cache object: dd747d5a8886e3af9f9a3260d88ee81c


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