示例#1
0
/*
 * Initialise other global values, for the AR8316.
 */
static int
ar8316_hw_global_setup(struct arswitch_softc *sc)
{

	arswitch_writereg(sc->sc_dev, 0x38, AR8X16_MAGIC);

	/* Enable CPU port and disable mirror port. */
	arswitch_writereg(sc->sc_dev, AR8X16_REG_CPU_PORT,
	    AR8X16_CPU_PORT_EN | AR8X16_CPU_MIRROR_DIS);

	/* Setup TAG priority mapping. */
	arswitch_writereg(sc->sc_dev, AR8X16_REG_TAG_PRIO, 0xfa50);

	/* Enable ARP frame acknowledge. */
	arswitch_modifyreg(sc->sc_dev, AR8X16_REG_AT_CTRL, 0,
	    AR8X16_AT_CTRL_ARP_EN);

	/*
	 * Flood address table misses to all ports, and enable forwarding of
	 * broadcasts to the cpu port.
	 */
	arswitch_writereg(sc->sc_dev, AR8X16_REG_FLOOD_MASK,
	    AR8X16_FLOOD_MASK_BCAST_TO_CPU | 0x003f003f);

	/* Enable jumbo frames. */
	arswitch_modifyreg(sc->sc_dev, AR8X16_REG_GLOBAL_CTRL,
	    AR8316_GLOBAL_CTRL_MTU_MASK, 9018 + 8 + 2);

	/* Setup service TAG. */
	arswitch_modifyreg(sc->sc_dev, AR8X16_REG_SERVICE_TAG,
	    AR8X16_SERVICE_TAG_MASK, 0);

	return (0);
}
示例#2
0
/*
 * Initialise other global values for the AR7240.
 */
static int
ar7240_hw_global_setup(struct arswitch_softc *sc)
{

	/* Enable CPU port; disable mirror port */
	arswitch_writereg(sc->sc_dev, AR8X16_REG_CPU_PORT,
	    AR8X16_CPU_PORT_EN | AR8X16_CPU_MIRROR_DIS);

	/* Setup TAG priority mapping */
	arswitch_writereg(sc->sc_dev, AR8X16_REG_TAG_PRIO, 0xfa50);

	/* Enable broadcast frames transmitted to the CPU */
	arswitch_writereg(sc->sc_dev, AR8X16_REG_FLOOD_MASK,
	    AR8X16_FLOOD_MASK_BCAST_TO_CPU | 0x003f003f);

	/* Setup MTU */
	arswitch_modifyreg(sc->sc_dev, AR8X16_REG_GLOBAL_CTRL,
	    AR7240_GLOBAL_CTRL_MTU_MASK,
	    SM(1536, AR7240_GLOBAL_CTRL_MTU_MASK));

	/* Service Tag */
	arswitch_modifyreg(sc->sc_dev, AR8X16_REG_SERVICE_TAG,
	    AR8X16_SERVICE_TAG_MASK, 0);

	return (0);
}
示例#3
0
/*
 * Initialise other global values, for the AR8327.
 */
static int
ar8327_hw_global_setup(struct arswitch_softc *sc)
{
	uint32_t t;

	/* enable CPU port and disable mirror port */
	t = AR8327_FWD_CTRL0_CPU_PORT_EN |
	    AR8327_FWD_CTRL0_MIRROR_PORT;
	arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL0, t);

	/* forward multicast and broadcast frames to CPU */
	t = (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_UC_FLOOD_S) |
	    (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_MC_FLOOD_S) |
	    (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_BC_FLOOD_S);
	arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL1, t);

	/* enable jumbo frames */
	/* XXX need to macro-shift the value! */
	arswitch_modifyreg(sc->sc_dev, AR8327_REG_MAX_FRAME_SIZE,
	    AR8327_MAX_FRAME_SIZE_MTU, 9018 + 8 + 2);

	/* Enable MIB counters */
	arswitch_modifyreg(sc->sc_dev, AR8327_REG_MODULE_EN,
	    AR8327_MODULE_EN_MIB, AR8327_MODULE_EN_MIB);

	return (0);
}
示例#4
0
static void
ar8327_reset_vlans(struct arswitch_softc *sc)
{
	int i;
	uint32_t mode, t;

	/*
	 * Disable mirroring.
	 */
	arswitch_modifyreg(sc->sc_dev, AR8327_REG_FWD_CTRL0,
	    AR8327_FWD_CTRL0_MIRROR_PORT,
	    (0xF << AR8327_FWD_CTRL0_MIRROR_PORT_S));

	/*
	 * For now, let's default to one portgroup, just so traffic
	 * flows.  All ports can see other ports.
	 */
	for (i = 0; i < AR8327_NUM_PORTS; i++) {
		/* set pvid = i */
		t = i << AR8327_PORT_VLAN0_DEF_SVID_S;
		t |= i << AR8327_PORT_VLAN0_DEF_CVID_S;
		arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(i), t);

		/* set egress == out_keep */
		mode = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH;

		t = AR8327_PORT_VLAN1_PORT_VLAN_PROP;
		t |= mode << AR8327_PORT_VLAN1_OUT_MODE_S;
		arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN1(i), t);

		/* Set ingress = out_keep; members = 0x3f for all ports */

		t = (0x3f & ~(1 << i));	/* all ports besides us */
		t |= AR8327_PORT_LOOKUP_LEARN;

		/* in_port_only, forward */
		t |= AR8X16_PORT_VLAN_MODE_PORT_ONLY << AR8327_PORT_LOOKUP_IN_MODE_S;
		t |= AR8X16_PORT_CTRL_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
		arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(i), t);

		/*
		 * Disable port mirroring entirely.
		 */
		arswitch_modifyreg(sc->sc_dev,
		    AR8327_REG_PORT_LOOKUP(i),
		    AR8327_PORT_LOOKUP_ING_MIRROR_EN,
		    0);
		arswitch_modifyreg(sc->sc_dev,
		    AR8327_REG_PORT_HOL_CTRL1(i),
		    AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN,
		    0);
	}
}
示例#5
0
static void
ar8327_port_disable_mirror(struct arswitch_softc *sc, int port)
{

	arswitch_modifyreg(sc->sc_dev,
	    AR8327_REG_PORT_LOOKUP(port),
	    AR8327_PORT_LOOKUP_ING_MIRROR_EN,
	    0);
	arswitch_modifyreg(sc->sc_dev,
	    AR8327_REG_PORT_HOL_CTRL1(port),
	    AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN,
	    0);
}
示例#6
0
/*
 * Initialise other global values, for the AR8327.
 */
static int
ar8327_hw_global_setup(struct arswitch_softc *sc)
{
	uint32_t t;

	/* enable CPU port and disable mirror port */
	t = AR8327_FWD_CTRL0_CPU_PORT_EN |
	    AR8327_FWD_CTRL0_MIRROR_PORT;
	arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL0, t);

	/* forward multicast and broadcast frames to CPU */
	t = (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_UC_FLOOD_S) |
	    (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_MC_FLOOD_S) |
	    (AR8327_PORTS_ALL << AR8327_FWD_CTRL1_BC_FLOOD_S);
	arswitch_writereg(sc->sc_dev, AR8327_REG_FWD_CTRL1, t);

	/* enable jumbo frames */
	/* XXX need to macro-shift the value! */
	arswitch_modifyreg(sc->sc_dev, AR8327_REG_MAX_FRAME_SIZE,
	    AR8327_MAX_FRAME_SIZE_MTU, 9018 + 8 + 2);

	/* Enable MIB counters */
	arswitch_modifyreg(sc->sc_dev, AR8327_REG_MODULE_EN,
	    AR8327_MODULE_EN_MIB, AR8327_MODULE_EN_MIB);

	/* Disable EEE on all ports due to stability issues */
	t = arswitch_readreg(sc->sc_dev, AR8327_REG_EEE_CTRL);
	t |= AR8327_EEE_CTRL_DISABLE_PHY(0) |
	    AR8327_EEE_CTRL_DISABLE_PHY(1) |
	    AR8327_EEE_CTRL_DISABLE_PHY(2) |
	    AR8327_EEE_CTRL_DISABLE_PHY(3) |
	    AR8327_EEE_CTRL_DISABLE_PHY(4);
	arswitch_writereg(sc->sc_dev, AR8327_REG_EEE_CTRL, t);

	/* Set the right number of ports */
	/* GMAC0 (CPU), GMAC1..5 (PHYs), GMAC6 (CPU) */
	sc->info.es_nports = 7;

	return (0);
}
示例#7
0
static int
ar8327_vlan_set_port(struct arswitch_softc *sc, uint32_t ports, int vid)
{
	int err, port;

	ARSWITCH_LOCK_ASSERT(sc, MA_OWNED);

	/* For port based vlans the vlanid is the same as the port index. */
	port = vid & ETHERSWITCH_VID_MASK;

	err = arswitch_modifyreg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(port),
	    0x7f, /* vlan membership mask */
	    (ports & 0x7f));

	if (err)
		return (err);
	return (0);
}
示例#8
0
/*
 * Initialise other global values, for the AR8316.
 */
static int
ar8316_hw_global_setup(struct arswitch_softc *sc)
{

	arswitch_writereg(sc->sc_dev, 0x38, 0xc000050e);

	/*
	 * Flood address table misses to all ports, and enable forwarding of
	 * broadcasts to the cpu port.
	 */
	arswitch_writereg(sc->sc_dev, AR8X16_REG_FLOOD_MASK,
	    AR8X16_FLOOD_MASK_BCAST_TO_CPU | 0x003f003f);

	arswitch_modifyreg(sc->sc_dev, AR8X16_REG_GLOBAL_CTRL,
	    AR8316_GLOBAL_CTRL_MTU_MASK, 9018 + 8 + 2);

	return (0);
}
示例#9
0
static void
ar8327_reset_vlans(struct arswitch_softc *sc)
{
	int i;
	uint32_t t;
	int ports;

	ARSWITCH_LOCK_ASSERT(sc, MA_NOTOWNED);
	ARSWITCH_LOCK(sc);

	/* Clear the existing VLAN configuration */
	memset(sc->vid, 0, sizeof(sc->vid));

	/*
	 * Disable mirroring.
	 */
	arswitch_modifyreg(sc->sc_dev, AR8327_REG_FWD_CTRL0,
	    AR8327_FWD_CTRL0_MIRROR_PORT,
	    (0xF << AR8327_FWD_CTRL0_MIRROR_PORT_S));

	/*
	 * XXX TODO: disable any Q-in-Q port configuration,
	 * tagging, egress filters, etc.
	 */

	/*
	 * For now, let's default to one portgroup, just so traffic
	 * flows.  All ports can see other ports. There are two CPU GMACs
	 * (GMAC0, GMAC6), GMAC1..GMAC5 are external PHYs.
	 *
	 * (ETHERSWITCH_VLAN_PORT)
	 */
	ports = 0x7f;

	/*
	 * XXX TODO: set things up correctly for vlans!
	 */
	for (i = 0; i < AR8327_NUM_PORTS; i++) {
		int egress, ingress;

		if (sc->vlan_mode == ETHERSWITCH_VLAN_PORT) {
			sc->vid[i] = i | ETHERSWITCH_VID_VALID;
			/* set egress == out_keep */
			ingress = AR8X16_PORT_VLAN_MODE_PORT_ONLY;
			/* in_port_only, forward */
			egress = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH;
		} else if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) {
			ingress = AR8X16_PORT_VLAN_MODE_SECURE;
			egress = AR8327_PORT_VLAN1_OUT_MODE_UNMOD;
		} else {
			/* set egress == out_keep */
			ingress = AR8X16_PORT_VLAN_MODE_PORT_ONLY;
			/* in_port_only, forward */
			egress = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH;
		}

		/* set pvid = 1; there's only one vlangroup to start with */
		t = 1 << AR8327_PORT_VLAN0_DEF_SVID_S;
		t |= 1 << AR8327_PORT_VLAN0_DEF_CVID_S;
		arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN0(i), t);

		t = AR8327_PORT_VLAN1_PORT_VLAN_PROP;
		t |= egress << AR8327_PORT_VLAN1_OUT_MODE_S;
		arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_VLAN1(i), t);

		/* Ports can see other ports */
		/* XXX not entirely true for dot1q? */
		t = (ports & ~(1 << i));	/* all ports besides us */
		t |= AR8327_PORT_LOOKUP_LEARN;

		t |= ingress << AR8327_PORT_LOOKUP_IN_MODE_S;
		t |= AR8X16_PORT_CTRL_STATE_FORWARD << AR8327_PORT_LOOKUP_STATE_S;
		arswitch_writereg(sc->sc_dev, AR8327_REG_PORT_LOOKUP(i), t);
	}

	/*
	 * Disable port mirroring entirely.
	 */
	for (i = 0; i < AR8327_NUM_PORTS; i++) {
		ar8327_port_disable_mirror(sc, i);
	}

	/*
	 * If dot1q - set pvid; dot1q, etc.
	 */
	if (sc->vlan_mode == ETHERSWITCH_VLAN_DOT1Q) {
		sc->vid[0] = 1;
		for (i = 0; i < AR8327_NUM_PORTS; i++) {
			/* Each port - pvid 1 */
			sc->hal.arswitch_vlan_set_pvid(sc, i, sc->vid[0]);
		}
		/* Initialise vlan1 - all ports, untagged */
		sc->hal.arswitch_set_dot1q_vlan(sc, ports, ports, sc->vid[0]);
		sc->vid[0] |= ETHERSWITCH_VID_VALID;
	}

	ARSWITCH_UNLOCK(sc);
}