📄 skethtool.c
字号:
(port == 0) ? sk98lin_etht_stats_port0 : sk98lin_etht_stats_port1; if (netif_running(pAC->dev[port])) { SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, port); } for(i = 0; i < SK98LIN_STATS_LEN; i++) { if (netif_running(pAC->dev[port])) { data[i] = (sk98lin_etht_stats[i].sizeof_stat == sizeof(uint64_t)) ? *(uint64_t *)((char *)pAC + sk98lin_etht_stats[i].stat_offset) : *(uint32_t *)((char *)pAC + sk98lin_etht_stats[i].stat_offset); } else { data[i] = (sk98lin_etht_stats[i].sizeof_stat == sizeof(uint64_t)) ? (uint64_t) 0 : (uint32_t) 0; } }}/***************************************************************************** * * SkGeSetSettings - configures the settings of a selected adapter * * Description: * Possible settings that may be altered are a)speed, b)duplex or * c)autonegotiation. * * Returns: * ==0: everything fine, no error * !=0: the return value is the error code of the failure */int SkGeSetSettings(struct net_device *dev, struct ethtool_cmd *ecmd){ DEV_NET *pNet = (DEV_NET*) dev->priv; SK_AC *pAC = pNet->pAC; int port = pNet->PortNr; SK_U32 Instance; char Buf[4]; unsigned int Len = 1; int Ret; if (port == 0) { Instance = (pAC->RlmtNets == 2) ? 1 : 2; } else { Instance = (pAC->RlmtNets == 2) ? 2 : 3; } if (((ecmd->autoneg == AUTONEG_DISABLE) || (ecmd->autoneg == AUTONEG_ENABLE)) && ((ecmd->duplex == DUPLEX_FULL) || (ecmd->duplex == DUPLEX_HALF))) { if (ecmd->autoneg == AUTONEG_DISABLE) { if (ecmd->duplex == DUPLEX_FULL) { *Buf = (char) SK_LMODE_FULL; } else { *Buf = (char) SK_LMODE_HALF; } } else { /* Autoneg on. Enable autoparam */ *Buf = (char) SK_LMODE_AUTOBOTH; } Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE, &Buf, &Len, Instance, pNet->NetNr); if (Ret != SK_PNMI_ERR_OK) { return -EINVAL; } } else if (ecmd->autoneg == AUTONEG_ENABLE) { /* Set default values */ *Buf = (char) SK_LMODE_AUTOBOTH; Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_LINK_MODE, &Buf, &Len, Instance, pNet->NetNr); } if ((ecmd->speed == SPEED_1000) || (ecmd->speed == SPEED_100) || (ecmd->speed == SPEED_10)) { if (ecmd->autoneg == AUTONEG_ENABLE) { *Buf = (char) SK_LSPEED_AUTO; } else if (ecmd->speed == SPEED_1000) { *Buf = (char) SK_LSPEED_1000MBPS; } else if (ecmd->speed == SPEED_100) { *Buf = (char) SK_LSPEED_100MBPS; } else { *Buf = (char) SK_LSPEED_10MBPS; } Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, &Buf, &Len, Instance, pNet->NetNr); if (Ret != SK_PNMI_ERR_OK) { return -EINVAL; } } else if (ecmd->autoneg == AUTONEG_ENABLE) { *Buf = (char) SK_LSPEED_AUTO; Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, &Buf, &Len, Instance, pNet->NetNr); } else { return -EINVAL; } return(0);}/***************************************************************************** * * SkGeSetWolSettings - configures the WOL settings of a selected adapter * * Description: * The WOL settings of a selected adapter are configured regarding * the parameters in the passed ethtool_wolinfo structure. * Note that currently only wake on magic packet is supported! * * Returns: * ==0: everything fine, no error * !=0: the return value is the error code of the failure */int SkGeSetWolSettings(struct net_device *dev, struct ethtool_wolinfo *ecmd){ DEV_NET *pNet = (DEV_NET*) dev->priv; SK_AC *pAC = pNet->pAC; if (ecmd->wolopts != WAKE_MAGIC && ecmd->wolopts != 0) return -EOPNOTSUPP; if (((ecmd->wolopts & WAKE_MAGIC) == WAKE_MAGIC) || (ecmd->wolopts == 0)) { pAC->WolInfo.ConfiguredWolOptions = ecmd->wolopts; return 0; } return -EFAULT;}/***************************************************************************** * * SkGeSetPauseParam - configures the pause parameters of an adapter * * Description: * This function sets the Rx or Tx pause parameters * * Returns: * ==0: everything fine, no error * !=0: the return value is the error code of the failure */int SkGeSetPauseParam(struct net_device *dev, struct ethtool_pauseparam *ecmd){ DEV_NET *pNet = (DEV_NET*) dev->priv; SK_AC *pAC = pNet->pAC; int port = pNet->PortNr; SK_GEPORT *pPort = &pAC->GIni.GP[port]; int PrevSpeedVal = pPort->PLinkSpeedUsed; SK_U32 Instance; char Buf[4]; int Ret; SK_BOOL prevAutonegValue = SK_TRUE; int prevTxPause = 0; int prevRxPause = 0; unsigned int Len = 1; if (port == 0) { Instance = (pAC->RlmtNets == 2) ? 1 : 2; } else { Instance = (pAC->RlmtNets == 2) ? 2 : 3; } /* ** we have to determine the current settings to see if ** the operator requested any modification of the flow ** control parameters... */ if (pPort->PFlowCtrlMode == SK_FLOW_MODE_LOC_SEND) { prevTxPause = 1; } if ((pPort->PFlowCtrlMode == SK_FLOW_MODE_SYMMETRIC) || (pPort->PFlowCtrlMode == SK_FLOW_MODE_SYM_OR_REM)) { prevTxPause = 1; prevRxPause = 1; } if ((prevRxPause == 0) && (prevTxPause == 0)) { prevAutonegValue = SK_FALSE; } /* ** perform modifications regarding the changes ** requested by the operator */ if (ecmd->autoneg != prevAutonegValue) { if (ecmd->autoneg == AUTONEG_DISABLE) { *Buf = (char) SK_FLOW_MODE_NONE; } else { *Buf = (char) SK_FLOW_MODE_SYMMETRIC; } } else { if(ecmd->rx_pause && ecmd->tx_pause) { *Buf = (char) SK_FLOW_MODE_SYMMETRIC; } else if (ecmd->rx_pause && !ecmd->tx_pause) { *Buf = (char) SK_FLOW_MODE_SYM_OR_REM; } else if(!ecmd->rx_pause && ecmd->tx_pause) { *Buf = (char) SK_FLOW_MODE_LOC_SEND; } else { *Buf = (char) SK_FLOW_MODE_NONE; } } Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_FLOWCTRL_MODE, &Buf, &Len, Instance, pNet->NetNr); if (Ret != SK_PNMI_ERR_OK) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL, ("ethtool (sk98lin): error changing rx/tx pause (%i)\n", Ret)); } else { Len = 1; /* set buffer length to correct value */ } /* ** It may be that autoneg has been disabled! Therefore ** set the speed to the previously used value... */ *Buf = (char) PrevSpeedVal; Ret = SkPnmiSetVar(pAC, pAC->IoBase, OID_SKGE_SPEED_MODE, &Buf, &Len, Instance, pNet->NetNr); if (Ret != SK_PNMI_ERR_OK) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_CTRL, ("ethtool (sk98lin): error setting speed (%i)\n", Ret)); } return 0;}/***************************************************************************** * * SkGeSetCoalesce - configures the IRQ moderation of an adapter * * Description: * Depending on the desired IRQ moderation parameters, either a) static, * b) dynamic or c) no moderation is configured. * * Returns: * ==0: everything fine, no error * !=0: the return value is the error code of the failure * * Notes: * The supported timeframe for the coalesced interrupts ranges from * 33.333us (30 IntsPerSec) down to 25us (40.000 IntsPerSec). * Any requested value that is not in this range will abort the request! */int SkGeSetCoalesce(struct net_device *dev, struct ethtool_coalesce *ecmd){ DEV_NET *pNet = (DEV_NET*) dev->priv; SK_AC *pAC = pNet->pAC; DIM_INFO *Info = &pAC->DynIrqModInfo; int PrevModeration = Info->IntModTypeSelect; Info->IntModTypeSelect = C_INT_MOD_NONE; /* initial default */ if ((ecmd->rx_coalesce_usecs) || (ecmd->tx_coalesce_usecs)) { if (ecmd->rx_coalesce_usecs) { if ((ecmd->rx_coalesce_usecs < 25) || (ecmd->rx_coalesce_usecs > 33333)) { return -EINVAL; } } if (ecmd->tx_coalesce_usecs) { if ((ecmd->tx_coalesce_usecs < 25) || (ecmd->tx_coalesce_usecs > 33333)) { return -EINVAL; } } if (!CHIP_ID_YUKON_2(pAC)) { if ((Info->MaskIrqModeration == IRQ_MASK_SP_RX) || (Info->MaskIrqModeration == IRQ_MASK_SP_TX) || (Info->MaskIrqModeration == IRQ_MASK_RX_TX_SP)) { Info->MaskIrqModeration = IRQ_MASK_SP_ONLY; } } Info->IntModTypeSelect = C_INT_MOD_STATIC; if (ecmd->rx_coalesce_usecs) { Info->MaxModIntsPerSec = 1000000 / ecmd->rx_coalesce_usecs; if (!CHIP_ID_YUKON_2(pAC)) { if (Info->MaskIrqModeration == IRQ_MASK_TX_ONLY) { Info->MaskIrqModeration = IRQ_MASK_TX_RX; } if (Info->MaskIrqModeration == IRQ_MASK_SP_ONLY) { Info->MaskIrqModeration = IRQ_MASK_SP_RX; } if (Info->MaskIrqModeration == IRQ_MASK_SP_TX) { Info->MaskIrqModeration = IRQ_MASK_RX_TX_SP; } } else { Info->MaskIrqModeration = Y2_IRQ_MASK; } } if (ecmd->tx_coalesce_usecs) { Info->MaxModIntsPerSec = 1000000 / ecmd->tx_coalesce_usecs; if (!CHIP_ID_YUKON_2(pAC)) { if (Info->MaskIrqModeration == IRQ_MASK_RX_ONLY) { Info->MaskIrqModeration = IRQ_MASK_TX_RX; } if (Info->MaskIrqModeration == IRQ_MASK_SP_ONLY) { Info->MaskIrqModeration = IRQ_MASK_SP_TX; } if (Info->MaskIrqModeration == IRQ_MASK_SP_RX) { Info->MaskIrqModeration = IRQ_MASK_RX_TX_SP; } } else { Info->MaskIrqModeration = Y2_IRQ_MASK; } } } if ((ecmd->rate_sample_interval) || (ecmd->rx_coalesce_usecs_low) || (ecmd->tx_coalesce_usecs_low) || (ecmd->rx_coalesce_usecs_high)|| (ecmd->tx_coalesce_usecs_high)) { if (ecmd->rate_sample_interval) { if ((ecmd->rate_sample_interval < 1) || (ecmd->rate_sample_interval > 10)) { return -EINVAL; } } if (ecmd->rx_coalesce_usecs_low) { if ((ecmd->rx_coalesce_usecs_low < 25) || (ecmd->rx_coalesce_usecs_low > 33333)) { return -EINVAL; } } if (ecmd->rx_coalesce_usecs_high) { if ((ecmd->rx_coalesce_usecs_high < 25) || (ecmd->rx_coalesce_usecs_high > 33333)) { return -EINVAL; } } if (ecmd->tx_coalesce_usecs_low) { if ((ecmd->tx_coalesce_usecs_low < 25) || (ecmd->tx_coalesce_usecs_low > 33333)) { return -EINVAL; } } if (ecmd->tx_coalesce_usecs_high) { if ((ecmd->tx_coalesce_usecs_high < 25) || (ecmd->tx_coalesce_usecs_high > 33333)) { return -EINVAL; } } Info->IntModTypeSelect = C_INT_MOD_DYNAMIC; if (ecmd->rate_sample_interval) { Info->DynIrqModSampleInterval = ecmd->rate_sample_interval; } if (ecmd->rx_coalesce_usecs_low) { Info->MaxModIntsPerSecLowerLimit = 1000000 / ecmd->rx_coalesce_usecs_low; } if (ecmd->tx_coalesce_usecs_low) { Info->MaxModIntsPerSecLowerLimit = 1000000 / ecmd->tx_coalesce_usecs_low; } if (ecmd->rx_coalesce_usecs_high) { Info->MaxModIntsPerSecUpperLimit = 1000000 / ecmd->rx_coalesce_usecs_high; } if (ecmd->tx_coalesce_usecs_high) { Info->MaxModIntsPerSecUpperLimit = 1000000 / ecmd->tx_coalesce_usecs_high; } } if ((PrevModeration == C_INT_MOD_NONE) && (Info->IntModTypeSelect != C_INT_MOD_NONE)) { SkDimEnableModerationIfNeeded(pAC); } if (PrevModeration != C_INT_MOD_NONE) { SkDimDisableModeration(pAC, PrevModeration); if (Info->IntModTypeSelect != C_INT_MOD_NONE) { SkDimEnableModerationIfNeeded(pAC); } } return 0;}#ifdef ENABLE_FUTURE_ETH/***************************************************************************** * * SkGeSetSG - set the SG parameters * * Description: * This function sets the SG parameters * * Returns: * ==0: everything fine, no error * !=0: the return value is the error code of the failure */int SkGeSetSG(struct net_device *dev, u32 data){ return ethtool_op_set_sg(dev, data);}#endif#ifdef ENABLE_FUTURE_ETH/***************************************************************************** * * SkGeSetTxCsum - set the TxCsum parameters * * Description: * This function sets the TxCsum parameters * * Returns: * ==0: everything fine, no error * !=0: the return value is the error code of the failure */int SkGeSetTxCsum(struct net_device *dev, u32 data){ return ethtool_op_set_tx_csum(dev, data);}#endif/***************************************************************************** * * SkGeSetRxCsum - set the SkGeSetRxCsum parameters * * Description: * This function sets the RxCsum parameters * * Returns: * ==0: everything fine, no error * !=0: the return value is the error code of the failure */int SkGeSetRxCsum(struct net_device *dev, u32 data){ DEV_NET *pNet = (DEV_NET*) dev->priv; SK_AC *pAC = pNet->pAC; int port = pNet->PortNr; pAC->RxPort[port].UseRxCsum = data; return 0;}/***************************************************************************** * * SkGePhysId - start the locate NIC feature of the elected adapter * * Description: * This function is used if the user want to locate a particular NIC. * All LEDs are regularly switched on and off, so the NIC can easily * be identified. * * Returns: * ==0: everything fine, no error, locateNIC test was started * !=0: one locateNIC test runs already * */int SkGePhysId(struct net_device *dev, u32 data){ DEV_NET *pNet = (DEV_NET*) dev->priv; SK_AC *pAC = pNet->pAC; SK_IOC IoC = pAC->IoBase; int port = pNet->PortNr; struct SK_NET_DEVICE *pDev = pAC->dev[port]; int OtherPort = (port) ? 0 : 1; struct SK_NET_DEVICE *pOtherDev = pAC->dev[OtherPort]; if (isLocateNICrunning) { return -EFAULT; } isLocateNICrunning = SK_TRUE; currentPortIndex = port; isDualNetCard = (pDev != pOtherDev) ? SK_TRUE : SK_FALSE; doSwitchLEDsOn = SK_FALSE; if (netif_running(pAC->dev[port])) { boardWasDown[0] = SK_FALSE; } else { (*pDev->open)(pDev); boardWasDown[0] = SK_TRUE; } if (isDualNetCard) { if (netif_running(pAC->dev[OtherPort])) { boardWasDown[1] = SK_FALSE; } else { (*pOtherDev->open)(pOtherDev); boardWasDown[1] = SK_TRUE; } } if ( (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) || (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) ) { SkMacClearRst(pAC, IoC, port); } if ((data < 1) || (data > 30)) { data = 3; /* three seconds default */ } nbrBlinkQuarterSeconds = 4*data;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -