static int mv_gw_switch_init(int port) { unsigned int i, p; unsigned char cnt; GT_LPORT port_list[MAX_SWITCH_PORTS]; struct mv_vlan_cfg *nc; GT_JUMBO_MODE jumbo_mode; GT_DEV_EVENT gt_event; printk("init switch layer... "); if (!qd_dev) { printk("qd_dev is NULL in %s\n",__func__); return -1; } ETH_DBG( ETH_DBG_LOAD, ("Device ID : 0x%x\n",qd_dev->deviceId)); ETH_DBG( ETH_DBG_LOAD, ("Base Reg Addr : 0x%x\n",qd_dev->baseRegAddr)); ETH_DBG( ETH_DBG_LOAD, ("No. of Ports : %d\n",qd_dev->numOfPorts)); ETH_DBG( ETH_DBG_LOAD, ("CPU Ports : %ld\n",qd_dev->cpuPortNum)); /* disable all ports */ for(p=0; p<qd_dev->numOfPorts; p++) { gstpSetPortState(qd_dev, p, GT_PORT_DISABLE); } /* set all ports to not modify the vlan tag on egress */ for(i=0; i<qd_dev->numOfPorts; i++) { if(gprtSetEgressMode(qd_dev, i, GT_UNMODIFY_EGRESS) != GT_OK) { printk("gprtSetEgressMode GT_UNMODIFY_EGRESS failed\n"); return -1; } } /* initialize Switch according to Switch ID */ switch (qd_dev->deviceId) { case GT_88E6065: /* set CPU port number */ if(gsysSetCPUPort(qd_dev, SWITCH_PORT_CPU) != GT_OK) { printk("gsysSetCPUPort failed\n"); return -1; } /* flush all counters for all ports */ if(gstatsFlushAll(qd_dev) != GT_OK) printk("gstatsFlushAll failed\n"); /* use Marvell Header mode */ if(gprtSetHeaderMode(qd_dev, SWITCH_PORT_CPU, GT_TRUE) != GT_OK) { printk("gprtSetHeaderMode GT_TRUE failed\n"); return -1; } /* init counters */ if(gprtClearAllCtr(qd_dev) != GT_OK) printk("gprtClearAllCtr failed\n"); if(gprtSetCtrMode(qd_dev, GT_CTR_ALL) != GT_OK) printk("gprtSetCtrMode failed\n"); break; case GT_88E6061: /* set CPU port number */ if(gsysSetCPUPort(qd_dev, SWITCH_PORT_CPU) != GT_OK) { printk("gsysSetCPUPort failed\n"); return -1; } /* use Marvell Header mode */ if(gprtSetHeaderMode(qd_dev,SWITCH_PORT_CPU,GT_TRUE) != GT_OK) { printk("gprtSetHeaderMode GT_TRUE failed\n"); return -1; } /* init counters */ if(gprtClearAllCtr(qd_dev) != GT_OK) printk("gprtClearAllCtr failed\n"); if(gprtSetCtrMode(qd_dev, GT_CTR_ALL) != GT_OK) printk("gprtSetCtrMode failed\n"); break; case GT_88E6161: case GT_88E6165: case GT_88E6171: /* flush all counters for all ports */ if(gstatsFlushAll(qd_dev) != GT_OK) { printk("gstatsFlushAll failed\n"); } /* use Marvell Header mode */ if(gprtSetHeaderMode(qd_dev,SWITCH_PORT_CPU,GT_TRUE) != GT_OK) { printk("gprtSetHeaderMode GT_TRUE failed\n"); return -1; } /* set all ports to work in Normal mode (non-DSA tag) */ for(i=0; i<qd_dev->numOfPorts; i++) { if (gprtSetFrameMode(qd_dev, i, GT_FRAME_MODE_NORMAL) != GT_OK) { printk("gprtSetFrameMode to GT_FRAME_MODE_NORMAL on port %d failed\n", i); return -1; } } /* Setup jumbo frames mode */ if( MV_RX_BUF_SIZE(gtw_config.mtu) <= 1522) jumbo_mode = GT_JUMBO_MODE_1522; else if( MV_RX_BUF_SIZE(gtw_config.mtu) <= 2048) jumbo_mode = GT_JUMBO_MODE_2048; else jumbo_mode = GT_JUMBO_MODE_10240; for(i=0; i<qd_dev->numOfPorts; i++) { if(gsysSetJumboMode(qd_dev, i, jumbo_mode) != GT_OK) { printk("gsysSetJumboMode %d failed\n",jumbo_mode); return -1; } } break; default: printk("Unsupported Switch. Switch ID is 0x%X.\n", qd_dev->deviceId); return -1; } /* set priorities rules */ for(i=0; i<qd_dev->numOfPorts; i++) { /* default port priority to queue zero */ if(gcosSetPortDefaultTc(qd_dev, i, 0) != GT_OK) printk("gcosSetPortDefaultTc failed (port %d)\n", i); /* enable IP TOS Prio */ if(gqosIpPrioMapEn(qd_dev, i, GT_TRUE) != GT_OK) printk("gqosIpPrioMapEn failed (port %d)\n",i); /* set IP QoS */ if(gqosSetPrioMapRule(qd_dev, i, GT_FALSE) != GT_OK) printk("gqosSetPrioMapRule failed (port %d)\n",i); /* disable Vlan QoS Prio */ if(gqosUserPrioMapEn(qd_dev, i, GT_FALSE) != GT_OK) printk("gqosUserPrioMapEn failed (port %d)\n",i); /* Set force flow control to FALSE for all ports */ if(gprtSetForceFc(qd_dev, i, GT_FALSE) != GT_OK) printk("gprtSetForceFc failed (port %d)\n",i); } /* 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. */ ETH_DBG( ETH_DBG_LOAD, ("Enabling Tunneling on ports: ")); for(i=0; i<qd_dev->numOfPorts; i++) { if(i != SWITCH_PORT_CPU) { if(gprtSetVlanTunnel(qd_dev, i, GT_TRUE) != GT_OK) { printk("gprtSetVlanTunnel failed (port %d)\n",i); return -1; } else { ETH_DBG( ETH_DBG_LOAD, ("%d ",i)); } } } ETH_DBG( ETH_DBG_LOAD, ("\n")); /* configure ports (excluding CPU port) for each network interface (VLAN): */ for(i=0, nc=>w_config.vlan_cfg[i]; i<gtw_config.vlans_num; i++,nc++) { ETH_DBG( ETH_DBG_LOAD, ("vlan%d configuration (nc->ports_mask = 0x%08x) \n", i, nc->ports_mask)); /* set port's defaul private vlan id and database number (DB per group): */ for(p=0; p<qd_dev->numOfPorts; p++) { if( MV_BIT_CHECK(nc->ports_mask, p) && (p != SWITCH_PORT_CPU) ) { ETH_DBG(ETH_DBG_LOAD,("port %d default private vlan id: 0x%x\n", p, MV_GTW_PORT_VLAN_ID(nc->vlan_grp_id,p))); if( gvlnSetPortVid(qd_dev, p, MV_GTW_PORT_VLAN_ID(nc->vlan_grp_id,p)) != GT_OK ) { printk("gvlnSetPortVid failed"); return -1; } if( gvlnSetPortVlanDBNum(qd_dev, p, MV_GTW_VLAN_TO_GROUP(nc->vlan_grp_id)) != GT_OK) { printk("gvlnSetPortVlanDBNum failed\n"); return -1; } } } /* set port's port-based vlan (CPU port is not part of VLAN) */ if(mv_gtw_set_port_based_vlan(nc->ports_mask & ~(1<<SWITCH_PORT_CPU)) != 0) { printk("mv_gtw_set_port_based_vlan failed\n"); } /* set vtu with group vlan id (used in tx) */ if(mv_gtw_set_vlan_in_vtu(nc->vlan_grp_id, nc->ports_mask | (1<<SWITCH_PORT_CPU)) != 0) { printk("mv_gtw_set_vlan_in_vtu failed\n"); } /* set vtu with each port private vlan id (used in rx) */ for(p=0; p<qd_dev->numOfPorts; p++) { if(MV_BIT_CHECK(nc->ports_mask, p) && (p!=SWITCH_PORT_CPU)) { if(mv_gtw_set_vlan_in_vtu(MV_GTW_PORT_VLAN_ID(nc->vlan_grp_id,p), nc->ports_mask & ~(1<<SWITCH_PORT_CPU)) != 0) { printk("mv_gtw_set_vlan_in_vtu failed\n"); } } } } /* set cpu-port with port-based vlan to all other ports */ ETH_DBG( ETH_DBG_LOAD, ("cpu port-based vlan:")); for(p=0,cnt=0; p<qd_dev->numOfPorts; p++) { if(p != SWITCH_PORT_CPU) { ETH_DBG( ETH_DBG_LOAD, ("%d ",p)); port_list[cnt] = p; cnt++; } } ETH_DBG( ETH_DBG_LOAD, ("\n")); if(gvlnSetPortVlanPorts(qd_dev, SWITCH_PORT_CPU, port_list, cnt) != GT_OK) { printk("gvlnSetPortVlanPorts failed\n"); return -1; } if(gfdbFlush(qd_dev,GT_FLUSH_ALL) != GT_OK) { printk("gfdbFlush failed\n"); } /* done! enable all Switch ports according to the net config table */ ETH_DBG( ETH_DBG_LOAD, ("enabling: ports ")); for(p=0; p<qd_dev->numOfPorts; p++) { if (MV_BIT_CHECK(switch_enabled_ports, p)) { ETH_DBG( ETH_DBG_LOAD, ("%d ",p)); if(gstpSetPortState(qd_dev, p, GT_PORT_FORWARDING) != GT_OK) { printk("gstpSetPortState failed\n"); } } } ETH_DBG( ETH_DBG_LOAD, ("\n")); #ifdef CONFIG_MV_GTW_LINK_STATUS /* Enable Phy Link Status Changed interrupt at Phy level for the all enabled ports */ for(p=0; p<qd_dev->numOfPorts; p++) { if(MV_BIT_CHECK(switch_enabled_ports, p) && (p != SWITCH_PORT_CPU)) { if(gprtPhyIntEnable(qd_dev, p, (GT_LINK_STATUS_CHANGED)) != GT_OK) { printk("gprtPhyIntEnable failed port %d\n", p); } } } if ((qd_dev->deviceId != GT_88E6161) && (qd_dev->deviceId != GT_88E6165) && (qd_dev->deviceId != GT_88E6171)) { if (switch_irq != -1) { if(eventSetActive(qd_dev, GT_PHY_INTERRUPT) != GT_OK) { printk("eventSetActive failed\n"); } } } else { gt_event.event = GT_DEV_INT_PHY; gt_event.portList = 0; gt_event.phyList = 0x1F; /* 0x1F is a bit mask for ports 0-4 */ if (switch_irq != -1) { if(eventSetDevInt(qd_dev, >_event) != GT_OK) { printk("eventSetDevInt failed\n"); } if(eventSetActive(qd_dev, GT_DEVICE_INT) != GT_OK) { printk("eventSetActive failed\n"); } } } #endif /* CONFIG_MV_GTW_LINK_STATUS */ /* Configure Ethernet related LEDs, currently according to Switch ID */ switch (qd_dev->deviceId) { case GT_88E6161: case GT_88E6165: case GT_88E6171: break; /* do nothing */ default: for(p=0; p<qd_dev->numOfPorts; p++) { if( (p != SWITCH_PORT_CPU) && (SWITCH_IS_PORT_CONNECTED(p)) ) { if(gprtSetPhyReg(qd_dev,p,22,0x1FFA)) { /* Configure Register 22 LED0 to 0xA for Link/Act */ printk("gprtSetPhyReg failed (port=%d)\n", p); } } } break; } /* printk("done\n"); */ return 0; }
GT_STATUS samplePTPInit(GT_QD_DEV *dev) { GT_PTP_CONFIG ptpCfg; GT_LPORT port; GT_STATUS status; /* * 1) Setup each port to forward PTP frame to CPU port */ /* setup EtypeType and Policy */ for(port=0; port<dev->numOfPorts; port++) { if ((status = gprtSetPortEType(dev, port, (GT_ETYPE)0x88F7)) != GT_OK) { MSG_PRINT(("gprtSetPortEType returned not OK\n")); return status; } if (port == dev->cpuPortNum) continue; if ((status = gprtSetPolicy(dev, port, POLICY_TYPE_ETYPE, FRAME_POLICY_TRAP)) != GT_OK) { MSG_PRINT(("gprtSetPolicy returned not OK\n")); return status; } } /* setup Frame Mode for CPU port */ if ((status = gprtSetFrameMode(dev, dev->cpuPortNum, GT_FRAME_MODE_ETHER_TYPE_DSA)) != GT_OK) { MSG_PRINT(("gprtSetFrameMode return failed\n")); return status; } /* * 2) Enable PTP Interrupt */ eventSetActive(dev, GT_AVB_INT); /* * 3) Configure PTP */ ptpCfg.ptpEType = 0x88F7; ptpCfg.msgIdTSEn = 0xd; /* id 0, 2, and 3 */ ptpCfg.tsArrPtr = 0x8; /* id 0 and 2 for ARR0, id 3 for ARR1 */ /* Transport specific bits present in PTP Common Header */ ptpCfg.transSpec = 1; /* starting bit location for the Message ID field in the PTP Common Header */ ptpCfg.msgIdStartBit = 4; ptpCfg.ptpArrIntEn = 0x3F; ptpCfg.ptpDepIntEn = 0x3F; ptpCfg.disTSOverwrite = 0; if ((status = gptpSetConfig(dev, &ptpCfg)) != GT_OK) { MSG_PRINT(("gptpSetConfig return failed\n")); return status; } if ((status = gptpSetPTPEn(dev, GT_TRUE)) != GT_OK) { MSG_PRINT(("gptpSetPTPEn return failed\n")); return status; } return GT_OK; }
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; }