blob: 448884233cafe853dacb31df5fa49d589269f5a5 [file] [log] [blame]
#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 2 /* number of 88E6183 devices connected */
#define DEVICE0_ID 1
#define DEVICE1_ID DEVICE0_ID + 1
#define DEVICE2_ID DEVICE0_ID + 2
#define DEVICE0_PHY_ADDR 0x11
#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 7
#define DEVICE0_CASCADE_PORT 6
#define DEVICE1_CPU_PORT 7
#define DEVICE1_CASCADE_PORT 6
#define DEVICE2_CPU_PORT 7
#define DEVICE2_CASCADE_PORT 6
extern GT_QD_DEV qddev[4];
GT_QD_DEV *qdMultiDev[N_OF_QD_DEVICES] = {0,};
GT_QD_DEV *qdDev0 = &qddev[1];
GT_QD_DEV *qdDev1 = NULL;
GT_QD_DEV *qdDev2 = NULL;
/*
* read mii register - see qdFFmii.c
*/
extern GT_BOOL ffReadMii(GT_QD_DEV* dev,
unsigned int portNumber ,
unsigned int MIIReg, unsigned int* value
);
/*
* write mii register - see qdFFmii.c
*/
extern GT_BOOL ffWriteMii(GT_QD_DEV* dev,
unsigned int portNumber ,
unsigned int MIIReg,
unsigned int value
);
GT_STATUS RubyStart(int phyAddr, GT_QD_DEV* d)
{
GT_STATUS status = GT_FAIL;
GT_SYS_CONFIG cfg;
memset((char*)&cfg,0,sizeof(GT_SYS_CONFIG));
MSG_PRINT(("Size of GT_QD_DEV %i\n",sizeof(GT_QD_DEV)));
if(d == NULL)
{
MSG_PRINT(("Device Structure is NULL.\n"));
return GT_FAIL;
}
memset((char*)d,0,sizeof(GT_QD_DEV));
cfg.BSPFunctions.readMii = ffReadMii;
cfg.BSPFunctions.writeMii = ffWriteMii;
#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. */
cfg.cpuPortNum = 10;
cfg.mode.scanMode = SMI_MULTI_ADDR_MODE;
cfg.mode.baseAddr = phyAddr; /* valid value in this case is either 0 or 0x10 */
if((status=qdLoadDriver(&cfg, d)) != GT_OK)
{
MSG_PRINT(("qdLoadDriver return Failed\n"));
return status;
}
MSG_PRINT(("Device ID : 0x%x\n",d->deviceId));
MSG_PRINT(("PHY Addr : 0x%x\n",d->phyAddr));
MSG_PRINT(("Base Addr : 0x%x\n",d->baseRegAddr));
MSG_PRINT(("CPU Ports : %d\n",d->cpuPortNum));
MSG_PRINT(("N Ports : %d\n",d->numOfPorts));
MSG_PRINT(("Device Group : 0x%x\n",d->devName));
MSG_PRINT(("QDDev : %#x\n",(unsigned long)&d));
/*
* start the QuarterDeck
*/
if((status=sysEnable(d)) != GT_OK)
{
MSG_PRINT(("sysConfig return Failed\n"));
return status;
}
return GT_OK;
}
GT_STATUS SwStart(int phyAddr, GT_QD_DEV* d)
{
return RubyStart(phyAddr,d);
}
GT_QD_DEV* loadDev(GT_QD_DEV* dev, int mode, int phyAddr, int cpuPort, unsigned int cfgMode)
{
GT_QD_DEV* d = dev;
GT_STATUS status = GT_FAIL;
GT_SYS_CONFIG cfg;
if((int)dev == -1)
goto printUse;
memset((char*)&cfg,0,sizeof(GT_SYS_CONFIG));
if(d == NULL)
{
d = (GT_QD_DEV*)malloc(sizeof(GT_QD_DEV));
if(d == NULL)
{
MSG_PRINT(("Failed to allocate Device Structure\n"));
return NULL;
}
}
memset((char*)d,0,sizeof(GT_QD_DEV));
cfg.BSPFunctions.readMii = ffReadMii;
cfg.BSPFunctions.writeMii = ffWriteMii;
#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. */
cfg.cpuPortNum = cpuPort;
cfg.skipInitSetup = (GT_U32)cfgMode;
switch(mode)
{
case SMI_MANUAL_MODE: /* Use QD located at manually defined base addr */
case SMI_MULTI_ADDR_MODE: /* Use QD in multi chip address mode */
cfg.mode.scanMode = mode;
cfg.mode.baseAddr = phyAddr; /* valid value in this case is either 0 or 0x10 */
break;
case SMI_AUTO_SCAN_MODE: /* Scan 0 or 0x10 base address to find the QD */
cfg.mode.scanMode = mode;
cfg.mode.baseAddr = 0;
break;
default:
MSG_PRINT(("Unknown Mode %i\n",mode));
goto printUse;
}
if((status=qdLoadDriver(&cfg, d)) != GT_OK)
{
MSG_PRINT(("qdLoadDriver return Failed\n"));
goto loadErr;
}
MSG_PRINT(("Device ID : 0x%x\n",d->deviceId));
MSG_PRINT(("PHY Addr : 0x%x\n",d->phyAddr));
MSG_PRINT(("Base Addr : 0x%x\n",d->baseRegAddr));
MSG_PRINT(("CPU Ports : %d\n",d->cpuPortNum));
/*
* start the QuarterDeck
*/
if((status=sysEnable(d)) != GT_OK)
{
MSG_PRINT(("sysConfig return Failed\n"));
goto loadErr;
}
return d;
printUse:
MSG_PRINT(("Usage: loadDev(Dev,mode,phyAddr,cpuPort)\n",SMI_AUTO_SCAN_MODE));
MSG_PRINT(("\tSMI_AUTO_SCAN_MODE : %i\n",SMI_AUTO_SCAN_MODE));
MSG_PRINT(("\tSMI_MANUAL_MODE : %i\n",SMI_MANUAL_MODE));
MSG_PRINT(("\tSMI_MULTI_ADDR_MODE : %i\n",SMI_MULTI_ADDR_MODE));
MSG_PRINT(("Example: loadDev(0,1,0x10,5)\n"));
MSG_PRINT(("for Manual mode, phy base address 0x10, and cpu port 5\n"));
loadErr:
if(dev)
return NULL;
if(d)
free(d);
return NULL;
}
/*
* 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;
int cpuPort;
int cascadePort;
int i,j;
/*
* Create QD Device Structure for each device.
*/
for(i=0; i<N_OF_QD_DEVICES; i++)
{
if(qdMultiDev[i] == NULL)
{
qdMultiDev[i] = (GT_QD_DEV*)malloc(sizeof(GT_QD_DEV));
if(qdMultiDev[i] == NULL)
{
while(i--)
{
free(qdMultiDev[i]);
qdMultiDev[i] = NULL;
}
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++)
{
switch (i)
{
case 0: /* if we are registering device 0 */
cpuPort = DEVICE0_CPU_PORT;
break;
case 1: /* if we are registering device 1 */
cpuPort = DEVICE1_CPU_PORT; /* where device 0 is connected */
break;
case 2: /* if we are registering device 2 */
cpuPort = 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;
}
MSG_PRINT(("Initializing QD Device %i...\n",i));
if(loadDev(qdMultiDev[i],SMI_MULTI_ADDR_MODE,DEVICE0_PHY_ADDR + i,cpuPort,0) == NULL)
{
MSG_PRINT(("QD Device %i is not initialized.\n",i));
free(qdMultiDev[i]);
qdMultiDev[i] = NULL;
continue;
}
/*
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.
*/
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 */
qdDev0 = qdMultiDev[i];
MSG_PRINT(("Use qdDev0 to access Device 0.\n"));
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 */
qdDev1 = qdMultiDev[i];
MSG_PRINT(("Use qdDev1 to access Device 1.\n"));
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 */
qdDev2 = qdMultiDev[i];
MSG_PRINT(("Use qdDev2 to access Device 2.\n"));
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.
*/
MSG_PRINT(("Setting InterSwitch Port and CPU Port...\n"));
for(j=0; j<qdMultiDev[i]->numOfPorts; j++)
{
if((j == cpuPort) || (j == cascadePort))
{
if((status=gprtSetInterswitchPort(qdMultiDev[i],j,GT_TRUE)) != GT_OK)
{
MSG_PRINT(("gprtSetInterswitchPort returned %i (port %i, mode TRUE)\n",status,j));
break;
}
}
else
{
if((status=gprtSetInterswitchPort(qdMultiDev[i],j,GT_FALSE)) != GT_OK)
{
MSG_PRINT(("gprtSetInterswitchPort returned %i (port %i, mode FALSE)\n",status,j));
break;
}
}
if((status=gprtSetCPUPort(qdMultiDev[i],j,cpuPort)) != GT_OK)
{
MSG_PRINT(("gprtSetCPUPort returned %i\n",status));
break;
}
}
/*
3. Set Cascading Port information (for From_CPU fram) for each device.
*/
MSG_PRINT(("Setting Cascade Port...\n"));
if((status=gsysSetCascadePort(qdMultiDev[i],cascadePort)) != GT_OK)
{
MSG_PRINT(("gsysSetCascadePort returned %i\n",status));
continue;
}
/*
4. Set Device ID (if required)
*/
MSG_PRINT(("Setting Device ID (%i)...\n",DEVICE0_ID+i));
if((status=gsysSetDeviceNumber(qdMultiDev[i],DEVICE0_ID+i)) != GT_OK)
{
MSG_PRINT(("gsysSetDeviceNumber returned %i\n",status));
continue;
}
}
return GT_OK;
errorExit:
/* code will be reached here only if N_OF_QD_DEVICES > 3 */
for(i=0; i<N_OF_QD_DEVICES; i++)
{
if(qdMultiDev[i] != NULL)
{
free(qdMultiDev[i]);
qdMultiDev[i] = NULL;
}
}
return GT_FAIL;
}