diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 11:47:02 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-23 11:47:02 -0700 |
commit | 5f05647dd81c11a6a165ccc8f0c1370b16f3bcb0 (patch) | |
tree | 7851ef1c93aa1aba7ef327ca4b75fd35e6d10f29 /drivers/net/via-velocity.c | |
parent | 02f36038c568111ad4fc433f6fa760ff5e38fab4 (diff) | |
parent | ec37a48d1d16c30b655ac5280209edf52a6775d4 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1699 commits)
bnx2/bnx2x: Unsupported Ethtool operations should return -EINVAL.
vlan: Calling vlan_hwaccel_do_receive() is always valid.
tproxy: use the interface primary IP address as a default value for --on-ip
tproxy: added IPv6 support to the socket match
cxgb3: function namespace cleanup
tproxy: added IPv6 support to the TPROXY target
tproxy: added IPv6 socket lookup function to nf_tproxy_core
be2net: Changes to use only priority codes allowed by f/w
tproxy: allow non-local binds of IPv6 sockets if IP_TRANSPARENT is enabled
tproxy: added tproxy sockopt interface in the IPV6 layer
tproxy: added udp6_lib_lookup function
tproxy: added const specifiers to udp lookup functions
tproxy: split off ipv6 defragmentation to a separate module
l2tp: small cleanup
nf_nat: restrict ICMP translation for embedded header
can: mcp251x: fix generation of error frames
can: mcp251x: fix endless loop in interrupt handler if CANINTF_MERRF is set
can-raw: add msg_flags to distinguish local traffic
9p: client code cleanup
rds: make local functions/variables static
...
Fix up conflicts in net/core/dev.c, drivers/net/pcmcia/smc91c92_cs.c and
drivers/net/wireless/ath/ath9k/debug.c as per David
Diffstat (limited to 'drivers/net/via-velocity.c')
-rw-r--r-- | drivers/net/via-velocity.c | 86 |
1 files changed, 78 insertions, 8 deletions
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index f53412368ce1..cab96ad49e60 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -312,13 +312,14 @@ VELOCITY_PARAM(flow_control, "Enable flow control ability"); #define MED_LNK_DEF 0 #define MED_LNK_MIN 0 -#define MED_LNK_MAX 4 +#define MED_LNK_MAX 5 /* speed_duplex[] is used for setting the speed and duplex mode of NIC. 0: indicate autonegotiation for both speed and duplex mode 1: indicate 100Mbps half duplex mode 2: indicate 100Mbps full duplex mode 3: indicate 10Mbps half duplex mode 4: indicate 10Mbps full duplex mode + 5: indicate 1000Mbps full duplex mode Note: if EEPROM have been set to the force mode, this option is ignored @@ -617,6 +618,9 @@ static u32 velocity_get_opt_media_mode(struct velocity_info *vptr) case SPD_DPX_10_HALF: status = VELOCITY_SPEED_10; break; + case SPD_DPX_1000_FULL: + status = VELOCITY_SPEED_1000 | VELOCITY_DUPLEX_FULL; + break; } vptr->mii_status = status; return status; @@ -922,6 +926,7 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) /* enable AUTO-NEGO mode */ mii_set_auto_on(vptr); } else { + u16 CTRL1000; u16 ANAR; u8 CHIPGCR; @@ -936,7 +941,11 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) BYTE_REG_BITS_ON(CHIPGCR_FCMODE, ®s->CHIPGCR); CHIPGCR = readb(®s->CHIPGCR); - CHIPGCR &= ~CHIPGCR_FCGMII; + + if (mii_status & VELOCITY_SPEED_1000) + CHIPGCR |= CHIPGCR_FCGMII; + else + CHIPGCR &= ~CHIPGCR_FCGMII; if (mii_status & VELOCITY_DUPLEX_FULL) { CHIPGCR |= CHIPGCR_FCFDX; @@ -952,7 +961,13 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) BYTE_REG_BITS_ON(TCR_TB2BDIS, ®s->TCR); } - MII_REG_BITS_OFF(ADVERTISE_1000FULL | ADVERTISE_1000HALF, MII_CTRL1000, vptr->mac_regs); + velocity_mii_read(vptr->mac_regs, MII_CTRL1000, &CTRL1000); + CTRL1000 &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); + if ((mii_status & VELOCITY_SPEED_1000) && + (mii_status & VELOCITY_DUPLEX_FULL)) { + CTRL1000 |= ADVERTISE_1000FULL; + } + velocity_mii_write(vptr->mac_regs, MII_CTRL1000, CTRL1000); if (!(mii_status & VELOCITY_DUPLEX_FULL) && (mii_status & VELOCITY_SPEED_10)) BYTE_REG_BITS_OFF(TESTCFG_HBDIS, ®s->TESTCFG); @@ -967,7 +982,7 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) ANAR |= ADVERTISE_100FULL; else ANAR |= ADVERTISE_100HALF; - } else { + } else if (mii_status & VELOCITY_SPEED_10) { if (mii_status & VELOCITY_DUPLEX_FULL) ANAR |= ADVERTISE_10FULL; else @@ -1013,6 +1028,9 @@ static void velocity_print_link_status(struct velocity_info *vptr) } else { VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: Link forced", vptr->dev->name); switch (vptr->options.spd_dpx) { + case SPD_DPX_1000_FULL: + VELOCITY_PRT(MSG_LEVEL_INFO, " speed 1000M bps full duplex\n"); + break; case SPD_DPX_100_HALF: VELOCITY_PRT(MSG_LEVEL_INFO, " speed 100M bps half duplex\n"); break; @@ -1954,7 +1972,7 @@ static int velocity_tx_srv(struct velocity_info *vptr) */ static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb) { - skb->ip_summed = CHECKSUM_NONE; + skb_checksum_none_assert(skb); if (rd->rdesc1.CSM & CSM_IPKT) { if (rd->rdesc1.CSM & CSM_IPOK) { @@ -2574,7 +2592,7 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb, td_ptr->tdesc1.cmd = TCPLS_NORMAL + (tdinfo->nskb_dma + 1) * 16; - if (vptr->vlgrp && vlan_tx_tag_present(skb)) { + if (vlan_tx_tag_present(skb)) { td_ptr->tdesc1.vlan = cpu_to_le16(vlan_tx_tag_get(skb)); td_ptr->tdesc1.TCR |= TCR0_VETAG; } @@ -3170,6 +3188,37 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; + + cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg; + if (vptr->options.spd_dpx == SPD_DPX_AUTO) { + cmd->advertising |= + ADVERTISED_10baseT_Half | + ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | + ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full; + } else { + switch (vptr->options.spd_dpx) { + case SPD_DPX_1000_FULL: + cmd->advertising |= ADVERTISED_1000baseT_Full; + break; + case SPD_DPX_100_HALF: + cmd->advertising |= ADVERTISED_100baseT_Half; + break; + case SPD_DPX_100_FULL: + cmd->advertising |= ADVERTISED_100baseT_Full; + break; + case SPD_DPX_10_HALF: + cmd->advertising |= ADVERTISED_10baseT_Half; + break; + case SPD_DPX_10_FULL: + cmd->advertising |= ADVERTISED_10baseT_Full; + break; + default: + break; + } + } if (status & VELOCITY_SPEED_1000) cmd->speed = SPEED_1000; else if (status & VELOCITY_SPEED_100) @@ -3200,14 +3249,35 @@ static int velocity_set_settings(struct net_device *dev, struct ethtool_cmd *cmd curr_status &= (~VELOCITY_LINK_FAIL); new_status |= ((cmd->autoneg) ? VELOCITY_AUTONEG_ENABLE : 0); + new_status |= ((cmd->speed == SPEED_1000) ? VELOCITY_SPEED_1000 : 0); new_status |= ((cmd->speed == SPEED_100) ? VELOCITY_SPEED_100 : 0); new_status |= ((cmd->speed == SPEED_10) ? VELOCITY_SPEED_10 : 0); new_status |= ((cmd->duplex == DUPLEX_FULL) ? VELOCITY_DUPLEX_FULL : 0); - if ((new_status & VELOCITY_AUTONEG_ENABLE) && (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE))) + if ((new_status & VELOCITY_AUTONEG_ENABLE) && + (new_status != (curr_status | VELOCITY_AUTONEG_ENABLE))) { ret = -EINVAL; - else + } else { + enum speed_opt spd_dpx; + + if (new_status & VELOCITY_AUTONEG_ENABLE) + spd_dpx = SPD_DPX_AUTO; + else if ((new_status & VELOCITY_SPEED_1000) && + (new_status & VELOCITY_DUPLEX_FULL)) { + spd_dpx = SPD_DPX_1000_FULL; + } else if (new_status & VELOCITY_SPEED_100) + spd_dpx = (new_status & VELOCITY_DUPLEX_FULL) ? + SPD_DPX_100_FULL : SPD_DPX_100_HALF; + else if (new_status & VELOCITY_SPEED_10) + spd_dpx = (new_status & VELOCITY_DUPLEX_FULL) ? + SPD_DPX_10_FULL : SPD_DPX_10_HALF; + else + return -EOPNOTSUPP; + + vptr->options.spd_dpx = spd_dpx; + velocity_set_media_mode(vptr, new_status); + } return ret; } |