/******************************************************************************* * driverConfig * * DESCRIPTION: * This function initializes the driver level of the quarterDeck software. * * INPUTS: * None. * OUTPUTS: * None. * RETURNS: * GT_OK - on success, or * GT_OUT_OF_CPU_MEM - if failed to allocate CPU memory, * GT_FAIL - otherwise. * * COMMENTS: * 1. This function should perform the following: * - Initialize the global switch configuration structure. * - Initialize Mii Interface * *******************************************************************************/ GT_STATUS driverConfig ( IN GT_QD_DEV *dev ) { GT_U16 deviceId; #ifdef CONFIG_ARCH_FEROCEON_KW GT_U16 tmp, phy; #endif GT_BOOL highSmiDevAddr; if(dev->accessMode == SMI_AUTO_SCAN_MODE) { /* Initialize the MII / SMI interface, search for the device */ if((deviceId = miiSmiIfInit(dev,&highSmiDevAddr)) == 0) { return GT_FAIL; } dev->baseRegAddr = (highSmiDevAddr)?0x10:0; } else { if((deviceId = miiSmiManualIfInit(dev,(GT_U32)dev->baseRegAddr)) == 0) { return GT_FAIL; } } /* Init the device's config struct. */ dev->deviceId = deviceId >> 4; dev->revision = (GT_U8)deviceId & 0xF; #ifdef CONFIG_ARCH_FEROCEON_KW if(mvBoardIdGet() == RD_88F6281A_ID) { /* Enable RGMII delay on Tx and Rx for CPU port */ miiSmiIfWriteRegister(dev, 0x14,0x1a, 0x81e7); miiSmiIfReadRegister(dev, 0x15,0x1a,&tmp); miiSmiIfWriteRegister(dev, 0x15,0x1a,0x18); miiSmiIfWriteRegister(dev, 0x14,0x1a,0xc1e7); /* swap MDI signals for PHYs 0,1,2,3,4 on RD_88F6281A_ID */ for(phy = 0; phy < 5; phy++) { miiSmiIfWriteRegister(dev, 0x1c,0x19,0xf); miiSmiIfWriteRegister(dev, 0x1c,0x18,(0x9414 + (phy*0x20))); miiSmiIfReadRegister(dev, 0x1c, 0x19,&tmp); /* used for delay */ /* testing - read phy register #20 miiSmiIfWriteRegister(dev, 0x1c,0x18,(0x9814+ (phy*0x20))); miiSmiIfReadRegister(dev, 0x1c, 0x19,&tmp); DBG_INFO(("phy-%d reg20 = 0x%x\n",phy,tmp)); */ } } #endif return GT_OK; }
/******************************************************************************* * miiSmiManualIfInit * * DESCRIPTION: * This function returns Device ID from the given base address * * INPUTS: * baseAddr - either 0x0 or 0x10. Indicates whether to use the low device * register address or high device register address. * The device register range is from 0x0 to 0xF or from 0x10 * to 0x1F for 5 port switchs and from 0x0 to 0x1B for 8 port * switchs. * * OUTPUTS: * None. * * RETURNS: * DEVICE_ID - on success * 0 - on error * * COMMENTS: * None. * *******************************************************************************/ GT_U16 miiSmiManualIfInit ( IN GT_QD_DEV *dev, IN GT_U32 baseAddr ) { GT_STATUS status; GT_U16 data; if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR+baseAddr,QD_REG_SWITCH_ID,&data)) != GT_OK) { return 0; } switch(data & 0xFF00) { case 0x0200: case 0x0300: case 0x0500: case 0x0600: case 0x1500: case 0xF500: case 0xF900: return data; default: break; } if(baseAddr != 0) return 0; if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR_8PORT+baseAddr,QD_REG_SWITCH_ID,&data)) != GT_OK) { return 0; } switch(data & 0xFF00) { case 0x0800: case 0x1A00: case 0x1000: case 0x0900: case 0x0400: case 0x1200: case 0x1400: case 0x1600: return data; default: break; } return 0; }
int mv_switch_reg_read(int switch_num, int port, int reg, int type, MV_U16 *value) { GT_STATUS status; GT_QD_DEV *qd; if (switch_num >= BOARD_MAX_CASCADED_SWITCHES) { printk(KERN_ERR "Wrong switch number\n"); return 1; } qd = &qd_dev[switch_num]; if (qd == NULL) { printk(KERN_ERR "Switch is not initialized\n"); return 1; } switch (type) { case MV_SWITCH_PHY_ACCESS: status = gprtGetPhyReg(qd, port, reg, value); break; case MV_SWITCH_PORT_ACCESS: status = gprtGetSwitchReg(qd, port, reg, value); break; case MV_SWITCH_GLOBAL_ACCESS: status = gprtGetGlobalReg(qd, reg, value); break; case MV_SWITCH_GLOBAL2_ACCESS: status = gprtGetGlobal2Reg(qd, reg, value); break; case MV_SWITCH_SMI_ACCESS: /* port means phyAddr */ status = miiSmiIfReadRegister(qd, port, reg, value); break; default: printk(KERN_ERR "%s Failed: Unexpected access type %d\n", __func__, type); return 1; } if (status != GT_OK) { printk(KERN_ERR "%s Failed: status = %d\n", __func__, status); return 2; } return 0; }
int mv_switch_reg_read(int port, int reg, int type, MV_U16 *value) { GT_STATUS status; if (qd_dev == NULL) { printk(KERN_ERR "Switch is not initialized\n"); return 1; } switch (type) { case MV_SWITCH_PHY_ACCESS: if (qsgmii_module) printk(KERN_ERR "warning: cannot read Switch PHY register when QSGMII module is connected\n"); status = gprtGetPhyReg(qd_dev, port, reg, value); break; case MV_SWITCH_PORT_ACCESS: status = gprtGetSwitchReg(qd_dev, port, reg, value); break; case MV_SWITCH_GLOBAL_ACCESS: status = gprtGetGlobalReg(qd_dev, reg, value); break; case MV_SWITCH_GLOBAL2_ACCESS: status = gprtGetGlobal2Reg(qd_dev, reg, value); break; case MV_SWITCH_SMI_ACCESS: /* port means phyAddr */ status = miiSmiIfReadRegister(qd_dev, port, reg, value); break; default: printk(KERN_ERR "%s Failed: Unexpected access type %d\n", __func__, type); return 1; } if (status != GT_OK) { printk(KERN_ERR "%s Failed: status = %d\n", __func__, status); return 2; } return 0; }
/******************************************************************************* * miiSmiIfInit * * DESCRIPTION: * This function initializes the MII / SMI interface. * * INPUTS: * None. * * OUTPUTS: * highSmiDevAddr - Indicates whether to use the high device register * addresses when accessing switch's registers (of all kinds) * i.e, the devices registers range is 0x10 to 0x1F, or to * use the low device register addresses (range 0x0 to 0xF). * GT_TRUE - use high addresses (0x10 to 0x1F). * GT_FALSE - use low addresses (0x0 to 0xF). * * RETURNS: * DEVICE_ID - on success * 0 - on error * * COMMENTS: * None. * *******************************************************************************/ GT_U16 miiSmiIfInit ( IN GT_QD_DEV *dev, OUT GT_BOOL * highSmiDevAddr ) { GT_STATUS status; GT_U16 data, data1; if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR,QD_REG_SWITCH_ID,&data)) != GT_OK) { return 0; } if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR+1,QD_REG_SWITCH_ID,&data1)) != GT_OK) { return 0; } switch(data & 0xFF00) { case 0x0200: case 0x0300: case 0x0500: case 0x0600: case 0x1500: case 0xC000: /* Melody */ case 0x0700: /* Spinnaker */ case 0x2200: /* Spinnaker */ case 0x2500: /* Spinnaker */ case 0xF500: case 0xF900: if (data == data1) { *highSmiDevAddr = GT_FALSE; return data; } break; default: break; } if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR+0x10,QD_REG_SWITCH_ID,&data)) != GT_OK) { return 0; } if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR+0x11,QD_REG_SWITCH_ID,&data1)) != GT_OK) { return 0; } switch(data & 0xFF00) { case 0x0200: case 0x0300: case 0x0500: case 0x0600: case 0x1500: case 0xC000: /* Melody */ case 0x0700: /* Spinnaker */ case 0x2200: /* Spinnaker */ case 0x2500: /* Spinnaker */ case 0xF500: case 0xF900: if (data == data1) { *highSmiDevAddr = GT_TRUE; return data; } break; default: break; } if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR_8PORT,QD_REG_SWITCH_ID,&data)) != GT_OK) { return 0; } if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR_8PORT+1,QD_REG_SWITCH_ID,&data1)) != GT_OK) { return 0; } switch(data & 0xFF00) { case 0x0800: case 0x1A00: case 0x1000: case 0x0900: case 0x0400: case 0x1200: case 0x1400: case 0x1600: case 0x1700: case 0x3200: case 0x3700: case 0x2400: /* Agate */ case 0x3500: /* Agate */ case 0x1100: /* Pearl */ case 0x3100: /* Pearl */ if (data == data1) { *highSmiDevAddr = GT_FALSE; return data; } break; default: break; } return 0; }
/******************************************************************************* * miiSmiManualIfInit * * DESCRIPTION: * This function returns Device ID from the given base address * * INPUTS: * baseAddr - either 0x0 or 0x10. Indicates whether to use the low device * register address or high device register address. * The device register range is from 0x0 to 0xF or from 0x10 * to 0x1F for 5 port switchs and from 0x0 to 0x1B for 8 port * switchs. * * OUTPUTS: * None. * * RETURNS: * DEVICE_ID - on success * 0 - on error * * COMMENTS: * None. * *******************************************************************************/ GT_U16 miiSmiManualIfInit ( IN GT_QD_DEV *dev, IN GT_U32 baseAddr ) { GT_STATUS status; GT_U16 data; if((status = miiSmiIfReadRegister(dev,(GT_U8)(PORT_REGS_START_ADDR+baseAddr),QD_REG_SWITCH_ID,&data)) != GT_OK) { return 0; } switch(data & 0xFF00) { case 0x0200: case 0x0300: case 0x0500: case 0x0600: case 0x1500: case 0xF500: case 0xF900: case 0x0700: /* Spinnaker */ case 0x2200: /* Spinnaker */ case 0x2500: /* Spinnaker */ return data; case 0xC000: /* Melody, Now it could be 0xc00 - 0xc07 */ return data&0xFF0F; default: break; } if(baseAddr != 0) return 0; if((status = miiSmiIfReadRegister(dev,(GT_U8)(PORT_REGS_START_ADDR_8PORT+baseAddr),QD_REG_SWITCH_ID,&data)) != GT_OK) { return 0; } switch(data & 0xFF00) { case 0x0800: case 0x1A00: case 0x1000: case 0x0900: case 0x0400: case 0x1200: case 0x1400: case 0x1600: case 0x3200: case 0x1700: case 0x3700: case 0x2400: /* Agate */ case 0x3500: /* Agate */ case 0x1100: /* Pearl */ case 0x3100: /* Pearl */ case 0xc100: /* ALP Fix */ return data; default: break; } return 0; }
/******************************************************************************* * miiSmiIfInit * * DESCRIPTION: * This function initializes the MII / SMI interface. * * INPUTS: * None. * * OUTPUTS: * highSmiDevAddr - Indicates whether to use the high device register * addresses when accessing switch's registers (of all kinds) * i.e, the devices registers range is 0x10 to 0x1F, or to * use the low device register addresses (range 0x0 to 0xF). * GT_TRUE - use high addresses (0x10 to 0x1F). * GT_FALSE - use low addresses (0x0 to 0xF). * * RETURNS: * DEVICE_ID - on success * 0 - on error * * COMMENTS: * None. * *******************************************************************************/ GT_U16 miiSmiIfInit ( IN GT_QD_DEV *dev, OUT GT_BOOL * highSmiDevAddr ) { GT_STATUS status; GT_U16 data, data1; if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR,QD_REG_SWITCH_ID,&data)) != GT_OK) { return 0; } if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR+1,QD_REG_SWITCH_ID,&data1)) != GT_OK) { return 0; } switch(data & 0xFF00) { case 0x0200: case 0x0300: case 0x0500: case 0x0600: case 0x1500: case 0xF500: case 0xF900: if (data == data1) { *highSmiDevAddr = GT_FALSE; return data; } break; default: break; } if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR+0x10,QD_REG_SWITCH_ID,&data)) != GT_OK) { return 0; } if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR+0x11,QD_REG_SWITCH_ID,&data1)) != GT_OK) { return 0; } switch(data & 0xFF00) { case 0x0200: case 0x0300: case 0x0500: case 0x0600: case 0x1500: case 0xF500: case 0xF900: if (data == data1) { *highSmiDevAddr = GT_TRUE; return data; } break; case 0x0800: case 0x1A00: case 0x1000: case 0x0900: case 0x0400: case 0x1200: case 0x1400: case 0x1600: if((status = miiSmiIfReadRegister(dev,PORT_REGS_START_ADDR+0xF,QD_REG_SWITCH_ID,&data1)) != GT_OK) { return 0; } if (data == data1) { *highSmiDevAddr = GT_FALSE; return data; } break; default: break; } return 0; }