| #include <Copyright.h> |
| /******************************************************************************** |
| * msApiInit.c |
| * |
| * DESCRIPTION: |
| * MS API initialization routine for devices supporting Multi Address Mode, |
| * such as 88E6183. Following setup will be used for this sample code. |
| * |
| * ------------------ |
| * |CPU Ethernet Dev| |
| * ------------------ |
| * | |
| * | |
| * | 8--------------9 8--------------9 8-------------- |
| * |----| QD Device 0|------| QD Device 1|-----| QD Device 2| |
| * -------------- -------------- -------------- |
| * 0 1 2 ... 7 0 1 2 ... 7 0 1 2 ... 7 |
| * |
| * |
| * Ethernet port of CPU is connected to port 8 of Device 0, |
| * port 9 of Device 0 is connected to port 8 of Device 1, and |
| * port 9 of Device 1 is connected to port 8 of Device 2. |
| * |
| * Device 0 uses Phy Address 1, |
| * Device 1 uses Phy Address 2, and |
| * Device 2 uses Phy Address 3 |
| * Notes: Phy Address 0 cannot be used in a Multi Chip Address Mode. |
| * |
| * Each Switch Device has to be configured to Multi Chip Address Mode. |
| * For detailed information for Multi Chip Address Mode configuration, |
| * please refer to your device's Datasheet. |
| * |
| * DEPENDENCIES: Platform |
| * |
| * FILE REVISION NUMBER: |
| * |
| *******************************************************************************/ |
| #include "msSample.h" |
| |
| /* |
| #define MULTI_ADDR_MODE |
| #define MANUAL_MODE |
| */ |
| |
| #define MULTI_ADDR_MODE |
| #define N_OF_QD_DEVICES 3 /* number of 88E6183 devices connected */ |
| |
| #define DEVICE0_ID 10 |
| #define DEVICE1_ID DEVICE0_ID + 1 |
| #define DEVICE2_ID DEVICE0_ID + 2 |
| |
| #define DEVICE0_PHY_ADDR 1 |
| #define DEVICE1_PHY_ADDR DEVICE0_PHY_ADDR + 1 |
| #define DEVICE2_PHY_ADDR DEVICE0_PHY_ADDR + 2 |
| |
| #define S_CPU_DEVICE DEVICE0_ID |
| |
| #define DEVICE0_CPU_PORT 8 |
| #define DEVICE0_CASCADE_PORT 9 |
| #define DEVICE1_CPU_PORT 8 |
| #define DEVICE1_CASCADE_PORT 9 |
| #define DEVICE2_CPU_PORT 8 |
| #define DEVICE2_CASCADE_PORT 9 |
| |
| GT_QD_DEV *qdMultiDev[N_OF_QD_DEVICES] = {0,}; |
| |
| /* |
| * Initialize each Switch Devices. This should be done in BSP driver init routine. |
| * Since BSP is not combined with QuarterDeck driver, we are doing here. |
| * This routine will setup Switch Devices according to the above description. |
| */ |
| |
| GT_STATUS qdMultiDevStart() |
| { |
| GT_STATUS status = GT_FAIL; |
| GT_SYS_CONFIG cfg; |
| int cpuPort; |
| int cascadePort; |
| int i,j; |
| |
| memset((char*)&cfg,0,sizeof(GT_SYS_CONFIG)); |
| |
| /* |
| * Create QD Device Structure for each device. |
| */ |
| for(i=0; i<N_OF_QD_DEVICES; i++) |
| { |
| qdMultiDev[i] = (GT_QD_DEV*)malloc(sizeof(GT_QD_DEV)); |
| |
| if(qdMultiDev[i] == NULL) |
| { |
| while(i--) |
| free(qdMultiDev[i]); |
| return GT_FAIL; |
| } |
| |
| memset((char*)qdMultiDev[i],0,sizeof(GT_QD_DEV)); |
| } |
| |
| /* |
| * Register all the required functions to QuarterDeck Driver for each device. |
| */ |
| for(i=0; i<N_OF_QD_DEVICES; i++) |
| { |
| cfg.BSPFunctions.readMii = gtBspReadMii; |
| cfg.BSPFunctions.writeMii = gtBspWriteMii; |
| #ifdef USE_SEMAPHORE |
| cfg.BSPFunctions.semCreate = osSemCreate; |
| cfg.BSPFunctions.semDelete = osSemDelete; |
| cfg.BSPFunctions.semTake = osSemWait; |
| cfg.BSPFunctions.semGive = osSemSignal; |
| #else |
| cfg.BSPFunctions.semCreate = NULL; |
| cfg.BSPFunctions.semDelete = NULL; |
| cfg.BSPFunctions.semTake = NULL; |
| cfg.BSPFunctions.semGive = NULL; |
| #endif |
| |
| cfg.initPorts = GT_TRUE; /* Set switch ports to Forwarding mode. If GT_FALSE, use Default Setting. */ |
| switch (i) |
| { |
| case 0: /* if we are registering device 0 */ |
| cfg.cpuPortNum = DEVICE0_CPU_PORT; |
| break; |
| case 1: /* if we are registering device 1 */ |
| cfg.cpuPortNum = DEVICE1_CPU_PORT; /* where device 0 is connected */ |
| break; |
| case 2: /* if we are registering device 2 */ |
| cfg.cpuPortNum = DEVICE2_CPU_PORT; /* where device 1 is connected */ |
| break; |
| default: /* we don't have any more device. it shouldn't happen in our sample setup. */ |
| goto errorExit; |
| } |
| |
| #ifdef MANUAL_MODE /* not defined. this is only for sample */ |
| /* user may want to use this mode when there are two QD switchs on the same MII bus. */ |
| cfg.mode.scanMode = SMI_MANUAL_MODE; /* Use QD located at manually defined base addr */ |
| cfg.mode.baseAddr = 0x10; /* valid value in this case is either 0 or 0x10 */ |
| #else |
| #ifdef MULTI_ADDR_MODE /* It should have been defined for this sample code */ |
| cfg.mode.scanMode = SMI_MULTI_ADDR_MODE; /* find a QD in indirect access mode */ |
| cfg.mode.baseAddr = DEVICE0_PHY_ADDR + i; /* this is the phyAddr used by QD family device. |
| Valid values are 1 ~ 31.*/ |
| #else |
| cfg.mode.scanMode = SMI_AUTO_SCAN_MODE; /* Scan 0 or 0x10 base address to find the QD */ |
| cfg.mode.baseAddr = 0; |
| #endif |
| #endif |
| |
| if((status=qdLoadDriver(&cfg, qdMultiDev[i])) != GT_OK) |
| { |
| MSG_PRINT(("qdLoadDriver return Failed\n")); |
| goto errorExit; |
| } |
| |
| MSG_PRINT(("Device ID : 0x%x\n",qdMultiDev[i]->deviceId)); |
| MSG_PRINT(("Base Reg Addr : 0x%x\n",qdMultiDev[i]->baseRegAddr)); |
| MSG_PRINT(("No of Ports : %d\n",qdMultiDev[i]->numOfPorts)); |
| MSG_PRINT(("CPU Ports : %d\n",qdMultiDev[i]->cpuPortNum)); |
| |
| /* |
| * start the QuarterDeck |
| */ |
| if((status=sysEnable(qdMultiDev[i])) != GT_OK) |
| { |
| MSG_PRINT(("sysConfig return Failed\n")); |
| goto errorExit; |
| } |
| } |
| |
| /* |
| Now, we need to configure Cascading information for each devices. |
| 1. Set Interswitch port mode for port 8 and 9 for device 0,1,and 2, |
| so that switch device can expect Marvell Tag from frames |
| ingressing/egressing this port. |
| 2. Set CPU Port information (for To_CPU frame) for each port of device. |
| 3. Set Cascading Port information (for From_CPU fram) for each device. |
| 4. Set Device ID (if required) |
| Note: DeviceID is hardware configurable. |
| */ |
| for(i=0; i<N_OF_QD_DEVICES; i++) |
| { |
| switch (i) |
| { |
| case 0: /* if we are registering device 0 */ |
| cpuPort = DEVICE0_CPU_PORT; /* where CPU Enet port is connected */ |
| cascadePort = DEVICE0_CASCADE_PORT; /* where device 1 is connected */ |
| break; |
| case 1: /* if we are registering device 1 */ |
| cpuPort = DEVICE1_CPU_PORT; /* where device 0 is connected */ |
| cascadePort = DEVICE1_CASCADE_PORT; /* where device 2 is connected */ |
| break; |
| case 2: /* if we are registering device 2 */ |
| cpuPort = DEVICE2_CPU_PORT; /* where device 1 is connected */ |
| cascadePort = DEVICE2_CASCADE_PORT; /* no need to setup for the given sample setup */ |
| break; |
| default: /* we don't have any more device. it shouldn't happen in our sample setup. */ |
| goto errorExit; |
| } |
| |
| /* |
| 1. Set Interswitch port mode for port 8 and 9 for device 0,1,and 2, |
| so that switch device can expect Marvell Tag from frames |
| ingressing/egressing this port. |
| 2. Set CPU Port information (for To_CPU frame) for each port of device. |
| */ |
| for(j=0; j<qdMultiDev[i]->numOfPorts; j++) |
| { |
| if((i == cpuPort) || (i == cascadePort)) |
| { |
| if((status=gprtSetInterswitchPort(qdMultiDev[i],j,GT_TRUE)) != GT_OK) |
| { |
| MSG_PRINT(("gprtSetInterswitchPort returned %i (port %i, mode TRUE)\n",status,j)); |
| goto errorExit; |
| } |
| } |
| else |
| { |
| if((status=gprtSetInterswitchPort(qdMultiDev[i],j,GT_FALSE)) != GT_OK) |
| { |
| MSG_PRINT(("gprtSetInterswitchPort returned %i (port %i, mode FALSE)\n",status,j)); |
| goto errorExit; |
| } |
| } |
| |
| if((status=gprtSetCPUPort(qdMultiDev[i],j,cpuPort)) != GT_OK) |
| { |
| MSG_PRINT(("gprtSetCPUPort returned %i\n",status)); |
| goto errorExit; |
| } |
| } |
| |
| /* |
| 3. Set Cascading Port information (for From_CPU fram) for each device. |
| */ |
| if((status=gsysSetCascadePort(qdMultiDev[i],cascadePort)) != GT_OK) |
| { |
| MSG_PRINT(("gsysSetCascadePort returned %i\n",status)); |
| goto errorExit; |
| } |
| |
| /* |
| 4. Set Device ID (if required) |
| */ |
| if((status=gsysSetDeviceNumber(qdMultiDev[i],DEVICE0_ID+i)) != GT_OK) |
| { |
| MSG_PRINT(("gsysSetDeviceNumber returned %i\n",status)); |
| goto errorExit; |
| } |
| |
| } |
| |
| MSG_PRINT(("QuarterDeck has been started.\n")); |
| |
| return GT_OK; |
| |
| errorExit: |
| |
| for(i=0; i<N_OF_QD_DEVICES; i++) |
| { |
| if(qdMultiDev[i] != NULL) |
| { |
| qdUnloadDriver(qdMultiDev[i]); |
| free(qdMultiDev[i]); |
| } |
| } |
| |
| MSG_PRINT(("QuarterDeck initialization failed.\n")); |
| |
| return status; |
| } |
| |