📄 skethtool.c
字号:
init_timer(&locateNICtimer); locateNICtimer.function = toggleLeds; locateNICtimer.data = (unsigned long) pNet; locateNICtimer.expires = jiffies + HZ; /* initially 1sec */ add_timer(&locateNICtimer); return 0;}/***************************************************************************** * * toggleLeds - Changes the LED state of an adapter * * Description: * This function changes the current state of all LEDs of an adapter so * that it can be located by a user. If the requested time interval for * this test has elapsed, this function cleans up everything that was * temporarily setup during the locate NIC test. This involves of course * also closing or opening any adapter so that the initial board state * is recovered. * * Returns: N/A * */static void toggleLeds(unsigned long ptr) /* holds the pointer to adapter control context */{ DEV_NET *pNet = (DEV_NET*) ptr; SK_AC *pAC = pNet->pAC; int port = pNet->PortNr; SK_IOC IoC = pAC->IoBase; struct SK_NET_DEVICE *pDev = pAC->dev[port]; int OtherPort = (port) ? 0 : 1; struct SK_NET_DEVICE *pOtherDev = pAC->dev[OtherPort]; SK_U16 PageSelect; SK_BOOL YukLedState; SK_U16 YukLedOn = (PHY_M_LED_MO_DUP(MO_LED_ON) | PHY_M_LED_MO_10(MO_LED_ON) | PHY_M_LED_MO_100(MO_LED_ON) | PHY_M_LED_MO_1000(MO_LED_ON) | PHY_M_LED_MO_RX(MO_LED_ON)); SK_U16 YukLedOff = (PHY_M_LED_MO_DUP(MO_LED_OFF) | PHY_M_LED_MO_10(MO_LED_OFF) | PHY_M_LED_MO_100(MO_LED_OFF) | PHY_M_LED_MO_1000(MO_LED_OFF) | PHY_M_LED_MO_RX(MO_LED_OFF) | PHY_M_LED_MO_TX(MO_LED_OFF)); nbrBlinkQuarterSeconds--; if (nbrBlinkQuarterSeconds <= 0) { /* * We have to stop the device again in case the device has no * been up. */ if (!boardWasDown[0]) { /* * The board is already up as we bring it up in case it is not. */ } else { (*pDev->stop)(pDev); } if (isDualNetCard) { if (!boardWasDown[1]) { /* * The board is already up as we bring it up in case it is not. */ } else { (*pOtherDev->stop)(pOtherDev); } } isDualNetCard = SK_FALSE; isLocateNICrunning = SK_FALSE; return; } doSwitchLEDsOn = (doSwitchLEDsOn) ? SK_FALSE : SK_TRUE; if ( (doSwitchLEDsOn) && (nbrBlinkQuarterSeconds > 2) ){ if ( (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) || (pAC->GIni.GIChipId == CHIP_ID_YUKON_2(pAC)) || (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) ) { YukLedOn = 0; YukLedState = 1; YukLedOn |= PHY_M_LEDC_INIT_CTRL(YukLedState ? 9 : 8); YukLedState = 1; YukLedOn |= PHY_M_LEDC_STA1_CTRL(YukLedState ? 9 : 8); YukLedState = 1; YukLedOn |= PHY_M_LEDC_STA0_CTRL(YukLedState ? 9 : 8); YukLedState = 1; YukLedOn |= PHY_M_LEDC_LOS_CTRL(YukLedState ? 9 : 8); /* save page register */ SkGmPhyRead(pAC, IoC, port, PHY_MARV_EXT_ADR, &PageSelect); /* select page 3 for LED control */ SkGmPhyWrite(pAC, IoC, port, PHY_MARV_EXT_ADR, 3); SkGmPhyWrite(pAC, IoC, port, PHY_MARV_PHY_CTRL, YukLedOn); /* restore page register */ SkGmPhyWrite(pAC, IoC, port, PHY_MARV_EXT_ADR, PageSelect); } else { SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_OVER,YukLedOn); } } else { if ( (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) || (pAC->GIni.GIChipId == CHIP_ID_YUKON_2(pAC)) || (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) ) { YukLedOn = 0; YukLedState = 1; YukLedOn |= PHY_M_LEDC_INIT_CTRL(YukLedState ? 9 : 8); YukLedState = 1; YukLedOn |= PHY_M_LEDC_STA1_CTRL(YukLedState ? 9 : 8); YukLedState = 1; YukLedOn |= PHY_M_LEDC_STA0_CTRL(YukLedState ? 9 : 8); YukLedState = 1; YukLedOn |= PHY_M_LEDC_LOS_CTRL(YukLedState ? 9 : 8); /* save page register */ SkGmPhyRead(pAC, IoC, port, PHY_MARV_EXT_ADR, &PageSelect); /* select page 3 for LED control */ SkGmPhyWrite(pAC, IoC, port, PHY_MARV_EXT_ADR, 3); SkGmPhyWrite(pAC, IoC, port, PHY_MARV_PHY_CTRL, YukLedOff); /* restore page register */ SkGmPhyWrite(pAC, IoC, port, PHY_MARV_EXT_ADR, PageSelect); } else { SkGmPhyWrite(pAC,IoC,port,PHY_MARV_LED_OVER,YukLedOff); } } locateNICtimer.function = toggleLeds; locateNICtimer.data = (unsigned long) pNet; locateNICtimer.expires = jiffies + (HZ/4); add_timer(&locateNICtimer);} #ifdef NETIF_F_TSO/***************************************************************************** * * SkGeSetTSO - set the TSO parameters * * Description: * This function sets the TSO parameters * * Returns: * ==0: everything fine, no error * !=0: the return value is the error code of the failure */int SkGeSetTSO(struct net_device *dev, u32 data){ DEV_NET *pNet = (DEV_NET*) dev->priv; SK_AC *pAC = pNet->pAC; if (CHIP_ID_YUKON_2(pAC)) { if (data) { if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) && (dev->mtu > ETH_MAX_MTU)) { dev->features &= ~NETIF_F_TSO; } else { dev->features |= NETIF_F_TSO; } } else { dev->features &= ~NETIF_F_TSO; } return 0; } return -EOPNOTSUPP;}#endif/****************************************************************************** * * Kernel 2.4 function mapper to new Ethtool functions (New SkEthIoctl) * *****************************************************************************//***************************************************************************** * * SkEthIoctl - IOCTL entry point for all ethtool queries * * Description: * Any IOCTL request that has to deal with the ethtool command tool is * dispatched via this function. * * Returns: * ==0: everything fine, no error * !=0: the return value is the error code of the failure */int SkEthIoctl(struct net_device *netdev, /* the pointer to netdev structure */struct ifreq *ifr) /* what interface the request refers to? */{ DEV_NET *pNet = (DEV_NET*) netdev->priv; SK_AC *pAC = pNet->pAC; void *pAddr = ifr->ifr_data; int port = pNet->PortNr; SK_PNMI_STRUCT_DATA *pPnmiStruct = &pAC->PnmiStruct; SK_U32 Size = sizeof(SK_PNMI_STRUCT_DATA); SK_U32 cmd; struct sk98lin_stats *sk98lin_etht_stats = (port == 0) ? sk98lin_etht_stats_port0 : sk98lin_etht_stats_port1; if (get_user(cmd, (uint32_t *) pAddr)) { return -EFAULT; } switch(cmd) {#ifdef ETHTOOL_GSET case ETHTOOL_GSET: { struct ethtool_cmd ecmd = { ETHTOOL_GSET }; SkGeGetSettings(netdev, &ecmd); if(copy_to_user(pAddr, &ecmd, sizeof(ecmd))) { return -EFAULT; } return 0; } break;#endif#ifdef ETHTOOL_SSET case ETHTOOL_SSET: { struct ethtool_cmd ecmd; if(copy_from_user(&ecmd, pAddr, sizeof(ecmd))) { return -EFAULT; } return SkGeSetSettings(netdev, &ecmd); } break;#endif#ifdef ETHTOOL_GLINK case ETHTOOL_GLINK: { struct ethtool_value edata = { ETHTOOL_GLINK }; edata.data = netif_carrier_ok(netdev); if (copy_to_user(pAddr, &edata, sizeof(edata))) return -EFAULT; return 0; }#endif#ifdef ETHTOOL_GDRVINFO case ETHTOOL_GDRVINFO: { struct ethtool_drvinfo drvinfo = { ETHTOOL_GDRVINFO }; SkGeGetDrvInfo(netdev, &drvinfo); if(copy_to_user(pAddr, &drvinfo, sizeof(drvinfo))) { return -EFAULT; } return 0; } break;#endif#ifdef ETHTOOL_GSTRINGS case ETHTOOL_GSTRINGS: { struct ethtool_gstrings gstrings = { ETHTOOL_GSTRINGS }; char *strings = NULL; int err = 0; if(copy_from_user(&gstrings, pAddr, sizeof(gstrings))) { return -EFAULT; } switch(gstrings.string_set) {#ifdef ETHTOOL_GSTATS case ETH_SS_STATS: { int i; gstrings.len = SK98LIN_STATS_LEN; if ((strings = kmalloc(SK98LIN_STATS_LEN*ETHT_STATSTRING_LEN,GFP_KERNEL)) == NULL) { return -ENOMEM; } 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 default: return -EOPNOTSUPP; } if(copy_to_user(pAddr, &gstrings, sizeof(gstrings))) { err = -EFAULT; } pAddr = (void *) ((unsigned long int) pAddr + offsetof(struct ethtool_gstrings, data)); if(!err && copy_to_user(pAddr, strings, gstrings.len * ETH_GSTRING_LEN)) { err = -EFAULT; } kfree(strings); return err; }#endif#ifdef ETHTOOL_GSTATS case ETHTOOL_GSTATS: { struct { struct ethtool_stats eth_stats; uint64_t data[SK98LIN_STATS_LEN]; } stats = { {ETHTOOL_GSTATS, SK98LIN_STATS_LEN} }; int i; 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])) { stats.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 { stats.data[i] = (sk98lin_etht_stats[i].sizeof_stat == sizeof(uint64_t)) ? (uint64_t) 0 : (uint32_t) 0; } } if(copy_to_user(pAddr, &stats, sizeof(stats))) { return -EFAULT; } return 0; }#endif#ifdef ETHTOOL_PHYS_ID case ETHTOOL_PHYS_ID: { struct ethtool_value blinkSecs; if(copy_from_user(&blinkSecs, pAddr, sizeof(blinkSecs))) { return -EFAULT; } return SkGePhysId(netdev, (u32) blinkSecs.data); }#endif#ifdef ETHTOOL_GPAUSEPARAM case ETHTOOL_GPAUSEPARAM: { struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM }; SkGeGetPauseParam(netdev, &epause); if(copy_to_user(pAddr, &epause, sizeof(epause))) { return -EFAULT; } return 0; }#endif#ifdef ETHTOOL_SPAUSEPARAM case ETHTOOL_SPAUSEPARAM: { struct ethtool_pauseparam epause; if(copy_from_user(&epause, pAddr, sizeof(epause))) { return -EFAULT; } return SkGeSetPauseParam(netdev, &epause); }#endif#ifdef ETHTOOL_GSG case ETHTOOL_GSG: { struct ethtool_value edata = { ETHTOOL_GSG }; edata.data = (netdev->features & NETIF_F_SG) != 0; if (copy_to_user(pAddr, &edata, sizeof(edata))) { return -EFAULT; } return 0; }#endif#ifdef ETHTOOL_SSG case ETHTOOL_SSG: { struct ethtool_value edata; if (copy_from_user(&edata, pAddr, sizeof(edata))) { return -EFAULT; } if (pAC->ChipsetType) { /* Don't handle if Genesis */ if (edata.data) { netdev->features |= NETIF_F_SG; } else { netdev->features &= ~NETIF_F_SG; } } return 0; }#endif#ifdef ETHTOOL_GRXCSUM case ETHTOOL_GRXCSUM: { struct ethtool_value edata = { ETHTOOL_GRXCSUM }; edata.data = pAC->RxPort[port].UseRxCsum; if (copy_to_user(pAddr, &edata, sizeof(edata))) { return -EFAULT; } return 0; }#endif#ifdef ETHTOOL_SRXCSUM case ETHTOOL_SRXCSUM: { struct ethtool_value edata; if (copy_from_user(&edata, pAddr, sizeof(edata))) { return -EFAULT; } pAC->RxPort[port].UseRxCsum = edata.data; return 0; }#endif#ifdef ETHTOOL_GTXCSUM case ETHTOOL_GTXCSUM: { struct ethtool_value edata = { ETHTOOL_GTXCSUM }; edata.data = ((netdev->features & NETIF_F_IP_CSUM) != 0); if (copy_to_user(pAddr, &edata, sizeof(edata))) { return -EFAULT; } return 0; }#endif#ifdef ETHTOOL_STXCSUM case ETHTOOL_STXCSUM: { struct ethtool_value edata; if (copy_from_user(&edata, pAddr, sizeof(edata))) { return -EFAULT; } if (pAC->ChipsetType) { /* Don't handle if Genesis */ if (edata.data) { netdev->features |= NETIF_F_IP_CSUM; } else { netdev->features &= ~NETIF_F_IP_CSUM; } } return 0; }#endif#ifdef ETHTOOL_NWAY_RST case ETHTOOL_NWAY_RST: { if(netif_running(netdev)) { (*netdev->stop)(netdev); (*netdev->open)(netdev); } return 0; }#endif#ifdef NETIF_F_TSO#ifdef ETHTOOL_GTSO case ETHTOOL_GTSO: { struct ethtool_value edata = { ETHTOOL_GTSO }; edata.data = (netdev->features & NETIF_F_TSO) != 0; if (copy_to_user(pAddr, &edata, sizeof(edata))) { return -EFAULT; } return 0; }#endif#ifdef ETHTOOL_STSO case ETHTOOL_STSO: { struct ethtool_value edata; if (CHIP_ID_YUKON_2(pAC)) { if (copy_from_user(&edata, pAddr, sizeof(edata))) { return -EFAULT; } if (edata.data) { netdev->features |= NETIF_F_TSO; } else { netdev->features &= ~NETIF_F_TSO; } return 0; } return -EOPNOTSUPP; }#endif#endif#ifdef ETHTOOL_GCOALESCE case ETHTOOL_GCOALESCE: { struct ethtool_coalesce ecoalesc = { ETHTOOL_GCOALESCE }; SkGeGetCoalesce(netdev, &ecoalesc); if(copy_to_user(pAddr, &ecoalesc, sizeof(ecoalesc))) { return -EFAULT; } return 0; }#endif#ifdef ETHTOOL_SCOALESCE case ETHTOOL_SCOALESCE: { struct ethtool_coalesce ecoalesc; if(copy_from_user(&ecoalesc, pAddr, sizeof(ecoalesc))) { return -EFAULT; } return SkGeSetCoalesce(netdev, &ecoalesc); }#endif#ifdef ETHTOOL_GWOL case ETHTOOL_GWOL: { struct ethtool_wolinfo ewol = { ETHTOOL_GWOL }; SkGeGetWolSettings(netdev, &ewol); if(copy_to_user(pAddr, &ewol, sizeof(ewol))) { return -EFAULT; } return 0; }#endif#ifdef ETHTOOL_SWOL case ETHTOOL_SWOL: { struct ethtool_wolinfo ewol; if(copy_from_user(&ewol, pAddr, sizeof(ewol))) { return -EFAULT; } return SkGeSetWolSettings(netdev, &ewol); }#endif default: return -EOPNOTSUPP; }} /* SkEthIoctl() *//******************************************************************************* * * End of file * ******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -