diff options
| -rw-r--r-- | drivers/net/skge.c | 98 | ||||
| -rw-r--r-- | drivers/net/skge.h | 6 |
2 files changed, 102 insertions, 2 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index a439d4304458..953f8023f24c 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
| @@ -59,6 +59,9 @@ | |||
| 59 | #define BLINK_MS 250 | 59 | #define BLINK_MS 250 |
| 60 | #define LINK_HZ HZ | 60 | #define LINK_HZ HZ |
| 61 | 61 | ||
| 62 | #define SKGE_EEPROM_MAGIC 0x9933aabb | ||
| 63 | |||
| 64 | |||
| 62 | MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); | 65 | MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); |
| 63 | MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>"); | 66 | MODULE_AUTHOR("Stephen Hemminger <shemminger@linux-foundation.org>"); |
| 64 | MODULE_LICENSE("GPL"); | 67 | MODULE_LICENSE("GPL"); |
| @@ -798,6 +801,98 @@ static int skge_phys_id(struct net_device *dev, u32 data) | |||
| 798 | return 0; | 801 | return 0; |
| 799 | } | 802 | } |
| 800 | 803 | ||
| 804 | static int skge_get_eeprom_len(struct net_device *dev) | ||
| 805 | { | ||
| 806 | struct skge_port *skge = netdev_priv(dev); | ||
| 807 | u32 reg2; | ||
| 808 | |||
| 809 | pci_read_config_dword(skge->hw->pdev, PCI_DEV_REG2, ®2); | ||
| 810 | return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8); | ||
| 811 | } | ||
| 812 | |||
| 813 | static u32 skge_vpd_read(struct pci_dev *pdev, int cap, u16 offset) | ||
| 814 | { | ||
| 815 | u32 val; | ||
| 816 | |||
| 817 | pci_write_config_word(pdev, cap + PCI_VPD_ADDR, offset); | ||
| 818 | |||
| 819 | do { | ||
| 820 | pci_read_config_word(pdev, cap + PCI_VPD_ADDR, &offset); | ||
| 821 | } while (!(offset & PCI_VPD_ADDR_F)); | ||
| 822 | |||
| 823 | pci_read_config_dword(pdev, cap + PCI_VPD_DATA, &val); | ||
| 824 | return val; | ||
| 825 | } | ||
| 826 | |||
| 827 | static void skge_vpd_write(struct pci_dev *pdev, int cap, u16 offset, u32 val) | ||
| 828 | { | ||
| 829 | pci_write_config_dword(pdev, cap + PCI_VPD_DATA, val); | ||
| 830 | pci_write_config_word(pdev, cap + PCI_VPD_ADDR, | ||
| 831 | offset | PCI_VPD_ADDR_F); | ||
| 832 | |||
| 833 | do { | ||
| 834 | pci_read_config_word(pdev, cap + PCI_VPD_ADDR, &offset); | ||
| 835 | } while (offset & PCI_VPD_ADDR_F); | ||
| 836 | } | ||
| 837 | |||
| 838 | static int skge_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | ||
| 839 | u8 *data) | ||
| 840 | { | ||
| 841 | struct skge_port *skge = netdev_priv(dev); | ||
| 842 | struct pci_dev *pdev = skge->hw->pdev; | ||
| 843 | int cap = pci_find_capability(pdev, PCI_CAP_ID_VPD); | ||
| 844 | int length = eeprom->len; | ||
| 845 | u16 offset = eeprom->offset; | ||
| 846 | |||
| 847 | if (!cap) | ||
| 848 | return -EINVAL; | ||
| 849 | |||
| 850 | eeprom->magic = SKGE_EEPROM_MAGIC; | ||
| 851 | |||
| 852 | while (length > 0) { | ||
| 853 | u32 val = skge_vpd_read(pdev, cap, offset); | ||
| 854 | int n = min_t(int, length, sizeof(val)); | ||
| 855 | |||
| 856 | memcpy(data, &val, n); | ||
| 857 | length -= n; | ||
| 858 | data += n; | ||
| 859 | offset += n; | ||
| 860 | } | ||
| 861 | return 0; | ||
| 862 | } | ||
| 863 | |||
| 864 | static int skge_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, | ||
| 865 | u8 *data) | ||
| 866 | { | ||
| 867 | struct skge_port *skge = netdev_priv(dev); | ||
| 868 | struct pci_dev *pdev = skge->hw->pdev; | ||
| 869 | int cap = pci_find_capability(pdev, PCI_CAP_ID_VPD); | ||
| 870 | int length = eeprom->len; | ||
| 871 | u16 offset = eeprom->offset; | ||
| 872 | |||
| 873 | if (!cap) | ||
| 874 | return -EINVAL; | ||
| 875 | |||
| 876 | if (eeprom->magic != SKGE_EEPROM_MAGIC) | ||
| 877 | return -EINVAL; | ||
| 878 | |||
| 879 | while (length > 0) { | ||
| 880 | u32 val; | ||
| 881 | int n = min_t(int, length, sizeof(val)); | ||
| 882 | |||
| 883 | if (n < sizeof(val)) | ||
| 884 | val = skge_vpd_read(pdev, cap, offset); | ||
| 885 | memcpy(&val, data, n); | ||
| 886 | |||
| 887 | skge_vpd_write(pdev, cap, offset, val); | ||
| 888 | |||
| 889 | length -= n; | ||
| 890 | data += n; | ||
| 891 | offset += n; | ||
| 892 | } | ||
| 893 | return 0; | ||
| 894 | } | ||
| 895 | |||
| 801 | static const struct ethtool_ops skge_ethtool_ops = { | 896 | static const struct ethtool_ops skge_ethtool_ops = { |
| 802 | .get_settings = skge_get_settings, | 897 | .get_settings = skge_get_settings, |
| 803 | .set_settings = skge_set_settings, | 898 | .set_settings = skge_set_settings, |
| @@ -810,6 +905,9 @@ static const struct ethtool_ops skge_ethtool_ops = { | |||
| 810 | .set_msglevel = skge_set_msglevel, | 905 | .set_msglevel = skge_set_msglevel, |
| 811 | .nway_reset = skge_nway_reset, | 906 | .nway_reset = skge_nway_reset, |
| 812 | .get_link = ethtool_op_get_link, | 907 | .get_link = ethtool_op_get_link, |
| 908 | .get_eeprom_len = skge_get_eeprom_len, | ||
| 909 | .get_eeprom = skge_get_eeprom, | ||
| 910 | .set_eeprom = skge_set_eeprom, | ||
| 813 | .get_ringparam = skge_get_ring_param, | 911 | .get_ringparam = skge_get_ring_param, |
| 814 | .set_ringparam = skge_set_ring_param, | 912 | .set_ringparam = skge_set_ring_param, |
| 815 | .get_pauseparam = skge_get_pauseparam, | 913 | .get_pauseparam = skge_get_pauseparam, |
diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 800329d99b21..51754246d59d 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Definitions for the new Marvell Yukon / SysKonenct driver. | 2 | * Definitions for the new Marvell Yukon / SysKonnect driver. |
| 3 | */ | 3 | */ |
| 4 | #ifndef _SKGE_H | 4 | #ifndef _SKGE_H |
| 5 | #define _SKGE_H | 5 | #define _SKGE_H |
| @@ -8,8 +8,10 @@ | |||
| 8 | #define PCI_DEV_REG1 0x40 | 8 | #define PCI_DEV_REG1 0x40 |
| 9 | #define PCI_PHY_COMA 0x8000000 | 9 | #define PCI_PHY_COMA 0x8000000 |
| 10 | #define PCI_VIO 0x2000000 | 10 | #define PCI_VIO 0x2000000 |
| 11 | |||
| 11 | #define PCI_DEV_REG2 0x44 | 12 | #define PCI_DEV_REG2 0x44 |
| 12 | #define PCI_REV_DESC 0x4 | 13 | #define PCI_VPD_ROM_SZ 7L<<14 /* VPD ROM size 0=256, 1=512, ... */ |
| 14 | #define PCI_REV_DESC 1<<2 /* Reverse Descriptor bytes */ | ||
| 13 | 15 | ||
| 14 | #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \ | 16 | #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \ |
| 15 | PCI_STATUS_SIG_SYSTEM_ERROR | \ | 17 | PCI_STATUS_SIG_SYSTEM_ERROR | \ |
