diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_hw.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 221 |
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 | ||
1277 | static int netxen_pci_set_window_warning_count; | ||
1278 | |||
1279 | static unsigned long | ||
1280 | netxen_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 */ |
1344 | static void netxen_nic_io_write_128M(struct netxen_adapter *adapter, | 1278 | static 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 | ||
1392 | static unsigned long | 1326 | static int |
1393 | netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, | 1327 | netxen_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, | 1342 | static int |
1429 | NETXEN_ADDR_QDR_NET, NETXEN_ADDR_QDR_NET_MAX_P3)) { | 1343 | netxen_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 | |
1369 | static int | ||
1370 | netxen_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 | |||
1399 | noremap: | ||
1400 | if (op == 0) /* read */ | ||
1401 | *data = readq(addr); | ||
1402 | else /* write */ | ||
1403 | writeq(*data, addr); | ||
1404 | |||
1405 | unlock: | ||
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 | ||
1498 | correct: | 1461 | correct: |
@@ -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 | ||
1569 | correct: | 1540 | correct: |
@@ -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 | ||
1633 | correct: | 1607 | correct: |
@@ -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 | ||
1695 | correct: | 1672 | correct: |