arswitch_7240.c revision 235377
190075Sobrien/*-
290075Sobrien * Copyright (c) 2011-2012 Stefan Bethke.
390075Sobrien * Copyright (c) 2012 Adrian Chadd.
490075Sobrien * All rights reserved.
590075Sobrien *
690075Sobrien * Redistribution and use in source and binary forms, with or without
790075Sobrien * modification, are permitted provided that the following conditions
890075Sobrien * are met:
990075Sobrien * 1. Redistributions of source code must retain the above copyright
1090075Sobrien *    notice, this list of conditions and the following disclaimer.
1190075Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1290075Sobrien *    notice, this list of conditions and the following disclaimer in the
1390075Sobrien *    documentation and/or other materials provided with the distribution.
1490075Sobrien *
1590075Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1690075Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1790075Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1890075Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1990075Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2090075Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2190075Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2290075Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2390075Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2490075Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2590075Sobrien * SUCH DAMAGE.
2690075Sobrien *
2790075Sobrien * $FreeBSD: head/sys/dev/etherswitch/arswitch/arswitch_7240.c 235377 2012-05-12 21:08:07Z adrian $
2890075Sobrien */
2990075Sobrien
3090075Sobrien#include <sys/param.h>
3190075Sobrien#include <sys/bus.h>
3290075Sobrien#include <sys/errno.h>
3390075Sobrien#include <sys/kernel.h>
3490075Sobrien#include <sys/module.h>
3590075Sobrien#include <sys/socket.h>
3690075Sobrien#include <sys/sockio.h>
3790075Sobrien#include <sys/sysctl.h>
3890075Sobrien#include <sys/systm.h>
3990075Sobrien
4090075Sobrien#include <net/if.h>
4190075Sobrien#include <net/if_arp.h>
4290075Sobrien#include <net/ethernet.h>
4390075Sobrien#include <net/if_dl.h>
4490075Sobrien#include <net/if_media.h>
4590075Sobrien#include <net/if_types.h>
4690075Sobrien
4790075Sobrien#include <machine/bus.h>
4890075Sobrien#include <dev/iicbus/iic.h>
4990075Sobrien#include <dev/iicbus/iiconf.h>
5090075Sobrien#include <dev/iicbus/iicbus.h>
5190075Sobrien#include <dev/mii/mii.h>
5290075Sobrien#include <dev/mii/miivar.h>
5390075Sobrien#include <dev/etherswitch/mdio.h>
5490075Sobrien
5590075Sobrien#include <dev/etherswitch/etherswitch.h>
5690075Sobrien
5790075Sobrien#include <dev/etherswitch/arswitch/arswitchreg.h>
5890075Sobrien#include <dev/etherswitch/arswitch/arswitchvar.h>
5990075Sobrien#include <dev/etherswitch/arswitch/arswitch_reg.h>
6090075Sobrien#include <dev/etherswitch/arswitch/arswitch_phy.h>	/* XXX for probe */
6190075Sobrien#include <dev/etherswitch/arswitch/arswitch_7240.h>
6290075Sobrien
6390075Sobrien#include "mdio_if.h"
6490075Sobrien#include "miibus_if.h"
6590075Sobrien#include "etherswitch_if.h"
6690075Sobrien
6790075Sobrien/*
6890075Sobrien * AR7240 specific functions
6990075Sobrien */
7090075Sobrienstatic int
7190075Sobrienar7240_hw_setup(struct arswitch_softc *sc)
7290075Sobrien{
7390075Sobrien
7490075Sobrien	/* Enable CPU port; disable mirror port */
7590075Sobrien	arswitch_writereg(sc->sc_dev, AR8X16_REG_CPU_PORT,
7690075Sobrien	    AR8X16_CPU_PORT_EN | AR8X16_CPU_MIRROR_DIS);
7790075Sobrien
7890075Sobrien	/*
7990075Sobrien	 * Let things settle; probing PHY4 doesn't seem reliable
8090075Sobrien	 * without a litle delay.
8190075Sobrien	 */
8290075Sobrien	DELAY(1000);
8390075Sobrien
8490075Sobrien	return (0);
8590075Sobrien}
8690075Sobrien
8790075Sobrien/*
8890075Sobrien * Initialise other global values for the AR7240.
8990075Sobrien */
9090075Sobrienstatic int
9190075Sobrienar7240_hw_global_setup(struct arswitch_softc *sc)
9290075Sobrien{
9390075Sobrien
9490075Sobrien	/* Setup TAG priority mapping */
9590075Sobrien	arswitch_writereg(sc->sc_dev, AR8X16_REG_TAG_PRIO, 0xfa50);
9690075Sobrien
9790075Sobrien	/* Enable broadcast frames transmitted to the CPU */
9890075Sobrien	arswitch_writereg(sc->sc_dev, AR8X16_REG_FLOOD_MASK,
9990075Sobrien	    AR8X16_FLOOD_MASK_BCAST_TO_CPU | 0x003f003f);
10090075Sobrien
10190075Sobrien	/* Setup MTU */
10290075Sobrien	arswitch_modifyreg(sc->sc_dev, AR8X16_REG_GLOBAL_CTRL,
10390075Sobrien	    AR7240_GLOBAL_CTRL_MTU_MASK,
10490075Sobrien	    SM(1536, AR7240_GLOBAL_CTRL_MTU_MASK));
10590075Sobrien
10690075Sobrien	/* Service Tag */
10790075Sobrien	arswitch_modifyreg(sc->sc_dev, AR8X16_REG_SERVICE_TAG,
10890075Sobrien	    AR8X16_SERVICE_TAG_MASK, 0);
10990075Sobrien
11090075Sobrien	return (0);
11190075Sobrien}
11290075Sobrien
11390075Sobrien/*
11490075Sobrien * The AR7240 probes the same as the AR8216.
11590075Sobrien *
11690075Sobrien * However, the support is slightly different.
11790075Sobrien *
11890075Sobrien * So instead of checking the PHY revision or mask register contents,
11990075Sobrien * we simply fall back to a hint check.
12090075Sobrien */
12190075Sobrienint
12290075Sobrienar7240_probe(device_t dev)
12390075Sobrien{
12490075Sobrien	int is_7240 = 0;
12590075Sobrien
12690075Sobrien	if (resource_int_value(device_get_name(dev), device_get_unit(dev),
12790075Sobrien	    "is_7240", &is_7240) != 0)
12890075Sobrien		return (ENXIO);
12990075Sobrien
13090075Sobrien	if (is_7240 == 0)
13190075Sobrien		return (ENXIO);
13290075Sobrien
13390075Sobrien	return (0);
13490075Sobrien}
13590075Sobrien
13690075Sobrienvoid
13790075Sobrienar7240_attach(struct arswitch_softc *sc)
13890075Sobrien{
13990075Sobrien
14090075Sobrien	sc->hal.arswitch_hw_setup = ar7240_hw_setup;
14190075Sobrien	sc->hal.arswitch_hw_global_setup = ar7240_hw_global_setup;
14290075Sobrien}
14390075Sobrien