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.c221
1 files changed, 99 insertions, 122 deletions
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 5f4bdda53d44..f677752dbe22 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -1274,72 +1274,6 @@ netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, ulong off)
1274 return data; 1274 return data;
1275} 1275}
1276 1276
1277static int netxen_pci_set_window_warning_count;
1278
1279static unsigned long
1280netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
1281 unsigned long long addr)
1282{
1283 void __iomem *offset;
1284 int window;
1285 unsigned long long qdr_max;
1286 uint8_t func = adapter->ahw.pci_func;
1287
1288 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1289 qdr_max = NETXEN_ADDR_QDR_NET_MAX_P2;
1290 } else {
1291 qdr_max = NETXEN_ADDR_QDR_NET_MAX_P3;
1292 }
1293
1294 if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1295 /* DDR network side */
1296 addr -= NETXEN_ADDR_DDR_NET;
1297 window = (addr >> 25) & 0x3ff;
1298 if (adapter->ahw.ddr_mn_window != window) {
1299 adapter->ahw.ddr_mn_window = window;
1300 offset = PCI_OFFSET_SECOND_RANGE(adapter,
1301 NETXEN_PCIX_PH_REG(PCIE_MN_WINDOW_REG(func)));
1302 writel(window, offset);
1303 /* MUST make sure window is set before we forge on... */
1304 readl(offset);
1305 }
1306 addr -= (window * NETXEN_WINDOW_ONE);
1307 addr += NETXEN_PCI_DDR_NET;
1308 } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
1309 addr -= NETXEN_ADDR_OCM0;
1310 addr += NETXEN_PCI_OCM0;
1311 } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
1312 addr -= NETXEN_ADDR_OCM1;
1313 addr += NETXEN_PCI_OCM1;
1314 } else if (ADDR_IN_RANGE(addr, NETXEN_ADDR_QDR_NET, qdr_max)) {
1315 /* QDR network side */
1316 addr -= NETXEN_ADDR_QDR_NET;
1317 window = (addr >> 22) & 0x3f;
1318 if (adapter->ahw.qdr_sn_window != window) {
1319 adapter->ahw.qdr_sn_window = window;
1320 offset = PCI_OFFSET_SECOND_RANGE(adapter,
1321 NETXEN_PCIX_PH_REG(PCIE_SN_WINDOW_REG(func)));
1322 writel((window << 22), offset);
1323 /* MUST make sure window is set before we forge on... */
1324 readl(offset);
1325 }
1326 addr -= (window * 0x400000);
1327 addr += NETXEN_PCI_QDR_NET;
1328 } else {
1329 /*
1330 * peg gdb frequently accesses memory that doesn't exist,
1331 * this limits the chit chat so debugging isn't slowed down.
1332 */
1333 if ((netxen_pci_set_window_warning_count++ < 8)
1334 || (netxen_pci_set_window_warning_count % 64 == 0))
1335 printk("%s: Warning:netxen_nic_pci_set_window()"
1336 " Unknown address range!\n",
1337 netxen_nic_driver_name);
1338 addr = -1UL;
1339 }
1340 return addr;
1341}
1342
1343/* window 1 registers only */ 1277/* window 1 registers only */
1344static void netxen_nic_io_write_128M(struct netxen_adapter *adapter, 1278static void netxen_nic_io_write_128M(struct netxen_adapter *adapter,
1345 void __iomem *addr, u32 data) 1279 void __iomem *addr, u32 data)
@@ -1389,69 +1323,90 @@ netxen_get_ioaddr(struct netxen_adapter *adapter, u32 offset)
1389 return (void __iomem *)off; 1323 return (void __iomem *)off;
1390} 1324}
1391 1325
1392static unsigned long 1326static int
1393netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, 1327netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter,
1394 unsigned long long addr) 1328 u64 addr, u32 *start)
1395{ 1329{
1396 int window; 1330 if (ADDR_IN_RANGE(addr, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) {
1397 u32 win_read; 1331 *start = (addr - NETXEN_ADDR_OCM0 + NETXEN_PCI_OCM0);
1398 1332 return 0;
1399 if (ADDR_IN_RANGE(addr, NETXEN_ADDR_DDR_NET, NETXEN_ADDR_DDR_NET_MAX)) {
1400 /* DDR network side */
1401 window = MN_WIN(addr);
1402 adapter->ahw.ddr_mn_window = window;
1403 NXWR32(adapter, adapter->ahw.mn_win_crb, window);
1404 win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
1405 if ((win_read << 17) != window) {
1406 printk(KERN_INFO "Written MNwin (0x%x) != "
1407 "Read MNwin (0x%x)\n", window, win_read);
1408 }
1409 addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_DDR_NET;
1410 } else if (ADDR_IN_RANGE(addr, 1333 } else if (ADDR_IN_RANGE(addr,
1411 NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX)) { 1334 NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
1412 if ((addr & 0x00ff800) == 0xff800) { 1335 *start = (addr - NETXEN_ADDR_OCM1 + NETXEN_PCI_OCM1);
1413 printk("%s: QM access not handled.\n", __func__); 1336 return 0;
1414 addr = -1UL; 1337 }
1415 }
1416 1338
1417 window = OCM_WIN(addr); 1339 return -EIO;
1418 adapter->ahw.ddr_mn_window = window; 1340}
1419 NXWR32(adapter, adapter->ahw.mn_win_crb, window);
1420 win_read = NXRD32(adapter, adapter->ahw.mn_win_crb);
1421 if ((win_read >> 7) != window) {
1422 printk(KERN_INFO "%s: Written OCMwin (0x%x) != "
1423 "Read OCMwin (0x%x)\n",
1424 __func__, window, win_read);
1425 }
1426 addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_OCM0_2M;
1427 1341
1428 } else if (ADDR_IN_RANGE(addr, 1342static int
1429 NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX_P3)) { 1343netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter,
1430 /* QDR network side */ 1344 u64 addr, u32 *start)
1431 window = MS_WIN(addr); 1345{
1432 adapter->ahw.qdr_sn_window = window; 1346 u32 win_read, window;
1433 NXWR32(adapter, adapter->ahw.ms_win_crb, window); 1347 struct pci_dev *pdev = adapter->pdev;
1434 win_read = NXRD32(adapter, adapter->ahw.ms_win_crb);
1435 if (win_read != window) {
1436 printk(KERN_INFO "%s: Written MSwin (0x%x) != "
1437 "Read MSwin (0x%x)\n",
1438 __func__, window, win_read);
1439 }
1440 addr = GET_MEM_OFFS_2M(addr) + NETXEN_PCI_QDR_NET;
1441 1348
1442 } else { 1349 if ((addr & 0x00ff800) == 0xff800) {
1443 /* 1350 if (printk_ratelimit())
1444 * peg gdb frequently accesses memory that doesn't exist, 1351 dev_warn(&pdev->dev, "QM access not handled\n");
1445 * this limits the chit chat so debugging isn't slowed down. 1352 return -EIO;
1446 */ 1353 }
1447 if ((netxen_pci_set_window_warning_count++ < 8) 1354
1448 || (netxen_pci_set_window_warning_count%64 == 0)) { 1355 window = OCM_WIN(addr);
1449 printk("%s: Warning:%s Unknown address range!\n", 1356 writel(window, adapter->ahw.ocm_win_crb);
1450 __func__, netxen_nic_driver_name); 1357 win_read = readl(adapter->ahw.ocm_win_crb);
1358 if ((win_read >> 7) != window) {
1359 if (printk_ratelimit())
1360 dev_warn(&pdev->dev, "failed to set OCM window\n");
1361 return -EIO;
1362 }
1363
1364 adapter->ahw.ocm_win = window;
1365 *start = NETXEN_PCI_OCM0_2M + GET_MEM_OFFS_2M(addr);
1366 return 0;
1451} 1367}
1452 addr = -1UL; 1368
1369static int
1370netxen_nic_pci_mem_access_direct(struct netxen_adapter *adapter, u64 off,
1371 u64 *data, int op)
1372{
1373 void __iomem *addr, *mem_ptr = NULL;
1374 resource_size_t mem_base;
1375 unsigned long flags;
1376 int ret = -EIO;
1377 u32 start;
1378
1379 write_lock_irqsave(&adapter->adapter_lock, flags);
1380
1381 ret = adapter->pci_set_window(adapter, off, &start);
1382 if (ret != 0)
1383 goto unlock;
1384
1385 addr = pci_base_offset(adapter, start);
1386 if (addr)
1387 goto noremap;
1388
1389 mem_base = pci_resource_start(adapter->pdev, 0) + (start & PAGE_MASK);
1390
1391 mem_ptr = ioremap(mem_base, PAGE_SIZE);
1392 if (mem_ptr == NULL) {
1393 ret = -EIO;
1394 goto unlock;
1453 } 1395 }
1454 return addr; 1396
1397 addr = mem_ptr + (start & (PAGE_SIZE - 1));
1398
1399noremap:
1400 if (op == 0) /* read */
1401 *data = readq(addr);
1402 else /* write */
1403 writeq(*data, addr);
1404
1405unlock:
1406 write_unlock_irqrestore(&adapter->adapter_lock, flags);
1407 if (mem_ptr)
1408 iounmap(mem_ptr);
1409 return ret;
1455} 1410}
1456 1411
1457#define MAX_CTL_CHECK 1000 1412#define MAX_CTL_CHECK 1000
@@ -1493,6 +1448,14 @@ netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter,
1493 goto correct; 1448 goto correct;
1494 } 1449 }
1495 1450
1451 if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) ||
1452 ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
1453 if (adapter->ahw.pci_len0 != 0) {
1454 return netxen_nic_pci_mem_access_direct(adapter,
1455 off, &data, 1);
1456 }
1457 }
1458
1496 return -EIO; 1459 return -EIO;
1497 1460
1498correct: 1461correct:
@@ -1564,6 +1527,14 @@ netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter,
1564 goto correct; 1527 goto correct;
1565 } 1528 }
1566 1529
1530 if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX) ||
1531 ADDR_IN_RANGE(off, NETXEN_ADDR_OCM1, NETXEN_ADDR_OCM1_MAX)) {
1532 if (adapter->ahw.pci_len0 != 0) {
1533 return netxen_nic_pci_mem_access_direct(adapter,
1534 off, data, 0);
1535 }
1536 }
1537
1567 return -EIO; 1538 return -EIO;
1568 1539
1569correct: 1540correct:
@@ -1628,6 +1599,9 @@ netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter,
1628 goto correct; 1599 goto correct;
1629 } 1600 }
1630 1601
1602 if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX))
1603 return netxen_nic_pci_mem_access_direct(adapter, off, &data, 1);
1604
1631 return -EIO; 1605 return -EIO;
1632 1606
1633correct: 1607correct:
@@ -1690,6 +1664,9 @@ netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter,
1690 goto correct; 1664 goto correct;
1691 } 1665 }
1692 1666
1667 if (ADDR_IN_RANGE(off, NETXEN_ADDR_OCM0, NETXEN_ADDR_OCM0_MAX))
1668 return netxen_nic_pci_mem_access_direct(adapter, off, data, 0);
1669
1693 return -EIO; 1670 return -EIO;
1694 1671
1695correct: 1672correct: