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_9340.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) 2013 Adrian Chadd <adrian@FreeBSD.org>
    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>      /* XXX for probe */
   63 #include <dev/etherswitch/arswitch/arswitch_9340.h>
   64 
   65 #include "mdio_if.h"
   66 #include "miibus_if.h"
   67 #include "etherswitch_if.h"
   68 
   69 /*
   70  * AR9340 specific functions
   71  */
   72 static int
   73 ar9340_hw_setup(struct arswitch_softc *sc)
   74 {
   75 
   76         return (0);
   77 }
   78 
   79 static int
   80 ar9340_atu_learn_default(struct arswitch_softc *sc)
   81 {
   82 
   83         /* Enable aging, MAC replacing */
   84         arswitch_writereg(sc->sc_dev, AR934X_REG_AT_CTRL,
   85             0x2b /* 5 min age time */ |
   86             AR934X_AT_CTRL_AGE_EN |
   87             AR934X_AT_CTRL_LEARN_CHANGE);
   88 
   89         /* Enable ARP frame acknowledge */
   90         arswitch_modifyreg(sc->sc_dev, AR934X_REG_QM_CTRL,
   91             AR934X_QM_CTRL_ARP_EN, AR934X_QM_CTRL_ARP_EN);
   92 
   93 #if 0
   94         /* Copy frame to CPU port, not just redirect it */
   95         arswitch_modifyreg(sc->sc_dev, AR934X_REG_QM_CTRL,
   96             AR934X_QM_CTRL_ARP_COPY_EN, AR934X_QM_CTRL_ARP_COPY_EN);
   97 #endif
   98 
   99         return (0);
  100 }
  101 
  102 /*
  103  * Initialise other global values for the AR9340.
  104  */
  105 static int
  106 ar9340_hw_global_setup(struct arswitch_softc *sc)
  107 {
  108 
  109         ARSWITCH_LOCK(sc);
  110 
  111         /* Enable CPU port; disable mirror port */
  112         arswitch_writereg(sc->sc_dev, AR8X16_REG_CPU_PORT,
  113             AR8X16_CPU_PORT_EN | AR8X16_CPU_MIRROR_DIS);
  114 
  115         /* Setup TAG priority mapping */
  116         arswitch_writereg(sc->sc_dev, AR8X16_REG_TAG_PRIO, 0xfa50);
  117 
  118         /* Enable Broadcast frames transmitted to the CPU */
  119         arswitch_modifyreg(sc->sc_dev, AR934X_REG_FLOOD_MASK,
  120             AR934X_FLOOD_MASK_BC_DP(0),
  121             AR934X_FLOOD_MASK_BC_DP(0));
  122         arswitch_modifyreg(sc->sc_dev, AR934X_REG_FLOOD_MASK,
  123             AR934X_FLOOD_MASK_MC_DP(0),
  124             AR934X_FLOOD_MASK_MC_DP(0));
  125 #if 0
  126         arswitch_modifyreg(sc->sc_dev, AR934X_REG_FLOOD_MASK,
  127             AR934X_FLOOD_MASK_UC_DP(0),
  128             AR934X_FLOOD_MASK_UC_DP(0));
  129 #endif
  130 
  131         /* Enable MIB counters */
  132         arswitch_modifyreg(sc->sc_dev, AR8X16_REG_MIB_FUNC0,
  133             AR934X_MIB_ENABLE, AR934X_MIB_ENABLE);
  134 
  135         /* Setup MTU */
  136         arswitch_modifyreg(sc->sc_dev, AR8X16_REG_GLOBAL_CTRL,
  137             AR7240_GLOBAL_CTRL_MTU_MASK,
  138             SM(1536, AR7240_GLOBAL_CTRL_MTU_MASK));
  139 
  140         /* Service Tag */
  141         arswitch_modifyreg(sc->sc_dev, AR8X16_REG_SERVICE_TAG,
  142             AR8X16_SERVICE_TAG_MASK, 0);
  143 
  144         /* Settle time */
  145         DELAY(1000);
  146 
  147         /*
  148          * Check PHY mode bits.
  149          *
  150          * This dictates whether the connected port is to be wired
  151          * up via GMII or MII.  I'm not sure why - this is an internal
  152          * wiring issue.
  153          */
  154         if (sc->is_gmii) {
  155                 device_printf(sc->sc_dev, "%s: GMII\n", __func__);
  156                 arswitch_modifyreg(sc->sc_dev, AR934X_REG_OPER_MODE0,
  157                     AR934X_OPER_MODE0_MAC_GMII_EN,
  158                     AR934X_OPER_MODE0_MAC_GMII_EN);
  159         } else if (sc->is_mii) {
  160                 device_printf(sc->sc_dev, "%s: MII\n", __func__);
  161                 arswitch_modifyreg(sc->sc_dev, AR934X_REG_OPER_MODE0,
  162                     AR934X_OPER_MODE0_PHY_MII_EN,
  163                     AR934X_OPER_MODE0_PHY_MII_EN);
  164         } else {
  165                 device_printf(sc->sc_dev, "%s: need is_gmii or is_mii set\n",
  166                     __func__);
  167                 ARSWITCH_UNLOCK(sc);
  168                 return (ENXIO);
  169         }
  170 
  171         /*
  172          * Whether to connect PHY 4 via MII (ie a switch port) or
  173          * treat it as a CPU port.
  174          */
  175         if (sc->phy4cpu) {
  176                 device_printf(sc->sc_dev, "%s: PHY4 - CPU\n", __func__);
  177                 arswitch_modifyreg(sc->sc_dev, AR934X_REG_OPER_MODE1,
  178                     AR934X_REG_OPER_MODE1_PHY4_MII_EN,
  179                     AR934X_REG_OPER_MODE1_PHY4_MII_EN);
  180                 sc->info.es_nports = 5;
  181         } else {
  182                 device_printf(sc->sc_dev, "%s: PHY4 - Local\n", __func__);
  183                 sc->info.es_nports = 6;
  184         }
  185 
  186         /* Settle time */
  187         DELAY(1000);
  188 
  189         ARSWITCH_UNLOCK(sc);
  190         return (0);
  191 }
  192 
  193 /*
  194  * The AR9340 switch probes (almost) the same as the AR7240 on-chip switch.
  195  *
  196  * However, the support is slightly different.
  197  *
  198  * So instead of checking the PHY revision or mask register contents,
  199  * we simply fall back to a hint check.
  200  */
  201 int
  202 ar9340_probe(device_t dev)
  203 {
  204         int is_9340 = 0;
  205 
  206         if (resource_int_value(device_get_name(dev), device_get_unit(dev),
  207             "is_9340", &is_9340) != 0)
  208                 return (ENXIO);
  209 
  210         if (is_9340 == 0)
  211                 return (ENXIO);
  212 
  213         return (0);
  214 }
  215 
  216 void
  217 ar9340_attach(struct arswitch_softc *sc)
  218 {
  219 
  220         sc->hal.arswitch_hw_setup = ar9340_hw_setup;
  221         sc->hal.arswitch_hw_global_setup = ar9340_hw_global_setup;
  222         sc->hal.arswitch_atu_learn_default = ar9340_atu_learn_default;
  223         /*
  224          * Note: the ar9340 table fetch code/registers matche
  225          * the ar8216/ar8316 for now because we're not supporting
  226          * static entry programming that includes any of the extra
  227          * bits in the AR9340.
  228          */
  229 
  230         /* Set the switch vlan capabilities. */
  231         sc->info.es_vlan_caps = ETHERSWITCH_VLAN_DOT1Q |
  232             ETHERSWITCH_VLAN_PORT | ETHERSWITCH_VLAN_DOUBLE_TAG;
  233         sc->info.es_nvlangroups = AR8X16_MAX_VLANS;
  234 }

Cache object: a3148c60c24cc8ce4944d762927eee8c


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