Commit 8a57d65b authored by Stephen Hemminger's avatar Stephen Hemminger

[PATCH] sk98: ethtool phy support

The basic stuff comes from the newer code from SysKonnect, but I redid
it using a per board timer rather than a global timer.
Signed-off-by: default avatarStephen Hemminger <shemminger@osdl.org>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 385b9037
...@@ -382,6 +382,8 @@ struct s_AC { ...@@ -382,6 +382,8 @@ struct s_AC {
SK_CSUM Csum; /* for checksum module */ SK_CSUM Csum; /* for checksum module */
SK_RLMT Rlmt; /* for rlmt module */ SK_RLMT Rlmt; /* for rlmt module */
spinlock_t SlowPathLock; /* Normal IRQ lock */ spinlock_t SlowPathLock; /* Normal IRQ lock */
struct timer_list BlinkTimer; /* for LED blinking */
int LedsOn;
SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */ SK_PNMI_STRUCT_DATA PnmiStruct; /* structure to get all Pnmi-Data */
int RlmtMode; /* link check mode to set */ int RlmtMode; /* link check mode to set */
int RlmtNets; /* Number of nets */ int RlmtNets; /* Number of nets */
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/delay.h>
/****************************************************************************** /******************************************************************************
* *
...@@ -320,6 +321,122 @@ static void getEthtoolStats(struct net_device *dev, ...@@ -320,6 +321,122 @@ static void getEthtoolStats(struct net_device *dev,
*data++ = pAC->stats.tx_window_errors; *data++ = pAC->stats.tx_window_errors;
} }
/*****************************************************************************
*
* 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.
*
* Returns: N/A
*
*/
static void toggleLeds(DEV_NET *pNet, int on)
{
SK_AC *pAC = pNet->pAC;
int port = pNet->PortNr;
void __iomem *io = pAC->IoBase;
if (pAC->GIni.GIGenesis) {
SK_OUT8(io, MR_ADDR(port,LNK_LED_REG),
on ? SK_LNK_ON : SK_LNK_OFF);
SkGeYellowLED(pAC, io,
on ? (LED_ON >> 1) : (LED_OFF >> 1));
SkGeXmitLED(pAC, io, MR_ADDR(port,RX_LED_INI),
on ? SK_LED_TST : SK_LED_DIS);
if (pAC->GIni.GP[port].PhyType == SK_PHY_BCOM)
SkXmPhyWrite(pAC, io, port, PHY_BCOM_P_EXT_CTRL,
on ? PHY_B_PEC_LED_ON : PHY_B_PEC_LED_OFF);
else if (pAC->GIni.GP[port].PhyType == SK_PHY_LONE)
SkXmPhyWrite(pAC, io, port, PHY_LONE_LED_CFG,
on ? 0x0800 : PHY_L_LC_LEDT);
else
SkGeXmitLED(pAC, io, MR_ADDR(port,TX_LED_INI),
on ? SK_LED_TST : SK_LED_DIS);
} else {
const 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));
const 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));
SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_CTRL,0);
SkGmPhyWrite(pAC,io,port,PHY_MARV_LED_OVER,
on ? YukLedOn : YukLedOff);
}
}
/*****************************************************************************
*
* skGeBlinkTimer - 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
*
*/
void SkGeBlinkTimer(unsigned long data)
{
struct net_device *dev = (struct net_device *) data;
DEV_NET *pNet = netdev_priv(dev);
SK_AC *pAC = pNet->pAC;
toggleLeds(pNet, pAC->LedsOn);
pAC->LedsOn = !pAC->LedsOn;
mod_timer(&pAC->BlinkTimer, jiffies + HZ/4);
}
/*****************************************************************************
*
* locateDevice - 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
*
*/
static int locateDevice(struct net_device *dev, u32 data)
{
DEV_NET *pNet = netdev_priv(dev);
SK_AC *pAC = pNet->pAC;
if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ))
data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ);
/* start blinking */
pAC->LedsOn = 0;
mod_timer(&pAC->BlinkTimer, jiffies);
msleep_interruptible(data * 1000);
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(data * HZ);
del_timer_sync(&pAC->BlinkTimer);
toggleLeds(pNet, 0);
return 0;
}
struct ethtool_ops SkGeEthtoolOps = { struct ethtool_ops SkGeEthtoolOps = {
.get_settings = getSettings, .get_settings = getSettings,
.set_settings = setSettings, .set_settings = setSettings,
...@@ -327,4 +444,5 @@ struct ethtool_ops SkGeEthtoolOps = { ...@@ -327,4 +444,5 @@ struct ethtool_ops SkGeEthtoolOps = {
.get_strings = getStrings, .get_strings = getStrings,
.get_stats_count = getStatsCount, .get_stats_count = getStatsCount,
.get_ethtool_stats = getEthtoolStats, .get_ethtool_stats = getEthtoolStats,
.phys_id = locateDevice,
}; };
...@@ -260,6 +260,7 @@ extern void SkDimEnableModerationIfNeeded(SK_AC *pAC); ...@@ -260,6 +260,7 @@ extern void SkDimEnableModerationIfNeeded(SK_AC *pAC);
extern void SkDimDisplayModerationSettings(SK_AC *pAC); extern void SkDimDisplayModerationSettings(SK_AC *pAC);
extern void SkDimStartModerationTimer(SK_AC *pAC); extern void SkDimStartModerationTimer(SK_AC *pAC);
extern void SkDimModerate(SK_AC *pAC); extern void SkDimModerate(SK_AC *pAC);
extern void SkGeBlinkTimer(unsigned long data);
#ifdef DEBUG #ifdef DEBUG
static void DumpMsg(struct sk_buff*, char*); static void DumpMsg(struct sk_buff*, char*);
...@@ -517,6 +518,11 @@ SK_BOOL DualNet; ...@@ -517,6 +518,11 @@ SK_BOOL DualNet;
} }
spin_lock_init(&pAC->SlowPathLock); spin_lock_init(&pAC->SlowPathLock);
/* setup phy_id blink timer */
pAC->BlinkTimer.function = SkGeBlinkTimer;
pAC->BlinkTimer.data = (unsigned long) dev;
init_timer(&pAC->BlinkTimer);
/* level 0 init common modules here */ /* level 0 init common modules here */
spin_lock_irqsave(&pAC->SlowPathLock, Flags); spin_lock_irqsave(&pAC->SlowPathLock, Flags);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment