diff options
Diffstat (limited to 'drivers/net/ksz884x.c')
-rw-r--r-- | drivers/net/ksz884x.c | 106 |
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 | */ |
3572 | static void hw_set_wol_frame(struct ksz_hw *hw, int i, uint mask_size, | 3571 | static 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 | */ |
3629 | static void hw_add_wol_arp(struct ksz_hw *hw, u8 *ip_addr) | 3628 | static 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 | */ |
3652 | static void hw_add_wol_bcast(struct ksz_hw *hw) | 3651 | static 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 | */ |
3670 | static void hw_add_wol_mcast(struct ksz_hw *hw) | 3669 | static 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 | */ |
3688 | static void hw_add_wol_ucast(struct ksz_hw *hw) | 3687 | static 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 | */ |
3703 | static void hw_enable_wol(struct ksz_hw *hw, u32 wol_enable, u8 *net_addr) | 3702 | static 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 | */ | ||
6593 | static 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 | */ |
6614 | static int netdev_set_rx_csum(struct net_device *dev, u32 data) | 6592 | static 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 | ||
6956 | static int __init pcidev_init(struct pci_dev *pdev, | 6926 | static 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]) { |