Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 231231
b: refs/heads/master
c: 4c11b8a
h: refs/heads/master
i:
  231229: 363e67d
  231227: cef6a61
  231223: 2c14a47
  231215: b909d91
  231199: fec74c5
  231167: 8c6008e
v: v3
  • Loading branch information
Jesse Brandeburg authored and Jeff Kirsher committed Jan 14, 2011
1 parent 01b83c8 commit de9a587
Show file tree
Hide file tree
Showing 21 changed files with 311 additions and 226 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 886d7f444cbf72d5a424ea5fee4e34a0219d4af1
refs/heads/master: 4c11b8adbc48bd21885fbc671df2f8ac04a75473
288 changes: 193 additions & 95 deletions trunk/drivers/net/arm/ks8695net.c
Original file line number Diff line number Diff line change
Expand Up @@ -854,12 +854,12 @@ ks8695_set_msglevel(struct net_device *ndev, u32 value)
}

/**
* ks8695_wan_get_settings - Get device-specific settings.
* ks8695_get_settings - Get device-specific settings.
* @ndev: The network device to read settings from
* @cmd: The ethtool structure to read into
*/
static int
ks8695_wan_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
ks8695_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
{
struct ks8695_priv *ksp = netdev_priv(ndev);
u32 ctrl;
Expand All @@ -870,50 +870,69 @@ ks8695_wan_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
SUPPORTED_TP | SUPPORTED_MII);
cmd->transceiver = XCVR_INTERNAL;

cmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
cmd->port = PORT_MII;
cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause);
cmd->phy_address = 0;

ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
if ((ctrl & WMC_WAND) == 0) {
/* auto-negotiation is enabled */
cmd->advertising |= ADVERTISED_Autoneg;
if (ctrl & WMC_WANA100F)
cmd->advertising |= ADVERTISED_100baseT_Full;
if (ctrl & WMC_WANA100H)
cmd->advertising |= ADVERTISED_100baseT_Half;
if (ctrl & WMC_WANA10F)
cmd->advertising |= ADVERTISED_10baseT_Full;
if (ctrl & WMC_WANA10H)
cmd->advertising |= ADVERTISED_10baseT_Half;
if (ctrl & WMC_WANAP)
cmd->advertising |= ADVERTISED_Pause;
cmd->autoneg = AUTONEG_ENABLE;

cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10;
cmd->duplex = (ctrl & WMC_WDS) ?
DUPLEX_FULL : DUPLEX_HALF;
} else {
/* auto-negotiation is disabled */
/* Port specific extras */
switch (ksp->dtype) {
case KS8695_DTYPE_HPNA:
cmd->phy_address = 0;
/* not supported for HPNA */
cmd->autoneg = AUTONEG_DISABLE;

cmd->speed = (ctrl & WMC_WANF100) ?
SPEED_100 : SPEED_10;
cmd->duplex = (ctrl & WMC_WANFF) ?
DUPLEX_FULL : DUPLEX_HALF;
/* BUG: Erm, dtype hpna implies no phy regs */
/*
ctrl = readl(KS8695_MISC_VA + KS8695_HMC);
cmd->speed = (ctrl & HMC_HSS) ? SPEED_100 : SPEED_10;
cmd->duplex = (ctrl & HMC_HDS) ? DUPLEX_FULL : DUPLEX_HALF;
*/
return -EOPNOTSUPP;
case KS8695_DTYPE_WAN:
cmd->advertising = ADVERTISED_TP | ADVERTISED_MII;
cmd->port = PORT_MII;
cmd->supported |= (SUPPORTED_Autoneg | SUPPORTED_Pause);
cmd->phy_address = 0;

ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
if ((ctrl & WMC_WAND) == 0) {
/* auto-negotiation is enabled */
cmd->advertising |= ADVERTISED_Autoneg;
if (ctrl & WMC_WANA100F)
cmd->advertising |= ADVERTISED_100baseT_Full;
if (ctrl & WMC_WANA100H)
cmd->advertising |= ADVERTISED_100baseT_Half;
if (ctrl & WMC_WANA10F)
cmd->advertising |= ADVERTISED_10baseT_Full;
if (ctrl & WMC_WANA10H)
cmd->advertising |= ADVERTISED_10baseT_Half;
if (ctrl & WMC_WANAP)
cmd->advertising |= ADVERTISED_Pause;
cmd->autoneg = AUTONEG_ENABLE;

cmd->speed = (ctrl & WMC_WSS) ? SPEED_100 : SPEED_10;
cmd->duplex = (ctrl & WMC_WDS) ?
DUPLEX_FULL : DUPLEX_HALF;
} else {
/* auto-negotiation is disabled */
cmd->autoneg = AUTONEG_DISABLE;

cmd->speed = (ctrl & WMC_WANF100) ?
SPEED_100 : SPEED_10;
cmd->duplex = (ctrl & WMC_WANFF) ?
DUPLEX_FULL : DUPLEX_HALF;
}
break;
case KS8695_DTYPE_LAN:
return -EOPNOTSUPP;
}

return 0;
}

/**
* ks8695_wan_set_settings - Set device-specific settings.
* ks8695_set_settings - Set device-specific settings.
* @ndev: The network device to configure
* @cmd: The settings to configure
*/
static int
ks8695_wan_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
ks8695_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
{
struct ks8695_priv *ksp = netdev_priv(ndev);
u32 ctrl;
Expand All @@ -937,85 +956,171 @@ ks8695_wan_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
ADVERTISED_100baseT_Full)) == 0)
return -EINVAL;

ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
switch (ksp->dtype) {
case KS8695_DTYPE_HPNA:
/* HPNA does not support auto-negotiation. */
return -EINVAL;
case KS8695_DTYPE_WAN:
ctrl = readl(ksp->phyiface_regs + KS8695_WMC);

ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H |
WMC_WANA10F | WMC_WANA10H);
if (cmd->advertising & ADVERTISED_100baseT_Full)
ctrl |= WMC_WANA100F;
if (cmd->advertising & ADVERTISED_100baseT_Half)
ctrl |= WMC_WANA100H;
if (cmd->advertising & ADVERTISED_10baseT_Full)
ctrl |= WMC_WANA10F;
if (cmd->advertising & ADVERTISED_10baseT_Half)
ctrl |= WMC_WANA10H;

/* force a re-negotiation */
ctrl |= WMC_WANR;
writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
break;
case KS8695_DTYPE_LAN:
return -EOPNOTSUPP;
}

ctrl &= ~(WMC_WAND | WMC_WANA100F | WMC_WANA100H |
WMC_WANA10F | WMC_WANA10H);
if (cmd->advertising & ADVERTISED_100baseT_Full)
ctrl |= WMC_WANA100F;
if (cmd->advertising & ADVERTISED_100baseT_Half)
ctrl |= WMC_WANA100H;
if (cmd->advertising & ADVERTISED_10baseT_Full)
ctrl |= WMC_WANA10F;
if (cmd->advertising & ADVERTISED_10baseT_Half)
ctrl |= WMC_WANA10H;

/* force a re-negotiation */
ctrl |= WMC_WANR;
writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
} else {
ctrl = readl(ksp->phyiface_regs + KS8695_WMC);

/* disable auto-negotiation */
ctrl |= WMC_WAND;
ctrl &= ~(WMC_WANF100 | WMC_WANFF);

if (cmd->speed == SPEED_100)
ctrl |= WMC_WANF100;
if (cmd->duplex == DUPLEX_FULL)
ctrl |= WMC_WANFF;

writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
switch (ksp->dtype) {
case KS8695_DTYPE_HPNA:
/* BUG: dtype_hpna implies no phy registers */
/*
ctrl = __raw_readl(KS8695_MISC_VA + KS8695_HMC);
ctrl &= ~(HMC_HSS | HMC_HDS);
if (cmd->speed == SPEED_100)
ctrl |= HMC_HSS;
if (cmd->duplex == DUPLEX_FULL)
ctrl |= HMC_HDS;
__raw_writel(ctrl, KS8695_MISC_VA + KS8695_HMC);
*/
return -EOPNOTSUPP;
case KS8695_DTYPE_WAN:
ctrl = readl(ksp->phyiface_regs + KS8695_WMC);

/* disable auto-negotiation */
ctrl |= WMC_WAND;
ctrl &= ~(WMC_WANF100 | WMC_WANFF);

if (cmd->speed == SPEED_100)
ctrl |= WMC_WANF100;
if (cmd->duplex == DUPLEX_FULL)
ctrl |= WMC_WANFF;

writel(ctrl, ksp->phyiface_regs + KS8695_WMC);
break;
case KS8695_DTYPE_LAN:
return -EOPNOTSUPP;
}
}

return 0;
}

/**
* ks8695_wan_nwayreset - Restart the autonegotiation on the port.
* ks8695_nwayreset - Restart the autonegotiation on the port.
* @ndev: The network device to restart autoneotiation on
*/
static int
ks8695_wan_nwayreset(struct net_device *ndev)
ks8695_nwayreset(struct net_device *ndev)
{
struct ks8695_priv *ksp = netdev_priv(ndev);
u32 ctrl;

ctrl = readl(ksp->phyiface_regs + KS8695_WMC);

if ((ctrl & WMC_WAND) == 0)
writel(ctrl | WMC_WANR,
ksp->phyiface_regs + KS8695_WMC);
else
/* auto-negotiation not enabled */
switch (ksp->dtype) {
case KS8695_DTYPE_HPNA:
/* No phy means no autonegotiation on hpna */
return -EINVAL;
case KS8695_DTYPE_WAN:
ctrl = readl(ksp->phyiface_regs + KS8695_WMC);

if ((ctrl & WMC_WAND) == 0)
writel(ctrl | WMC_WANR,
ksp->phyiface_regs + KS8695_WMC);
else
/* auto-negotiation not enabled */
return -EINVAL;
break;
case KS8695_DTYPE_LAN:
return -EOPNOTSUPP;
}

return 0;
}

/**
* ks8695_wan_get_pause - Retrieve network pause/flow-control advertising
* ks8695_get_link - Retrieve link status of network interface
* @ndev: The network interface to retrive the link status of.
*/
static u32
ks8695_get_link(struct net_device *ndev)
{
struct ks8695_priv *ksp = netdev_priv(ndev);
u32 ctrl;

switch (ksp->dtype) {
case KS8695_DTYPE_HPNA:
/* HPNA always has link */
return 1;
case KS8695_DTYPE_WAN:
/* WAN we can read the PHY for */
ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
return ctrl & WMC_WLS;
case KS8695_DTYPE_LAN:
return -EOPNOTSUPP;
}
return 0;
}

/**
* ks8695_get_pause - Retrieve network pause/flow-control advertising
* @ndev: The device to retrieve settings from
* @param: The structure to fill out with the information
*/
static void
ks8695_wan_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
ks8695_get_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
{
struct ks8695_priv *ksp = netdev_priv(ndev);
u32 ctrl;

ctrl = readl(ksp->phyiface_regs + KS8695_WMC);
switch (ksp->dtype) {
case KS8695_DTYPE_HPNA:
/* No phy link on hpna to configure */
return;
case KS8695_DTYPE_WAN:
ctrl = readl(ksp->phyiface_regs + KS8695_WMC);

/* advertise Pause */
param->autoneg = (ctrl & WMC_WANAP);
/* advertise Pause */
param->autoneg = (ctrl & WMC_WANAP);

/* current Rx Flow-control */
ctrl = ks8695_readreg(ksp, KS8695_DRXC);
param->rx_pause = (ctrl & DRXC_RFCE);
/* current Rx Flow-control */
ctrl = ks8695_readreg(ksp, KS8695_DRXC);
param->rx_pause = (ctrl & DRXC_RFCE);

/* current Tx Flow-control */
ctrl = ks8695_readreg(ksp, KS8695_DTXC);
param->tx_pause = (ctrl & DTXC_TFCE);
/* current Tx Flow-control */
ctrl = ks8695_readreg(ksp, KS8695_DTXC);
param->tx_pause = (ctrl & DTXC_TFCE);
break;
case KS8695_DTYPE_LAN:
/* The LAN's "phy" is a direct-attached switch */
return;
}
}

/**
* ks8695_set_pause - Configure pause/flow-control
* @ndev: The device to configure
* @param: The pause parameters to set
*
* TODO: Implement this
*/
static int
ks8695_set_pause(struct net_device *ndev, struct ethtool_pauseparam *param)
{
return -EOPNOTSUPP;
}

/**
Expand All @@ -1035,17 +1140,12 @@ ks8695_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info)
static const struct ethtool_ops ks8695_ethtool_ops = {
.get_msglevel = ks8695_get_msglevel,
.set_msglevel = ks8695_set_msglevel,
.get_drvinfo = ks8695_get_drvinfo,
};

static const struct ethtool_ops ks8695_wan_ethtool_ops = {
.get_msglevel = ks8695_get_msglevel,
.set_msglevel = ks8695_set_msglevel,
.get_settings = ks8695_wan_get_settings,
.set_settings = ks8695_wan_set_settings,
.nway_reset = ks8695_wan_nwayreset,
.get_link = ethtool_op_get_link,
.get_pauseparam = ks8695_wan_get_pause,
.get_settings = ks8695_get_settings,
.set_settings = ks8695_set_settings,
.nway_reset = ks8695_nwayreset,
.get_link = ks8695_get_link,
.get_pauseparam = ks8695_get_pause,
.set_pauseparam = ks8695_set_pause,
.get_drvinfo = ks8695_get_drvinfo,
};

Expand Down Expand Up @@ -1441,6 +1541,7 @@ ks8695_probe(struct platform_device *pdev)

/* driver system setup */
ndev->netdev_ops = &ks8695_netdev_ops;
SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
ndev->watchdog_timeo = msecs_to_jiffies(watchdog);

netif_napi_add(ndev, &ksp->napi, ks8695_poll, NAPI_WEIGHT);
Expand Down Expand Up @@ -1507,15 +1608,12 @@ ks8695_probe(struct platform_device *pdev)
if (ksp->phyiface_regs && ksp->link_irq == -1) {
ks8695_init_switch(ksp);
ksp->dtype = KS8695_DTYPE_LAN;
SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
} else if (ksp->phyiface_regs && ksp->link_irq != -1) {
ks8695_init_wan_phy(ksp);
ksp->dtype = KS8695_DTYPE_WAN;
SET_ETHTOOL_OPS(ndev, &ks8695_wan_ethtool_ops);
} else {
/* No initialisation since HPNA does not have a PHY */
ksp->dtype = KS8695_DTYPE_HPNA;
SET_ETHTOOL_OPS(ndev, &ks8695_ethtool_ops);
}

/* And bring up the net_device with the net core */
Expand Down
Loading

0 comments on commit de9a587

Please sign in to comment.