aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/qlcnic/qlcnic_hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/qlcnic/qlcnic_hw.c')
-rw-r--r--drivers/net/qlcnic/qlcnic_hw.c135
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
62static 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
71static const struct crb_128M_2M_block_map 57static const struct crb_128M_2M_block_map
72crb_128M_2M_map[64] __cacheline_aligned_in_smp = { 58crb_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)
426void qlcnic_set_multi(struct net_device *netdev) 416void 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
897qlcnic_pci_mem_access_direct(struct qlcnic_adapter *adapter, u64 off, 883qlcnic_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
925noremap:
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:
931unlock: 903unlock:
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
909void
910qlcnic_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
920void
921qlcnic_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
941int 933int
@@ -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
973correct: 964correct:
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
1071correct: 1058correct:
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);