📄 skge.c
字号:
{ SK_AC *pAC = pNet->pAC; SK_BOOL bStatus = SK_FALSE; /* Variable used to store the MAC RX FIFO RP, RPLev*/ SK_U32 MACFifoRP = 0; SK_U32 MACFifoRLev = 0; /* Variable used to store the PCI RX FIFO RP, RPLev*/ SK_U32 RXFifoRP = 0; SK_U8 RXFifoRLev = 0; SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ("==> CheckRXCounters()\n")); /*Check if statistic counters hangs*/ if (pNet->LastJiffies == pAC->dev[pNet->PortNr]->last_rx) { /* Now read the values of read pointer/level from MAC RX FIFO again */ SK_IN32(pAC->IoBase, MR_ADDR(pNet->PortNr, RX_GMF_RP), &MACFifoRP); SK_IN32(pAC->IoBase, MR_ADDR(pNet->PortNr, RX_GMF_RLEV), &MACFifoRLev); /* Now read the values of read pointer/level from RX FIFO again */ SK_IN8(pAC->IoBase, Q_ADDR(pAC->GIni.GP[pNet->PortNr].PRxQOff, Q_RX_RP), &RXFifoRP); SK_IN8(pAC->IoBase, Q_ADDR(pAC->GIni.GP[pNet->PortNr].PRxQOff, Q_RX_RL), &RXFifoRLev); /* Check if the MAC RX hang */ if ((MACFifoRP == pNet->PreviousMACFifoRP) && (MACFifoRLev != 0) && (MACFifoRLev >= pNet->PreviousMACFifoRLev)){ bStatus = SK_TRUE; } /* Check if the PCI RX hang */ if ((RXFifoRP == pNet->PreviousRXFifoRP) && (RXFifoRLev != 0) && (RXFifoRLev >= pNet->PreviousRXFifoRLev)){ /*Set the flag to indicate that the RX FIFO hangs*/ bStatus = SK_TRUE; } } /* Store now the values of counters for next check */ pNet->LastJiffies = pAC->dev[pNet->PortNr]->last_rx; /* Store the values of read pointer/level from MAC RX FIFO for next test */ pNet->PreviousMACFifoRP = MACFifoRP; pNet->PreviousMACFifoRLev = MACFifoRLev; /* Store the values of read pointer/level from RX FIFO for next test */ pNet->PreviousRXFifoRP = RXFifoRP; pNet->PreviousRXFifoRLev = RXFifoRLev; SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ("<== CheckRXCounters()\n")); return bStatus;}/******************************************************************************* CheckRxPath - Checks if the RX path** Description:* This function is called periodical by a timer. ** Notes:** Function Parameters:** Returns:* None.**/static void CheckRxPath(DEV_NET *pNet) /* holds the pointer to adapter control context */{ unsigned long Flags; /* for the spin locks */ /* Initialize the pAC structure.*/ SK_AC *pAC = pNet->pAC; SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ("==> CheckRxPath()\n")); /*If the statistics are not changed then could be an RX problem */ if (CheckRXCounters(pNet)){ /* * First we try the simple solution by resetting the Level Timer */ /* Stop Level Timer of Status BMU */ SK_OUT8(pAC->IoBase, STAT_LEV_TIMER_CTRL, TIM_STOP); /* Start Level Timer of Status BMU */ SK_OUT8(pAC->IoBase, STAT_LEV_TIMER_CTRL, TIM_START); if (!CheckRXCounters(pNet)) { return; } spin_lock_irqsave(&pAC->SlowPathLock, Flags); SkLocalEventQueue(pAC, SKGE_DRV, SK_DRV_RECOVER,pNet->PortNr,-1,SK_TRUE); /* Reset the fifo counters */ pNet->PreviousMACFifoRP = 0; pNet->PreviousMACFifoRLev = 0; pNet->PreviousRXFifoRP = 0; pNet->PreviousRXFifoRLev = 0; spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); } SK_DBG_MSG(pAC, SK_DBGMOD_DRV, SK_DBGCAT_DRV_MSG, ("<== CheckRxPath()\n"));}#endif#ifdef CONFIG_PM/***************************************************************************** * * sk98lin_resume - Resume the the card * * Description: * This function resumes the card into the D0 state * * Returns: N/A * */static int sk98lin_resume(struct pci_dev *pdev) /* the device that is to resume */{ struct net_device *dev = pci_get_drvdata(pdev); DEV_NET *pNet = (DEV_NET*) dev->priv; SK_AC *pAC = pNet->pAC; SK_U16 PmCtlSts;#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19) int rCode;#endif#ifndef USE_ASF_DASH_FW if (pAC->GIni.GIChipId != CHIP_ID_YUKON_EX) {#endif /* Set the power state to D0 */ pci_set_power_state(pdev, 0);#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) pci_restore_state(pdev);#else pci_restore_state(pdev, pAC->PciState);#endif#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19) rCode = pci_enable_device(pdev); if (rCode) return rCode;#else pci_enable_device(pdev);#endif pci_set_master(pdev); pci_enable_wake(pdev, 3, 0); pci_enable_wake(pdev, 4, 0);#ifndef USE_ASF_DASH_FW }#endif /* Set the adapter power state to D0 */ SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); PmCtlSts &= ~(PCI_PM_STATE_D3); /* reset all DState bits */ PmCtlSts |= PCI_PM_STATE_D0; SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PmCtlSts);#ifdef USE_ASF_DASH_FW SkAsfResume(pAC, pAC->IoBase);#endif#ifdef USE_ASF_DASH_FW pAC->ReturningFromSuspend = SK_TRUE; pAC->SendWolPattern = SK_TRUE; pAC->ReceivedPacket = SK_FALSE;#endif /* Reinit the adapter and start the port again */ pAC->BoardLevel = SK_INIT_DATA; SkDrvLeaveDiagMode(pAC);#ifdef USE_ASF_DASH_FW printk("sk98lin: resume complete\n");#endif return 0;} /***************************************************************************** * * sk98lin_suspend - Suspend the card * * Description: * This function suspends the card into a defined state * * Returns: N/A * */#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10)static int sk98lin_suspend(struct pci_dev *pdev, /* pointer to the device that is to suspend */pm_message_t state) /* what power state is desired by Linux? */#elsestatic int sk98lin_suspend(struct pci_dev *pdev, /* pointer to the device that is to suspend */SK_U32 state) /* what power state is desired by Linux? */#endif{ struct net_device *dev = pci_get_drvdata(pdev); DEV_NET *pNet = (DEV_NET*) dev->priv; SK_AC *pAC = pNet->pAC; SK_U16 PciPMControlStatus; SK_U16 PciPMCapabilities; SK_MAC_ADDR MacAddr; int i; /* GEnesis and first yukon revs do not support power management */ if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { if (pAC->GIni.GIChipRev == 0) { return 0; /* power management not supported */ } } if (pAC->GIni.GIChipId == CHIP_ID_GENESIS) { return 0; /* not supported for this chipset */ } if (pAC->WolInfo.ConfiguredWolOptions == 0) { return 0; /* WOL possible, but disabled via ethtool */ } if(netif_running(dev)) { netif_stop_queue(dev); /* stop device if running */ }#ifdef USE_ASF_DASH_FW pAC->LinkSpeed = pAC->GIni.GP[0].PLinkSpeed; pAC->LinkSpeedSet = SK_TRUE; /* Write zeroes to ASF Fifo. */ SetRamAddr(pAC, SK_ST_FIFOTYPE, SK_ST_BUFADDR_LOW, SK_ST_BUFADDR_HIGH); AccessRamBuf(pAC, SK_ST_BUFSIZE, SK_FALSE);#endif /* Read the PM control/status register from the PCI config space */ SK_IN16(pAC->IoBase, PCI_C(pAC, PCI_PM_CTL_STS), &PciPMControlStatus); /* Read the power management capabilities from the PCI config space */ SK_IN16(pAC->IoBase, PCI_C(pAC, PCI_PM_CAP_REG), &PciPMCapabilities); /* Enable WakeUp with Magic Packet - get MAC address from adapter */ for (i = 0; i < SK_MAC_ADDR_LEN; i++) { /* virtual address: will be used for data */ SK_IN8(pAC->IoBase, (B2_MAC_1 + i), &MacAddr.a[i]); } SkDrvEnterDiagMode(pAC); SkEnableWOMagicPacket(pAC, pAC->IoBase, MacAddr);#ifndef USE_ASF_DASH_FW if (pAC->GIni.GIChipId != CHIP_ID_YUKON_EX) {#endif#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9) pci_save_state(pdev);#else pci_save_state(pdev, pAC->PciState);#endif /* Possibly we need to evaluate the return values */ pci_enable_wake(pdev, 3, 1); /* D3 hot */ pci_enable_wake(pdev, 4, 1); /* D3 cold */ pci_disable_device(pdev);#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10) pci_set_power_state(pdev, pci_choose_state(pdev, state)); /* set the state */#else pci_set_power_state(pdev, state); /* set the state */#endif#ifndef USE_ASF_DASH_FW }#endif#ifdef USE_ASF_DASH_FW printk("sk98lin: suspend complete\n");#endif return 0;}/****************************************************************************** * * SkEnableWOMagicPacket - Enable Wake on Magic Packet on the adapter * * Context: * init, pageable * the adapter should be de-initialized before calling this function * * Returns: * nothing */static void SkEnableWOMagicPacket(SK_AC *pAC, /* Adapter Control Context */SK_IOC IoC, /* I/O control context */SK_MAC_ADDR MacAddr) /* MacAddr expected in magic packet */{ SK_U16 Word; SK_U32 DWord; int Port; int i; /* Use port 0 as long as we do not have any dual port cards which support WOL */ Port = 0; DWord = 0; SK_OUT16(IoC, B0_CTST, 0x0002); /* clear S/W Reset */ SK_OUT16(IoC, GMAC_LINK_CTRL, 0x0002); /* clear Link Reset */ /* * PHY Configuration: * Autonegotiation is enabled, advertise 10 HD, 10 FD, * 100 HD, and 100 FD. */ if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) || (pAC->GIni.GIChipId == CHIP_ID_YUKON_EC_U) || (pAC->GIni.GIChipId == CHIP_ID_YUKON_XL) || (pAC->GIni.GIChipId == CHIP_ID_YUKON_EX) || (pAC->GIni.GIChipId == CHIP_ID_YUKON) || (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE)) { SK_OUT32(pAC->IoBase, 0x1c84, 0x7000); SK_OUT32(pAC->IoBase, 0x1c88, 0x0); SK_OUT32(pAC->IoBase, 0x1c84, 0x7000); SK_OUT32(pAC->IoBase, 0x1c88, 0x0); SK_OUT8(IoC, B0_POWER_CTRL, 0xa9); /* enable VAUX */ /* WA code for COMA mode */ /* Only for yukon plus based chipsets rev A3 */ if ( (pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) && (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) ) { SK_IN32(IoC, B2_GP_IO, &DWord); DWord |= GP_DIR_9; /* set to output */ DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ SK_OUT32(IoC, B2_GP_IO, DWord); /* clear PHY reset */ } if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) || (pAC->GIni.GIChipId == CHIP_ID_YUKON)) { SK_OUT32(IoC, GPHY_CTRL, 0x01f04001); /* set PHY reset */ SK_OUT32(IoC, GPHY_CTRL, 0x01f04002); /* clear PHY reset */ } else { SK_OUT8(IoC, GPHY_CTRL, 0x02); /* clear PHY reset */ } SK_OUT8(IoC, GMAC_CTRL, 0x02); /* clear MAC reset */#ifdef USE_ASF_DASH_FW SkSetFWLinkParams(pAC, IoC, Port);#else SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_AUNE_ADV, 0x01e1); /* Advertise 10/100 HD/FD */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_1000T_CTRL, 0x0000); /* Do not advertise 1000 HD/FD */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, 0xb300); /* 100 MBps, Autoneg, FD */ GM_OUT16(IoC, Port, GM_GP_CTRL, 0x383a);#endif } else if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) || (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE_P)) { SK_OUT8(IoC, B0_POWER_CTRL, 0xa9); /* enable VAUX */ SK_OUT8(IoC, GPHY_CTRL, 0x02); /* clear PHY reset */ SK_OUT8(IoC, GMAC_CTRL, 0x02); /* clear MAC reset */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, 0x0130); /* Enable Automatic Crossover */ SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, 0xb300); /* 100 MBit, disable Autoneg */ /* * MAC Configuration: * Set the MAC to 100 HD and enable the auto update * features for Speed and Duplex Mode. * If autonegotiation completes successfully, the * MAC takes the link parameters from the PHY. * If the link partner doesn't support autonegotiation, * the MAC can receive magic packets if the link partner * uses 100 HD. */ GM_OUT16(IoC, Port, GM_GP_CTRL, 0x383a); }#ifdef USE_ASF_DASH_FW SkAsfSuspend(pAC, pAC->IoBase);#endif /* * Set Up Magic Packet parameters */#ifndef USE_ASF_DASH_FW for (i = 0; i < 6; i+=2) { /* Set up magic packet MAC address */ SK_IN16(IoC, B2_MAC_1 + i, &Word); SK_OUT16(IoC, WOL_MAC_ADDR_LO + i, Word); } Word = 0x0; Word |= WOL_CTL_ENA_PME_ON_MAGIC_PKT; /* Enable PME on magic packet */ Word |= WOL_CTL_ENA_MAGIC_PKT_UNIT; /* Enable magic packet unit */ SK_OUT16(IoC, WOL_CTRL_STAT, Word);#endif#ifdef USE_ASF_DASH_FW for (i = 0; i < 6; i+=2) { /* Delete magic packet MAC address */ SK_OUT16(IoC, WOL_MAC_ADDR_LO + i, 0x0); } Word = 0x0; Word |= WOL_CTL_DIS_PME_ON_MAGIC_PKT; /* Disable PME on magic packet */ Word |= WOL_CTL_DIS_MAGIC_PKT_UNIT; /* Disable magic packet unit */ Word |= WOL_CTL_DIS_PME_ON_LINK_CHG; /* Disable PME on link change */ Word |= WOL_CTL_DIS_LINK_CHG_UNIT; /* Disable link change unit */ SK_OUT16(IoC, WOL_CTRL_STAT, Word);#endif /* * Set up PME generation */ /* set PME legacy mode */ /* Only for PCI express based chipsets */ if ((pAC->GIni.GIChipId == CHIP_ID_YUKON_EC) || (pAC->GIni.GIChipId == CHIP_ID_YUKON_FE) || (CHIP_ID_YUKON_2(pAC))) { if (pAC->GIni.GIChipId != CHIP_ID_YUKON_EX) { SkPciReadCfgDWord(pAC, PCI_OUR_REG_1, &DWord); DWord |= 0x8000; SkPciWriteCfgDWord(pAC, PCI_OUR_REG_1, DWord); } }#ifndef USE_ASF_DASH_FW SK_OUT8(IoC, RX_GMF_CTRL_T, (SK_U8)GMF_RST_SET);#endif SK_OUT16(IoC, B0_CTST, Y2_HW_WOL_OFF);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -