aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ksz884x.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ksz884x.c')
-rw-r--r--drivers/net/ksz884x.c106
1 files changed, 38 insertions, 68 deletions
diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c
index 37504a398906..41ea5920c158 100644
--- a/drivers/net/ksz884x.c
+++ b/drivers/net/ksz884x.c
@@ -1221,7 +1221,6 @@ struct ksz_port_info {
1221#define LINK_INT_WORKING (1 << 0) 1221#define LINK_INT_WORKING (1 << 0)
1222#define SMALL_PACKET_TX_BUG (1 << 1) 1222#define SMALL_PACKET_TX_BUG (1 << 1)
1223#define HALF_DUPLEX_SIGNAL_BUG (1 << 2) 1223#define HALF_DUPLEX_SIGNAL_BUG (1 << 2)
1224#define IPV6_CSUM_GEN_HACK (1 << 3)
1225#define RX_HUGE_FRAME (1 << 4) 1224#define RX_HUGE_FRAME (1 << 4)
1226#define STP_SUPPORT (1 << 8) 1225#define STP_SUPPORT (1 << 8)
1227 1226
@@ -3570,7 +3569,7 @@ static void hw_cfg_wol(struct ksz_hw *hw, u16 frame, int set)
3570 * This routine is used to program Wake-on-LAN pattern. 3569 * This routine is used to program Wake-on-LAN pattern.
3571 */ 3570 */
3572static void hw_set_wol_frame(struct ksz_hw *hw, int i, uint mask_size, 3571static void hw_set_wol_frame(struct ksz_hw *hw, int i, uint mask_size,
3573 u8 *mask, uint frame_size, u8 *pattern) 3572 const u8 *mask, uint frame_size, const u8 *pattern)
3574{ 3573{
3575 int bits; 3574 int bits;
3576 int from; 3575 int from;
@@ -3626,9 +3625,9 @@ static void hw_set_wol_frame(struct ksz_hw *hw, int i, uint mask_size,
3626 * 3625 *
3627 * This routine is used to add ARP pattern for waking up the host. 3626 * This routine is used to add ARP pattern for waking up the host.
3628 */ 3627 */
3629static void hw_add_wol_arp(struct ksz_hw *hw, u8 *ip_addr) 3628static void hw_add_wol_arp(struct ksz_hw *hw, const u8 *ip_addr)
3630{ 3629{
3631 u8 mask[6] = { 0x3F, 0xF0, 0x3F, 0x00, 0xC0, 0x03 }; 3630 static const u8 mask[6] = { 0x3F, 0xF0, 0x3F, 0x00, 0xC0, 0x03 };
3632 u8 pattern[42] = { 3631 u8 pattern[42] = {
3633 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 3632 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
3634 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3633 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -3651,8 +3650,8 @@ static void hw_add_wol_arp(struct ksz_hw *hw, u8 *ip_addr)
3651 */ 3650 */
3652static void hw_add_wol_bcast(struct ksz_hw *hw) 3651static void hw_add_wol_bcast(struct ksz_hw *hw)
3653{ 3652{
3654 u8 mask[] = { 0x3F }; 3653 static const u8 mask[] = { 0x3F };
3655 u8 pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 3654 static const u8 pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
3656 3655
3657 hw_set_wol_frame(hw, 2, 1, mask, MAC_ADDR_LEN, pattern); 3656 hw_set_wol_frame(hw, 2, 1, mask, MAC_ADDR_LEN, pattern);
3658} 3657}
@@ -3669,7 +3668,7 @@ static void hw_add_wol_bcast(struct ksz_hw *hw)
3669 */ 3668 */
3670static void hw_add_wol_mcast(struct ksz_hw *hw) 3669static void hw_add_wol_mcast(struct ksz_hw *hw)
3671{ 3670{
3672 u8 mask[] = { 0x3F }; 3671 static const u8 mask[] = { 0x3F };
3673 u8 pattern[] = { 0x33, 0x33, 0xFF, 0x00, 0x00, 0x00 }; 3672 u8 pattern[] = { 0x33, 0x33, 0xFF, 0x00, 0x00, 0x00 };
3674 3673
3675 memcpy(&pattern[3], &hw->override_addr[3], 3); 3674 memcpy(&pattern[3], &hw->override_addr[3], 3);
@@ -3687,7 +3686,7 @@ static void hw_add_wol_mcast(struct ksz_hw *hw)
3687 */ 3686 */
3688static void hw_add_wol_ucast(struct ksz_hw *hw) 3687static void hw_add_wol_ucast(struct ksz_hw *hw)
3689{ 3688{
3690 u8 mask[] = { 0x3F }; 3689 static const u8 mask[] = { 0x3F };
3691 3690
3692 hw_set_wol_frame(hw, 0, 1, mask, MAC_ADDR_LEN, hw->override_addr); 3691 hw_set_wol_frame(hw, 0, 1, mask, MAC_ADDR_LEN, hw->override_addr);
3693} 3692}
@@ -3700,7 +3699,7 @@ static void hw_add_wol_ucast(struct ksz_hw *hw)
3700 * 3699 *
3701 * This routine is used to enable Wake-on-LAN depending on driver settings. 3700 * This routine is used to enable Wake-on-LAN depending on driver settings.
3702 */ 3701 */
3703static void hw_enable_wol(struct ksz_hw *hw, u32 wol_enable, u8 *net_addr) 3702static void hw_enable_wol(struct ksz_hw *hw, u32 wol_enable, const u8 *net_addr)
3704{ 3703{
3705 hw_cfg_wol(hw, KS8841_WOL_MAGIC_ENABLE, (wol_enable & WAKE_MAGIC)); 3704 hw_cfg_wol(hw, KS8841_WOL_MAGIC_ENABLE, (wol_enable & WAKE_MAGIC));
3706 hw_cfg_wol(hw, KS8841_WOL_FRAME0_ENABLE, (wol_enable & WAKE_UCAST)); 3705 hw_cfg_wol(hw, KS8841_WOL_FRAME0_ENABLE, (wol_enable & WAKE_UCAST));
@@ -3748,7 +3747,6 @@ static int hw_init(struct ksz_hw *hw)
3748 if (1 == rc) 3747 if (1 == rc)
3749 hw->features |= HALF_DUPLEX_SIGNAL_BUG; 3748 hw->features |= HALF_DUPLEX_SIGNAL_BUG;
3750 } 3749 }
3751 hw->features |= IPV6_CSUM_GEN_HACK;
3752 return rc; 3750 return rc;
3753} 3751}
3754 3752
@@ -4887,8 +4885,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
4887 left = hw_alloc_pkt(hw, skb->len, num); 4885 left = hw_alloc_pkt(hw, skb->len, num);
4888 if (left) { 4886 if (left) {
4889 if (left < num || 4887 if (left < num ||
4890 ((hw->features & IPV6_CSUM_GEN_HACK) && 4888 ((CHECKSUM_PARTIAL == skb->ip_summed) &&
4891 (CHECKSUM_PARTIAL == skb->ip_summed) &&
4892 (ETH_P_IPV6 == htons(skb->protocol)))) { 4889 (ETH_P_IPV6 == htons(skb->protocol)))) {
4893 struct sk_buff *org_skb = skb; 4890 struct sk_buff *org_skb = skb;
4894 4891
@@ -4898,7 +4895,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
4898 goto unlock; 4895 goto unlock;
4899 } 4896 }
4900 skb_copy_and_csum_dev(org_skb, skb->data); 4897 skb_copy_and_csum_dev(org_skb, skb->data);
4901 org_skb->ip_summed = 0; 4898 org_skb->ip_summed = CHECKSUM_NONE;
4902 skb->len = org_skb->len; 4899 skb->len = org_skb->len;
4903 copy_old_skb(org_skb, skb); 4900 copy_old_skb(org_skb, skb);
4904 } 4901 }
@@ -6001,6 +5998,7 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
6001 struct dev_priv *priv = netdev_priv(dev); 5998 struct dev_priv *priv = netdev_priv(dev);
6002 struct dev_info *hw_priv = priv->adapter; 5999 struct dev_info *hw_priv = priv->adapter;
6003 struct ksz_port *port = &priv->port; 6000 struct ksz_port *port = &priv->port;
6001 u32 speed = ethtool_cmd_speed(cmd);
6004 int rc; 6002 int rc;
6005 6003
6006 /* 6004 /*
@@ -6009,11 +6007,11 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
6009 */ 6007 */
6010 if (cmd->autoneg && priv->advertising == cmd->advertising) { 6008 if (cmd->autoneg && priv->advertising == cmd->advertising) {
6011 cmd->advertising |= ADVERTISED_ALL; 6009 cmd->advertising |= ADVERTISED_ALL;
6012 if (10 == cmd->speed) 6010 if (10 == speed)
6013 cmd->advertising &= 6011 cmd->advertising &=
6014 ~(ADVERTISED_100baseT_Full | 6012 ~(ADVERTISED_100baseT_Full |
6015 ADVERTISED_100baseT_Half); 6013 ADVERTISED_100baseT_Half);
6016 else if (100 == cmd->speed) 6014 else if (100 == speed)
6017 cmd->advertising &= 6015 cmd->advertising &=
6018 ~(ADVERTISED_10baseT_Full | 6016 ~(ADVERTISED_10baseT_Full |
6019 ADVERTISED_10baseT_Half); 6017 ADVERTISED_10baseT_Half);
@@ -6035,8 +6033,8 @@ static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
6035 port->force_link = 0; 6033 port->force_link = 0;
6036 } else { 6034 } else {
6037 port->duplex = cmd->duplex + 1; 6035 port->duplex = cmd->duplex + 1;
6038 if (cmd->speed != 1000) 6036 if (1000 != speed)
6039 port->speed = cmd->speed; 6037 port->speed = speed;
6040 if (cmd->autoneg) 6038 if (cmd->autoneg)
6041 port->force_link = 0; 6039 port->force_link = 0;
6042 else 6040 else
@@ -6208,7 +6206,7 @@ static int netdev_set_wol(struct net_device *dev,
6208 struct dev_info *hw_priv = priv->adapter; 6206 struct dev_info *hw_priv = priv->adapter;
6209 6207
6210 /* Need to find a way to retrieve the device IP address. */ 6208 /* Need to find a way to retrieve the device IP address. */
6211 u8 net_addr[] = { 192, 168, 1, 1 }; 6209 static const u8 net_addr[] = { 192, 168, 1, 1 };
6212 6210
6213 if (wol->wolopts & ~hw_priv->wol_support) 6211 if (wol->wolopts & ~hw_priv->wol_support)
6214 return -EINVAL; 6212 return -EINVAL;
@@ -6583,57 +6581,33 @@ static void netdev_get_ethtool_stats(struct net_device *dev,
6583} 6581}
6584 6582
6585/** 6583/**
6586 * netdev_get_rx_csum - get receive checksum support 6584 * netdev_set_features - set receive checksum support
6587 * @dev: Network device. 6585 * @dev: Network device.
6588 * 6586 * @features: New device features (offloads).
6589 * This function gets receive checksum support setting.
6590 *
6591 * Return true if receive checksum is enabled; false otherwise.
6592 */
6593static u32 netdev_get_rx_csum(struct net_device *dev)
6594{
6595 struct dev_priv *priv = netdev_priv(dev);
6596 struct dev_info *hw_priv = priv->adapter;
6597 struct ksz_hw *hw = &hw_priv->hw;
6598
6599 return hw->rx_cfg &
6600 (DMA_RX_CSUM_UDP |
6601 DMA_RX_CSUM_TCP |
6602 DMA_RX_CSUM_IP);
6603}
6604
6605/**
6606 * netdev_set_rx_csum - set receive checksum support
6607 * @dev: Network device.
6608 * @data: Zero to disable receive checksum support.
6609 * 6587 *
6610 * This function sets receive checksum support setting. 6588 * This function sets receive checksum support setting.
6611 * 6589 *
6612 * Return 0 if successful; otherwise an error code. 6590 * Return 0 if successful; otherwise an error code.
6613 */ 6591 */
6614static int netdev_set_rx_csum(struct net_device *dev, u32 data) 6592static int netdev_set_features(struct net_device *dev, u32 features)
6615{ 6593{
6616 struct dev_priv *priv = netdev_priv(dev); 6594 struct dev_priv *priv = netdev_priv(dev);
6617 struct dev_info *hw_priv = priv->adapter; 6595 struct dev_info *hw_priv = priv->adapter;
6618 struct ksz_hw *hw = &hw_priv->hw; 6596 struct ksz_hw *hw = &hw_priv->hw;
6619 u32 new_setting = hw->rx_cfg;
6620 6597
6621 if (data)
6622 new_setting |=
6623 (DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP |
6624 DMA_RX_CSUM_IP);
6625 else
6626 new_setting &=
6627 ~(DMA_RX_CSUM_UDP | DMA_RX_CSUM_TCP |
6628 DMA_RX_CSUM_IP);
6629 new_setting &= ~DMA_RX_CSUM_UDP;
6630 mutex_lock(&hw_priv->lock); 6598 mutex_lock(&hw_priv->lock);
6631 if (new_setting != hw->rx_cfg) { 6599
6632 hw->rx_cfg = new_setting; 6600 /* see note in hw_setup() */
6633 if (hw->enabled) 6601 if (features & NETIF_F_RXCSUM)
6634 writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL); 6602 hw->rx_cfg |= DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP;
6635 } 6603 else
6604 hw->rx_cfg &= ~(DMA_RX_CSUM_TCP | DMA_RX_CSUM_IP);
6605
6606 if (hw->enabled)
6607 writel(hw->rx_cfg, hw->io + KS_DMA_RX_CTRL);
6608
6636 mutex_unlock(&hw_priv->lock); 6609 mutex_unlock(&hw_priv->lock);
6610
6637 return 0; 6611 return 0;
6638} 6612}
6639 6613
@@ -6658,12 +6632,6 @@ static struct ethtool_ops netdev_ethtool_ops = {
6658 .get_strings = netdev_get_strings, 6632 .get_strings = netdev_get_strings,
6659 .get_sset_count = netdev_get_sset_count, 6633 .get_sset_count = netdev_get_sset_count,
6660 .get_ethtool_stats = netdev_get_ethtool_stats, 6634 .get_ethtool_stats = netdev_get_ethtool_stats,
6661 .get_rx_csum = netdev_get_rx_csum,
6662 .set_rx_csum = netdev_set_rx_csum,
6663 .get_tx_csum = ethtool_op_get_tx_csum,
6664 .set_tx_csum = ethtool_op_set_tx_csum,
6665 .get_sg = ethtool_op_get_sg,
6666 .set_sg = ethtool_op_set_sg,
6667}; 6635};
6668 6636
6669/* 6637/*
@@ -6828,14 +6796,15 @@ static int __init netdev_init(struct net_device *dev)
6828 /* 500 ms timeout */ 6796 /* 500 ms timeout */
6829 dev->watchdog_timeo = HZ / 2; 6797 dev->watchdog_timeo = HZ / 2;
6830 6798
6831 dev->features |= NETIF_F_IP_CSUM; 6799 dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_RXCSUM;
6832 6800
6833 /* 6801 /*
6834 * Hardware does not really support IPv6 checksum generation, but 6802 * Hardware does not really support IPv6 checksum generation, but
6835 * driver actually runs faster with this on. Refer IPV6_CSUM_GEN_HACK. 6803 * driver actually runs faster with this on.
6836 */ 6804 */
6837 dev->features |= NETIF_F_IPV6_CSUM; 6805 dev->hw_features |= NETIF_F_IPV6_CSUM;
6838 dev->features |= NETIF_F_SG; 6806
6807 dev->features |= dev->hw_features;
6839 6808
6840 sema_init(&priv->proc_sem, 1); 6809 sema_init(&priv->proc_sem, 1);
6841 6810
@@ -6860,6 +6829,7 @@ static const struct net_device_ops netdev_ops = {
6860 .ndo_start_xmit = netdev_tx, 6829 .ndo_start_xmit = netdev_tx,
6861 .ndo_tx_timeout = netdev_tx_timeout, 6830 .ndo_tx_timeout = netdev_tx_timeout,
6862 .ndo_change_mtu = netdev_change_mtu, 6831 .ndo_change_mtu = netdev_change_mtu,
6832 .ndo_set_features = netdev_set_features,
6863 .ndo_set_mac_address = netdev_set_mac_address, 6833 .ndo_set_mac_address = netdev_set_mac_address,
6864 .ndo_validate_addr = eth_validate_addr, 6834 .ndo_validate_addr = eth_validate_addr,
6865 .ndo_do_ioctl = netdev_ioctl, 6835 .ndo_do_ioctl = netdev_ioctl,
@@ -6953,7 +6923,7 @@ static void read_other_addr(struct ksz_hw *hw)
6953#define PCI_VENDOR_ID_MICREL_KS 0x16c6 6923#define PCI_VENDOR_ID_MICREL_KS 0x16c6
6954#endif 6924#endif
6955 6925
6956static int __init pcidev_init(struct pci_dev *pdev, 6926static int __devinit pcidev_init(struct pci_dev *pdev,
6957 const struct pci_device_id *id) 6927 const struct pci_device_id *id)
6958{ 6928{
6959 struct net_device *dev; 6929 struct net_device *dev;
@@ -7241,7 +7211,7 @@ static int pcidev_suspend(struct pci_dev *pdev, pm_message_t state)
7241 struct ksz_hw *hw = &hw_priv->hw; 7211 struct ksz_hw *hw = &hw_priv->hw;
7242 7212
7243 /* Need to find a way to retrieve the device IP address. */ 7213 /* Need to find a way to retrieve the device IP address. */
7244 u8 net_addr[] = { 192, 168, 1, 1 }; 7214 static const u8 net_addr[] = { 192, 168, 1, 1 };
7245 7215
7246 for (i = 0; i < hw->dev_count; i++) { 7216 for (i = 0; i < hw->dev_count; i++) {
7247 if (info->netdev[i]) { 7217 if (info->netdev[i]) {