/******************************************************************************* * gstatsGetPortCounter3 * * DESCRIPTION: * This routine gets a specific counter of the given port * * INPUTS: * port - the logical port number. * counter - the counter which will be read * * OUTPUTS: * statsData - points to 32bit data storage for the MIB counter * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * This function supports Gigabit Switch and Spinnaker family * *******************************************************************************/ GT_STATUS gstatsGetPortCounter3 ( IN GT_QD_DEV *dev, IN GT_LPORT port, IN GT_STATS_COUNTERS3 counter, OUT GT_U32 *statsData ) { GT_STATUS retVal; GT_U8 hwPort; /* physical port number */ DBG_INFO(("gstatsGetPortCounters3 Called.\n")); /* translate logical port to physical port */ hwPort = GT_LPORT_2_PORT(port); /* check if device supports this feature */ if((retVal = IS_VALID_API_CALL(dev,hwPort, DEV_RMON)) != GT_OK) { return retVal; } /* Only 88E6093 Switch supports this status. */ if (!IS_IN_DEV_GROUP(dev,DEV_RMON_TYPE_3)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } retVal = statsOperationPerform(dev,STATS_READ_COUNTER,hwPort,counter,(GT_VOID*)statsData); if(retVal != GT_OK) { DBG_INFO(("Failed (statsOperationPerform returned GT_FAIL).\n")); return retVal; } DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * gpcsGetFCValue * * DESCRIPTION: * This routine retrieves Flow Control Value which will be used for Forcing * Flow Control enabled or disabled. * * INPUTS: * port - the logical port number. * * OUTPUTS: * state - GT_TRUE if FC Force value is one (flow control enabled) * GT_FALSE otherwise (flow control disabled) * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_NOT_SUPPORTED - if current device does not support this feature. * * COMMENTS: * * GalTis: * *******************************************************************************/ GT_STATUS gpcsGetFCValue ( IN GT_QD_DEV *dev, IN GT_LPORT port, OUT GT_BOOL *state ) { GT_U16 data; /* Used to poll the SWReset bit */ GT_STATUS retVal; /* Functions return value. */ GT_U8 hwPort; /* the physical port number */ DBG_INFO(("gpcsGetFCValue Called.\n")); /* check if the given Switch supports this feature. */ if (!IS_IN_DEV_GROUP(dev,DEV_FC_WITH_VALUE)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } /* translate LPORT to hardware port */ hwPort = GT_LPORT_2_PORT(port); /* Get the FCValue bit. */ retVal = hwGetPortRegField(dev,hwPort, QD_REG_PCS_CONTROL,7,1,&data); /* translate binary to BOOL */ BIT_2_BOOL(data, *state); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); } else { DBG_INFO(("OK.\n")); } /* return */ return retVal; }
/******************************************************************************* * gpcsGetForceSpeed * * DESCRIPTION: * This routine retrieves Force Speed value * * INPUTS: * port - the logical port number. * * OUTPUTS: * state - GT_PORT_FORCED_SPEED_MODE (10, 100, 1000, or no force speed) * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_NOT_SUPPORTED - if current device does not support this feature. * * COMMENTS: * * GalTis: * *******************************************************************************/ GT_STATUS gpcsGetForceSpeed ( IN GT_QD_DEV *dev, IN GT_LPORT port, OUT GT_PORT_FORCED_SPEED_MODE *mode ) { GT_U16 data; /* Used to poll the SWReset bit */ GT_STATUS retVal; /* Functions return value. */ GT_U8 hwPort; /* the physical port number */ DBG_INFO(("gpcsGetForceSpeed Called.\n")); /* check if the given Switch supports this feature. */ if (!IS_IN_DEV_GROUP(dev,DEV_FORCE_WITH_VALUE)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } /* translate LPORT to hardware port */ hwPort = GT_LPORT_2_PORT(port); /* Get the ForceSpeed bits. */ retVal = hwGetPortRegField(dev,hwPort, QD_REG_PCS_CONTROL,0,2,&data); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); } else { DBG_INFO(("OK.\n")); } *mode = data; /* return */ return retVal; }
/******************************************************************************* * qdAccessRegs * * DESCRIPTION: * This function access registers through device interface * (like Marvell F2R on ethernet) by user, to be used by upper layers. * * INPUTS: * regList - list of HW_DEV_RW_REG. * HW_DEV_RW_REG includes: * cmd - HW_REG_READ, HW_REG_WRITE, HW_REG_WAIT_TILL_0 or HW_REG_WAIT_TILL_1 * addr - SMI Address * reg - Register offset * data - INPUT,OUTPUT:Value in the Register or Bit number * * OUTPUTS: * regList - list of HW_DEV_RW_REG. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * None. * *******************************************************************************/ GT_STATUS qdAccessRegs ( IN GT_QD_DEV *dev, INOUT HW_DEV_REG_ACCESS *regList ) { if((dev->accessMode == SMI_MULTI_ADDR_MODE) && (dev->fgtHwAccessMod == HW_ACCESS_MODE_SMI)) { if(qdMultiAddrAccess(dev, regList) != GT_TRUE) { return GT_FAIL; } } else { if ((IS_IN_DEV_GROUP(dev,DEV_RMGMT)) && (dev->fgtHwAccess != NULL) && (dev->fgtHwAccessMod == HW_ACCESS_MODE_F2R) ) { if(dev->fgtHwAccess(dev, regList) != GT_TRUE) { if(fgtAccessRegs(dev, regList) != GT_TRUE) { return GT_FAIL; } } } else { if(fgtAccessRegs(dev, regList) != GT_TRUE) { return GT_FAIL; } } } return GT_OK; }
/******************************************************************************* * eventSetActive * * DESCRIPTION: * This routine enables/disables the receive of an hardware driven event. * * INPUTS: * eventType - the event type. any combination of the folowing: * GT_STATS_DONE, GT_VTU_PROB, GT_VTU_DONE, GT_ATU_FULL(or GT_ATU_PROB), * GT_ATU_DONE, GT_PHY_INTERRUPT, and GT_EE_INTERRUPT * * OUTPUTS: * None. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * None. * * GalTis: * *******************************************************************************/ GT_STATUS eventSetActive ( IN GT_QD_DEV *dev, IN GT_U32 eventType ) { GT_STATUS retVal; GT_U16 data; GT_U16 intMask; DBG_INFO(("eventSetActive Called.\n")); data = (GT_U16) eventType; if (IS_IN_DEV_GROUP(dev,DEV_EXTERNAL_PHY_ONLY)) { intMask = GT_NO_INTERNAL_PHY_INT_MASK; } else { intMask = GT_INT_MASK; } if(data & ~intMask) { DBG_INFO(("Invalid event type.\n")); return GT_FAIL; } /* Set the IntEn bit. */ retVal = hwSetGlobalRegField(dev,QD_REG_GLOBAL_CONTROL,0,7,data); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); return retVal; } DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * gstatsGetPortAllCounters * * DESCRIPTION: * This routine gets all counters of the given port * * INPUTS: * port - the logical port number. * * OUTPUTS: * statsCounterSet - points to GT_STATS_COUNTER_SET for the MIB counters * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * None * * GalTis: * *******************************************************************************/ GT_STATUS gstatsGetPortAllCounters ( IN GT_QD_DEV *dev, IN GT_LPORT port, OUT GT_STATS_COUNTER_SET *statsCounterSet ) { GT_STATUS retVal; GT_U8 hwPort; /* physical port number */ DBG_INFO(("gstatsFlushPort Called.\n")); /* translate logical port to physical port */ hwPort = GT_LPORT_2_PORT(port); /* check if device supports this feature */ if((retVal = IS_VALID_API_CALL(dev,hwPort, DEV_RMON)) != GT_OK) { return retVal; } /* Gigabit Switch does not support this status. */ if (!IS_IN_DEV_GROUP(dev,DEV_RMON_TYPE_1)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } retVal = statsOperationPerform(dev,STATS_READ_ALL,hwPort,0,(GT_VOID*)statsCounterSet); if(retVal != GT_OK) { DBG_INFO(("Failed (statsOperationPerform returned GT_FAIL).\n")); return retVal; } DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * geventGetAgeIntEn * * DESCRIPTION: * This routine gets Age Interrupt Enable for the port. * When it's enabled, ATU Age Violation interrupts from this port are enabled. * An Age Violation will occur anytime a port is Locked(gprtSetLockedPort) * and the ingressing frame's SA is contained in the ATU as a non-Static * entry with a EntryState less than 0x4. * * INPUTS: * port - the logical port number * mode - GT_TRUE to enable Age Interrupt, * GT_FALUSE to disable * * OUTPUTS: * None. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_NOT_SUPPORTED - if current device does not support this feature. * * COMMENTS: * *******************************************************************************/ GT_STATUS geventGetAgeIntEn ( IN GT_QD_DEV *dev, IN GT_LPORT port, OUT GT_BOOL *mode ) { GT_U16 data; GT_STATUS retVal; /* Functions return value. */ GT_U8 hwPort; /* the physical port number */ DBG_INFO(("geventGetAgeIntEn Called.\n")); /* translate LPORT to hardware port */ hwPort = GT_LPORT_2_PORT(port); if (!IS_IN_DEV_GROUP(dev,DEV_PORT_BASED_AGE_INT)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } /* Get Age Interrupt Enable Mode. */ retVal = hwGetPortRegField(dev,hwPort, QD_REG_PORT_ASSOCIATION,11,1,&data); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); } else { DBG_INFO(("OK.\n")); } BIT_2_BOOL(data, *mode); return retVal; }
/******************************************************************************* * gpavGetIngressMonitor * * DESCRIPTION: * This routine gets the Ingress Monitor bit in the PAV. * * INPUTS: * port - the logical port number. * * OUTPUTS: * mode - the ingress monitor bit in the PAV * GT_FALSE: Ingress Monitor enabled * GT_TRUE: Ingress Monitor disabled * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_BAD_PARAM - on bad parameters * * COMMENTS: * * * GalTis: * *******************************************************************************/ GT_STATUS gpavGetIngressMonitor ( IN GT_QD_DEV *dev, IN GT_LPORT port, OUT GT_BOOL *mode ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data; /* The register's read data. */ GT_U8 phyPort; /* Physical port. */ DBG_INFO(("grcGetIngressMonitor Called.\n")); if(mode == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } phyPort = GT_LPORT_2_PORT(port); /* check if device supports this feature */ if (!IS_IN_DEV_GROUP(dev,DEV_ENABLE_MONITORING)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } retVal = hwGetPortRegField(dev,phyPort,QD_REG_PORT_ASSOCIATION,15,1,&data); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); return retVal; } BIT_2_BOOL(data,*mode); DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * gstuDelEntry * * DESCRIPTION: * Deletes STU entry specified by user. * * INPUTS: * stuEntry - the STU entry to be deleted * * OUTPUTS: * None. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_NOT_SUPPORTED - if current device does not support this feature. * * COMMENTS: * Valid SID is 1 ~ 63. * *******************************************************************************/ GT_STATUS gstuDelEntry ( IN GT_QD_DEV *dev, IN GT_STU_ENTRY *stuEntry ) { GT_U8 valid; GT_STATUS retVal; GT_STU_ENTRY entry; DBG_INFO(("gstuDelEntry Called.\n")); /* check if device supports this feature */ if (!IS_IN_DEV_GROUP(dev,DEV_802_1S_STU)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } if((stuEntry->sid == 0) || (stuEntry->sid > 0x3F)) { DBG_INFO(("GT_BAD_PARAM\n")); return GT_BAD_PARAM; } entry.sid = stuEntry->sid; valid = 0; /* for delete operation */ retVal = stuOperationPerform(dev,LOAD_PURGE_STU_ENTRY,&valid, &entry); if(retVal != GT_OK) { DBG_INFO(("Failed (stuOperationPerform returned GT_FAIL).\n")); return retVal; } DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * gpavSetIngressMonitor * * DESCRIPTION: * This routine sets the Ingress Monitor bit in the PAV. * * INPUTS: * port - the logical port number. * mode - the ingress monitor bit in the PAV * GT_FALSE: Ingress Monitor enabled * GT_TRUE: Ingress Monitor disabled * OUTPUTS: * None. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * * * GalTis: * *******************************************************************************/ GT_STATUS gpavSetIngressMonitor ( IN GT_QD_DEV *dev, IN GT_LPORT port, IN GT_BOOL mode ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data; /* Data to be set into the */ /* register. */ GT_U8 phyPort; /* Physical port. */ DBG_INFO(("gpavSetIngressMonitorCalled.\n")); phyPort = GT_LPORT_2_PORT(port); BOOL_2_BIT(mode,data); /* check if device supports this feature */ if((retVal = IS_VALID_API_CALL(dev,phyPort, DEV_PORT_MONITORING)) != GT_OK ) return retVal; if (!IS_IN_DEV_GROUP(dev,DEV_ENABLE_MONITORING)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } retVal = hwSetPortRegField(dev,phyPort,QD_REG_PORT_ASSOCIATION,15,1,data); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); return retVal; } DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * gsysGetInitReady * * DESCRIPTION: * This routine get the InitReady bit. This bit is set to a one when the ATU, * the Queue Controller and the Statistics Controller are done with their * initialization and are ready to accept frames. * * INPUTS: * None. * * OUTPUTS: * mode - GT_TRUE: switch is ready, GT_FALSE otherwise. * * RETURNS: * GT_OK - on success * GT_BAD_PARAM - on bad parameter * GT_FAIL - on error * * COMMENTS: * None. * * GalTis: * *******************************************************************************/ GT_STATUS gsysGetInitReady ( IN GT_QD_DEV *dev, OUT GT_BOOL *mode ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data; /* The register's read data. */ DBG_INFO(("gsysGetInitReady Called.\n")); /* check if device supports this feature */ if (!IS_IN_DEV_GROUP(dev,DEV_QD_PLUS|DEV_ENHANCED_FE_SWITCH)) { DBG_INFO(("Not Supported.\n")); return GT_NOT_SUPPORTED; } if(mode == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* get the bits from hardware */ retVal = hwGetGlobalRegField(dev,QD_REG_GLOBAL_STATUS,11,1,&data); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); return retVal; } BIT_2_BOOL(data,*mode); DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * gsysGetSW_Mode * * DESCRIPTION: * This routine get the Switch mode. These two bits returen * the current value of the SW_MODE[1:0] pins. * * INPUTS: * None. * * OUTPUTS: * mode - GT_TRUE Discard is enabled, GT_FALSE otherwise. * * RETURNS: * GT_OK - on success * GT_BAD_PARAM - on bad parameter * GT_FAIL - on error * * COMMENTS: * None. * * GalTis: * *******************************************************************************/ GT_STATUS gsysGetSW_Mode ( IN GT_QD_DEV *dev, OUT GT_SW_MODE *mode ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data; /* The register's read data. */ DBG_INFO(("gsysGetSW_Mode Called.\n")); /* check if device supports this feature */ if (!(IS_IN_DEV_GROUP(dev,DEV_SWITCH_MODE)) ) { DBG_INFO(("Not Supported.\n")); return GT_NOT_SUPPORTED; } if(mode == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* get the bits from hardware */ retVal = hwGetGlobalRegField(dev,QD_REG_GLOBAL_STATUS,12,2,&data); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); return retVal; } *mode = data; DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * gsysSetQoSWeight * * DESCRIPTION: * Programmable Round Robin Weights. * Each port has 4/8 output Queues. Queue 3/7 has the highest priority and * Queue 0 has the lowest priority. When a scheduling mode of port is * configured as Weighted Round Robin queuing mode, the access sequece of the * Queue is 3,2,3,1,3,2,3,0,3,2,3,1,3,2,3 by default. * (Queue is 7,6,5,7,1,6,7,4 by default. That is after 6390.) * This sequence can be configured with this API. * * INPUTS: * weight - access sequence of the queue * * OUTPUTS: * None. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_NOT_SUPPORTED - if current device does not support this feature. * * COMMENTS: * None * *******************************************************************************/ GT_STATUS gsysSetQoSWeight ( IN GT_QD_DEV *dev, IN GT_QoS_WEIGHT *weight ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data; GT_U32 len, i; int length_loc, entry_num; DBG_INFO(("gsysSetQoSWeight Called.\n")); /* Check if Switch supports this feature. */ if (!IS_IN_DEV_GROUP(dev,DEV_QoS_WEIGHT)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } if (IS_IN_DEV_GROUP(dev,DEV_QoS_WEIGHT_1)) { length_loc = 0x40; entry_num = 2; } else { length_loc = 0x20; entry_num = 4; } if (weight->len > 128) { DBG_INFO(("GT_BAD_PARAM\n")); return GT_BAD_PARAM; } gtSemTake(dev,dev->tblRegsSem,OS_WAIT_FOREVER); len = weight->len/entry_num; /* program QoS Weight Table, 4/2 sequences at a time */ for(i=0; i<len; i++) { /* Wait until the QoS Weight Table is ready. */ #ifdef GT_RMGMT_ACCESS { HW_DEV_REG_ACCESS regAccess; regAccess.entries = 2; regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0; regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS); regAccess.rw_reg_list[0].reg = QD_REG_QOS_WEIGHT; regAccess.rw_reg_list[0].data = 15; regAccess.rw_reg_list[1].cmd = HW_REG_WRITE; regAccess.rw_reg_list[1].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL2_REG_ACCESS); regAccess.rw_reg_list[1].reg = QD_REG_QOS_WEIGHT; if (IS_IN_DEV_GROUP(dev,DEV_QoS_WEIGHT_1)) { data = (GT_U16)((1 << 15) | (i << 8) | (weight->queue[i*2] & 0x7) | ((weight->queue[i*2+1] & 0x7) << 4); } else { data = (GT_U16)((1 << 15) | (i << 8) | (weight->queue[i*4] & 0x3) | ((weight->queue[i*4+1] & 0x3) << 2) | ((weight->queue[i*4+2] & 0x3) << 4) | ((weight->queue[i*4+3] & 0x3) << 6)); } regAccess.rw_reg_list[1].data = data; retVal = hwAccessMultiRegs(dev, ®Access); if(retVal != GT_OK) { gtSemGive(dev,dev->tblRegsSem); return retVal; } } #else data = 1; while(data == 1) { retVal = hwGetGlobal2RegField(dev,QD_REG_QOS_WEIGHT,15,1,&data); if(retVal != GT_OK) { gtSemGive(dev,dev->tblRegsSem); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_QoS_WEIGHT_1)) { data = (GT_U16)((1 << 15) | (i << 8) | (weight->queue[i*2] & 0x7) | ((weight->queue[i*2+1] & 0x7) << 4)); } else { data = (GT_U16)((1 << 15) | (i << 8) | (weight->queue[i*4] & 0x3) | ((weight->queue[i*4+1] & 0x3) << 2) | ((weight->queue[i*4+2] & 0x3) << 4) | ((weight->queue[i*4+3] & 0x3) << 6)); } retVal = hwWriteGlobal2Reg(dev, QD_REG_QOS_WEIGHT, data); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); gtSemGive(dev,dev->tblRegsSem); return retVal; } #endif }
/******************************************************************************* * gprtGetSerdesReg * * DESCRIPTION: * This routine reads Phy Serdes Registers. * * INPUTS: * port - The logical port number. * regAddr - The register's address. * * OUTPUTS: * data - The read register's data. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * None. * * GalTis: * *******************************************************************************/ GT_STATUS gprtGetSerdesReg ( IN GT_QD_DEV *dev, IN GT_LPORT port, IN GT_U32 regAddr, OUT GT_U16 *data ) { GT_U8 hwPort, serdesPort; /* the physical port number */ GT_U8 pageNum = _getSerdesPageNumber(dev); GT_PHY_INFO serdesInfo; DBG_INFO(("gprtGetSerdesReg Called.\n")); if(!IS_IN_DEV_GROUP(dev,DEV_SERDES_UP_PORT)) { return GT_NOT_SUPPORTED; } /* check if input is logical port number */ /* hwPort = GT_LPORT_2_PORT(port); GT_GET_SERDES_PORT(dev,&hwPort); */ hwPort = qdLong2Char(port); serdesPort = hwPort; GT_GET_SERDES_PORT(dev,&serdesPort); if(hwPort > dev->maxPhyNum) { /* check if input is physical serdes address */ if(dev->validSerdesVec & (1<<port)) { hwPort = (GT_U8)port; } else return GT_NOT_SUPPORTED; } //printf("===GT_GET_SERDES_PORT serdesPort = %d ,hwPort = %d\r\n",serdesPort,hwPort); gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER); /* check if the port is configurable */ if((serdesInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY) { gtSemGive(dev,dev->phyRegsSem); return GT_NOT_SUPPORTED; } if(driverFindPhyInformation(dev,hwPort,&serdesInfo) != GT_OK) { DBG_INFO(("Unknown PHY device.\n")); gtSemGive(dev,dev->phyRegsSem); return GT_FAIL; } /* Get Serdes Register. */ /* Write to Serdes Register */ //printf("===hwReadPagedPhyReg serdesPort= %d, pageNum = %d,regAddr = %x,serdesInfo.anyPage = %d \r\n",serdesPort,pageNum,(GT_U8)regAddr,serdesInfo.anyPage); if(hwReadPagedPhyReg(dev,serdesPort,pageNum,(GT_U8)regAddr,serdesInfo.anyPage,data) != GT_OK) { DBG_INFO(("Failed.\n")); gtSemGive(dev,dev->phyRegsSem); return GT_FAIL; } gtSemGive(dev,dev->phyRegsSem); return GT_OK; }
/******************************************************************************* * gprtSetSerdesMode * * DESCRIPTION: * This routine sets Serdes Interface Mode. * * INPUTS: * port - The physical SERDES device address(4/5) * mode - Serdes Interface Mode * * OUTPUTS: * None. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * logical port number is supported only for the devices made production * before 2009. * (Serdes devices: 88E6131, 88E6122, 88E6108, 88E6161, 88E6165 family) * *******************************************************************************/ GT_STATUS gprtSetSerdesMode ( IN GT_QD_DEV *dev, IN GT_LPORT port, IN GT_SERDES_MODE mode ) { GT_U16 u16Data; GT_U8 hwPort, serdesPort; /* the physical port number */ GT_U8 pageNum = _getSerdesPageNumber(dev); GT_STATUS retVal; GT_PHY_INFO serdesInfo; DBG_INFO(("gprtSetSerdesMode Called.\n")); if(!IS_IN_DEV_GROUP(dev,DEV_SERDES_CORE)) { return GT_NOT_SUPPORTED; } if(IS_IN_DEV_GROUP(dev,DEV_SERDES_CORE_1)) { return GT_NOT_SUPPORTED; } /* check if input is logical port number */ hwPort = GT_LPORT_2_PORT(port); serdesPort = hwPort; GT_GET_SERDES_PORT(dev,&serdesPort); u16Data = mode; gtSemTake(dev,dev->phyRegsSem,OS_WAIT_FOREVER); /* check if the port is configurable */ if((serdesInfo.phyId=GT_GET_PHY_ID(dev,hwPort)) == GT_INVALID_PHY) { gtSemGive(dev,dev->phyRegsSem); return GT_NOT_SUPPORTED; } if(driverFindPhyInformation(dev,hwPort,&serdesInfo) != GT_OK) { DBG_INFO(("Unknown PHY device.\n")); gtSemGive(dev,dev->phyRegsSem); return GT_FAIL; } /* Set Serdes Register. */ if(hwSetPagedPhyRegField(dev,serdesPort, pageNum, 16,0,2,serdesInfo.anyPage,u16Data) != GT_OK) { DBG_INFO(("Failed.\n")); gtSemGive(dev,dev->phyRegsSem); return GT_FAIL; } gtSemGive(dev,dev->phyRegsSem); retVal = hwSerdesReset(dev,serdesPort,pageNum, 0xFF); gtSemGive(dev,dev->phyRegsSem); return retVal; }
/******************************************************************************* * statsCapture * * DESCRIPTION: * This function is used to capture all counters of a port. * * INPUTS: * port - port number * * OUTPUTS: * None. * * RETURNS: * GT_OK on success, * GT_FAIL otherwise. * * COMMENTS: * If Semaphore is used, Semaphore should be acquired before this function call. *******************************************************************************/ static GT_STATUS statsCapture ( IN GT_QD_DEV *dev, IN GT_U8 port ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data, histoData;/* Data to be set into the */ /* register. */ GT_U16 portNum; if (IS_IN_DEV_GROUP(dev,DEV_RMON_PORT_BITS)) { portNum = (port + 1) << 5; } else { portNum = (GT_U16)port; } /* Get the Histogram mode bit. */ retVal = hwReadGlobalReg(dev,QD_REG_STATS_OPERATION,&histoData); if(retVal != GT_OK) { return retVal; } histoData &= 0xC00; #ifdef GT_RMGMT_ACCESS { HW_DEV_REG_ACCESS regAccess; regAccess.entries = 1; regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0; regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS); regAccess.rw_reg_list[0].reg = QD_REG_STATS_OPERATION; regAccess.rw_reg_list[0].data = 15; retVal = hwAccessMultiRegs(dev, ®Access); if(retVal != GT_OK) { return retVal; } } #else data = 1; while(data == 1) { retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data); if(retVal != GT_OK) { return retVal; } } #endif data = (1 << 15) | (GT_STATS_CAPTURE_PORT << 12) | portNum | histoData; retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data); if(retVal != GT_OK) { return retVal; } return GT_OK; }
/******************************************************************************* * gprtSetPolicy * * DESCRIPTION: * This routine sets the Policy for ports. * Supported Policies are defined as GT_FRAME_POLICY as follows: * FRAME_POLICY_NONE - normal frame switching * FRAME_POLICY_MIRROR - mirror (copy) frame to MirrorDest port * FRAME_POLICY_TRAP - trap(re-direct) frame to the CPUDest port * FRAME_POLICY_DISCARD - discard(filter) the frame * Supported Policy types are defined as GT_POLICY_TYPE: * POLICY_TYPE_DA - DA Policy Mapping * DA Policy Mapping occurs when the DA of a frame is contained in * the ATU address database with an Entry State that indicates Policy. * POLICY_TYPE_SA - SA Policy Mapping * SA Policy Mapping occurs when the SA of a frame is contained in * the ATU address database with an Entry State that indicates Policy. * POLICY_TYPE_VTU - VTU Policy Mapping * VTU Policy Mapping occurs when the VID of a frame is contained in * the VTU database with the VidPolicy is enabled. * POLICY_TYPE_ETYPE - EtherType Policy Mapping * EType Policy Mapping occurs when the EtherType of a frame matches * the PortEType (see gprtSetPortEType API) * POLICY_TYPE_PPPoE - PPPoE Policy Mapping * PPPoE Policy Mapping occurs when the EtherType of a frame matches 0x8863 * POLICY_TYPE_VBAS - VBAS Policy Mapping * VBAS Policy Mapping occurs when the EtherType of a frame matches 0x8200 * POLICY_TYPE_OPT82 - DHCP Option 82 Policy Mapping * DHCP Option 82 Policy Mapping occurs when the ingressing frame is an * IPv4 UDP with a UDP Destination port = 0x0043 or 0x0044, or an * IPv6 UDP with a UDP Destination port = 0x0223 or 0x0222 * POLICY_TYPE_UDP - UDP Policy Mapping * UDP Policy Mapping occurs when the ingressing frame is * a Broadcast IPv4 UDP or a Multicast IPv6 UDP. * * INPUTS: * port - logical port number. * type - policy type (GT_POLICY_TYPE) * policy - policy (GT_FRAME_POLICY) * * OUTPUTS: * None. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_BAD_PARAM - on bad parameters * GT_NOT_SUPPORTED - if current device does not support this feature. * * COMMENTS: * * GalTis: * *******************************************************************************/ GT_STATUS gprtSetPolicy ( IN GT_QD_DEV *dev, IN GT_LPORT port, IN GT_POLICY_TYPE type, IN GT_FRAME_POLICY policy ) { GT_STATUS retVal; /* Functions return value. */ GT_U8 hwPort; /* Physical port. */ GT_U8 offset; DBG_INFO(("gprtSetPolicy Called.\n")); /* translate LPORT to hardware port */ hwPort = GT_LPORT_2_PORT(port); /* check if device supports this feature */ if (!IS_IN_DEV_GROUP(dev,DEV_POLICY)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } switch (policy) { case FRAME_POLICY_NONE: case FRAME_POLICY_MIRROR: case FRAME_POLICY_TRAP: case FRAME_POLICY_DISCARD: break; default: DBG_INFO(("Bad Policy\n")); return GT_BAD_PARAM; } switch (type) { case POLICY_TYPE_DA: offset = 14; break; case POLICY_TYPE_SA: offset = 12; break; case POLICY_TYPE_VTU: offset = 10; break; case POLICY_TYPE_ETYPE: offset = 8; break; case POLICY_TYPE_PPPoE: offset = 6; break; case POLICY_TYPE_VBAS: offset = 4; break; case POLICY_TYPE_OPT82: offset = 2; break; case POLICY_TYPE_UDP: offset = 0; break; default: DBG_INFO(("Bad Parameter\n")); return GT_BAD_PARAM; } retVal = hwSetPortRegField(dev,hwPort, QD_REG_POLICY_CONTROL, offset, 2, (GT_U16)policy); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); return retVal; } DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * qdLoadDriver * * DESCRIPTION: * QuarterDeck Driver Initialization Routine. * This is the first routine that needs be called by system software. * It takes *cfg from system software, and retures a pointer (*dev) * to a data structure which includes infomation related to this QuarterDeck * device. This pointer (*dev) is then used for all the API functions. * * INPUTS: * cfg - Holds device configuration parameters provided by system software. * * OUTPUTS: * dev - Holds device information to be used for each API call. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_ALREADY_EXIST - if device already started * GT_BAD_PARAM - on bad parameters * * COMMENTS: * qdUnloadDriver is also provided to do driver cleanup. * *******************************************************************************/ GT_STATUS qdLoadDriver ( IN GT_SYS_CONFIG *cfg, OUT GT_QD_DEV *dev ) { GT_STATUS retVal; GT_LPORT port; DBG_INFO(("qdLoadDriver Called.\n")); /* Check for parameters validity */ if(dev == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* Check for parameters validity */ if(cfg == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* The initialization was already done. */ if(dev->devEnabled) { DBG_INFO(("QuarterDeck already started.\n")); return GT_ALREADY_EXIST; } if(gtRegister(dev,&(cfg->BSPFunctions)) != GT_TRUE) { DBG_INFO(("gtRegister Failed.\n")); return GT_FAIL; } dev->accessMode = (GT_U8)cfg->mode.scanMode; if (dev->accessMode == SMI_MULTI_ADDR_MODE) { dev->baseRegAddr = 0; dev->phyAddr = (GT_U8)cfg->mode.baseAddr; } else { dev->baseRegAddr = (GT_U8)cfg->mode.baseAddr; dev->phyAddr = 0; } /* Initialize the driver */ retVal = driverConfig(dev); if(retVal != GT_OK) { DBG_INFO(("driverConfig Failed.\n")); return retVal; } /* Initialize dev fields. */ dev->cpuPortNum = cfg->cpuPortNum; dev->maxPhyNum = 5; dev->devGroup = 0; dev->devStorage = 0; /* Assign Device Name */ switch(dev->deviceId) { case GT_88E6021: dev->numOfPorts = 3; dev->maxPorts = 3; dev->maxPhyNum = 2; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6021; break; case GT_88E6051: dev->numOfPorts = 5; dev->maxPorts = 5; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6051; break; case GT_88E6052: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6052; break; case GT_88E6060: if((dev->cpuPortNum != 4)&&(dev->cpuPortNum != 5)) { return GT_FAIL; } dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6060; break; case GT_88E6031: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 3; dev->validPortVec = 0x31; /* port 0, 4, and 5 */ dev->validPhyVec = 0x31; /* port 0, 4, and 5 */ dev->devName = DEV_88E6061; break; case GT_88E6061: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6061; break; case GT_88E6035: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 3; dev->validPortVec = 0x31; /* port 0, 4, and 5 */ dev->validPhyVec = 0x31; /* port 0, 4, and 5 */ dev->devName = DEV_88E6065; break; case GT_88E6055: dev->numOfPorts = 5; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = 0x2F; /* port 0,1,2,3, and 5 */ dev->validPhyVec = 0x2F; /* port 0,1,2,3, and 5 */ dev->devName = DEV_88E6065; break; case GT_88E6065: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6065; break; case GT_88E6063: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6063; break; case GT_FH_VPN: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FH_VPN; break; case GT_FF_EG: if(dev->cpuPortNum != 5) { return GT_FAIL; } dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FF_EG; break; case GT_FF_HG: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FF_HG; break; case GT_88E6083: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 8; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6083; break; case GT_88E6153: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6183; break; case GT_88E6181: dev->numOfPorts = 8; dev->maxPorts = 8; dev->maxPhyNum = 8; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6181; break; case GT_88E6183: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6183; break; case GT_88E6093: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6093; break; case GT_88E6092: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6092; break; case GT_88E6095: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6095; break; case GT_88E6045: dev->numOfPorts = 6; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = 0x60F; dev->validPhyVec = 0x60F; dev->devName = DEV_88E6095; break; case GT_88E6097: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6097; break; case GT_88E6096: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6096; break; case GT_88E6047: dev->numOfPorts = 6; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = 0x60F; dev->validPhyVec = 0x60F; dev->devName = DEV_88E6097; break; case GT_88E6046: dev->numOfPorts = 6; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = 0x60F; dev->validPhyVec = 0x60F; dev->devName = DEV_88E6096; break; case GT_88E6085: dev->numOfPorts = 10; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = 0x6FF; dev->validPhyVec = 0x6FF; dev->devName = DEV_88E6096; break; case GT_88E6152: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6182; break; case GT_88E6155: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6185; break; case GT_88E6182: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6182; break; case GT_88E6185: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6185; break; case GT_88E6121: dev->numOfPorts = 3; dev->maxPorts = 8; dev->maxPhyNum = 3; dev->validPortVec = 0xE; /* port 1, 2, and 3 */ dev->validPhyVec = 0xE; /* port 1, 2, and 3 */ dev->devName = DEV_88E6108; break; case GT_88E6122: dev->numOfPorts = 6; dev->maxPorts = 8; dev->maxPhyNum = 16; dev->validPortVec = 0x7E; /* port 1 ~ 6 */ dev->validPhyVec = 0xF07E; /* port 1 ~ 6, 12 ~ 15 (serdes) */ dev->validSerdesVec = 0xF000; dev->devName = DEV_88E6108; break; case GT_88E6131: case GT_88E6108: dev->numOfPorts = 8; dev->maxPorts = 8; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->validSerdesVec = 0xF000; dev->devName = DEV_88E6108; break; case GT_88E6123: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = 0x23; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6161; break; case GT_88E6140: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6165; break; case GT_88E6161: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6161; break; case GT_88E6165: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6165; break; case GT_KW2_INT : dev->deviceId = GT_88E6351; /* fall through */ case GT_88E6351: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 7; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->devName = DEV_88E6351; break; case GT_88E6175: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 7; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->devName = DEV_88E6175; break; case GT_88E6125 : dev->numOfPorts = 4; dev->maxPorts = 7; dev->maxPhyNum = 7; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPortVec &= ~(0x7); dev->validPhyVec = 0x78; dev->devName = DEV_88E6171; break; case GT_88E6171 : dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 7; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->devName = DEV_88E6171; break; case GT_88E6321 : dev->numOfPorts = 4; dev->maxPorts = 7; dev->maxPhyNum = 7; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPortVec &= ~(0x7); dev->validPhyVec = 0x78; dev->devName = DEV_88E6371; break; case GT_88E6350 : dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 7; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->devName = DEV_88E6371; break; default: DBG_INFO(("Unknown Device. Initialization failed\n")); return GT_FAIL; } dev->cpuPortNum = GT_PORT_2_LPORT(cfg->cpuPortNum); if(dev->cpuPortNum == GT_INVALID_PORT) { if(GT_LPORT_2_PORT((GT_LPORT)cfg->cpuPortNum) != GT_INVALID_PORT) { dev->cpuPortNum = cfg->cpuPortNum; } else { return GT_BAD_CPU_PORT; } } /* Initialize the MultiAddress Register Access semaphore. */ if((dev->multiAddrSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the ATU semaphore. */ if((dev->atuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the VTU semaphore. */ if((dev->vtuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the STATS semaphore. */ if((dev->statsRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PIRL semaphore. */ if((dev->pirlRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PTP semaphore. */ if((dev->ptpRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the Table semaphore. */ if((dev->tblRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the EEPROM Configuration semaphore. */ if((dev->eepromRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PHY Device Register Access semaphore. */ if((dev->phyRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the ports states to forwarding mode. */ if(cfg->initPorts == GT_TRUE) { for (port=0; port<dev->numOfPorts; port++) { if((retVal = gstpSetPortState(dev,port,GT_PORT_FORWARDING)) != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } } if(cfg->skipInitSetup == GT_SKIP_INIT_SETUP) { dev->devEnabled = 1; dev->devNum = cfg->devNum; DBG_INFO(("OK.\n")); return GT_OK; } if(IS_IN_DEV_GROUP(dev,DEV_ENHANCED_CPU_PORT)) { if((retVal = gsysSetRsvd2CpuEnables(dev,0)) != GT_OK) { DBG_INFO(("gsysGetRsvd2CpuEnables failed.\n")); qdUnloadDriver(dev); return retVal; } if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK) { DBG_INFO(("gsysSetRsvd2Cpu failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_CPU_DEST_PER_PORT)) { for (port=0; port<dev->numOfPorts; port++) { retVal = gprtSetCPUPort(dev,port,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } } if(IS_IN_DEV_GROUP(dev,DEV_CPU_PORT)) { retVal = gsysSetCPUPort(dev,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if(IS_IN_DEV_GROUP(dev,DEV_CPU_DEST)) { retVal = gsysSetCPUDest(dev,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if(IS_IN_DEV_GROUP(dev,DEV_MULTICAST)) { if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK) { DBG_INFO(("gsysSetRsvd2Cpu failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) { retVal = gpirlInitialize(dev); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_PIRL2_RESOURCE)) { retVal = gpirl2Initialize(dev); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } dev->devEnabled = 1; dev->devNum = cfg->devNum; DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * driverFindPhyInformation * * DESCRIPTION: * This function gets information of Phy connected to the given port. * PhyInfo structure should have valid Phy ID. * * INPUTS: * hwPort - port number where the Phy is connected * * OUTPUTS: * phyId - Phy ID * * RETURNS: * GT_OK - if found Marvell Phy, * GT_FAIL - othrwise. * * COMMENTS: * None. * *******************************************************************************/ GT_STATUS driverFindPhyInformation ( IN GT_QD_DEV *dev, IN GT_U8 hwPort, OUT GT_PHY_INFO *phyInfo ) { GT_U32 phyId; GT_U16 data; phyId = phyInfo->phyId; switch (phyId & PHY_MODEL_MASK) { case DEV_E3082: phyInfo->anyPage = 0xFFFFFFFF; phyInfo->flag = GT_PHY_VCT_CAPABLE|GT_PHY_DTE_CAPABLE| GT_PHY_MAC_IF_LOOP|GT_PHY_EXTERNAL_LOOP| GT_PHY_COPPER; phyInfo->vctType = GT_PHY_VCT_TYPE1; phyInfo->exStatusType = 0; if ((phyId & PHY_REV_MASK) < 9) phyInfo->dteType = GT_PHY_DTE_TYPE1; /* need workaround */ else phyInfo->dteType = GT_PHY_DTE_TYPE5; phyInfo->pktGenType = 0; phyInfo->macIfLoopType = GT_PHY_LOOPBACK_TYPE1; phyInfo->lineLoopType = 0; phyInfo->exLoopType = GT_PHY_EX_LB_TYPE0; phyInfo->pageType = GT_PHY_NO_PAGE; break; case DEV_E104X: phyInfo->anyPage = 0xFFFFFFFF; phyInfo->flag = GT_PHY_VCT_CAPABLE|GT_PHY_GIGABIT| GT_PHY_MAC_IF_LOOP|GT_PHY_EXTERNAL_LOOP; phyInfo->dteType = 0; if ((phyId & PHY_REV_MASK) < 3) phyInfo->flag &= ~GT_PHY_VCT_CAPABLE; /* VCT is not supported */ else if ((phyId & PHY_REV_MASK) == 3) phyInfo->vctType = GT_PHY_VCT_TYPE3; /* Need workaround */ else phyInfo->vctType = GT_PHY_VCT_TYPE2; phyInfo->exStatusType = 0; phyInfo->pktGenType = 0; phyInfo->macIfLoopType = GT_PHY_LOOPBACK_TYPE1; phyInfo->lineLoopType = 0; phyInfo->exLoopType = GT_PHY_EX_LB_TYPE0; phyInfo->pageType = GT_PHY_NO_PAGE; break; case DEV_E1111: phyInfo->anyPage = 0xFFF1FE0C; phyInfo->flag = GT_PHY_VCT_CAPABLE|GT_PHY_DTE_CAPABLE| GT_PHY_EX_CABLE_STATUS| GT_PHY_MAC_IF_LOOP|GT_PHY_LINE_LOOP|GT_PHY_EXTERNAL_LOOP| GT_PHY_GIGABIT|GT_PHY_RESTRICTED_PAGE; phyInfo->vctType = GT_PHY_VCT_TYPE2; phyInfo->exStatusType = GT_PHY_EX_STATUS_TYPE1; if ((phyId & PHY_REV_MASK) < 2) phyInfo->dteType = GT_PHY_DTE_TYPE3; /* Need workaround */ else phyInfo->dteType = GT_PHY_DTE_TYPE2; phyInfo->pktGenType = GT_PHY_PKTGEN_TYPE1; phyInfo->macIfLoopType = GT_PHY_LOOPBACK_TYPE1; phyInfo->lineLoopType = 0; phyInfo->exLoopType = GT_PHY_EX_LB_TYPE0; phyInfo->pageType = GT_PHY_PAGE_DIS_AUTO1; break; case DEV_E1112: phyInfo->anyPage = 0x1BC0780C; phyInfo->flag = GT_PHY_VCT_CAPABLE|GT_PHY_DTE_CAPABLE| GT_PHY_EX_CABLE_STATUS| GT_PHY_GIGABIT|GT_PHY_RESTRICTED_PAGE| GT_PHY_MAC_IF_LOOP|GT_PHY_LINE_LOOP|GT_PHY_EXTERNAL_LOOP| GT_PHY_PKT_GENERATOR; phyInfo->vctType = GT_PHY_VCT_TYPE4; phyInfo->exStatusType = GT_PHY_EX_STATUS_TYPE2; phyInfo->dteType = GT_PHY_DTE_TYPE4; phyInfo->pktGenType = GT_PHY_PKTGEN_TYPE2; phyInfo->macIfLoopType = GT_PHY_LOOPBACK_TYPE1; phyInfo->lineLoopType = 0; phyInfo->exLoopType = GT_PHY_EX_LB_TYPE0; phyInfo->pageType = GT_PHY_PAGE_DIS_AUTO2; break; case DEV_E114X: phyInfo->anyPage = 0x2FF1FE0C; phyInfo->flag = GT_PHY_VCT_CAPABLE|GT_PHY_DTE_CAPABLE| GT_PHY_EX_CABLE_STATUS| GT_PHY_MAC_IF_LOOP|GT_PHY_LINE_LOOP|GT_PHY_EXTERNAL_LOOP| GT_PHY_GIGABIT|GT_PHY_RESTRICTED_PAGE; phyInfo->vctType = GT_PHY_VCT_TYPE2; phyInfo->exStatusType = GT_PHY_EX_STATUS_TYPE1; if ((phyId & PHY_REV_MASK) < 4) phyInfo->dteType = GT_PHY_DTE_TYPE3; /* Need workaround */ else phyInfo->dteType = GT_PHY_DTE_TYPE2; phyInfo->pktGenType = GT_PHY_PKTGEN_TYPE1; phyInfo->macIfLoopType = GT_PHY_LOOPBACK_TYPE1; phyInfo->lineLoopType = 0; phyInfo->exLoopType = GT_PHY_EX_LB_TYPE0; phyInfo->pageType = GT_PHY_PAGE_DIS_AUTO1; break; case DEV_E1149: phyInfo->anyPage = 0x2040FFFF; phyInfo->flag = GT_PHY_VCT_CAPABLE|GT_PHY_DTE_CAPABLE| GT_PHY_EX_CABLE_STATUS| GT_PHY_GIGABIT| GT_PHY_MAC_IF_LOOP|GT_PHY_LINE_LOOP|GT_PHY_EXTERNAL_LOOP| GT_PHY_PKT_GENERATOR; phyInfo->vctType = GT_PHY_VCT_TYPE4; phyInfo->exStatusType = GT_PHY_EX_STATUS_TYPE3; phyInfo->dteType = GT_PHY_DTE_TYPE4; phyInfo->pktGenType = GT_PHY_PKTGEN_TYPE2; phyInfo->macIfLoopType = GT_PHY_LOOPBACK_TYPE1; phyInfo->lineLoopType = 0; phyInfo->exLoopType = GT_PHY_EX_LB_TYPE0; phyInfo->pageType = GT_PHY_PAGE_WRITE_BACK; break; case DEV_G15LV: if (IS_IN_DEV_GROUP(dev,DEV_88E6108)) { phyInfo->anyPage = 0x2040FFFF; phyInfo->flag = GT_PHY_VCT_CAPABLE|GT_PHY_DTE_CAPABLE| GT_PHY_EX_CABLE_STATUS| GT_PHY_GIGABIT| GT_PHY_MAC_IF_LOOP|GT_PHY_LINE_LOOP|GT_PHY_EXTERNAL_LOOP| GT_PHY_PKT_GENERATOR; phyInfo->vctType = GT_PHY_VCT_TYPE4; phyInfo->exStatusType = GT_PHY_EX_STATUS_TYPE3; phyInfo->dteType = GT_PHY_DTE_TYPE4; phyInfo->pktGenType = GT_PHY_PKTGEN_TYPE2; phyInfo->macIfLoopType = GT_PHY_LOOPBACK_TYPE1; phyInfo->lineLoopType = 0; phyInfo->exLoopType = GT_PHY_EX_LB_TYPE0; phyInfo->pageType = GT_PHY_PAGE_WRITE_BACK; } else /* 88E6165 family */ { phyInfo->anyPage = 0x2040FFFF; phyInfo->flag = GT_PHY_ADV_VCT_CAPABLE|GT_PHY_DTE_CAPABLE| GT_PHY_EX_CABLE_STATUS| GT_PHY_GIGABIT| GT_PHY_MAC_IF_LOOP|GT_PHY_LINE_LOOP|GT_PHY_EXTERNAL_LOOP| GT_PHY_PKT_GENERATOR; phyInfo->vctType = GT_PHY_ADV_VCT_TYPE2; phyInfo->exStatusType = GT_PHY_EX_STATUS_TYPE6; phyInfo->dteType = GT_PHY_DTE_TYPE4; phyInfo->pktGenType = GT_PHY_PKTGEN_TYPE2; phyInfo->macIfLoopType = GT_PHY_LOOPBACK_TYPE1; phyInfo->lineLoopType = 0; phyInfo->exLoopType = GT_PHY_EX_LB_TYPE0; phyInfo->pageType = GT_PHY_PAGE_WRITE_BACK; } break; case DEV_EC010: phyInfo->anyPage = 0x2040780C; phyInfo->flag = GT_PHY_VCT_CAPABLE|GT_PHY_DTE_CAPABLE| GT_PHY_EX_CABLE_STATUS| GT_PHY_GIGABIT|GT_PHY_RESTRICTED_PAGE| GT_PHY_MAC_IF_LOOP|GT_PHY_LINE_LOOP|GT_PHY_EXTERNAL_LOOP; phyInfo->vctType = GT_PHY_VCT_TYPE2; phyInfo->exStatusType = 0; phyInfo->dteType = GT_PHY_DTE_TYPE3; /* Need workaround */ phyInfo->pktGenType = 0; phyInfo->macIfLoopType = GT_PHY_LOOPBACK_TYPE1; phyInfo->lineLoopType = 0; phyInfo->exLoopType = GT_PHY_EX_LB_TYPE0; phyInfo->pageType = GT_PHY_PAGE_WRITE_BACK; break; case DEV_S15LV: phyInfo->anyPage = 0xFFFFFFFF; phyInfo->flag = GT_PHY_SERDES_CORE|GT_PHY_GIGABIT| GT_PHY_MAC_IF_LOOP|GT_PHY_LINE_LOOP|GT_PHY_EXTERNAL_LOOP| GT_PHY_PKT_GENERATOR; phyInfo->vctType = 0; phyInfo->exStatusType = 0; phyInfo->dteType = 0; phyInfo->pktGenType = GT_PHY_PKTGEN_TYPE3; phyInfo->macIfLoopType = GT_PHY_LOOPBACK_TYPE3; phyInfo->lineLoopType = GT_PHY_LINE_LB_TYPE4; phyInfo->exLoopType = 0; phyInfo->pageType = GT_PHY_NO_PAGE; break; case DEV_G65G: phyInfo->anyPage = 0x2040FFFF; phyInfo->flag = GT_PHY_ADV_VCT_CAPABLE|GT_PHY_DTE_CAPABLE| GT_PHY_EX_CABLE_STATUS| GT_PHY_GIGABIT| GT_PHY_MAC_IF_LOOP|GT_PHY_LINE_LOOP|GT_PHY_EXTERNAL_LOOP| GT_PHY_PKT_GENERATOR; phyInfo->vctType = GT_PHY_ADV_VCT_TYPE2; phyInfo->exStatusType = GT_PHY_EX_STATUS_TYPE6; phyInfo->dteType = GT_PHY_DTE_TYPE4; phyInfo->pktGenType = GT_PHY_PKTGEN_TYPE2; phyInfo->macIfLoopType = GT_PHY_LOOPBACK_TYPE1; phyInfo->lineLoopType = 0; phyInfo->exLoopType = GT_PHY_EX_LB_TYPE0; phyInfo->pageType = GT_PHY_PAGE_WRITE_BACK; break; default: return GT_FAIL; } if (phyInfo->flag & GT_PHY_GIGABIT) { if(hwGetPhyRegField(dev,hwPort,15,12,4,&data) != GT_OK) { DBG_INFO(("Not able to read Phy Reg(port:%d,offset:%d).\n",hwPort,15)); return GT_FAIL; } if(data & QD_GIGPHY_1000X_CAP) phyInfo->flag |= GT_PHY_FIBER; if(data & QD_GIGPHY_1000T_CAP) { phyInfo->flag |= GT_PHY_COPPER; } else { phyInfo->flag &= ~(GT_PHY_VCT_CAPABLE|GT_PHY_EX_CABLE_STATUS|GT_PHY_DTE_CAPABLE|GT_PHY_ADV_VCT_CAPABLE); } } return GT_OK; }
/******************************************************************************* * gpcsSetRGMIITimingDelay * * DESCRIPTION: * RGMII receive/transmit Timing Control. This api adds delay to RXCLK for * IND inputs and GTXCLK for OUTD outputs when port is in RGMII mode. * Change to this bit are disruptive to normal operation. Hence any changes * to this register must be done only while the port's link is down. * * INPUTS: * port - the logical port number. * rxmode - GT_FALSE for default setup, GT_TRUE for adding delay to rxclk * txmode - GT_FALSE for default setup, GT_TRUE for adding delay to txclk * * OUTPUTS: * None * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_NOT_SUPPORTED - if current device does not support this feature. * * COMMENTS: * *******************************************************************************/ GT_STATUS gpcsSetRGMIITimingDelay ( IN GT_QD_DEV *dev, IN GT_LPORT port, IN GT_BOOL rxmode, IN GT_BOOL txmode ) { GT_U16 data; GT_STATUS retVal; /* Functions return value. */ GT_U8 hwPort; /* the physical port number */ DBG_INFO(("gpcsSetRGMIITimingDelay Called.\n")); if (!IS_IN_DEV_GROUP(dev,DEV_RGMII_TIMING)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } /* translate LPORT to hardware port */ hwPort = GT_LPORT_2_PORT(port); if (hwPort < (dev->maxPorts - 2)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } if(((dev->devName==DEV_88E6165)||(dev->devName==DEV_88E6161))&& ((hwPort==4)||((hwPort==5)&&(dev->revision==2)))) /* 88E6123 revision A2 */ { if(hwWritePortReg(dev,4,0x1A,0x81E7) != GT_OK) { DBG_INFO(("Failed.\n")); return GT_FAIL; } if(hwReadPortReg(dev,5,0x1A,&data) != GT_OK) { DBG_INFO(("Failed.\n")); return GT_FAIL; } if((hwPort==5)&&(dev->revision==2)) /* 88E6123 revision A2 */ { data &= 0xfff9; data |= (rxmode) ? 0x2 : 0; data |= (txmode) ? 0x1: 0; } else { data &= 0xffe7; data |= (rxmode) ? 0x10 : 0; data |= (txmode) ? 0x8: 0; } if(hwWritePortReg(dev,5,0x1A, data) != GT_OK) { DBG_INFO(("Failed.\n")); return GT_FAIL; } if(hwWritePortReg(dev,4,0x1A,0xC1E7) != GT_OK) { DBG_INFO(("Failed.\n")); return GT_FAIL; } } else { data = (rxmode) ? 2 : 0; data |= (txmode) ? 1 : 0; /* Set the register bit(s). */ retVal = hwSetPortRegField(dev,hwPort, QD_REG_PCS_CONTROL,14,2,data); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); } else { DBG_INFO(("OK.\n")); } } /* return */ return retVal; }
/******************************************************************************* * gstuAddEntry * * DESCRIPTION: * Creates or update the entry in STU table based on user input. * * INPUTS: * stuEntry - stu entry to insert to the STU. * * OUTPUTS: * None * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_NOT_SUPPORTED - if current device does not support this feature. * * COMMENTS: * Valid SID is 1 ~ 63. * *******************************************************************************/ GT_STATUS gstuAddEntry ( IN GT_QD_DEV *dev, IN GT_STU_ENTRY *stuEntry ) { GT_U8 valid; GT_STATUS retVal; GT_U8 port; GT_LPORT lport; GT_STU_ENTRY tmpStuEntry; GT_BOOL found; int count = 50000; GT_STU_ENTRY entry; DBG_INFO(("gstuAddEntry Called.\n")); /* check if device supports this feature */ if (!IS_IN_DEV_GROUP(dev,DEV_802_1S_STU)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } if((stuEntry->sid == 0) || (stuEntry->sid > 0x3F)) { DBG_INFO(("GT_BAD_PARAM\n")); return GT_BAD_PARAM; } entry.sid = stuEntry->sid; valid = 1; /* for load operation */ for(port=0; port<dev->maxPorts; port++) { lport = GT_PORT_2_LPORT(port); if (lport == GT_INVALID_PORT) entry.portState[port] = 0; else entry.portState[port] = stuEntry->portState[lport]; } retVal = stuOperationPerform(dev,LOAD_PURGE_STU_ENTRY,&valid, &entry); if(retVal != GT_OK) { DBG_INFO(("Failed (stuOperationPerform returned GT_FAIL).\n")); return retVal; } /* verify that the given entry has been added */ tmpStuEntry.sid = stuEntry->sid; if((retVal = gstuFindSidEntry(dev,&tmpStuEntry,&found)) != GT_OK) { while(count--); if((retVal = gstuFindSidEntry(dev,&tmpStuEntry,&found)) != GT_OK) { DBG_INFO(("Added entry cannot be found\n")); return retVal; } } if(found == GT_FALSE) { DBG_INFO(("Added entry cannot be found\n")); return GT_FAIL; } DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * qdLoadDriver * * DESCRIPTION: * QuarterDeck Driver Initialization Routine. * This is the first routine that needs be called by system software. * It takes *cfg from system software, and retures a pointer (*dev) * to a data structure which includes infomation related to this QuarterDeck * device. This pointer (*dev) is then used for all the API functions. * * INPUTS: * cfg - Holds device configuration parameters provided by system software. * * OUTPUTS: * dev - Holds device information to be used for each API call. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_ALREADY_EXIST - if device already started * GT_BAD_PARAM - on bad parameters * * COMMENTS: * qdUnloadDriver is also provided to do driver cleanup. * *******************************************************************************/ GT_STATUS qdLoadDriver ( IN GT_SYS_CONFIG *cfg, OUT GT_QD_DEV *dev ) { GT_STATUS retVal; GT_LPORT port; DBG_INFO(("qdLoadDriver Called.\n")); /* Check for parameters validity */ if(dev == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* Check for parameters validity */ if(cfg == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* The initialization was already done. */ if(dev->devEnabled) { DBG_INFO(("QuarterDeck already started.\n")); return GT_ALREADY_EXIST; } #ifdef GT_PORT_MAP_IN_DEV /* Modified to add port mapping functions into device ssystem configuration. */ if (dev->lport2port == NULL) { dev->lport2port = lport2port; } if (dev->port2lport == NULL) { dev->port2lport = port2lport; } if (dev->lportvec2portvec == NULL) { dev->lportvec2portvec = lportvec2portvec; } if (dev->portvec2lportvec == NULL) { dev->portvec2lportvec = portvec2lportvec; } #endif if(gtRegister(dev,&(cfg->BSPFunctions)) != GT_TRUE) { DBG_INFO(("gtRegister Failed.\n")); return GT_FAIL; } dev->accessMode = (GT_U8)cfg->mode.scanMode; if (dev->accessMode == SMI_MULTI_ADDR_MODE) { dev->baseRegAddr = 0; dev->phyAddr = (GT_U8)cfg->mode.baseAddr; } else { dev->baseRegAddr = (GT_U8)cfg->mode.baseAddr; dev->phyAddr = 0; } /* Initialize the driver */ retVal = driverConfig(dev); if(retVal != GT_OK) { DBG_INFO(("driverConfig Failed.\n")); return retVal; } /* Initialize dev fields. */ dev->cpuPortNum = cfg->cpuPortNum; dev->maxPhyNum = 5; dev->devGroup = 0; dev->devStorage = 0; /* Assign Device Name */ dev->devName = 0; dev->devName1 = 0; dev->validSerdesVec = 0; if((dev->deviceId&0xfff8)==GT_88EC000) /* device id 0xc00 - 0xc07 are GT_88EC0XX */ dev->deviceId=GT_88EC000; switch(dev->deviceId) { case GT_88E6021: dev->numOfPorts = 3; dev->maxPorts = 3; dev->maxPhyNum = 2; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6021; break; case GT_88E6051: dev->numOfPorts = 5; dev->maxPorts = 5; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6051; break; case GT_88E6052: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6052; break; case GT_88E6060: if((dev->cpuPortNum != 4)&&(dev->cpuPortNum != 5)) { return GT_FAIL; } dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6060; break; case GT_88E6031: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 3; dev->validPortVec = 0x31; /* port 0, 4, and 5 */ dev->validPhyVec = 0x31; /* port 0, 4, and 5 */ dev->devName = DEV_88E6061; break; case GT_88E6061: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6061; break; case GT_88E6035: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 3; dev->validPortVec = 0x31; /* port 0, 4, and 5 */ dev->validPhyVec = 0x31; /* port 0, 4, and 5 */ dev->devName = DEV_88E6065; break; case GT_88E6065: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6065; break; case GT_88E6063: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6063; break; case GT_FH_VPN: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FH_VPN; break; case GT_FF_EG: if(dev->cpuPortNum != 5) { return GT_FAIL; } dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FF_EG; break; case GT_FF_HG: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FF_HG; break; case GT_88E6083: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 8; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6083; break; case GT_88E6153: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6183; break; case GT_88E6181: dev->numOfPorts = 8; dev->maxPorts = 8; dev->maxPhyNum = 8; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6181; break; case GT_88E6183: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6183; break; case GT_88E6093: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6093; break; case GT_88E6092: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6092; break; case GT_88E6095: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6095; break; case GT_88E6097: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6097; break; case GT_88E6096: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6096; break; case GT_88E6046: dev->numOfPorts = 6; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = 0x60F; dev->validPhyVec = 0x60F; dev->devName = DEV_88E6096; break; case GT_88E6085: dev->numOfPorts = 10; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = 0x6FF; dev->validPhyVec = 0x6FF; dev->devName = DEV_88E6096; break; case GT_88E6152: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = 0x28F; dev->validPhyVec = 0x28F; dev->devName = DEV_88E6182; break; case GT_88E6155: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = 0x28F; dev->validPhyVec = 0x28F; dev->devName = DEV_88E6185; break; case GT_88E6182: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6182; break; case GT_88E6185: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6185; break; case GT_88E6121: dev->numOfPorts = 3; dev->maxPorts = 8; dev->maxPhyNum = 3; dev->validPortVec = 0xE; /* port 1, 2, and 3 */ dev->validPhyVec = 0xE; /* port 1, 2, and 3 */ dev->devName = DEV_88E6108; break; case GT_88E6122: dev->numOfPorts = 6; dev->maxPorts = 8; dev->maxPhyNum = 16; dev->validPortVec = 0x7E; /* port 1 ~ 6 */ dev->validPhyVec = 0xF07E; /* port 1 ~ 6, 12 ~ 15 (serdes) */ dev->validSerdesVec = 0xF000; dev->devName = DEV_88E6108; break; case GT_88E6131: case GT_88E6108: dev->numOfPorts = 8; dev->maxPorts = 8; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->validSerdesVec = 0xF000; dev->devName = DEV_88E6108; break; case GT_88E6123: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = 0x23; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6161; break; case GT_88E6161: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6161; break; case GT_88E6165: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 14; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x303F; dev->validSerdesVec = 0x3000; dev->devName = DEV_88E6165; break; case GT_88E6351: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName = DEV_88E6351; break; case GT_88E6175: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88E6175; /* test device group 1 */ break; case GT_88E6171 : dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName = DEV_88E6171; break; case GT_88E6350 : dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName = DEV_88E6371; break; case GT_88EC000 : dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88EC000; break; case GT_88E6020: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88E3020; break; case GT_88E6070: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88E3020; break; case GT_88E6071: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88E3020; break; case GT_88E6220: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88E3020; break; case GT_88E6250: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->devName1 = DEV_88E3020; break; case GT_88E6172: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x1F; dev->validSerdesVec = 0x8000; dev->devName = DEV_88E6172; break; case GT_88E6176: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->validSerdesVec = 0x8000; dev->devName = DEV_88E6176; break; case GT_88E6240: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->validSerdesVec = 0x8000; dev->devName = DEV_88E6240; break; case GT_88E6352: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x7F; dev->validSerdesVec = 0x8000; dev->devName = DEV_88E6352; break; case GT_88E6320: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x18; dev->validSerdesVec = 0x3000; dev->devName1 = DEV_88E6320; break; case GT_88E6321: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 12; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x18; dev->validSerdesVec = 0x3000; dev->devName1 = DEV_88E6321; break; case GT_88E6999: /* Opus */ dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6999; break; case GT_88E6390: /* Peridot Full Featured Device */ dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6390; break; case GT_88E6360: /* Peridot 5 GE PHY version */ dev->numOfPorts = 5; dev->maxPorts = 5; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6390; break; case GT_88E6290: /* Peridot FE PHY version */ dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6290; break; case GT_88E6290A: /* Peridot Forced FE PHY (no AutoNeg) for Automotive */ dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6290A; break; case GT_88E6191: /* Peridot No AVB */ dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6190; break; case GT_88E6190: /* Peridot No AVB, Z80 NIC, TCAM nor Cut Through */ dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = 0x0; dev->validSerdesVec = 0x0000; dev->devName1 = DEV_88E6191; break; default: DBG_INFO(("Unknown Device. Initialization failed\n")); return GT_FAIL; } dev->cpuPortNum = GT_PORT_2_LPORT(cfg->cpuPortNum); if(dev->cpuPortNum == GT_INVALID_PORT) { if(GT_LPORT_2_PORT((GT_LPORT)cfg->cpuPortNum) != GT_INVALID_PORT) { dev->cpuPortNum = cfg->cpuPortNum; } else { return GT_BAD_CPU_PORT; } } /* Initialize the MultiAddress Register Access semaphore. */ if((dev->multiAddrSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the ATU semaphore. */ if((dev->atuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the VTU semaphore. */ if((dev->vtuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the STATS semaphore. */ if((dev->statsRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PIRL semaphore. */ if((dev->pirlRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PTP semaphore. */ if((dev->ptpRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the Table semaphore. */ if((dev->tblRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the EEPROM Configuration semaphore. */ if((dev->eepromRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PHY Device Register Access semaphore. */ if((dev->phyRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the Remote management Register Access semaphore. */ if((dev->hwAccessRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the ports states to forwarding mode. */ if(cfg->initPorts == GT_TRUE) { for (port=0; port<dev->numOfPorts; port++) { if((retVal = gstpSetPortState(dev,port,GT_PORT_FORWARDING)) != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } } dev->use_mad = GT_FALSE; #ifdef GT_USE_MAD { int portPhyAddr=0; unsigned int validPhyVec = dev->validPhyVec; while((validPhyVec&1)==0) { validPhyVec >>= 1; portPhyAddr++; } DBG_INFO(("@@@@@@@@@@ qd_madInit\n")); if((retVal = qd_madInit(dev, portPhyAddr)) != GT_OK) { DBG_INFO(("Initialize MAD failed.\n")); qdUnloadDriver(dev); return retVal; } } #endif if(cfg->skipInitSetup == GT_SKIP_INIT_SETUP) { dev->devEnabled = 1; dev->devNum = cfg->devNum; DBG_INFO(("OK.\n")); return GT_OK; } if(IS_IN_DEV_GROUP(dev,DEV_ENHANCED_CPU_PORT)) { if((retVal = gsysSetRsvd2CpuEnables(dev,0)) != GT_OK) { DBG_INFO(("gsysGetRsvd2CpuEnables failed.\n")); qdUnloadDriver(dev); return retVal; } if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK) { DBG_INFO(("gsysSetRsvd2Cpu failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_CPU_DEST_PER_PORT)) { for (port=0; port<dev->numOfPorts; port++) { retVal = gprtSetCPUPort(dev,port,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } } if(IS_IN_DEV_GROUP(dev,DEV_CPU_PORT)) { retVal = gsysSetCPUPort(dev,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if(IS_IN_DEV_GROUP(dev,DEV_CPU_DEST)) { retVal = gsysSetCPUDest(dev,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if(IS_IN_DEV_GROUP(dev,DEV_MULTICAST)) { if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK) { DBG_INFO(("gsysSetRsvd2Cpu failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) { retVal = gpirlInitialize(dev); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_PIRL2_RESOURCE)) { retVal = gpirl2Initialize(dev); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } else if (IS_IN_DEV_GROUP(dev,DEV_PIRL3_RESOURCE)) { retVal = gpirl3Initialize(dev); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if(IS_IN_DEV_GROUP(dev,DEV_CPU_PORT_NEED_INIT)) { retVal = gsysInitCPUPort(dev,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } dev->devEnabled = 1; dev->devNum = cfg->devNum; DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * gstpSetMode * * DESCRIPTION: * This routine Enable the Spanning tree. * * INPUTS: * en - GT_TRUE for enable, GT_FALSE for disable. * * OUTPUTS: * None. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * when enabled, this function sets all port to blocking state, and inserts * the BPDU MAC into the ATU to be captured to CPU, on disable all port are * being modified to be in forwarding state. * * GalTis: * *******************************************************************************/ GT_STATUS gstpSetMode ( IN GT_QD_DEV *dev, IN GT_BOOL en ) { GT_STATUS retVal = GT_OK; /* Functions return value. */ GT_ATU_ENTRY atuEntry; /* The ATU entry data to be set */ GT_U32 i, dbNum; DBG_INFO(("gstpSetMode Called.\n")); if(dev->deviceId == GT_88E6051) { DBG_INFO(("Failed.\n")); return GT_FAIL; } if((en == GT_TRUE) && (dev->stpMode == 1)) { DBG_INFO(("OK.\n")); return GT_OK; } switch(dev->deviceId) { case GT_88E6051: case GT_88E6052: dbNum = 1; break; case GT_FF_HG: case GT_FF_EG: case GT_88E6021: case GT_88E6060: case GT_88E6031: case GT_88E6061: case GT_88E6063: case GT_FH_VPN: case GT_88E6083: case GT_88E6153: case GT_88E6181: case GT_88E6183: case GT_88E6093: dbNum = 16; break; case GT_88E6035: case GT_88E6055: case GT_88E6065: dbNum = 64; break; default: if (!IS_IN_DEV_GROUP(dev,DEV_ENHANCED_MULTICAST)) { dbNum = 64; } else { dbNum = 0; retVal = enhancedBPDUSet(dev,en); } break; } for (i=0; i<dbNum; i++) { /* Set the Atu entry parameters. */ atuEntry.macAddr.arEther[0] = 0x01; atuEntry.macAddr.arEther[1] = 0x80; atuEntry.macAddr.arEther[2] = 0xC2; atuEntry.macAddr.arEther[3] = 0x00; atuEntry.macAddr.arEther[4] = 0x00; atuEntry.macAddr.arEther[5] = 0x00; atuEntry.portVec = GT_LPORTVEC_2_PORTVEC((1<<dev->cpuPortNum)); if(IS_IN_DEV_GROUP(dev,DEV_ATU_EXT_PRI)) { if(IS_IN_DEV_GROUP(dev,DEV_FQPRI_IN_TABLE)) { atuEntry.exPrio.useMacFPri = GT_TRUE; atuEntry.exPrio.macFPri = 7; } else { atuEntry.exPrio.useMacFPri = 0; atuEntry.exPrio.macFPri = 0; } atuEntry.exPrio.macQPri = 3; atuEntry.prio = 0; } else { atuEntry.prio = 3; atuEntry.exPrio.useMacFPri = 0; atuEntry.exPrio.macFPri = 0; atuEntry.exPrio.macQPri = 0; } atuEntry.DBNum = (GT_U8)i; atuEntry.entryState.mcEntryState = GT_MC_PRIO_MGM_STATIC; if(en == GT_TRUE) { retVal = gfdbAddMacEntry(dev,&atuEntry); } else { if(dev->stpMode == 0) break; retVal = gfdbDelAtuEntry(dev,&atuEntry); } if (retVal != GT_OK) break; } if(retVal == GT_OK) { if(en == GT_TRUE) dev->stpMode = 1; else dev->stpMode = 2; DBG_INFO(("OK.\n")); } else { dev->stpMode = 0; DBG_INFO(("Failed.\n")); } return retVal; }
/******************************************************************************* * qdLoadDriver * * DESCRIPTION: * QuarterDeck Driver Initialization Routine. * This is the first routine that needs be called by system software. * It takes *cfg from system software, and retures a pointer (*dev) * to a data structure which includes infomation related to this QuarterDeck * device. This pointer (*dev) is then used for all the API functions. * * INPUTS: * cfg - Holds device configuration parameters provided by system software. * * OUTPUTS: * dev - Holds device information to be used for each API call. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * GT_ALREADY_EXIST - if device already started * GT_BAD_PARAM - on bad parameters * * COMMENTS: * qdUnloadDriver is also provided to do driver cleanup. * *******************************************************************************/ GT_STATUS qdLoadDriver ( IN GT_SYS_CONFIG *cfg, OUT GT_QD_DEV *dev ) { GT_STATUS retVal; GT_LPORT port; DBG_INFO(("qdLoadDriver Called.\n")); /* Check for parameters validity */ if(dev == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* Check for parameters validity */ if(cfg == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* The initialization was already done. */ if(dev->devEnabled) { DBG_INFO(("QuarterDeck already started.\n")); return GT_ALREADY_EXIST; } if(gtRegister(dev,&(cfg->BSPFunctions)) != GT_TRUE) { DBG_INFO(("gtRegister Failed.\n")); return GT_FAIL; } dev->accessMode = cfg->mode.scanMode; if (dev->accessMode == SMI_MULTI_ADDR_MODE) { dev->baseRegAddr = 0; dev->phyAddr = cfg->mode.baseAddr; } else { dev->baseRegAddr = cfg->mode.baseAddr; dev->phyAddr = 0; } /* Initialize the driver */ retVal = driverConfig(dev); if(retVal != GT_OK) { DBG_INFO(("driverConfig Failed.\n")); return retVal; } /* Initialize dev fields. */ dev->cpuPortNum = cfg->cpuPortNum; dev->maxPhyNum = 5; dev->devGroup = 0; /* Assign Device Name */ switch(dev->deviceId) { case GT_88E6021: dev->numOfPorts = 3; dev->maxPorts = 3; dev->maxPhyNum = 2; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6021; break; case GT_88E6051: dev->numOfPorts = 5; dev->maxPorts = 5; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6051; break; case GT_88E6052: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6052; break; case GT_88E6060: if((dev->cpuPortNum != 4)&&(dev->cpuPortNum != 5)) { return GT_FAIL; } dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6060; break; case GT_88E6031: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 3; dev->validPortVec = 0x31; /* port 0, 4, and 5 */ dev->validPhyVec = 0x31; /* port 0, 4, and 5 */ dev->devName = DEV_88E6061; break; case GT_88E6061: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6061; break; case GT_88E6035: dev->numOfPorts = 3; dev->maxPorts = 6; dev->maxPhyNum = 3; dev->validPortVec = 0x31; /* port 0, 4, and 5 */ dev->validPhyVec = 0x31; /* port 0, 4, and 5 */ dev->devName = DEV_88E6065; break; case GT_88E6055: dev->numOfPorts = 5; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = 0x2F; /* port 0,1,2,3, and 5 */ dev->validPhyVec = 0x2F; /* port 0,1,2,3, and 5 */ dev->devName = DEV_88E6065; break; case GT_88E6065: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6065; break; case GT_88E6063: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6063; break; case GT_FH_VPN: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FH_VPN; break; case GT_FF_EG: if(dev->cpuPortNum != 5) { return GT_FAIL; } dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FF_EG; break; case GT_FF_HG: dev->numOfPorts = 7; dev->maxPorts = 7; dev->maxPhyNum = 5; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_FF_HG; break; case GT_88E6083: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 8; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6083; break; case GT_88E6153: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6183; break; case GT_88E6181: dev->numOfPorts = 8; dev->maxPorts = 8; dev->maxPhyNum = 8; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6181; break; case GT_88E6183: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6183; break; case GT_88E6093: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6093; break; case GT_88E6092: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6092; break; case GT_88E6095: dev->numOfPorts = 11; dev->maxPorts = 11; dev->maxPhyNum = 11; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6095; break; case GT_88E6152: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6182; break; case GT_88E6155: dev->numOfPorts = 6; dev->maxPorts = 6; dev->maxPhyNum = 6; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6185; break; case GT_88E6182: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6182; break; case GT_88E6185: dev->numOfPorts = 10; dev->maxPorts = 10; dev->maxPhyNum = 10; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6185; break; case GT_88E6131: case GT_88E6108: dev->numOfPorts = 8; dev->maxPorts = 8; dev->maxPhyNum = 16; dev->validPortVec = (1 << dev->numOfPorts) - 1; dev->validPhyVec = (1 << dev->maxPhyNum) - 1; dev->devName = DEV_88E6108; break; default: DBG_INFO(("Unknown Device. Initialization failed\n")); return GT_FAIL; } /* Initialize the MultiAddress Register Access semaphore. */ if((dev->multiAddrSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the ATU semaphore. */ if((dev->atuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the VTU semaphore. */ if((dev->vtuRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the STATS semaphore. */ if((dev->statsRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the PIRL semaphore. */ if((dev->pirlRegsSem = gtSemCreate(dev,GT_SEM_FULL)) == 0) { DBG_INFO(("semCreate Failed.\n")); qdUnloadDriver(dev); return GT_FAIL; } /* Initialize the ports states to forwarding mode. */ if(cfg->initPorts == GT_TRUE) { for (port=0; port<dev->numOfPorts; port++) { if((retVal = gstpSetPortState(dev,port,GT_PORT_FORWARDING)) != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } } if(IS_IN_DEV_GROUP(dev,DEV_ENHANCED_CPU_PORT)) { if((retVal = gsysSetRsvd2CpuEnables(dev,0)) != GT_OK) { DBG_INFO(("gsysGetRsvd2CpuEnables failed.\n")); qdUnloadDriver(dev); return retVal; } if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK) { DBG_INFO(("gsysSetRsvd2Cpu failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH)) { for (port=0; port<dev->numOfPorts; port++) { retVal = gprtSetCPUPort(dev,port,dev->cpuPortNum); if((retVal != GT_OK) && (retVal != GT_NOT_SUPPORTED)) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } } if(IS_IN_DEV_GROUP(dev,DEV_CPU_PORT)) { retVal = gsysSetCPUPort(dev,dev->cpuPortNum); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } if(IS_IN_DEV_GROUP(dev,DEV_MULTICAST)) { if((retVal = gsysSetRsvd2Cpu(dev,GT_FALSE)) != GT_OK) { DBG_INFO(("gsysSetRsvd2Cpu failed.\n")); qdUnloadDriver(dev); return retVal; } } if (IS_IN_DEV_GROUP(dev,DEV_PIRL_RESOURCE)) { retVal = gpirlInitialize(dev); if(retVal != GT_OK) { DBG_INFO(("Failed.\n")); qdUnloadDriver(dev); return retVal; } } dev->devEnabled = 1; dev->devNum = cfg->devNum; DBG_INFO(("OK.\n")); return GT_OK; }
static GT_STATUS statsOperationPerform ( IN GT_QD_DEV *dev, IN GT_STATS_OPERATION statsOp, IN GT_U8 port, IN GT_STATS_COUNTERS counter, OUT GT_VOID *statsData ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data,histoData; /* Data to be set into the */ /* register. */ GT_U32 statsCounter; GT_U32 lastCounter; GT_U16 portNum; gtSemTake(dev,dev->statsRegsSem,OS_WAIT_FOREVER); if (!((IS_IN_DEV_GROUP(dev,DEV_GIGABIT_SWITCH)) || (IS_IN_DEV_GROUP(dev,DEV_RMON_REALTIME_SUPPORT)))) { if (IS_IN_DEV_GROUP(dev,DEV_MELODY_SWITCH)) lastCounter = (GT_U32)STATS2_Late; else lastCounter = (GT_U32)STATS_OutDiscards; } else { lastCounter = (GT_U32)STATS2_Late; } if (IS_IN_DEV_GROUP(dev,DEV_RMON_PORT_BITS)) { portNum = (port + 1) << 5; } else { portNum = (GT_U16)port; } /* Wait until the stats in ready. */ #ifdef GT_RMGMT_ACCESS { HW_DEV_REG_ACCESS regAccess; regAccess.entries = 2; regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0; regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS); regAccess.rw_reg_list[0].reg = QD_REG_STATS_OPERATION; regAccess.rw_reg_list[0].data = 15; regAccess.rw_reg_list[1].cmd = HW_REG_READ; regAccess.rw_reg_list[1].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS); regAccess.rw_reg_list[1].reg = QD_REG_STATS_OPERATION; regAccess.rw_reg_list[1].data = 0; retVal = hwAccessMultiRegs(dev, ®Access); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } histoData = qdLong2Short(regAccess.rw_reg_list[1].data); } #else data = 1; while(data == 1) { retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } } /* Get the Histogram mode bit. */ retVal = hwReadGlobalReg(dev,QD_REG_STATS_OPERATION,&histoData); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } #endif histoData &= 0xC00; /* Set the STAT Operation register */ switch (statsOp) { case STATS_FLUSH_ALL: data = (1 << 15) | (GT_STATS_FLUSH_ALL << 12) | histoData; retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data); gtSemGive(dev,dev->statsRegsSem); return retVal; case STATS_FLUSH_PORT: data = (1 << 15) | (GT_STATS_FLUSH_PORT << 12) | portNum | histoData; retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data); gtSemGive(dev,dev->statsRegsSem); return retVal; case STATS_READ_COUNTER: retVal = statsCapture(dev,port); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } retVal = statsReadCounter(dev,counter,(GT_U32*)statsData); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } break; case STATS_READ_REALTIME_COUNTER: retVal = statsReadRealtimeCounter(dev,port,counter,(GT_U32*)statsData); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } break; case STATS_READ_ALL: retVal = statsCapture(dev,port); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } for(statsCounter=0; statsCounter<=lastCounter; statsCounter++) { retVal = statsReadCounter(dev,statsCounter,((GT_U32*)statsData + statsCounter)); if(retVal != GT_OK) { gtSemGive(dev,dev->statsRegsSem); return retVal; } } break; default: gtSemGive(dev,dev->statsRegsSem); return GT_FAIL; } gtSemGive(dev,dev->statsRegsSem); return GT_OK; }
/******************************************************************************* * gprtGetPortCtr2 * * DESCRIPTION: * This routine gets the port InDiscards, InFiltered, and OutFiltered counters. * * INPUTS: * port - the logical port number. * * OUTPUTS: * ctr - the counters value. * * RETURNS: * GT_OK - on success * GT_FAIL - on error * * COMMENTS: * * * GalTis: * *******************************************************************************/ GT_STATUS gprtGetPortCtr2 ( IN GT_QD_DEV *dev, IN GT_LPORT port, OUT GT_PORT_STAT2 *ctr ) { #ifndef GT_RMGMT_ACCESS GT_U16 count; /* counters current value */ #endif GT_U8 hwPort; /* physical port number */ DBG_INFO(("gprtGetPortCtr2 Called.\n")); if (!IS_IN_DEV_GROUP(dev,DEV_88E6093_FAMILY)) { DBG_INFO(("GT_NOT_SUPPORTED\n")); return GT_NOT_SUPPORTED; } if(ctr == NULL) { DBG_INFO(("Failed.\n")); return GT_BAD_PARAM; } /* translate logical port to physical port */ hwPort = GT_LPORT_2_PORT(port); #ifdef GT_RMGMT_ACCESS { HW_DEV_REG_ACCESS regAccess; regAccess.entries = 4; regAccess.rw_reg_list[0].cmd = HW_REG_READ; regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, hwPort, PORT_ACCESS); regAccess.rw_reg_list[0].reg = QD_REG_INDISCARD_LO_COUNTER; regAccess.rw_reg_list[0].data = 0; regAccess.rw_reg_list[1].cmd = HW_REG_READ; regAccess.rw_reg_list[1].addr = CALC_SMI_DEV_ADDR(dev, hwPort, PORT_ACCESS); regAccess.rw_reg_list[1].reg = QD_REG_INDISCARD_HI_COUNTER; regAccess.rw_reg_list[1].data = 0; regAccess.rw_reg_list[2].cmd = HW_REG_READ; regAccess.rw_reg_list[2].addr = CALC_SMI_DEV_ADDR(dev, hwPort, PORT_ACCESS); regAccess.rw_reg_list[2].reg = QD_REG_INFILTERED_COUNTER; regAccess.rw_reg_list[2].data = 0; regAccess.rw_reg_list[3].cmd = HW_REG_READ; regAccess.rw_reg_list[3].addr = CALC_SMI_DEV_ADDR(dev, hwPort, PORT_ACCESS); regAccess.rw_reg_list[3].reg = QD_REG_OUTFILTERED_COUNTER; regAccess.rw_reg_list[3].data = 0; if(hwAccessMultiRegs(dev, ®Access) != GT_OK) { return GT_FAIL; } ctr->inDiscardLo = regAccess.rw_reg_list[0].data; ctr->inDiscardHi = regAccess.rw_reg_list[1].data; ctr->inFiltered = regAccess.rw_reg_list[2].data; ctr->outFiltered = regAccess.rw_reg_list[3].data; } #else /* get InDiscard Low counter value */ if(hwReadPortReg(dev,hwPort, QD_REG_INDISCARD_LO_COUNTER, &count) != GT_OK) { DBG_INFO(("Failed (Read inDiscardLo).\n")); return GT_FAIL; } ctr->inDiscardLo = count; /* get InDiscard High counter value */ if(hwReadPortReg(dev,hwPort, QD_REG_INDISCARD_HI_COUNTER, &count) != GT_OK) { DBG_INFO(("Failed (Read inDiscardHi).\n")); return GT_FAIL; } ctr->inDiscardHi = count; /* get InFiltered counter value */ if(hwReadPortReg(dev,hwPort, QD_REG_INFILTERED_COUNTER, &count) != GT_OK) { DBG_INFO(("Failed (Read inFiltered).\n")); return GT_FAIL; } ctr->inFiltered = count; /* get OutFiltered counter value */ if(hwReadPortReg(dev,hwPort, QD_REG_OUTFILTERED_COUNTER, &count) != GT_OK) { DBG_INFO(("Failed (Read outFiltered).\n")); return GT_FAIL; } ctr->outFiltered = count; #endif DBG_INFO(("OK.\n")); return GT_OK; }
/******************************************************************************* * statsReadRealtimeCounter * * DESCRIPTION: * This function is used to read a realtime counter. * * INPUTS: * port - port to be accessed * counter - counter to be read if it's read operation * * OUTPUTS: * statsData - points to the data storage where the MIB counter will be saved. * * RETURNS: * GT_OK on success, * GT_FAIL otherwise. * * COMMENTS: * If Semaphore is used, Semaphore should be acquired before this function call. *******************************************************************************/ static GT_STATUS statsReadRealtimeCounter ( IN GT_QD_DEV *dev, IN GT_U8 port, IN GT_U32 counter, OUT GT_U32 *statsData ) { GT_STATUS retVal; /* Functions return value. */ GT_U16 data, histoData;/* Data to be set into the register. */ GT_U16 counter3_2; /* Counter Register Bytes 3 & 2 */ GT_U16 counter1_0; /* Counter Register Bytes 1 & 0 */ /* Get the Histogram mode bit. */ retVal = hwReadGlobalReg(dev,QD_REG_STATS_OPERATION,&histoData); if(retVal != GT_OK) { return retVal; } histoData &= 0xC00; #ifdef GT_RMGMT_ACCESS { HW_DEV_REG_ACCESS regAccess; regAccess.entries = 1; regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0; regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS); regAccess.rw_reg_list[0].reg = QD_REG_STATS_OPERATION; regAccess.rw_reg_list[0].data = 15; retVal = hwAccessMultiRegs(dev, ®Access); if(retVal != GT_OK) { return retVal; } } #else data = 1; while(data == 1) { retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data); if(retVal != GT_OK) { return retVal; } } #endif data = (GT_U16)((1 << 15) | (GT_STATS_READ_COUNTER << 12) | ((port+1) << 5) | (counter&0x7f) | histoData); if (counter & 0x80) { if (IS_IN_DEV_GROUP(dev,DEV_RMON_TYPE_4)) { data |= (1<<9); } else if (IS_IN_DEV_GROUP(dev,DEV_RMON_TYPE_5)) { data |= (1<<10); } } retVal = hwWriteGlobalReg(dev,QD_REG_STATS_OPERATION,data); if(retVal != GT_OK) { return retVal; } #ifdef GT_RMGMT_ACCESS { HW_DEV_REG_ACCESS regAccess; regAccess.entries = 1; regAccess.rw_reg_list[0].cmd = HW_REG_WAIT_TILL_0; regAccess.rw_reg_list[0].addr = CALC_SMI_DEV_ADDR(dev, 0, GLOBAL_REG_ACCESS); regAccess.rw_reg_list[0].reg = QD_REG_STATS_OPERATION; regAccess.rw_reg_list[0].data = 15; retVal = hwAccessMultiRegs(dev, ®Access); if(retVal != GT_OK) { return retVal; } } #else data = 1; while(data == 1) { retVal = hwGetGlobalRegField(dev,QD_REG_STATS_OPERATION,15,1,&data); if(retVal != GT_OK) { return retVal; } } #endif retVal = hwReadGlobalReg(dev,QD_REG_STATS_COUNTER3_2,&counter3_2); if(retVal != GT_OK) { return retVal; } retVal = hwReadGlobalReg(dev,QD_REG_STATS_COUNTER1_0,&counter1_0); if(retVal != GT_OK) { return retVal; } *statsData = (counter3_2 << 16) | counter1_0; return GT_OK; }