aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_hw.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netxen/netxen_nic_hw.c')
-rw-r--r--drivers/net/netxen/netxen_nic_hw.c1048
1 files changed, 474 insertions, 574 deletions
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 52a3798d8d94..b1cf46a0c48c 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -19,10 +19,11 @@
19 * MA 02111-1307, USA. 19 * MA 02111-1307, USA.
20 * 20 *
21 * The full GNU General Public License is included in this distribution 21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE. 22 * in the file called "COPYING".
23 * 23 *
24 */ 24 */
25 25
26#include <linux/slab.h>
26#include "netxen_nic.h" 27#include "netxen_nic.h"
27#include "netxen_nic_hw.h" 28#include "netxen_nic_hw.h"
28 29
@@ -31,6 +32,7 @@
31#define MASK(n) ((1ULL<<(n))-1) 32#define MASK(n) ((1ULL<<(n))-1)
32#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff)) 33#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
33#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff)) 34#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
35#define OCM_WIN_P3P(addr) (addr & 0xffc0000)
34#define MS_WIN(addr) (addr & 0x0ffc0000) 36#define MS_WIN(addr) (addr & 0x0ffc0000)
35 37
36#define GET_MEM_OFFS_2M(addr) (addr & MASK(18)) 38#define GET_MEM_OFFS_2M(addr) (addr & MASK(18))
@@ -41,6 +43,11 @@
41#define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000)) 43#define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000))
42#define CRB_INDIRECT_2M (0x1e0000UL) 44#define CRB_INDIRECT_2M (0x1e0000UL)
43 45
46static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
47 void __iomem *addr, u32 data);
48static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter,
49 void __iomem *addr);
50
44#ifndef readq 51#ifndef readq
45static inline u64 readq(void __iomem *addr) 52static inline u64 readq(void __iomem *addr)
46{ 53{
@@ -326,7 +333,7 @@ netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg)
326 if (done == 1) 333 if (done == 1)
327 break; 334 break;
328 if (++timeout >= NETXEN_PCIE_SEM_TIMEOUT) 335 if (++timeout >= NETXEN_PCIE_SEM_TIMEOUT)
329 return -1; 336 return -EIO;
330 msleep(1); 337 msleep(1);
331 } 338 }
332 339
@@ -339,8 +346,7 @@ netxen_pcie_sem_lock(struct netxen_adapter *adapter, int sem, u32 id_reg)
339void 346void
340netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem) 347netxen_pcie_sem_unlock(struct netxen_adapter *adapter, int sem)
341{ 348{
342 int val; 349 NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
343 val = NXRD32(adapter, NETXEN_PCIE_REG(PCIE_SEM_UNLOCK(sem)));
344} 350}
345 351
346int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port) 352int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
@@ -534,7 +540,7 @@ void netxen_p2_nic_set_multi(struct net_device *netdev)
534 struct netxen_adapter *adapter = netdev_priv(netdev); 540 struct netxen_adapter *adapter = netdev_priv(netdev);
535 struct dev_mc_list *mc_ptr; 541 struct dev_mc_list *mc_ptr;
536 u8 null_addr[6]; 542 u8 null_addr[6];
537 int index = 0; 543 int i;
538 544
539 memset(null_addr, 0, 6); 545 memset(null_addr, 0, 6);
540 546
@@ -549,7 +555,7 @@ void netxen_p2_nic_set_multi(struct net_device *netdev)
549 return; 555 return;
550 } 556 }
551 557
552 if (netdev->mc_count == 0) { 558 if (netdev_mc_empty(netdev)) {
553 adapter->set_promisc(adapter, 559 adapter->set_promisc(adapter,
554 NETXEN_NIU_NON_PROMISC_MODE); 560 NETXEN_NIU_NON_PROMISC_MODE);
555 netxen_nic_disable_mcast_filter(adapter); 561 netxen_nic_disable_mcast_filter(adapter);
@@ -558,23 +564,20 @@ void netxen_p2_nic_set_multi(struct net_device *netdev)
558 564
559 adapter->set_promisc(adapter, NETXEN_NIU_ALLMULTI_MODE); 565 adapter->set_promisc(adapter, NETXEN_NIU_ALLMULTI_MODE);
560 if (netdev->flags & IFF_ALLMULTI || 566 if (netdev->flags & IFF_ALLMULTI ||
561 netdev->mc_count > adapter->max_mc_count) { 567 netdev_mc_count(netdev) > adapter->max_mc_count) {
562 netxen_nic_disable_mcast_filter(adapter); 568 netxen_nic_disable_mcast_filter(adapter);
563 return; 569 return;
564 } 570 }
565 571
566 netxen_nic_enable_mcast_filter(adapter); 572 netxen_nic_enable_mcast_filter(adapter);
567 573
568 for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next, index++) 574 i = 0;
569 netxen_nic_set_mcast_addr(adapter, index, mc_ptr->dmi_addr); 575 netdev_for_each_mc_addr(mc_ptr, netdev)
570 576 netxen_nic_set_mcast_addr(adapter, i++, mc_ptr->dmi_addr);
571 if (index != netdev->mc_count)
572 printk(KERN_WARNING "%s: %s multicast address count mismatch\n",
573 netxen_nic_driver_name, netdev->name);
574 577
575 /* Clear out remaining addresses */ 578 /* Clear out remaining addresses */
576 for (; index < adapter->max_mc_count; index++) 579 while (i < adapter->max_mc_count)
577 netxen_nic_set_mcast_addr(adapter, index, null_addr); 580 netxen_nic_set_mcast_addr(adapter, i++, null_addr);
578} 581}
579 582
580static int 583static int
@@ -685,6 +688,9 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
685 struct list_head *head; 688 struct list_head *head;
686 nx_mac_list_t *cur; 689 nx_mac_list_t *cur;
687 690
691 if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
692 return;
693
688 list_splice_tail_init(&adapter->mac_list, &del_list); 694 list_splice_tail_init(&adapter->mac_list, &del_list);
689 695
690 nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list); 696 nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list);
@@ -696,16 +702,14 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
696 } 702 }
697 703
698 if ((netdev->flags & IFF_ALLMULTI) || 704 if ((netdev->flags & IFF_ALLMULTI) ||
699 (netdev->mc_count > adapter->max_mc_count)) { 705 (netdev_mc_count(netdev) > adapter->max_mc_count)) {
700 mode = VPORT_MISS_MODE_ACCEPT_MULTI; 706 mode = VPORT_MISS_MODE_ACCEPT_MULTI;
701 goto send_fw_cmd; 707 goto send_fw_cmd;
702 } 708 }
703 709
704 if (netdev->mc_count > 0) { 710 if (!netdev_mc_empty(netdev)) {
705 for (mc_ptr = netdev->mc_list; mc_ptr; 711 netdev_for_each_mc_addr(mc_ptr, netdev)
706 mc_ptr = mc_ptr->next) {
707 nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list); 712 nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr, &del_list);
708 }
709 } 713 }
710 714
711send_fw_cmd: 715send_fw_cmd:
@@ -769,17 +773,20 @@ int netxen_p3_nic_set_mac_addr(struct netxen_adapter *adapter, u8 *addr)
769int netxen_config_intr_coalesce(struct netxen_adapter *adapter) 773int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
770{ 774{
771 nx_nic_req_t req; 775 nx_nic_req_t req;
772 u64 word; 776 u64 word[6];
773 int rv; 777 int rv, i;
774 778
775 memset(&req, 0, sizeof(nx_nic_req_t)); 779 memset(&req, 0, sizeof(nx_nic_req_t));
780 memset(word, 0, sizeof(word));
776 781
777 req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23); 782 req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
778 783
779 word = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16); 784 word[0] = NETXEN_CONFIG_INTR_COALESCE | ((u64)adapter->portnum << 16);
780 req.req_hdr = cpu_to_le64(word); 785 req.req_hdr = cpu_to_le64(word[0]);
781 786
782 memcpy(&req.words[0], &adapter->coal, sizeof(adapter->coal)); 787 memcpy(&word[0], &adapter->coal, sizeof(adapter->coal));
788 for (i = 0; i < 6; i++)
789 req.words[i] = cpu_to_le64(word[i]);
783 790
784 rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1); 791 rv = netxen_send_cmd_descs(adapter, (struct cmd_desc_type0 *)&req, 1);
785 if (rv != 0) { 792 if (rv != 0) {
@@ -1025,7 +1032,7 @@ static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
1025 return 0; 1032 return 0;
1026} 1033}
1027 1034
1028int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac) 1035int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 *mac)
1029{ 1036{
1030 __le32 *pmac = (__le32 *) mac; 1037 __le32 *pmac = (__le32 *) mac;
1031 u32 offset; 1038 u32 offset;
@@ -1050,7 +1057,7 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
1050 return 0; 1057 return 0;
1051} 1058}
1052 1059
1053int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac) 1060int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, u64 *mac)
1054{ 1061{
1055 uint32_t crbaddr, mac_hi, mac_lo; 1062 uint32_t crbaddr, mac_hi, mac_lo;
1056 int pci_func = adapter->ahw.pci_func; 1063 int pci_func = adapter->ahw.pci_func;
@@ -1073,89 +1080,71 @@ int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
1073 * Changes the CRB window to the specified window. 1080 * Changes the CRB window to the specified window.
1074 */ 1081 */
1075static void 1082static void
1076netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw) 1083netxen_nic_pci_set_crbwindow_128M(struct netxen_adapter *adapter,
1084 u32 window)
1077{ 1085{
1078 void __iomem *offset; 1086 void __iomem *offset;
1079 u32 tmp; 1087 int count = 10;
1080 int count = 0; 1088 u8 func = adapter->ahw.pci_func;
1081 uint8_t func = adapter->ahw.pci_func;
1082 1089
1083 if (adapter->curr_window == wndw) 1090 if (adapter->ahw.crb_win == window)
1084 return; 1091 return;
1085 /* 1092
1086 * Move the CRB window.
1087 * We need to write to the "direct access" region of PCI
1088 * to avoid a race condition where the window register has
1089 * not been successfully written across CRB before the target
1090 * register address is received by PCI. The direct region bypasses
1091 * the CRB bus.
1092 */
1093 offset = PCI_OFFSET_SECOND_RANGE(adapter, 1093 offset = PCI_OFFSET_SECOND_RANGE(adapter,
1094 NETXEN_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(func))); 1094 NETXEN_PCIX_PH_REG(PCIE_CRB_WINDOW_REG(func)));
1095 1095
1096 if (wndw & 0x1) 1096 writel(window, offset);
1097 wndw = NETXEN_WINDOW_ONE; 1097 do {
1098 if (window == readl(offset))
1099 break;
1098 1100
1099 writel(wndw, offset); 1101 if (printk_ratelimit())
1102 dev_warn(&adapter->pdev->dev,
1103 "failed to set CRB window to %d\n",
1104 (window == NETXEN_WINDOW_ONE));
1105 udelay(1);
1100 1106
1101 /* MUST make sure window is set before we forge on... */ 1107 } while (--count > 0);
1102 while ((tmp = readl(offset)) != wndw) {
1103 printk(KERN_WARNING "%s: %s WARNING: CRB window value not "
1104 "registered properly: 0x%08x.\n",
1105 netxen_nic_driver_name, __func__, tmp);
1106 mdelay(1);
1107 if (count >= 10)
1108 break;
1109 count++;
1110 }
1111 1108
1112 if (wndw == NETXEN_WINDOW_ONE) 1109 if (count > 0)
1113 adapter->curr_window = 1; 1110 adapter->ahw.crb_win = window;
1114 else
1115 adapter->curr_window = 0;
1116} 1111}
1117 1112
1118/* 1113/*
1119 * Return -1 if off is not valid, 1114 * Returns < 0 if off is not valid,
1120 * 1 if window access is needed. 'off' is set to offset from 1115 * 1 if window access is needed. 'off' is set to offset from
1121 * CRB space in 128M pci map 1116 * CRB space in 128M pci map
1122 * 0 if no window access is needed. 'off' is set to 2M addr 1117 * 0 if no window access is needed. 'off' is set to 2M addr
1123 * In: 'off' is offset from base in 128M pci map 1118 * In: 'off' is offset from base in 128M pci map
1124 */ 1119 */
1125static int 1120static int
1126netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, ulong *off) 1121netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter,
1122 ulong off, void __iomem **addr)
1127{ 1123{
1128 crb_128M_2M_sub_block_map_t *m; 1124 crb_128M_2M_sub_block_map_t *m;
1129 1125
1130 1126
1131 if (*off >= NETXEN_CRB_MAX) 1127 if ((off >= NETXEN_CRB_MAX) || (off < NETXEN_PCI_CRBSPACE))
1132 return -1; 1128 return -EINVAL;
1133
1134 if (*off >= NETXEN_PCI_CAMQM && (*off < NETXEN_PCI_CAMQM_2M_END)) {
1135 *off = (*off - NETXEN_PCI_CAMQM) + NETXEN_PCI_CAMQM_2M_BASE +
1136 (ulong)adapter->ahw.pci_base0;
1137 return 0;
1138 }
1139
1140 if (*off < NETXEN_PCI_CRBSPACE)
1141 return -1;
1142 1129
1143 *off -= NETXEN_PCI_CRBSPACE; 1130 off -= NETXEN_PCI_CRBSPACE;
1144 1131
1145 /* 1132 /*
1146 * Try direct map 1133 * Try direct map
1147 */ 1134 */
1148 m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)]; 1135 m = &crb_128M_2M_map[CRB_BLK(off)].sub_block[CRB_SUBBLK(off)];
1149 1136
1150 if (m->valid && (m->start_128M <= *off) && (m->end_128M > *off)) { 1137 if (m->valid && (m->start_128M <= off) && (m->end_128M > off)) {
1151 *off = *off + m->start_2M - m->start_128M + 1138 *addr = adapter->ahw.pci_base0 + m->start_2M +
1152 (ulong)adapter->ahw.pci_base0; 1139 (off - m->start_128M);
1153 return 0; 1140 return 0;
1154 } 1141 }
1155 1142
1156 /* 1143 /*
1157 * Not in direct map, use crb window 1144 * Not in direct map, use crb window
1158 */ 1145 */
1146 *addr = adapter->ahw.pci_base0 + CRB_INDIRECT_2M +
1147 (off & MASK(16));
1159 return 1; 1148 return 1;
1160} 1149}
1161 1150
@@ -1165,52 +1154,78 @@ netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, ulong *off)
1165 * side effect: lock crb window 1154 * side effect: lock crb window
1166 */ 1155 */
1167static void 1156static void
1168netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off) 1157netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong off)
1169{ 1158{
1170 u32 win_read; 1159 u32 window;
1160 void __iomem *addr = adapter->ahw.pci_base0 + CRB_WINDOW_2M;
1171 1161
1172 adapter->crb_win = CRB_HI(*off); 1162 off -= NETXEN_PCI_CRBSPACE;
1173 writel(adapter->crb_win, (adapter->ahw.pci_base0 + CRB_WINDOW_2M)); 1163
1174 /* 1164 window = CRB_HI(off);
1175 * Read back value to make sure write has gone through before trying 1165
1176 * to use it. 1166 if (adapter->ahw.crb_win == window)
1177 */ 1167 return;
1178 win_read = readl(adapter->ahw.pci_base0 + CRB_WINDOW_2M); 1168
1179 if (win_read != adapter->crb_win) { 1169 writel(window, addr);
1180 printk(KERN_ERR "%s: Written crbwin (0x%x) != " 1170 if (readl(addr) != window) {
1181 "Read crbwin (0x%x), off=0x%lx\n", 1171 if (printk_ratelimit())
1182 __func__, adapter->crb_win, win_read, *off); 1172 dev_warn(&adapter->pdev->dev,
1173 "failed to set CRB window to %d off 0x%lx\n",
1174 window, off);
1183 } 1175 }
1184 *off = (*off & MASK(16)) + CRB_INDIRECT_2M + 1176 adapter->ahw.crb_win = window;
1185 (ulong)adapter->ahw.pci_base0; 1177}
1178
1179static void __iomem *
1180netxen_nic_map_indirect_address_128M(struct netxen_adapter *adapter,
1181 ulong win_off, void __iomem **mem_ptr)
1182{
1183 ulong off = win_off;
1184 void __iomem *addr;
1185 resource_size_t mem_base;
1186
1187 if (ADDR_IN_WINDOW1(win_off))
1188 off = NETXEN_CRB_NORMAL(win_off);
1189
1190 addr = pci_base_offset(adapter, off);
1191 if (addr)
1192 return addr;
1193
1194 if (adapter->ahw.pci_len0 == 0)
1195 off -= NETXEN_PCI_CRBSPACE;
1196
1197 mem_base = pci_resource_start(adapter->pdev, 0);
1198 *mem_ptr = ioremap(mem_base + (off & PAGE_MASK), PAGE_SIZE);
1199 if (*mem_ptr)
1200 addr = *mem_ptr + (off & (PAGE_SIZE - 1));
1201
1202 return addr;
1186} 1203}
1187 1204
1188static int 1205static int
1189netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data) 1206netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, ulong off, u32 data)
1190{ 1207{
1191 unsigned long flags; 1208 unsigned long flags;
1192 void __iomem *addr; 1209 void __iomem *addr, *mem_ptr = NULL;
1193
1194 if (ADDR_IN_WINDOW1(off))
1195 addr = NETXEN_CRB_NORMALIZE(adapter, off);
1196 else
1197 addr = pci_base_offset(adapter, off);
1198 1210
1199 BUG_ON(!addr); 1211 addr = netxen_nic_map_indirect_address_128M(adapter, off, &mem_ptr);
1212 if (!addr)
1213 return -EIO;
1200 1214
1201 if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ 1215 if (ADDR_IN_WINDOW1(off)) { /* Window 1 */
1202 read_lock(&adapter->adapter_lock); 1216 netxen_nic_io_write_128M(adapter, addr, data);
1203 writel(data, addr); 1217 } else { /* Window 0 */
1204 read_unlock(&adapter->adapter_lock); 1218 write_lock_irqsave(&adapter->ahw.crb_lock, flags);
1205 } else { /* Window 0 */ 1219 netxen_nic_pci_set_crbwindow_128M(adapter, 0);
1206 write_lock_irqsave(&adapter->adapter_lock, flags);
1207 addr = pci_base_offset(adapter, off);
1208 netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1209 writel(data, addr); 1220 writel(data, addr);
1210 netxen_nic_pci_change_crbwindow_128M(adapter, 1); 1221 netxen_nic_pci_set_crbwindow_128M(adapter,
1211 write_unlock_irqrestore(&adapter->adapter_lock, flags); 1222 NETXEN_WINDOW_ONE);
1223 write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
1212 } 1224 }
1213 1225
1226 if (mem_ptr)
1227 iounmap(mem_ptr);
1228
1214 return 0; 1229 return 0;
1215} 1230}
1216 1231
@@ -1218,28 +1233,27 @@ static u32
1218netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off) 1233netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, ulong off)
1219{ 1234{
1220 unsigned long flags; 1235 unsigned long flags;
1221 void __iomem *addr; 1236 void __iomem *addr, *mem_ptr = NULL;
1222 u32 data; 1237 u32 data;
1223 1238
1224 if (ADDR_IN_WINDOW1(off)) 1239 addr = netxen_nic_map_indirect_address_128M(adapter, off, &mem_ptr);
1225 addr = NETXEN_CRB_NORMALIZE(adapter, off); 1240 if (!addr)
1226 else 1241 return -EIO;
1227 addr = pci_base_offset(adapter, off);
1228
1229 BUG_ON(!addr);
1230 1242
1231 if (ADDR_IN_WINDOW1(off)) { /* Window 1 */ 1243 if (ADDR_IN_WINDOW1(off)) { /* Window 1 */
1232 read_lock(&adapter->adapter_lock); 1244 data = netxen_nic_io_read_128M(adapter, addr);
1245 } else { /* Window 0 */
1246 write_lock_irqsave(&adapter->ahw.crb_lock, flags);
1247 netxen_nic_pci_set_crbwindow_128M(adapter, 0);
1233 data = readl(addr); 1248 data = readl(addr);
1234 read_unlock(&adapter->adapter_lock); 1249 netxen_nic_pci_set_crbwindow_128M(adapter,
1235 } else { /* Window 0 */ 1250 NETXEN_WINDOW_ONE);
1236 write_lock_irqsave(&adapter->adapter_lock, flags); 1251 write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
1237 netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1238 data = readl(addr);
1239 netxen_nic_pci_change_crbwindow_128M(adapter, 1);
1240 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1241 } 1252 }
1242 1253
1254 if (mem_ptr)
1255 iounmap(mem_ptr);
1256
1243 return data; 1257 return data;
1244} 1258}
1245 1259
@@ -1248,28 +1262,30 @@ netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, ulong off, u32 data)
1248{ 1262{
1249 unsigned long flags; 1263 unsigned long flags;
1250 int rv; 1264 int rv;
1265 void __iomem *addr = NULL;
1251 1266
1252 rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off); 1267 rv = netxen_nic_pci_get_crb_addr_2M(adapter, off, &addr);
1253 1268
1254 if (rv == -1) { 1269 if (rv == 0) {
1255 printk(KERN_ERR "%s: invalid offset: 0x%016lx\n", 1270 writel(data, addr);
1256 __func__, off); 1271 return 0;
1257 dump_stack();
1258 return -1;
1259 } 1272 }
1260 1273
1261 if (rv == 1) { 1274 if (rv > 0) {
1262 write_lock_irqsave(&adapter->adapter_lock, flags); 1275 /* indirect access */
1276 write_lock_irqsave(&adapter->ahw.crb_lock, flags);
1263 crb_win_lock(adapter); 1277 crb_win_lock(adapter);
1264 netxen_nic_pci_set_crbwindow_2M(adapter, &off); 1278 netxen_nic_pci_set_crbwindow_2M(adapter, off);
1265 writel(data, (void __iomem *)off); 1279 writel(data, addr);
1266 crb_win_unlock(adapter); 1280 crb_win_unlock(adapter);
1267 write_unlock_irqrestore(&adapter->adapter_lock, flags); 1281 write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
1268 } else 1282 return 0;
1269 writel(data, (void __iomem *)off); 1283 }
1270
1271 1284
1272 return 0; 1285 dev_err(&adapter->pdev->dev,
1286 "%s: invalid offset: 0x%016lx\n", __func__, off);
1287 dump_stack();
1288 return -EIO;
1273} 1289}
1274 1290
1275static u32 1291static u32
@@ -1278,102 +1294,37 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
1278 unsigned long flags; 1294 unsigned long flags;
1279 int rv; 1295 int rv;
1280 u32 data; 1296 u32 data;
1297 void __iomem *addr = NULL;
1281 1298
1282 rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off); 1299 rv = netxen_nic_pci_get_crb_addr_2M(adapter, off, &addr);
1283 1300
1284 if (rv == -1) { 1301 if (rv == 0)
1285 printk(KERN_ERR "%s: invalid offset: 0x%016lx\n", 1302 return readl(addr);
1286 __func__, off);
1287 dump_stack();
1288 return -1;
1289 }
1290 1303
1291 if (rv == 1) { 1304 if (rv > 0) {
1292 write_lock_irqsave(&adapter->adapter_lock, flags); 1305 /* indirect access */
1306 write_lock_irqsave(&adapter->ahw.crb_lock, flags);
1293 crb_win_lock(adapter); 1307 crb_win_lock(adapter);
1294 netxen_nic_pci_set_crbwindow_2M(adapter, &off); 1308 netxen_nic_pci_set_crbwindow_2M(adapter, off);
1295 data = readl((void __iomem *)off); 1309 data = readl(addr);
1296 crb_win_unlock(adapter); 1310 crb_win_unlock(adapter);
1297 write_unlock_irqrestore(&adapter->adapter_lock, flags); 1311 write_unlock_irqrestore(&adapter->ahw.crb_lock, flags);
1298 } else 1312 return data;
1299 data = readl((void __iomem *)off);
1300
1301 return data;
1302}
1303
1304static int netxen_pci_set_window_warning_count;
1305
1306static unsigned long
1307netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
1308 unsigned long long addr)
1309{
1310 void __iomem *offset;
1311 int window;
1312 unsigned long long qdr_max;
1313 uint8_t func = adapter->ahw.pci_func;
1314
1315 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1316 qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2;
1317 } else {
1318 qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3;
1319 } 1313 }
1320 1314
1321 if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { 1315 dev_err(&adapter->pdev->dev,
1322 /* DDR network side */ 1316 "%s: invalid offset: 0x%016lx\n", __func__, off);
1323 addr -= NETXEN_ADDR_DDR_NET; 1317 dump_stack();
1324 window = (addr >> 25) & 0x3ff; 1318 return -1;
1325 if (adapter->ahw.ddr_mn_window != window) {
1326 adapter->ahw.ddr_mn_window = window;
1327 offset = PCI_OFFSET_SECOND_RANGE(adapter,
1328 NETXEN_PCIX_PH_REG(PCIE_MN_WINDOW_REG(func)));
1329 writel(window, offset);
1330 /* MUST make sure window is set before we forge on... */
1331 readl(offset);
1332 }
1333 addr -= (window * NETXEN_WINDOW_ONE);
1334 addr += NETXEN_PCI_DDR_NET;
1335 } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
1336 addr -= NETXEN_ADDR_OCM0;
1337 addr += NETXEN_PCI_OCM0;
1338 } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
1339 addr -= NETXEN_ADDR_OCM1;
1340 addr += NETXEN_PCI_OCM1;
1341 } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) {
1342 /* QDR network side */
1343 addr -= NETXEN_ADDR_QDR_NET;
1344 window = (addr >> 22) & 0x3f;
1345 if (adapter->ahw.qdr_sn_window != window) {
1346 adapter->ahw.qdr_sn_window = window;
1347 offset = PCI_OFFSET_SECOND_RANGE(adapter,
1348 NETXEN_PCIX_PH_REG(PCIE_SN_WINDOW_REG(func)));
1349 writel((window << 22), offset);
1350 /* MUST make sure window is set before we forge on... */
1351 readl(offset);
1352 }
1353 addr -= (window * 0x400000);
1354 addr += NETXEN_PCI_QDR_NET;
1355 } else {
1356 /*
1357 * peg gdb frequently accesses memory that doesn't exist,
1358 * this limits the chit chat so debugging isn't slowed down.
1359 */
1360 if ((netxen_pci_set_window_warning_count++ < 8)
1361 || (netxen_pci_set_window_warning_count % 64 == 0))
1362 printk("%s: Warning:netxen_nic_pci_set_window()"
1363 " Unknown address range!\n",
1364 netxen_nic_driver_name);
1365 addr = -1UL;
1366 }
1367 return addr;
1368} 1319}
1369 1320
1370/* window 1 registers only */ 1321/* window 1 registers only */
1371static void netxen_nic_io_write_128M(struct netxen_adapter *adapter, 1322static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
1372 void __iomem *addr, u32 data) 1323 void __iomem *addr, u32 data)
1373{ 1324{
1374 read_lock(&adapter->adapter_lock); 1325 read_lock(&adapter->ahw.crb_lock);
1375 writel(data, addr); 1326 writel(data, addr);
1376 read_unlock(&adapter->adapter_lock); 1327 read_unlock(&adapter->ahw.crb_lock);
1377} 1328}
1378 1329
1379static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter, 1330static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter,
@@ -1381,9 +1332,9 @@ static u32 netxen_nic_io_read_128M(struct netxen_adapter *adapter,
1381{ 1332{
1382 u32 val; 1333 u32 val;
1383 1334
1384 read_lock(&adapter->adapter_lock); 1335 read_lock(&adapter->ahw.crb_lock);
1385 val = readl(addr); 1336 val = readl(addr);
1386 read_unlock(&adapter->adapter_lock); 1337 read_unlock(&adapter->ahw.crb_lock);
1387 1338
1388 return val; 1339 return val;
1389} 1340}
@@ -1403,488 +1354,437 @@ static u32 netxen_nic_io_read_2M(struct netxen_adapter *adapter,
1403void __iomem * 1354void __iomem *
1404netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset) 1355netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset)
1405{ 1356{
1406 ulong off = offset; 1357 void __iomem *addr = NULL;
1407 1358
1408 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { 1359 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1409 if (offset < NETXEN_CRB_PCIX_HOST2 && 1360 if ((offset < NETXEN_CRB_PCIX_HOST2) &&
1410 offset > NETXEN_CRB_PCIX_HOST) 1361 (offset > NETXEN_CRB_PCIX_HOST))
1411 return PCI_OFFSET_SECOND_RANGE(adapter, offset); 1362 addr = PCI_OFFSET_SECOND_RANGE(adapter, offset);
1412 return NETXEN_CRB_NORMALIZE(adapter, offset); 1363 else
1364 addr = NETXEN_CRB_NORMALIZE(adapter, offset);
1365 } else {
1366 WARN_ON(netxen_nic_pci_get_crb_addr_2M(adapter,
1367 offset, &addr));
1413 } 1368 }
1414 1369
1415 BUG_ON(netxen_nic_pci_get_crb_addr_2M(adapter, &off)); 1370 return addr;
1416 return (void __iomem *)off;
1417} 1371}
1418 1372
1419static unsigned long 1373static int
1420netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, 1374netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
1421 unsigned long long addr) 1375 u64 addr, u32 *start)
1422{ 1376{
1423 int window; 1377 if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
1424 u32 win_read; 1378 *start = (addr - NETXEN_ADDR_OCM0 + NETXEN_PCI_OCM0);
1425 1379 return 0;
1426 if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1427 /* DDR network side */
1428 window = MN_WIN(addr);
1429 adapter->ahw.ddr_mn_window = window;
1430 NXWR32(adapter, adapter->ahw.mn_win_crb, window);
1431 win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
1432 if ((win_read << 17) != window) {
1433 printk(KERN_INFO "Written MNwin (0x%x) != "
1434 "Read MNwin (0x%x)\n", window, win_read);
1435 }
1436 addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_DDR_NET;
1437 } else if (ADDR_IN_RANGE(addr, 1380 } else if (ADDR_IN_RANGE(addr,
1438 NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { 1381 NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
1439 if ((addr & 0x00ff800) == 0xff800) { 1382 *start = (addr - NETXEN_ADDR_OCM1 + NETXEN_PCI_OCM1);
1440 printk("%s: QM access not handled.\n", __func__); 1383 return 0;
1441 addr = -1UL; 1384 }
1442 } 1385
1386 return -EIO;
1387}
1443 1388
1389static int
1390netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
1391 u64 addr, u32 *start)
1392{
1393 u32 window;
1394 struct pci_dev *pdev = adapter->pdev;
1395
1396 if ((addr & 0x00ff800) == 0xff800) {
1397 if (printk_ratelimit())
1398 dev_warn(&pdev->dev, "QM access not handled\n");
1399 return -EIO;
1400 }
1401
1402 if (NX_IS_REVISION_P3P(adapter->ahw.revision_id))
1403 window = OCM_WIN_P3P(addr);
1404 else
1444 window = OCM_WIN(addr); 1405 window = OCM_WIN(addr);
1445 adapter->ahw.ddr_mn_window = window;
1446 NXWR32(adapter, adapter->ahw.mn_win_crb, window);
1447 win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
1448 if ((win_read >> 7) != window) {
1449 printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
1450 "Read OCMwin (0x%x)\n",
1451 __func__, window, win_read);
1452 }
1453 addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_OCM0_2M;
1454 1406
1455 } else if (ADDR_IN_RANGE(addr, 1407 writel(window, adapter->ahw.ocm_win_crb);
1456 NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX_P3)) { 1408 /* read back to flush */
1457 /* QDR network side */ 1409 readl(adapter->ahw.ocm_win_crb);
1458 window = MS_WIN(addr);
1459 adapter->ahw.qdr_sn_window = window;
1460 NXWR32(adapter, adapter->ahw.ms_win_crb, window);
1461 win_read = NXRD32(adapter, adapter->ahw.ms_win_crb);
1462 if (win_read != window) {
1463 printk(KERN_INFO "%s: Written MSwin (0x%x) != "
1464 "Read MSwin (0x%x)\n",
1465 __func__, window, win_read);
1466 }
1467 addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_QDR_NET;
1468 1410
1469 } else { 1411 adapter->ahw.ocm_win = window;
1470 /* 1412 *start = NETXEN_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr);
1471 * peg gdb frequently accesses memory that doesn't exist, 1413 return 0;
1472 * this limits the chit chat so debugging isn't slowed down.
1473 */
1474 if ((netxen_pci_set_window_warning_count++ < 8)
1475 || (netxen_pci_set_window_warning_count%64 == 0)) {
1476 printk("%s: Warning:%s Unknown address range!\n",
1477 __func__, netxen_nic_driver_name);
1478} 1414}
1479 addr = -1UL; 1415
1416static int
1417netxen_nic_pci_mem_access_direct(struct netxen_adapter *adapter, u64 off,
1418 u64 *data, int op)
1419{
1420 void __iomem *addr, *mem_ptr = NULL;
1421 resource_size_t mem_base;
1422 int ret = -EIO;
1423 u32 start;
1424
1425 spin_lock(&adapter->ahw.mem_lock);
1426
1427 ret = adapter->pci_set_window(adapter, off, &start);
1428 if (ret != 0)
1429 goto unlock;
1430
1431 addr = pci_base_offset(adapter, start);
1432 if (addr)
1433 goto noremap;
1434
1435 mem_base = pci_resource_start(adapter->pdev, 0) + (start & PAGE_MASK);
1436
1437 mem_ptr = ioremap(mem_base, PAGE_SIZE);
1438 if (mem_ptr == NULL) {
1439 ret = -EIO;
1440 goto unlock;
1480 } 1441 }
1481 return addr; 1442
1443 addr = mem_ptr + (start & (PAGE_SIZE - 1));
1444
1445noremap:
1446 if (op == 0) /* read */
1447 *data = readq(addr);
1448 else /* write */
1449 writeq(*data, addr);
1450
1451unlock:
1452 spin_unlock(&adapter->ahw.mem_lock);
1453
1454 if (mem_ptr)
1455 iounmap(mem_ptr);
1456 return ret;
1482} 1457}
1483 1458
1484#define MAX_CTL_CHECK 1000 1459#define MAX_CTL_CHECK 1000
1485 1460
1486static int 1461static int
1487netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter, 1462netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
1488 u64 off, void *data, int size) 1463 u64 off, u64 data)
1489{ 1464{
1490 unsigned long flags; 1465 int j, ret;
1491 int i, j, ret = 0, loop, sz[2], off0; 1466 u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo;
1492 uint32_t temp;
1493 uint64_t off8, tmpw, word[2] = {0, 0};
1494 void __iomem *mem_crb; 1467 void __iomem *mem_crb;
1495 1468
1496 if (size != 8) 1469 /* Only 64-bit aligned access */
1470 if (off & 7)
1497 return -EIO; 1471 return -EIO;
1498 1472
1473 /* P2 has different SIU and MIU test agent base addr */
1499 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, 1474 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
1500 NETXEN_ADDR_QDR_NET_MAX_P2)) { 1475 NETXEN_ADDR_QDR_NET_MAX_P2)) {
1501 mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET); 1476 mem_crb = pci_base_offset(adapter,
1477 NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE);
1478 addr_hi = SIU_TEST_AGT_ADDR_HI;
1479 data_lo = SIU_TEST_AGT_WRDATA_LO;
1480 data_hi = SIU_TEST_AGT_WRDATA_HI;
1481 off_lo = off & SIU_TEST_AGT_ADDR_MASK;
1482 off_hi = SIU_TEST_AGT_UPPER_ADDR(off);
1502 goto correct; 1483 goto correct;
1503 } 1484 }
1504 1485
1505 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { 1486 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1506 mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET); 1487 mem_crb = pci_base_offset(adapter,
1488 NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
1489 addr_hi = MIU_TEST_AGT_ADDR_HI;
1490 data_lo = MIU_TEST_AGT_WRDATA_LO;
1491 data_hi = MIU_TEST_AGT_WRDATA_HI;
1492 off_lo = off & MIU_TEST_AGT_ADDR_MASK;
1493 off_hi = 0;
1507 goto correct; 1494 goto correct;
1508 } 1495 }
1509 1496
1510 return -EIO; 1497 if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) ||
1511 1498 ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
1512correct: 1499 if (adapter->ahw.pci_len0 != 0) {
1513 off8 = off & 0xfffffff8; 1500 return netxen_nic_pci_mem_access_direct(adapter,
1514 off0 = off & 0x7; 1501 off, &data, 1);
1515 sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1516 sz[1] = size - sz[0];
1517 loop = ((off0 + size - 1) >> 3) + 1;
1518
1519 if ((size != 8) || (off0 != 0)) {
1520 for (i = 0; i < loop; i++) {
1521 if (adapter->pci_mem_read(adapter,
1522 off8 + (i << 3), &word[i], 8))
1523 return -1;
1524 } 1502 }
1525 } 1503 }
1526 1504
1527 switch (size) { 1505 return -EIO;
1528 case 1:
1529 tmpw = *((uint8_t *)data);
1530 break;
1531 case 2:
1532 tmpw = *((uint16_t *)data);
1533 break;
1534 case 4:
1535 tmpw = *((uint32_t *)data);
1536 break;
1537 case 8:
1538 default:
1539 tmpw = *((uint64_t *)data);
1540 break;
1541 }
1542 word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8));
1543 word[0] |= tmpw << (off0 * 8);
1544 1506
1545 if (loop == 2) { 1507correct:
1546 word[1] &= ~(~0ULL << (sz[1] * 8)); 1508 spin_lock(&adapter->ahw.mem_lock);
1547 word[1] |= tmpw >> (sz[0] * 8); 1509 netxen_nic_pci_set_crbwindow_128M(adapter, 0);
1510
1511 writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO));
1512 writel(off_hi, (mem_crb + addr_hi));
1513 writel(data & 0xffffffff, (mem_crb + data_lo));
1514 writel((data >> 32) & 0xffffffff, (mem_crb + data_hi));
1515 writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
1516 writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
1517 (mem_crb + TEST_AGT_CTRL));
1518
1519 for (j = 0; j < MAX_CTL_CHECK; j++) {
1520 temp = readl((mem_crb + TEST_AGT_CTRL));
1521 if ((temp & TA_CTL_BUSY) == 0)
1522 break;
1548 } 1523 }
1549 1524
1550 write_lock_irqsave(&adapter->adapter_lock, flags); 1525 if (j >= MAX_CTL_CHECK) {
1551 netxen_nic_pci_change_crbwindow_128M(adapter, 0); 1526 if (printk_ratelimit())
1552 1527 dev_err(&adapter->pdev->dev,
1553 for (i = 0; i < loop; i++) {
1554 writel((uint32_t)(off8 + (i << 3)),
1555 (mem_crb+MIU_TEST_AGT_ADDR_LO));
1556 writel(0,
1557 (mem_crb+MIU_TEST_AGT_ADDR_HI));
1558 writel(word[i] & 0xffffffff,
1559 (mem_crb+MIU_TEST_AGT_WRDATA_LO));
1560 writel((word[i] >> 32) & 0xffffffff,
1561 (mem_crb+MIU_TEST_AGT_WRDATA_HI));
1562 writel(MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
1563 (mem_crb+MIU_TEST_AGT_CTRL));
1564 writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE|MIU_TA_CTL_WRITE,
1565 (mem_crb+MIU_TEST_AGT_CTRL));
1566
1567 for (j = 0; j < MAX_CTL_CHECK; j++) {
1568 temp = readl(
1569 (mem_crb+MIU_TEST_AGT_CTRL));
1570 if ((temp & MIU_TA_CTL_BUSY) == 0)
1571 break;
1572 }
1573
1574 if (j >= MAX_CTL_CHECK) {
1575 if (printk_ratelimit())
1576 dev_err(&adapter->pdev->dev,
1577 "failed to write through agent\n"); 1528 "failed to write through agent\n");
1578 ret = -1; 1529 ret = -EIO;
1579 break; 1530 } else
1580 } 1531 ret = 0;
1581 }
1582 1532
1583 netxen_nic_pci_change_crbwindow_128M(adapter, 1); 1533 netxen_nic_pci_set_crbwindow_128M(adapter, NETXEN_WINDOW_ONE);
1584 write_unlock_irqrestore(&adapter->adapter_lock, flags); 1534 spin_unlock(&adapter->ahw.mem_lock);
1585 return ret; 1535 return ret;
1586} 1536}
1587 1537
1588static int 1538static int
1589netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter, 1539netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
1590 u64 off, void *data, int size) 1540 u64 off, u64 *data)
1591{ 1541{
1592 unsigned long flags; 1542 int j, ret;
1593 int i, j = 0, k, start, end, loop, sz[2], off0[2]; 1543 u32 temp, off_lo, off_hi, addr_hi, data_hi, data_lo;
1594 uint32_t temp; 1544 u64 val;
1595 uint64_t off8, val, word[2] = {0, 0};
1596 void __iomem *mem_crb; 1545 void __iomem *mem_crb;
1597 1546
1598 if (size != 8) 1547 /* Only 64-bit aligned access */
1548 if (off & 7)
1599 return -EIO; 1549 return -EIO;
1600 1550
1551 /* P2 has different SIU and MIU test agent base addr */
1601 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, 1552 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
1602 NETXEN_ADDR_QDR_NET_MAX_P2)) { 1553 NETXEN_ADDR_QDR_NET_MAX_P2)) {
1603 mem_crb = pci_base_offset(adapter, NETXEN_CRB_QDR_NET); 1554 mem_crb = pci_base_offset(adapter,
1555 NETXEN_CRB_QDR_NET+SIU_TEST_AGT_BASE);
1556 addr_hi = SIU_TEST_AGT_ADDR_HI;
1557 data_lo = SIU_TEST_AGT_RDDATA_LO;
1558 data_hi = SIU_TEST_AGT_RDDATA_HI;
1559 off_lo = off & SIU_TEST_AGT_ADDR_MASK;
1560 off_hi = SIU_TEST_AGT_UPPER_ADDR(off);
1604 goto correct; 1561 goto correct;
1605 } 1562 }
1606 1563
1607 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { 1564 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1608 mem_crb = pci_base_offset(adapter, NETXEN_CRB_DDR_NET); 1565 mem_crb = pci_base_offset(adapter,
1566 NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
1567 addr_hi = MIU_TEST_AGT_ADDR_HI;
1568 data_lo = MIU_TEST_AGT_RDDATA_LO;
1569 data_hi = MIU_TEST_AGT_RDDATA_HI;
1570 off_lo = off & MIU_TEST_AGT_ADDR_MASK;
1571 off_hi = 0;
1609 goto correct; 1572 goto correct;
1610 } 1573 }
1611 1574
1575 if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) ||
1576 ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
1577 if (adapter->ahw.pci_len0 != 0) {
1578 return netxen_nic_pci_mem_access_direct(adapter,
1579 off, data, 0);
1580 }
1581 }
1582
1612 return -EIO; 1583 return -EIO;
1613 1584
1614correct: 1585correct:
1615 off8 = off & 0xfffffff8; 1586 spin_lock(&adapter->ahw.mem_lock);
1616 off0[0] = off & 0x7; 1587 netxen_nic_pci_set_crbwindow_128M(adapter, 0);
1617 off0[1] = 0;
1618 sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1619 sz[1] = size - sz[0];
1620 loop = ((off0[0] + size - 1) >> 3) + 1;
1621
1622 write_lock_irqsave(&adapter->adapter_lock, flags);
1623 netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1624
1625 for (i = 0; i < loop; i++) {
1626 writel((uint32_t)(off8 + (i << 3)),
1627 (mem_crb+MIU_TEST_AGT_ADDR_LO));
1628 writel(0,
1629 (mem_crb+MIU_TEST_AGT_ADDR_HI));
1630 writel(MIU_TA_CTL_ENABLE,
1631 (mem_crb+MIU_TEST_AGT_CTRL));
1632 writel(MIU_TA_CTL_START|MIU_TA_CTL_ENABLE,
1633 (mem_crb+MIU_TEST_AGT_CTRL));
1634 1588
1635 for (j = 0; j < MAX_CTL_CHECK; j++) { 1589 writel(off_lo, (mem_crb + MIU_TEST_AGT_ADDR_LO));
1636 temp = readl( 1590 writel(off_hi, (mem_crb + addr_hi));
1637 (mem_crb+MIU_TEST_AGT_CTRL)); 1591 writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
1638 if ((temp & MIU_TA_CTL_BUSY) == 0) 1592 writel((TA_CTL_START|TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL));
1639 break;
1640 }
1641 1593
1642 if (j >= MAX_CTL_CHECK) { 1594 for (j = 0; j < MAX_CTL_CHECK; j++) {
1643 if (printk_ratelimit()) 1595 temp = readl(mem_crb + TEST_AGT_CTRL);
1644 dev_err(&adapter->pdev->dev, 1596 if ((temp & TA_CTL_BUSY) == 0)
1645 "failed to read through agent\n");
1646 break; 1597 break;
1647 }
1648
1649 start = off0[i] >> 2;
1650 end = (off0[i] + sz[i] - 1) >> 2;
1651 for (k = start; k <= end; k++) {
1652 word[i] |= ((uint64_t) readl(
1653 (mem_crb +
1654 MIU_TEST_AGT_RDDATA(k))) << (32*k));
1655 }
1656 } 1598 }
1657 1599
1658 netxen_nic_pci_change_crbwindow_128M(adapter, 1); 1600 if (j >= MAX_CTL_CHECK) {
1659 write_unlock_irqrestore(&adapter->adapter_lock, flags); 1601 if (printk_ratelimit())
1660 1602 dev_err(&adapter->pdev->dev,
1661 if (j >= MAX_CTL_CHECK) 1603 "failed to read through agent\n");
1662 return -1; 1604 ret = -EIO;
1663
1664 if (sz[0] == 8) {
1665 val = word[0];
1666 } else { 1605 } else {
1667 val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) |
1668 ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8));
1669 }
1670 1606
1671 switch (size) { 1607 temp = readl(mem_crb + data_hi);
1672 case 1: 1608 val = ((u64)temp << 32);
1673 *(uint8_t *)data = val; 1609 val |= readl(mem_crb + data_lo);
1674 break; 1610 *data = val;
1675 case 2: 1611 ret = 0;
1676 *(uint16_t *)data = val;
1677 break;
1678 case 4:
1679 *(uint32_t *)data = val;
1680 break;
1681 case 8:
1682 *(uint64_t *)data = val;
1683 break;
1684 } 1612 }
1685 return 0; 1613
1614 netxen_nic_pci_set_crbwindow_128M(adapter, NETXEN_WINDOW_ONE);
1615 spin_unlock(&adapter->ahw.mem_lock);
1616
1617 return ret;
1686} 1618}
1687 1619
1688static int 1620static int
1689netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, 1621netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
1690 u64 off, void *data, int size) 1622 u64 off, u64 data)
1691{ 1623{
1692 int i, j, ret = 0, loop, sz[2], off0; 1624 int i, j, ret;
1693 uint32_t temp; 1625 u32 temp, off8;
1694 uint64_t off8, tmpw, word[2] = {0, 0}; 1626 u64 stride;
1695 void __iomem *mem_crb; 1627 void __iomem *mem_crb;
1696 1628
1697 if (size != 8) 1629 /* Only 64-bit aligned access */
1630 if (off & 7)
1698 return -EIO; 1631 return -EIO;
1699 1632
1633 /* P3 onward, test agent base for MIU and SIU is same */
1700 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, 1634 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
1701 NETXEN_ADDR_QDR_NET_MAX_P3)) { 1635 NETXEN_ADDR_QDR_NET_MAX_P3)) {
1702 mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET); 1636 mem_crb = netxen_get_ioaddr(adapter,
1637 NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE);
1703 goto correct; 1638 goto correct;
1704 } 1639 }
1705 1640
1706 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { 1641 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1707 mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET); 1642 mem_crb = netxen_get_ioaddr(adapter,
1643 NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
1708 goto correct; 1644 goto correct;
1709 } 1645 }
1710 1646
1647 if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX))
1648 return netxen_nic_pci_mem_access_direct(adapter, off, &data, 1);
1649
1711 return -EIO; 1650 return -EIO;
1712 1651
1713correct: 1652correct:
1714 off8 = off & 0xfffffff8; 1653 stride = NX_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8;
1715 off0 = off & 0x7;
1716 sz[0] = (size < (8 - off0)) ? size : (8 - off0);
1717 sz[1] = size - sz[0];
1718 loop = ((off0 + size - 1) >> 3) + 1;
1719
1720 if ((size != 8) || (off0 != 0)) {
1721 for (i = 0; i < loop; i++) {
1722 if (adapter->pci_mem_read(adapter,
1723 off8 + (i << 3), &word[i], 8))
1724 return -1;
1725 }
1726 }
1727 1654
1728 switch (size) { 1655 off8 = off & ~(stride-1);
1729 case 1:
1730 tmpw = *((uint8_t *)data);
1731 break;
1732 case 2:
1733 tmpw = *((uint16_t *)data);
1734 break;
1735 case 4:
1736 tmpw = *((uint32_t *)data);
1737 break;
1738 case 8:
1739 default:
1740 tmpw = *((uint64_t *)data);
1741 break;
1742 }
1743 1656
1744 word[0] &= ~((~(~0ULL << (sz[0] * 8))) << (off0 * 8)); 1657 spin_lock(&adapter->ahw.mem_lock);
1745 word[0] |= tmpw << (off0 * 8);
1746 1658
1747 if (loop == 2) { 1659 writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
1748 word[1] &= ~(~0ULL << (sz[1] * 8)); 1660 writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
1749 word[1] |= tmpw >> (sz[0] * 8);
1750 }
1751
1752 /*
1753 * don't lock here - write_wx gets the lock if each time
1754 * write_lock_irqsave(&adapter->adapter_lock, flags);
1755 * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1756 */
1757 1661
1758 for (i = 0; i < loop; i++) { 1662 i = 0;
1759 writel(off8 + (i << 3), mem_crb+MIU_TEST_AGT_ADDR_LO); 1663 if (stride == 16) {
1760 writel(0, mem_crb+MIU_TEST_AGT_ADDR_HI); 1664 writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
1761 writel(word[i] & 0xffffffff, mem_crb+MIU_TEST_AGT_WRDATA_LO); 1665 writel((TA_CTL_START | TA_CTL_ENABLE),
1762 writel((word[i] >> 32) & 0xffffffff, 1666 (mem_crb + TEST_AGT_CTRL));
1763 mem_crb+MIU_TEST_AGT_WRDATA_HI);
1764 writel((MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE),
1765 mem_crb+MIU_TEST_AGT_CTRL);
1766 writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE | MIU_TA_CTL_WRITE,
1767 mem_crb+MIU_TEST_AGT_CTRL);
1768 1667
1769 for (j = 0; j < MAX_CTL_CHECK; j++) { 1668 for (j = 0; j < MAX_CTL_CHECK; j++) {
1770 temp = readl(mem_crb + MIU_TEST_AGT_CTRL); 1669 temp = readl(mem_crb + TEST_AGT_CTRL);
1771 if ((temp & MIU_TA_CTL_BUSY) == 0) 1670 if ((temp & TA_CTL_BUSY) == 0)
1772 break; 1671 break;
1773 } 1672 }
1774 1673
1775 if (j >= MAX_CTL_CHECK) { 1674 if (j >= MAX_CTL_CHECK) {
1776 if (printk_ratelimit()) 1675 ret = -EIO;
1777 dev_err(&adapter->pdev->dev, 1676 goto done;
1778 "failed to write through agent\n");
1779 ret = -1;
1780 break;
1781 } 1677 }
1678
1679 i = (off & 0xf) ? 0 : 2;
1680 writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i)),
1681 mem_crb + MIU_TEST_AGT_WRDATA(i));
1682 writel(readl(mem_crb + MIU_TEST_AGT_RDDATA(i+1)),
1683 mem_crb + MIU_TEST_AGT_WRDATA(i+1));
1684 i = (off & 0xf) ? 2 : 0;
1782 } 1685 }
1783 1686
1784 /* 1687 writel(data & 0xffffffff,
1785 * netxen_nic_pci_change_crbwindow_128M(adapter, 1); 1688 mem_crb + MIU_TEST_AGT_WRDATA(i));
1786 * write_unlock_irqrestore(&adapter->adapter_lock, flags); 1689 writel((data >> 32) & 0xffffffff,
1787 */ 1690 mem_crb + MIU_TEST_AGT_WRDATA(i+1));
1691
1692 writel((TA_CTL_ENABLE | TA_CTL_WRITE), (mem_crb + TEST_AGT_CTRL));
1693 writel((TA_CTL_START | TA_CTL_ENABLE | TA_CTL_WRITE),
1694 (mem_crb + TEST_AGT_CTRL));
1695
1696 for (j = 0; j < MAX_CTL_CHECK; j++) {
1697 temp = readl(mem_crb + TEST_AGT_CTRL);
1698 if ((temp & TA_CTL_BUSY) == 0)
1699 break;
1700 }
1701
1702 if (j >= MAX_CTL_CHECK) {
1703 if (printk_ratelimit())
1704 dev_err(&adapter->pdev->dev,
1705 "failed to write through agent\n");
1706 ret = -EIO;
1707 } else
1708 ret = 0;
1709
1710done:
1711 spin_unlock(&adapter->ahw.mem_lock);
1712
1788 return ret; 1713 return ret;
1789} 1714}
1790 1715
1791static int 1716static int
1792netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, 1717netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
1793 u64 off, void *data, int size) 1718 u64 off, u64 *data)
1794{ 1719{
1795 int i, j = 0, k, start, end, loop, sz[2], off0[2]; 1720 int j, ret;
1796 uint32_t temp; 1721 u32 temp, off8;
1797 uint64_t off8, val, word[2] = {0, 0}; 1722 u64 val, stride;
1798 void __iomem *mem_crb; 1723 void __iomem *mem_crb;
1799 1724
1800 if (size != 8) 1725 /* Only 64-bit aligned access */
1726 if (off & 7)
1801 return -EIO; 1727 return -EIO;
1802 1728
1729 /* P3 onward, test agent base for MIU and SIU is same */
1803 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET, 1730 if (ADDR_IN_RANGE(off, NETXEN_ADDR_QDR_NET,
1804 NETXEN_ADDR_QDR_NET_MAX_P3)) { 1731 NETXEN_ADDR_QDR_NET_MAX_P3)) {
1805 mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_QDR_NET); 1732 mem_crb = netxen_get_ioaddr(adapter,
1733 NETXEN_CRB_QDR_NET+MIU_TEST_AGT_BASE);
1806 goto correct; 1734 goto correct;
1807 } 1735 }
1808 1736
1809 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) { 1737 if (ADDR_IN_RANGE(off, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1810 mem_crb = netxen_get_ioaddr(adapter, NETXEN_CRB_DDR_NET); 1738 mem_crb = netxen_get_ioaddr(adapter,
1739 NETXEN_CRB_DDR_NET+MIU_TEST_AGT_BASE);
1811 goto correct; 1740 goto correct;
1812 } 1741 }
1813 1742
1743 if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
1744 return netxen_nic_pci_mem_access_direct(adapter,
1745 off, data, 0);
1746 }
1747
1814 return -EIO; 1748 return -EIO;
1815 1749
1816correct: 1750correct:
1817 off8 = off & 0xfffffff8; 1751 stride = NX_IS_REVISION_P3P(adapter->ahw.revision_id) ? 16 : 8;
1818 off0[0] = off & 0x7;
1819 off0[1] = 0;
1820 sz[0] = (size < (8 - off0[0])) ? size : (8 - off0[0]);
1821 sz[1] = size - sz[0];
1822 loop = ((off0[0] + size - 1) >> 3) + 1;
1823 1752
1824 /* 1753 off8 = off & ~(stride-1);
1825 * don't lock here - write_wx gets the lock if each time
1826 * write_lock_irqsave(&adapter->adapter_lock, flags);
1827 * netxen_nic_pci_change_crbwindow_128M(adapter, 0);
1828 */
1829 1754
1830 for (i = 0; i < loop; i++) { 1755 spin_lock(&adapter->ahw.mem_lock);
1831 writel(off8 + (i << 3), mem_crb + MIU_TEST_AGT_ADDR_LO);
1832 writel(0, mem_crb + MIU_TEST_AGT_ADDR_HI);
1833 writel(MIU_TA_CTL_ENABLE, mem_crb + MIU_TEST_AGT_CTRL);
1834 writel(MIU_TA_CTL_START | MIU_TA_CTL_ENABLE,
1835 mem_crb + MIU_TEST_AGT_CTRL);
1836 1756
1837 for (j = 0; j < MAX_CTL_CHECK; j++) { 1757 writel(off8, (mem_crb + MIU_TEST_AGT_ADDR_LO));
1838 temp = readl(mem_crb + MIU_TEST_AGT_CTRL); 1758 writel(0, (mem_crb + MIU_TEST_AGT_ADDR_HI));
1839 if ((temp & MIU_TA_CTL_BUSY) == 0) 1759 writel(TA_CTL_ENABLE, (mem_crb + TEST_AGT_CTRL));
1840 break; 1760 writel((TA_CTL_START | TA_CTL_ENABLE), (mem_crb + TEST_AGT_CTRL));
1841 }
1842 1761
1843 if (j >= MAX_CTL_CHECK) { 1762 for (j = 0; j < MAX_CTL_CHECK; j++) {
1844 if (printk_ratelimit()) 1763 temp = readl(mem_crb + TEST_AGT_CTRL);
1845 dev_err(&adapter->pdev->dev, 1764 if ((temp & TA_CTL_BUSY) == 0)
1846 "failed to read through agent\n");
1847 break; 1765 break;
1848 }
1849
1850 start = off0[i] >> 2;
1851 end = (off0[i] + sz[i] - 1) >> 2;
1852 for (k = start; k <= end; k++) {
1853 temp = readl(mem_crb + MIU_TEST_AGT_RDDATA(k));
1854 word[i] |= ((uint64_t)temp << (32 * k));
1855 }
1856 } 1766 }
1857 1767
1858 /* 1768 if (j >= MAX_CTL_CHECK) {
1859 * netxen_nic_pci_change_crbwindow_128M(adapter, 1); 1769 if (printk_ratelimit())
1860 * write_unlock_irqrestore(&adapter->adapter_lock, flags); 1770 dev_err(&adapter->pdev->dev,
1861 */ 1771 "failed to read through agent\n");
1862 1772 ret = -EIO;
1863 if (j >= MAX_CTL_CHECK)
1864 return -1;
1865
1866 if (sz[0] == 8) {
1867 val = word[0];
1868 } else { 1773 } else {
1869 val = ((word[0] >> (off0[0] * 8)) & (~(~0ULL << (sz[0] * 8)))) | 1774 off8 = MIU_TEST_AGT_RDDATA_LO;
1870 ((word[1] & (~(~0ULL << (sz[1] * 8)))) << (sz[0] * 8)); 1775 if ((stride == 16) && (off & 0xf))
1871 } 1776 off8 = MIU_TEST_AGT_RDDATA_UPPER_LO;
1872 1777
1873 switch (size) { 1778 temp = readl(mem_crb + off8 + 4);
1874 case 1: 1779 val = (u64)temp << 32;
1875 *(uint8_t *)data = val; 1780 val |= readl(mem_crb + off8);
1876 break; 1781 *data = val;
1877 case 2: 1782 ret = 0;
1878 *(uint16_t *)data = val;
1879 break;
1880 case 4:
1881 *(uint32_t *)data = val;
1882 break;
1883 case 8:
1884 *(uint64_t *)data = val;
1885 break;
1886 } 1783 }
1887 return 0; 1784
1785 spin_unlock(&adapter->ahw.mem_lock);
1786
1787 return ret;
1888} 1788}
1889 1789
1890void 1790void
@@ -2037,10 +1937,10 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
2037 return; 1937 return;
2038 } 1938 }
2039 1939
2040 if (adapter->phy_read 1940 if (adapter->phy_read &&
2041 && adapter->phy_read(adapter, 1941 adapter->phy_read(adapter,
2042 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, 1942 NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
2043 &status) == 0) { 1943 &status) == 0) {
2044 if (netxen_get_phy_link(status)) { 1944 if (netxen_get_phy_link(status)) {
2045 switch (netxen_get_phy_speed(status)) { 1945 switch (netxen_get_phy_speed(status)) {
2046 case 0: 1946 case 0:
@@ -2067,10 +1967,10 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
2067 adapter->link_duplex = -1; 1967 adapter->link_duplex = -1;
2068 break; 1968 break;
2069 } 1969 }
2070 if (adapter->phy_read 1970 if (adapter->phy_read &&
2071 && adapter->phy_read(adapter, 1971 adapter->phy_read(adapter,
2072 NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG, 1972 NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
2073 &autoneg) != 0) 1973 &autoneg) != 0)
2074 adapter->link_autoneg = autoneg; 1974 adapter->link_autoneg = autoneg;
2075 } else 1975 } else
2076 goto link_down; 1976 goto link_down;