📄 skethtool.c
字号:
ecmd->use_adaptive_tx_coalesce = 1; ecmd->tx_coalesce_usecs_low = 1000000 / Info->MaxModIntsPerSecLowerLimit; ecmd->tx_coalesce_usecs_high = 1000000 / Info->MaxModIntsPerSecUpperLimit; } } } return(0);}/***************************************************************************** * * SkGeGetRxCsum - retrieves the RxCsum parameters * * Description: * All current RxCsum parameters of a selected adapter are placed * in the passed net_device structure and are returned. * * Returns: N/A * */SK_U32 SkGeGetRxCsum(struct net_device *dev){ DEV_NET *pNet = (DEV_NET*) dev->priv; SK_AC *pAC = pNet->pAC; int port = pNet->PortNr; return pAC->RxPort[port].UseRxCsum;}/***************************************************************************** * * SkGeGetStrings - retrieves the statistic strings * * Description: * N/A * * Returns: N/A * */void SkGeGetStrings(struct net_device *dev, u32 stringset, u8 *strings){ DEV_NET *pNet = (DEV_NET*) dev->priv; int port = pNet->PortNr; int i;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,19) struct sk98lin_stats *sk98lin_etht_stats = (port == 0) ? sk98lin_etht_stats_port0 : sk98lin_etht_stats_port1; switch(stringset) { case ETH_SS_STATS: { for(i=0; i < SK98LIN_STATS_LEN; i++) { memcpy(&strings[i * ETHT_STATSTRING_LEN], &(sk98lin_etht_stats[i].stat_string), ETHT_STATSTRING_LEN); } break; } }#endif}/***************************************************************************** * * SkGeGetStatsLen - retrieves the statistic count * * Description: * N/A * * Returns: N/A * */int SkGeGetStatsLen(struct net_device *dev){ return SK98LIN_STATS_LEN;}/***************************************************************************** * * SkGeGetEthStats - retrieves the card statistics * * Description: * All current statistics of a selected adapter are placed * in the passed ethtool_stats structure and are returned. * * Returns: N/A * */void SkGeGetEthStats(struct net_device *dev, struct ethtool_stats *stats, u64 *data){ DEV_NET *pNet = (DEV_NET*) dev->priv; SK_AC *pAC = pNet->pAC; SK_U32 Size = sizeof(SK_PNMI_STRUCT_DATA); SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct; int port = pNet->PortNr; int i; struct sk98lin_stats *sk98lin_etht_stats = (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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -