static ssize_t mv_switch_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	const char *name = attr->attr.name;
	int off = 0;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	if (!strcmp(name, "stats"))
		mv_switch_stats_print();
	else if (!strcmp(name, "status"))
		mv_switch_status_print();
	else
		off = mv_switch_help(buf);

	return off;
}
Exemplo n.º 2
0
int mv_switch_init(int mtu, unsigned int switch_ports_mask)
{
	unsigned int p;
	unsigned char cnt;
	GT_LPORT port_list[MAX_SWITCH_PORTS];

	if (qd_dev == NULL) {
		printk(KERN_ERR "%s: qd_dev not initialized, call mv_switch_load() first\n", __func__);
		return -1;
	}

	/* general Switch initialization - relevant for all Switch devices */

	/* disable all ports */
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(switch_ports_mask, p))
			if (gstpSetPortState(qd_dev, p, GT_PORT_DISABLE) != GT_OK) {
				printk(KERN_ERR "gstpSetPortState failed\n");
				return -1;
			}
	}

	/* flush All counters for all ports */
	if (gstatsFlushAll(qd_dev) != GT_OK)
		printk(KERN_ERR "gstatsFlushAll failed\n");

	/* set all ports not to unmodify the vlan tag on egress */
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(switch_ports_mask, p)) {
			if (gprtSetEgressMode(qd_dev, p, GT_UNMODIFY_EGRESS) != GT_OK) {
				printk(KERN_ERR "gprtSetEgressMode GT_UNMODIFY_EGRESS failed\n");
				return -1;
			}
		}
	}

	/* initializes the PVT Table (cross-chip port based VLAN) to all one's (initial state) */
	if (gpvtInitialize(qd_dev) != GT_OK) {
		printk(KERN_ERR "gpvtInitialize failed\n");
		return -1;
	}

	/* set all ports to work in Normal mode */
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(switch_ports_mask, p)) {
			if (gprtSetFrameMode(qd_dev, p, GT_FRAME_MODE_NORMAL) != GT_OK) {
				printk(KERN_ERR "gprtSetFrameMode GT_FRAME_MODE_NORMAL failed\n");
				return -1;
			}
		}
	}

	/* set priorities rules */
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(switch_ports_mask, p)) {
			/* default port priority to queue zero */
			if (gcosSetPortDefaultTc(qd_dev, p, 0) != GT_OK)
				printk(KERN_ERR "gcosSetPortDefaultTc failed (port %d)\n", p);

			/* enable IP TOS Prio */
			if (gqosIpPrioMapEn(qd_dev, p, GT_TRUE) != GT_OK)
				printk(KERN_ERR "gqosIpPrioMapEn failed (port %d)\n", p);

			/* set IP QoS */
			if (gqosSetPrioMapRule(qd_dev, p, GT_FALSE) != GT_OK)
				printk(KERN_ERR "gqosSetPrioMapRule failed (port %d)\n", p);

			/* disable Vlan QoS Prio */
			if (gqosUserPrioMapEn(qd_dev, p, GT_FALSE) != GT_OK)
				printk(KERN_ERR "gqosUserPrioMapEn failed (port %d)\n", p);
		}
	}

	/* specific Switch initialization according to Switch ID */
	switch (qd_dev->deviceId) {
	case GT_88E6161:
	case GT_88E6165:
	case GT_88E6171:
	case GT_88E6351:
	case GT_88E6172:
	case GT_88E6176:
		/* set Header Mode in all ports to False */
		for (p = 0; p < qd_dev->numOfPorts; p++) {
			if (MV_BIT_CHECK(switch_ports_mask, p)) {
				if (gprtSetHeaderMode(qd_dev, p, GT_FALSE) != GT_OK) {
					printk(KERN_ERR "gprtSetHeaderMode GT_FALSE failed\n");
					return -1;
				}
			}
		}

		if (gprtSetHeaderMode(qd_dev, qd_cpu_port, GT_TRUE) != GT_OK) {
			printk(KERN_ERR "gprtSetHeaderMode GT_TRUE failed\n");
			return -1;
		}

		mv_switch_jumbo_mode_set(mtu);
		break;

	default:
		printk(KERN_ERR "Unsupported Switch. Switch ID is 0x%X.\n", qd_dev->deviceId);
		return -1;
	}

	/* The switch CPU port is not part of the VLAN, but rather connected by tunneling to each */
	/* of the VLAN's ports. Our MAC addr will be added during start operation to the VLAN DB  */
	/* at switch level to forward packets with this DA to CPU port.                           */
	SWITCH_DBG(SWITCH_DBG_LOAD, ("Enabling Tunneling on ports: "));
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(switch_ports_mask, p) && (p != qd_cpu_port)) {
			if (gprtSetVlanTunnel(qd_dev, p, GT_TRUE) != GT_OK) {
				printk(KERN_ERR "gprtSetVlanTunnel failed (port %d)\n", p);
				return -1;
			} else {
				SWITCH_DBG(SWITCH_DBG_LOAD, ("%d ", p));
			}
		}
	}
	SWITCH_DBG(SWITCH_DBG_LOAD, ("\n"));

	/* set cpu-port with port-based vlan to all other ports */
	SWITCH_DBG(SWITCH_DBG_LOAD, ("cpu port-based vlan:"));
	for (p = 0, cnt = 0; p < qd_dev->numOfPorts; p++) {
		if (p != qd_cpu_port) {
			SWITCH_DBG(SWITCH_DBG_LOAD, ("%d ", p));
			port_list[cnt] = p;
			cnt++;
		}
	}
	SWITCH_DBG(SWITCH_DBG_LOAD, ("\n"));
	if (gvlnSetPortVlanPorts(qd_dev, qd_cpu_port, port_list, cnt) != GT_OK) {
		printk(KERN_ERR "gvlnSetPortVlanPorts failed\n");
		return -1;
	}

	if (gfdbFlush(qd_dev, GT_FLUSH_ALL) != GT_OK)
		printk(KERN_ERR "gfdbFlush failed\n");

	mv_switch_link_detection_init();

	/* Configure Ethernet related LEDs, currently according to Switch ID */
	switch (qd_dev->deviceId) {
	case GT_88E6161:
	case GT_88E6165:
	case GT_88E6171:
	case GT_88E6351:
	case GT_88E6172:
	case GT_88E6176:
		break;		/* do nothing */

	default:
		for (p = 0; p < qd_dev->numOfPorts; p++) {
			if ((p != qd_cpu_port) && ((p))) {
				if (gprtSetPhyReg(qd_dev, p, 22, 0x1FFA)) {
					/* Configure Register 22 LED0 to 0xA for Link/Act */
					printk(KERN_ERR "gprtSetPhyReg failed (port=%d)\n", p);
				}
			}
		}
		break;
	}

	/* enable all relevant ports (ports connected to the MAC or external ports) */
	for (p = 0; p < qd_dev->numOfPorts; p++) {
		if (MV_BIT_CHECK(switch_ports_mask, p)) {
			if ((mvBoardSwitchPortMap(MV_SWITCH_DEF_INDEX, p) != -1) ||
			    (mvBoardSwitchConnectedPortGet(MV_ETH_PORT_0) == p) ||
			    (mvBoardSwitchConnectedPortGet(MV_ETH_PORT_1) == p)) {
				if (gstpSetPortState(qd_dev, p, GT_PORT_FORWARDING) != GT_OK) {
					printk(KERN_ERR "gstpSetPortState failed\n");
					return -1;
				}
			}
		}
	}

#ifdef SWITCH_DEBUG
	/* for debug: */
	mv_switch_status_print();
#endif

	return 0;
}