| #include <Copyright.h> |
| /******************************************************************************** |
| * crossChipTrunk.c |
| * |
| * DESCRIPTION: |
| * This sample shows how to setup the Cross Chip TRUNK |
| * |
| * DEPENDENCIES: |
| * Please check the device's spec. if the device supports this feature. |
| * At the moment this sample was written, 88E6095 was the only device support |
| * this feature. |
| * |
| * FILE REVISION NUMBER: |
| * |
| * COMMENTS: |
| *******************************************************************************/ |
| |
| #include "msSample.h" |
| |
| #define N_OF_QD_DEVICES 2 |
| |
| /* qdMultiDev is defined in sample/MultiDevice/msApiInit.c */ |
| extern GT_QD_DEV *qdMultiDev[N_OF_QD_DEVICES]; |
| |
| /* |
| #ifndef TRUNK_MEMBER |
| #define MAX_PORT_IN_TRUNK 4 |
| |
| typedef struct _TRUNK_SET { |
| GT_U32 devIndex; |
| GT_U32 port; |
| } TRUNK_SET; |
| |
| typedef struct _TRUNK_MEMBER { |
| GT_U32 trunkId; |
| GT_U32 nTrunkPort; |
| TRUNK_SET trunkSet[MAX_PORT_IN_TRUNK]; |
| } TRUNK_MEMBER; |
| |
| #endif |
| */ |
| |
| GT_STATUS sampleCrossChipTrunk(GT_QD_DEV *dev[], TRUNK_MEMBER* tm); |
| |
| /* |
| Setup Trunk with the following member ports: |
| Port 0,1,2 of Device 0, and |
| Port 0 of Device 1, |
| where Device 0 is the first Switch Device Structure in qdMultiDev array |
| and Device 1 is the second Switch Device Structure in qdMultiDev array. |
| */ |
| GT_STATUS crossChipTrunkSetup() |
| { |
| TRUNK_MEMBER tm; |
| |
| tm.trunkId = 1; |
| tm.nTrunkPort = 4; |
| tm.trunkSet[0].devIndex = 0; |
| tm.trunkSet[0].port = 0; |
| tm.trunkSet[1].devIndex = 0; |
| tm.trunkSet[1].port = 1; |
| tm.trunkSet[2].devIndex = 0; |
| tm.trunkSet[2].port = 2; |
| tm.trunkSet[3].devIndex = 1; |
| tm.trunkSet[3].port = 0; |
| |
| return sampleCrossChipTrunk(qdMultiDev, &tm); |
| } |
| |
| GT_STATUS sampleCrossChipTrunk(GT_QD_DEV *dev[], TRUNK_MEMBER* tm) |
| { |
| GT_STATUS status; |
| int i,j,index; |
| GT_U32 mask, trunkId; |
| TRUNK_SET* ts; |
| GT_U32 portVec[N_OF_QD_DEVICES]; |
| GT_U32 casecadeVec = 0xC0; /* Port 6 and 7. ToDo : get this value from user or device */ |
| |
| /* |
| * Enable Trunk for each member of the Trunk and set the Trunk ID (1). |
| */ |
| |
| printf("Setting TRUNK\n"); |
| printf("Trunk ID : %i\n",(unsigned int)tm->trunkId); |
| printf("N Ports : %i\n",(unsigned int)tm->nTrunkPort); |
| printf("1st Port : Dev %i, Port %i\n", |
| (unsigned int)tm->trunkSet[0].devIndex,(unsigned int)tm->trunkSet[0].port); |
| printf("2nd Port : Dev %i, Port %i\n", |
| (unsigned int)tm->trunkSet[1].devIndex,(unsigned int)tm->trunkSet[1].port); |
| printf("3rd Port : Dev %i, Port %i\n", |
| (unsigned int)tm->trunkSet[2].devIndex,(unsigned int)tm->trunkSet[2].port); |
| printf("4th Port : Dev %i, Port %i\n", |
| (unsigned int)tm->trunkSet[3].devIndex,(unsigned int)tm->trunkSet[3].port); |
| |
| trunkId = tm->trunkId; |
| |
| for(i=0; i<N_OF_QD_DEVICES; i++) |
| portVec[i] = 0; |
| |
| printf("Enabling TRUNK for each member port.\n"); |
| for(i=0; i<tm->nTrunkPort; i++) |
| { |
| ts = &tm->trunkSet[i]; |
| |
| if(ts->devIndex >= N_OF_QD_DEVICES) |
| { |
| printf("Device %i is supported. Max Device Number is %i\n",(unsigned int)ts->devIndex,N_OF_QD_DEVICES-1); |
| return GT_FAIL; |
| } |
| |
| if((dev[ts->devIndex] == NULL) || (!dev[ts->devIndex]->devEnabled)) |
| { |
| printf("Device %i is not initialized\n",(unsigned int)ts->devIndex); |
| return GT_FAIL; |
| } |
| |
| /* enabled trunk on the given port */ |
| if((status = gprtSetTrunkPort(dev[ts->devIndex],ts->port,GT_TRUE,trunkId)) != GT_OK) |
| { |
| MSG_PRINT(("gprtSetTrunkPort return Failed\n")); |
| return status; |
| } |
| |
| portVec[ts->devIndex] |= (1 << ts->port); |
| } |
| |
| /* |
| * Set Trunk Route Table for the given Trunk ID. |
| */ |
| printf("Setting TRUNK Routing Table\n"); |
| for(i=0; i<N_OF_QD_DEVICES; i++) |
| { |
| if((dev[i] == NULL) || (!dev[i]->devEnabled)) |
| { |
| printf("Device %i is not initialized\n",i); |
| break; |
| } |
| |
| if((status = gsysSetTrunkRouting(dev[i],trunkId,portVec[i]|casecadeVec)) != GT_OK) |
| { |
| MSG_PRINT(("gsysSetTrunkRouting return Failed\n")); |
| return status; |
| } |
| } |
| |
| /* |
| * Set Trunk Mask Table for load balancing. |
| */ |
| printf("Setting TRUNK Mask for Load Balancing\n"); |
| for(i=0; i<8; i++) |
| { |
| /* choose a port to be used for the given addr combo index */ |
| index = i % tm->nTrunkPort; |
| ts = &tm->trunkSet[index]; |
| |
| for(j=0; j<N_OF_QD_DEVICES; j++) |
| { |
| if((dev[j] == NULL) || (!dev[j]->devEnabled)) |
| { |
| printf("Device %i is not initialized\n",j); |
| continue; |
| } |
| |
| if(portVec[j] == 0) |
| continue; |
| |
| if((status = gsysGetTrunkMaskTable(dev[j],i,&mask)) != GT_OK) |
| { |
| MSG_PRINT(("gsysGetTrunkMaskTable return Failed\n")); |
| return status; |
| } |
| |
| mask &= ~portVec[j]; |
| |
| if(ts->devIndex == j) |
| mask |= (1 << ts->port); |
| |
| if((status = gsysSetTrunkMaskTable(dev[j],i,mask)) != GT_OK) |
| { |
| MSG_PRINT(("gsysSetTrunkMaskTable return Failed\n")); |
| return status; |
| } |
| } |
| } |
| |
| return GT_OK; |
| } |
| |
| |
| |
| /* |
| Assumption 1: Device ID, Cascading Port, CPU Port, and Interswitch Port are |
| already set properly. For more information, please refer to the |
| sample/MultiDevice/msApiInit.c |
| |
| Assumption 2: Port 0,1,2 of Device 0 and Port 0 of Device 1 are member of a |
| trunk with Trunk ID 1. |
| */ |
| |
| GT_STATUS sampleFixedCrossChipTrunk(GT_QD_DEV *dev[]) |
| { |
| GT_STATUS status; |
| int i; |
| GT_U32 mask, trunkBit, trunkId; |
| |
| /* |
| * Enable Trunk for each member of the Trunk and set the Trunk ID (1). |
| */ |
| |
| trunkId = 1; |
| |
| if((dev[0] == NULL) || (!dev[0]->devEnabled)) |
| { |
| printf("Device 0 is not initialized\n"); |
| return GT_FAIL; |
| } |
| if((dev[1] == NULL) || (!dev[1]->devEnabled)) |
| { |
| printf("Device 1 is not initialized\n"); |
| return GT_FAIL; |
| } |
| |
| /* setup for Device 0 port 0 */ |
| if((status = gprtSetTrunkPort(dev[0],0,GT_TRUE,trunkId)) != GT_OK) |
| { |
| MSG_PRINT(("gprtSetTrunkPort return Failed\n")); |
| return status; |
| } |
| |
| /* setup for Device 0 port 1 */ |
| if((status = gprtSetTrunkPort(dev[0],1,GT_TRUE,trunkId)) != GT_OK) |
| { |
| MSG_PRINT(("gprtSetTrunkPort return Failed\n")); |
| return status; |
| } |
| |
| /* setup for Device 0 port 2 */ |
| if((status = gprtSetTrunkPort(dev[0],2,GT_TRUE,trunkId)) != GT_OK) |
| { |
| MSG_PRINT(("gprtSetTrunkPort return Failed\n")); |
| return status; |
| } |
| |
| /* setup for Device 1 port 0 */ |
| if((status = gprtSetTrunkPort(dev[1],0,GT_TRUE,trunkId)) != GT_OK) |
| { |
| MSG_PRINT(("gprtSetTrunkPort return Failed\n")); |
| return status; |
| } |
| |
| |
| /* |
| * Set Trunk Route Table for the given Trunk ID. |
| */ |
| |
| /* setup for Device 0, trunk ID 1 : port 0,1,2, and 9 (cascading port, assumption1) */ |
| if((status = gsysSetTrunkRouting(dev[0],trunkId,0x7|0x200)) != GT_OK) |
| { |
| MSG_PRINT(("gsysSetTrunkRouting return Failed\n")); |
| return status; |
| } |
| |
| /* setup for Device 1, trunk ID 1 : port 0, and 8 (cascading port, assumption1) */ |
| if((status = gsysSetTrunkRouting(dev[1],trunkId,0x1|0x100)) != GT_OK) |
| { |
| MSG_PRINT(("gsysSetTrunkRouting return Failed\n")); |
| return status; |
| } |
| |
| |
| /* |
| * Set Trunk Mask Table for load balancing. |
| */ |
| |
| /* |
| Trunk Mask Table for Device 0: |
| |
| 10 9 8 7 6 5 4 3 2 1 0 |
| TrunkMask[0] 1 1 1 1 1 1 1 1 0 0 1 |
| TrunkMask[1] 1 1 1 1 1 1 1 1 0 1 0 |
| TrunkMask[2] 1 1 1 1 1 1 1 1 1 0 0 |
| TrunkMask[3] 1 1 1 1 1 1 1 1 0 0 0 |
| TrunkMask[4] 1 1 1 1 1 1 1 1 0 0 1 |
| TrunkMask[5] 1 1 1 1 1 1 1 1 0 1 0 |
| TrunkMask[6] 1 1 1 1 1 1 1 1 1 0 0 |
| TrunkMask[7] 1 1 1 1 1 1 1 1 0 0 0 |
| |
| |
| Trunk Mask Table for Device 1: |
| |
| 10 9 8 7 6 5 4 3 2 1 0 |
| TrunkMask[0] 1 1 1 1 1 1 1 1 1 1 0 |
| TrunkMask[1] 1 1 1 1 1 1 1 1 1 1 0 |
| TrunkMask[2] 1 1 1 1 1 1 1 1 1 1 0 |
| TrunkMask[3] 1 1 1 1 1 1 1 1 1 1 1 |
| TrunkMask[4] 1 1 1 1 1 1 1 1 1 1 0 |
| TrunkMask[5] 1 1 1 1 1 1 1 1 1 1 0 |
| TrunkMask[6] 1 1 1 1 1 1 1 1 1 1 0 |
| TrunkMask[7] 1 1 1 1 1 1 1 1 1 1 1 |
| |
| */ |
| |
| /* setup for Device 0 */ |
| for(i=0; i<8; i++) |
| { |
| if((i%4) == 3) |
| { |
| trunkBit = 0; |
| } |
| else |
| { |
| trunkBit = 1 << (i%4); |
| } |
| |
| mask = 0x7F8 | trunkBit; |
| |
| if((status = gsysSetTrunkMaskTable(dev[0],i,mask)) != GT_OK) |
| { |
| MSG_PRINT(("gsysSetTrunkMaskTable return Failed\n")); |
| return status; |
| } |
| |
| } |
| |
| /* setup for Device 1 */ |
| for(i=0; i<8; i++) |
| { |
| if((i%4) == 3) |
| { |
| trunkBit = 1; |
| } |
| else |
| { |
| trunkBit = 0; |
| } |
| |
| mask = 0x7FE | trunkBit; |
| |
| if((status = gsysSetTrunkMaskTable(dev[1],i,mask)) != GT_OK) |
| { |
| MSG_PRINT(("gsysSetTrunkMaskTable return Failed\n")); |
| return status; |
| } |
| |
| } |
| return GT_OK; |
| } |