diff options
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_hw.c')
-rw-r--r-- | drivers/net/qlcnic/qlcnic_hw.c | 135 |
1 files changed, 60 insertions, 75 deletions
diff --git a/drivers/net/qlcnic/qlcnic_hw.c b/drivers/net/qlcnic/qlcnic_hw.c index da00e162b6d3..7a72b8d06bcb 100644 --- a/drivers/net/qlcnic/qlcnic_hw.c +++ b/drivers/net/qlcnic/qlcnic_hw.c | |||
@@ -24,6 +24,7 @@ | |||
24 | 24 | ||
25 | #include "qlcnic.h" | 25 | #include "qlcnic.h" |
26 | 26 | ||
27 | #include <linux/slab.h> | ||
27 | #include <net/ip.h> | 28 | #include <net/ip.h> |
28 | 29 | ||
29 | #define MASK(n) ((1ULL<<(n))-1) | 30 | #define MASK(n) ((1ULL<<(n))-1) |
@@ -53,21 +54,6 @@ static inline void writeq(u64 val, void __iomem *addr) | |||
53 | } | 54 | } |
54 | #endif | 55 | #endif |
55 | 56 | ||
56 | #define ADDR_IN_RANGE(addr, low, high) \ | ||
57 | (((addr) < (high)) && ((addr) >= (low))) | ||
58 | |||
59 | #define PCI_OFFSET_FIRST_RANGE(adapter, off) \ | ||
60 | ((adapter)->ahw.pci_base0 + (off)) | ||
61 | |||
62 | static void __iomem *pci_base_offset(struct qlcnic_adapter *adapter, | ||
63 | unsigned long off) | ||
64 | { | ||
65 | if (ADDR_IN_RANGE(off, FIRST_PAGE_GROUP_START, FIRST_PAGE_GROUP_END)) | ||
66 | return PCI_OFFSET_FIRST_RANGE(adapter, off); | ||
67 | |||
68 | return NULL; | ||
69 | } | ||
70 | |||
71 | static const struct crb_128M_2M_block_map | 57 | static const struct crb_128M_2M_block_map |
72 | crb_128M_2M_map[64] __cacheline_aligned_in_smp = { | 58 | crb_128M_2M_map[64] __cacheline_aligned_in_smp = { |
73 | {{{0, 0, 0, 0} } }, /* 0: PCI */ | 59 | {{{0, 0, 0, 0} } }, /* 0: PCI */ |
@@ -309,8 +295,12 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg) | |||
309 | done = QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_LOCK(sem))); | 295 | done = QLCRD32(adapter, QLCNIC_PCIE_REG(PCIE_SEM_LOCK(sem))); |
310 | if (done == 1) | 296 | if (done == 1) |
311 | break; | 297 | break; |
312 | if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT) | 298 | if (++timeout >= QLCNIC_PCIE_SEM_TIMEOUT) { |
299 | dev_err(&adapter->pdev->dev, | ||
300 | "Failed to acquire sem=%d lock;reg_id=%d\n", | ||
301 | sem, id_reg); | ||
313 | return -EIO; | 302 | return -EIO; |
303 | } | ||
314 | msleep(1); | 304 | msleep(1); |
315 | } | 305 | } |
316 | 306 | ||
@@ -426,10 +416,13 @@ static int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, u8 *addr) | |||
426 | void qlcnic_set_multi(struct net_device *netdev) | 416 | void qlcnic_set_multi(struct net_device *netdev) |
427 | { | 417 | { |
428 | struct qlcnic_adapter *adapter = netdev_priv(netdev); | 418 | struct qlcnic_adapter *adapter = netdev_priv(netdev); |
429 | struct dev_mc_list *mc_ptr; | 419 | struct netdev_hw_addr *ha; |
430 | u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | 420 | u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
431 | u32 mode = VPORT_MISS_MODE_DROP; | 421 | u32 mode = VPORT_MISS_MODE_DROP; |
432 | 422 | ||
423 | if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC) | ||
424 | return; | ||
425 | |||
433 | qlcnic_nic_add_mac(adapter, adapter->mac_addr); | 426 | qlcnic_nic_add_mac(adapter, adapter->mac_addr); |
434 | qlcnic_nic_add_mac(adapter, bcast_addr); | 427 | qlcnic_nic_add_mac(adapter, bcast_addr); |
435 | 428 | ||
@@ -445,8 +438,8 @@ void qlcnic_set_multi(struct net_device *netdev) | |||
445 | } | 438 | } |
446 | 439 | ||
447 | if (!netdev_mc_empty(netdev)) { | 440 | if (!netdev_mc_empty(netdev)) { |
448 | netdev_for_each_mc_addr(mc_ptr, netdev) { | 441 | netdev_for_each_mc_addr(ha, netdev) { |
449 | qlcnic_nic_add_mac(adapter, mc_ptr->dmi_addr); | 442 | qlcnic_nic_add_mac(adapter, ha->addr); |
450 | } | 443 | } |
451 | } | 444 | } |
452 | 445 | ||
@@ -874,13 +867,6 @@ qlcnic_pci_set_window_2M(struct qlcnic_adapter *adapter, | |||
874 | u64 addr, u32 *start) | 867 | u64 addr, u32 *start) |
875 | { | 868 | { |
876 | u32 window; | 869 | u32 window; |
877 | struct pci_dev *pdev = adapter->pdev; | ||
878 | |||
879 | if ((addr & 0x00ff800) == 0xff800) { | ||
880 | if (printk_ratelimit()) | ||
881 | dev_warn(&pdev->dev, "QM access not handled\n"); | ||
882 | return -EIO; | ||
883 | } | ||
884 | 870 | ||
885 | window = OCM_WIN_P3P(addr); | 871 | window = OCM_WIN_P3P(addr); |
886 | 872 | ||
@@ -897,8 +883,7 @@ static int | |||
897 | qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off, | 883 | qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off, |
898 | u64 *data, int op) | 884 | u64 *data, int op) |
899 | { | 885 | { |
900 | void __iomem *addr, *mem_ptr = NULL; | 886 | void __iomem *addr; |
901 | resource_size_t mem_base; | ||
902 | int ret; | 887 | int ret; |
903 | u32 start; | 888 | u32 start; |
904 | 889 | ||
@@ -908,21 +893,8 @@ qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off, | |||
908 | if (ret != 0) | 893 | if (ret != 0) |
909 | goto unlock; | 894 | goto unlock; |
910 | 895 | ||
911 | addr = pci_base_offset(adapter, start); | 896 | addr = adapter->ahw.pci_base0 + start; |
912 | if (addr) | ||
913 | goto noremap; | ||
914 | |||
915 | mem_base = pci_resource_start(adapter->pdev, 0) + (start & PAGE_MASK); | ||
916 | 897 | ||
917 | mem_ptr = ioremap(mem_base, PAGE_SIZE); | ||
918 | if (mem_ptr == NULL) { | ||
919 | ret = -EIO; | ||
920 | goto unlock; | ||
921 | } | ||
922 | |||
923 | addr = mem_ptr + (start & (PAGE_SIZE - 1)); | ||
924 | |||
925 | noremap: | ||
926 | if (op == 0) /* read */ | 898 | if (op == 0) /* read */ |
927 | *data = readq(addr); | 899 | *data = readq(addr); |
928 | else /* write */ | 900 | else /* write */ |
@@ -931,11 +903,31 @@ noremap: | |||
931 | unlock: | 903 | unlock: |
932 | mutex_unlock(&adapter->ahw.mem_lock); | 904 | mutex_unlock(&adapter->ahw.mem_lock); |
933 | 905 | ||
934 | if (mem_ptr) | ||
935 | iounmap(mem_ptr); | ||
936 | return ret; | 906 | return ret; |
937 | } | 907 | } |
938 | 908 | ||
909 | void | ||
910 | qlcnic_pci_camqm_read_2M(struct qlcnic_adapter *adapter, u64 off, u64 *data) | ||
911 | { | ||
912 | void __iomem *addr = adapter->ahw.pci_base0 + | ||
913 | QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM); | ||
914 | |||
915 | mutex_lock(&adapter->ahw.mem_lock); | ||
916 | *data = readq(addr); | ||
917 | mutex_unlock(&adapter->ahw.mem_lock); | ||
918 | } | ||
919 | |||
920 | void | ||
921 | qlcnic_pci_camqm_write_2M(struct qlcnic_adapter *adapter, u64 off, u64 data) | ||
922 | { | ||
923 | void __iomem *addr = adapter->ahw.pci_base0 + | ||
924 | QLCNIC_PCI_CAMQM_2M_BASE + (off - QLCNIC_PCI_CAMQM); | ||
925 | |||
926 | mutex_lock(&adapter->ahw.mem_lock); | ||
927 | writeq(data, addr); | ||
928 | mutex_unlock(&adapter->ahw.mem_lock); | ||
929 | } | ||
930 | |||
939 | #define MAX_CTL_CHECK 1000 | 931 | #define MAX_CTL_CHECK 1000 |
940 | 932 | ||
941 | int | 933 | int |
@@ -944,7 +936,6 @@ qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter, | |||
944 | { | 936 | { |
945 | int i, j, ret; | 937 | int i, j, ret; |
946 | u32 temp, off8; | 938 | u32 temp, off8; |
947 | u64 stride; | ||
948 | void __iomem *mem_crb; | 939 | void __iomem *mem_crb; |
949 | 940 | ||
950 | /* Only 64-bit aligned access */ | 941 | /* Only 64-bit aligned access */ |
@@ -953,7 +944,7 @@ qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter, | |||
953 | 944 | ||
954 | /* P3 onward, test agent base for MIU and SIU is same */ | 945 | /* P3 onward, test agent base for MIU and SIU is same */ |
955 | if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET, | 946 | if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET, |
956 | QLCNIC_ADDR_QDR_NET_MAX_P3)) { | 947 | QLCNIC_ADDR_QDR_NET_MAX)) { |
957 | mem_crb = qlcnic_get_ioaddr(adapter, | 948 | mem_crb = qlcnic_get_ioaddr(adapter, |
958 | QLCNIC_CRB_QDR_NET+MIU_TEST_AGT_BASE); | 949 | QLCNIC_CRB_QDR_NET+MIU_TEST_AGT_BASE); |
959 | goto correct; | 950 | goto correct; |
@@ -971,9 +962,7 @@ qlcnic_pci_mem_write_2M(struct qlcnic_adapter *adapter, | |||
971 | return -EIO; | 962 | return -EIO; |
972 | 963 | ||
973 | correct: | 964 | correct: |
974 | stride = QLCNIC_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8; | 965 | off8 = off & ~0xf; |
975 | |||
976 | off8 = off & ~(stride-1); | ||
977 | 966 | ||
978 | mutex_lock(&adapter->ahw.mem_lock); | 967 | mutex_lock(&adapter->ahw.mem_lock); |
979 | 968 | ||
@@ -981,30 +970,28 @@ correct: | |||
981 | writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); | 970 | writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI)); |
982 | 971 | ||
983 | i = 0; | 972 | i = 0; |
984 | if (stride == 16) { | 973 | writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL)); |
985 | writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL)); | 974 | writel((TA_CTL_START | TA_CTL_ENABLE), |
986 | writel((TA_CTL_START | TA_CTL_ENABLE), | 975 | (mem_crb + TEST_AGT_CTRL)); |
987 | (mem_crb + TEST_AGT_CTRL)); | ||
988 | |||
989 | for (j = 0; j < MAX_CTL_CHECK; j++) { | ||
990 | temp = readl(mem_crb + TEST_AGT_CTRL); | ||
991 | if ((temp & TA_CTL_BUSY) == 0) | ||
992 | break; | ||
993 | } | ||
994 | 976 | ||
995 | if (j >= MAX_CTL_CHECK) { | 977 | for (j = 0; j < MAX_CTL_CHECK; j++) { |
996 | ret = -EIO; | 978 | temp = readl(mem_crb + TEST_AGT_CTRL); |
997 | goto done; | 979 | if ((temp & TA_CTL_BUSY) == 0) |
998 | } | 980 | break; |
981 | } | ||
999 | 982 | ||
1000 | i = (off & 0xf) ? 0 : 2; | 983 | if (j >= MAX_CTL_CHECK) { |
1001 | writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i)), | 984 | ret = -EIO; |
1002 | mem_crb + MIU_TEST_AGT_WRDATA(i)); | 985 | goto done; |
1003 | writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i+1)), | ||
1004 | mem_crb + MIU_TEST_AGT_WRDATA(i+1)); | ||
1005 | i = (off & 0xf) ? 2 : 0; | ||
1006 | } | 986 | } |
1007 | 987 | ||
988 | i = (off & 0xf) ? 0 : 2; | ||
989 | writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i)), | ||
990 | mem_crb + MIU_TEST_AGT_WRDATA(i)); | ||
991 | writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i+1)), | ||
992 | mem_crb + MIU_TEST_AGT_WRDATA(i+1)); | ||
993 | i = (off & 0xf) ? 2 : 0; | ||
994 | |||
1008 | writel(data & 0xffffffff, | 995 | writel(data & 0xffffffff, |
1009 | mem_crb + MIU_TEST_AGT_WRDATA(i)); | 996 | mem_crb + MIU_TEST_AGT_WRDATA(i)); |
1010 | writel((data >> 32) & 0xffffffff, | 997 | writel((data >> 32) & 0xffffffff, |
@@ -1040,7 +1027,7 @@ qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter, | |||
1040 | { | 1027 | { |
1041 | int j, ret; | 1028 | int j, ret; |
1042 | u32 temp, off8; | 1029 | u32 temp, off8; |
1043 | u64 val, stride; | 1030 | u64 val; |
1044 | void __iomem *mem_crb; | 1031 | void __iomem *mem_crb; |
1045 | 1032 | ||
1046 | /* Only 64-bit aligned access */ | 1033 | /* Only 64-bit aligned access */ |
@@ -1049,7 +1036,7 @@ qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter, | |||
1049 | 1036 | ||
1050 | /* P3 onward, test agent base for MIU and SIU is same */ | 1037 | /* P3 onward, test agent base for MIU and SIU is same */ |
1051 | if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET, | 1038 | if (ADDR_IN_RANGE(off, QLCNIC_ADDR_QDR_NET, |
1052 | QLCNIC_ADDR_QDR_NET_MAX_P3)) { | 1039 | QLCNIC_ADDR_QDR_NET_MAX)) { |
1053 | mem_crb = qlcnic_get_ioaddr(adapter, | 1040 | mem_crb = qlcnic_get_ioaddr(adapter, |
1054 | QLCNIC_CRB_QDR_NET+MIU_TEST_AGT_BASE); | 1041 | QLCNIC_CRB_QDR_NET+MIU_TEST_AGT_BASE); |
1055 | goto correct; | 1042 | goto correct; |
@@ -1069,9 +1056,7 @@ qlcnic_pci_mem_read_2M(struct qlcnic_adapter *adapter, | |||
1069 | return -EIO; | 1056 | return -EIO; |
1070 | 1057 | ||
1071 | correct: | 1058 | correct: |
1072 | stride = QLCNIC_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8; | 1059 | off8 = off & ~0xf; |
1073 | |||
1074 | off8 = off & ~(stride-1); | ||
1075 | 1060 | ||
1076 | mutex_lock(&adapter->ahw.mem_lock); | 1061 | mutex_lock(&adapter->ahw.mem_lock); |
1077 | 1062 | ||
@@ -1093,7 +1078,7 @@ correct: | |||
1093 | ret = -EIO; | 1078 | ret = -EIO; |
1094 | } else { | 1079 | } else { |
1095 | off8 = MIU_TEST_AGT_RDDATA_LO; | 1080 | off8 = MIU_TEST_AGT_RDDATA_LO; |
1096 | if ((stride == 16) && (off & 0xf)) | 1081 | if (off & 0xf) |
1097 | off8 = MIU_TEST_AGT_RDDATA_UPPER_LO; | 1082 | off8 = MIU_TEST_AGT_RDDATA_UPPER_LO; |
1098 | 1083 | ||
1099 | temp = readl(mem_crb + off8 + 4); | 1084 | temp = readl(mem_crb + off8 + 4); |