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; }
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; }