diff options
author | Dhananjay Phadke <dhananjay@netxen.com> | 2008-07-21 19:44:03 -0700 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-07-22 17:51:44 -0400 |
commit | 3ce06a320f8d5a3f16960e63021cc372283efffb (patch) | |
tree | cea5b02fc44b8c2367c57d7c249592683edffcc9 /drivers | |
parent | e4c93c817ce650401db42db6c869cf7688217ff4 (diff) |
netxen: add 2MB PCI memory support
New revision of netxen chip has 2MB PCI memory. Older chips
had 128MB addressable PCI memory. To retain compatibility,
this patch adds function pointers based on pci bar0 size.
Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 70 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_ethtool.c | 31 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.c | 1359 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_hw.h | 21 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_init.c | 54 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_isr.c | 4 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 138 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_niu.c | 87 |
8 files changed, 1492 insertions, 272 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index acc7d79457d..29ab2ce30d6 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -799,6 +799,12 @@ struct netxen_hardware_context { unsigned long first_page_group_start; void __iomem *db_base; unsigned long db_len; + unsigned long pci_len0; + + int qdr_sn_window; + int ddr_mn_window; + unsigned long mn_win_crb; + unsigned long ms_win_crb; u8 revision_id; u16 board_type; @@ -894,6 +900,8 @@ struct netxen_adapter { struct work_struct tx_timeout_task; u32 curr_window; + u32 crb_win; + rwlock_t adapter_lock; u32 cmd_producer; __le32 *cmd_consumer; @@ -947,6 +955,17 @@ struct netxen_adapter { int (*init_port) (struct netxen_adapter *, int); void (*init_niu) (struct netxen_adapter *); int (*stop_port) (struct netxen_adapter *); + + int (*hw_read_wx)(struct netxen_adapter *, ulong, void *, int); + int (*hw_write_wx)(struct netxen_adapter *, ulong, void *, int); + int (*pci_mem_read)(struct netxen_adapter *, u64, void *, int); + int (*pci_mem_write)(struct netxen_adapter *, u64, void *, int); + int (*pci_write_immediate)(struct netxen_adapter *, u64, u32); + u32 (*pci_read_immediate)(struct netxen_adapter *, u64); + void (*pci_write_normalize)(struct netxen_adapter *, u64, u32); + u32 (*pci_read_normalize)(struct netxen_adapter *, u64); + unsigned long (*pci_set_window)(struct netxen_adapter *, + unsigned long long); }; /* netxen_adapter structure */ /* @@ -1022,19 +1041,52 @@ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu); int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu); void netxen_nic_init_niu_gb(struct netxen_adapter *adapter); -void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw); void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val); int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off); void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value); -void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 * value); +void netxen_nic_read_w0(struct netxen_adapter *adapter, u32 index, u32 *value); +void netxen_nic_write_w1(struct netxen_adapter *adapter, u32 index, u32 value); +void netxen_nic_read_w1(struct netxen_adapter *adapter, u32 index, u32 *value); int netxen_nic_get_board_info(struct netxen_adapter *adapter); -int netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, - int len); -int netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, - int len); + +int netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, + ulong off, void *data, int len); +int netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, + ulong off, void *data, int len); +int netxen_nic_pci_mem_read_128M(struct netxen_adapter *adapter, + u64 off, void *data, int size); +int netxen_nic_pci_mem_write_128M(struct netxen_adapter *adapter, + u64 off, void *data, int size); +int netxen_nic_pci_write_immediate_128M(struct netxen_adapter *adapter, + u64 off, u32 data); +u32 netxen_nic_pci_read_immediate_128M(struct netxen_adapter *adapter, u64 off); +void netxen_nic_pci_write_normalize_128M(struct netxen_adapter *adapter, + u64 off, u32 data); +u32 netxen_nic_pci_read_normalize_128M(struct netxen_adapter *adapter, u64 off); +unsigned long netxen_nic_pci_set_window_128M(struct netxen_adapter *adapter, + unsigned long long addr); +void netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, + u32 wndw); + +int netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, + ulong off, void *data, int len); +int netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, + ulong off, void *data, int len); +int netxen_nic_pci_mem_read_2M(struct netxen_adapter *adapter, + u64 off, void *data, int size); +int netxen_nic_pci_mem_write_2M(struct netxen_adapter *adapter, + u64 off, void *data, int size); void netxen_crb_writelit_adapter(struct netxen_adapter *adapter, unsigned long off, int data); +int netxen_nic_pci_write_immediate_2M(struct netxen_adapter *adapter, + u64 off, u32 data); +u32 netxen_nic_pci_read_immediate_2M(struct netxen_adapter *adapter, u64 off); +void netxen_nic_pci_write_normalize_2M(struct netxen_adapter *adapter, + u64 off, u32 data); +u32 netxen_nic_pci_read_normalize_2M(struct netxen_adapter *adapter, u64 off); +unsigned long netxen_nic_pci_set_window_2M(struct netxen_adapter *adapter, + unsigned long long addr); /* Functions from netxen_nic_init.c */ void netxen_free_adapter_offload(struct netxen_adapter *adapter); @@ -1129,7 +1181,7 @@ dma_watchdog_shutdown_request(struct netxen_adapter *adapter) u32 ctrl; /* check if already inactive */ - if (netxen_nic_hw_read_wx(adapter, + if (adapter->hw_read_wx(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) printk(KERN_ERR "failed to read dma watchdog status\n"); @@ -1149,7 +1201,7 @@ dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter) { u32 ctrl; - if (netxen_nic_hw_read_wx(adapter, + if (adapter->hw_read_wx(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) printk(KERN_ERR "failed to read dma watchdog status\n"); @@ -1161,7 +1213,7 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter) { u32 ctrl; - if (netxen_nic_hw_read_wx(adapter, + if (adapter->hw_read_wx(adapter, NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) printk(KERN_ERR "failed to read dma watchdog status\n"); diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index cacc5280605..7e49e610607 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -93,17 +93,21 @@ static void netxen_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo) { struct netxen_adapter *adapter = netdev_priv(dev); + unsigned long flags; u32 fw_major = 0; u32 fw_minor = 0; u32 fw_build = 0; strncpy(drvinfo->driver, netxen_nic_driver_name, 32); strncpy(drvinfo->version, NETXEN_NIC_LINUX_VERSIONID, 32); - fw_major = readl(NETXEN_CRB_NORMALIZE(adapter, - NETXEN_FW_VERSION_MAJOR)); - fw_minor = readl(NETXEN_CRB_NORMALIZE(adapter, - NETXEN_FW_VERSION_MINOR)); - fw_build = readl(NETXEN_CRB_NORMALIZE(adapter, NETXEN_FW_VERSION_SUB)); + write_lock_irqsave(&adapter->adapter_lock, flags); + fw_major = adapter->pci_read_normalize(adapter, + NETXEN_FW_VERSION_MAJOR); + fw_minor = adapter->pci_read_normalize(adapter, + NETXEN_FW_VERSION_MINOR); + fw_build = adapter->pci_read_normalize(adapter, + NETXEN_FW_VERSION_SUB); + write_unlock_irqrestore(&adapter->adapter_lock, flags); sprintf(drvinfo->fw_version, "%d.%d.%d", fw_major, fw_minor, fw_build); strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32); @@ -361,19 +365,18 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { struct netxen_adapter *adapter = netdev_priv(dev); __u32 mode, *regs_buff = p; - void __iomem *addr; int i, window; memset(p, 0, NETXEN_NIC_REGS_LEN); regs->version = (1 << 24) | (adapter->ahw.revision_id << 16) | (adapter->pdev)->device; /* which mode */ - NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_MODE, ®s_buff[0]); + adapter->hw_read_wx(adapter, NETXEN_NIU_MODE, ®s_buff[0], 4); mode = regs_buff[0]; /* Common registers to all the modes */ - NETXEN_NIC_LOCKED_READ_REG(NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER, - ®s_buff[2]); + adapter->hw_read_wx(adapter, + NETXEN_NIU_STRAP_VALUE_SAVE_HIGHER, ®s_buff[2], 4); /* GB/XGB Mode */ mode = (mode / 2) - 1; window = 0; @@ -384,9 +387,9 @@ netxen_nic_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) window = adapter->physical_port * NETXEN_NIC_PORT_WINDOW; - NETXEN_NIC_LOCKED_READ_REG(niu_registers[mode]. - reg[i - 3] + window, - ®s_buff[i]); + adapter->hw_read_wx(adapter, + niu_registers[mode].reg[i - 3] + window, + ®s_buff[i], 4); } } @@ -410,7 +413,7 @@ static u32 netxen_nic_test_link(struct net_device *dev) return !val; } } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { - val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE)); + val = adapter->pci_read_normalize(adapter, CRB_XG_STATE); return (val == XG_LINK_UP) ? 0 : 1; } return -EIO; @@ -668,7 +671,7 @@ static int netxen_nic_reg_test(struct net_device *dev) data_written = (u32)0xa5a5a5a5; netxen_nic_reg_write(adapter, CRB_SCRATCHPAD_TEST, data_written); - data_read = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_SCRATCHPAD_TEST)); + data_read = adapter->pci_read_normalize(adapter, CRB_SCRATCHPAD_TEST); if (data_written != data_read) return 1; diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index a472873f48b..defbeeac5db 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -38,6 +38,248 @@ #include <net/ip.h> +#define MASK(n) ((1ULL<<(n))-1) +#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff)) +#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff)) +#define MS_WIN(addr) (addr & 0x0ffc0000) + +#define GET_MEM_OFFS_2M(addr) (addr & MASK(18)) + +#define CRB_BLK(off) ((off >> 20) & 0x3f) +#define CRB_SUBBLK(off) ((off >> 16) & 0xf) +#define CRB_WINDOW_2M (0x130060) +#define CRB_HI(off) ((crb_hub_agt[CRB_BLK(off)] << 20) | ((off) & 0xf0000)) +#define CRB_INDIRECT_2M (0x1e0000UL) + +#define CRB_WIN_LOCK_TIMEOUT 100000000 +static crb_128M_2M_block_map_t crb_128M_2M_map[64] = { + {{{0, 0, 0, 0} } }, /* 0: PCI */ + {{{1, 0x0100000, 0x0102000, 0x120000}, /* 1: PCIE */ + {1, 0x0110000, 0x0120000, 0x130000}, + {1, 0x0120000, 0x0122000, 0x124000}, + {1, 0x0130000, 0x0132000, 0x126000}, + {1, 0x0140000, 0x0142000, 0x128000}, + {1, 0x0150000, 0x0152000, 0x12a000}, + {1, 0x0160000, 0x0170000, 0x110000}, + {1, 0x0170000, 0x0172000, 0x12e000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {1, 0x01e0000, 0x01e0800, 0x122000}, + {0, 0x0000000, 0x0000000, 0x000000} } }, + {{{1, 0x0200000, 0x0210000, 0x180000} } },/* 2: MN */ + {{{0, 0, 0, 0} } }, /* 3: */ + {{{1, 0x0400000, 0x0401000, 0x169000} } },/* 4: P2NR1 */ + {{{1, 0x0500000, 0x0510000, 0x140000} } },/* 5: SRE */ + {{{1, 0x0600000, 0x0610000, 0x1c0000} } },/* 6: NIU */ + {{{1, 0x0700000, 0x0704000, 0x1b8000} } },/* 7: QM */ + {{{1, 0x0800000, 0x0802000, 0x170000}, /* 8: SQM0 */ + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {1, 0x08f0000, 0x08f2000, 0x172000} } }, + {{{1, 0x0900000, 0x0902000, 0x174000}, /* 9: SQM1*/ + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {1, 0x09f0000, 0x09f2000, 0x176000} } }, + {{{0, 0x0a00000, 0x0a02000, 0x178000}, /* 10: SQM2*/ + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {1, 0x0af0000, 0x0af2000, 0x17a000} } }, + {{{0, 0x0b00000, 0x0b02000, 0x17c000}, /* 11: SQM3*/ + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {1, 0x0bf0000, 0x0bf2000, 0x17e000} } }, + {{{1, 0x0c00000, 0x0c04000, 0x1d4000} } },/* 12: I2Q */ + {{{1, 0x0d00000, 0x0d04000, 0x1a4000} } },/* 13: TMR */ + {{{1, 0x0e00000, 0x0e04000, 0x1a0000} } },/* 14: ROMUSB */ + {{{1, 0x0f00000, 0x0f01000, 0x164000} } },/* 15: PEG4 */ + {{{0, 0x1000000, 0x1004000, 0x1a8000} } },/* 16: XDMA */ + {{{1, 0x1100000, 0x1101000, 0x160000} } },/* 17: PEG0 */ + {{{1, 0x1200000, 0x1201000, 0x161000} } },/* 18: PEG1 */ + {{{1, 0x1300000, 0x1301000, 0x162000} } },/* 19: PEG2 */ + {{{1, 0x1400000, 0x1401000, 0x163000} } },/* 20: PEG3 */ + {{{1, 0x1500000, 0x1501000, 0x165000} } },/* 21: P2ND */ + {{{1, 0x1600000, 0x1601000, 0x166000} } },/* 22: P2NI */ + {{{0, 0, 0, 0} } }, /* 23: */ + {{{0, 0, 0, 0} } }, /* 24: */ + {{{0, 0, 0, 0} } }, /* 25: */ + {{{0, 0, 0, 0} } }, /* 26: */ + {{{0, 0, 0, 0} } }, /* 27: */ + {{{0, 0, 0, 0} } }, /* 28: */ + {{{1, 0x1d00000, 0x1d10000, 0x190000} } },/* 29: MS */ + {{{1, 0x1e00000, 0x1e01000, 0x16a000} } },/* 30: P2NR2 */ + {{{1, 0x1f00000, 0x1f10000, 0x150000} } },/* 31: EPG */ + {{{0} } }, /* 32: PCI */ + {{{1, 0x2100000, 0x2102000, 0x120000}, /* 33: PCIE */ + {1, 0x2110000, 0x2120000, 0x130000}, + {1, 0x2120000, 0x2122000, 0x124000}, + {1, 0x2130000, 0x2132000, 0x126000}, + {1, 0x2140000, 0x2142000, 0x128000}, + {1, 0x2150000, 0x2152000, 0x12a000}, + {1, 0x2160000, 0x2170000, 0x110000}, + {1, 0x2170000, 0x2172000, 0x12e000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000}, + {0, 0x0000000, 0x0000000, 0x000000} } }, + {{{1, 0x2200000, 0x2204000, 0x1b0000} } },/* 34: CAM */ + {{{0} } }, /* 35: */ + {{{0} } }, /* 36: */ + {{{0} } }, /* 37: */ + {{{0} } }, /* 38: */ + {{{0} } }, /* 39: */ + {{{1, 0x2800000, 0x2804000, 0x1a4000} } },/* 40: TMR */ + {{{1, 0x2900000, 0x2901000, 0x16b000} } },/* 41: P2NR3 */ + {{{1, 0x2a00000, 0x2a00400, 0x1ac400} } },/* 42: RPMX1 */ + {{{1, 0x2b00000, 0x2b00400, 0x1ac800} } },/* 43: RPMX2 */ + {{{1, 0x2c00000, 0x2c00400, 0x1acc00} } },/* 44: RPMX3 */ + {{{1, 0x2d00000, 0x2d00400, 0x1ad000} } },/* 45: RPMX4 */ + {{{1, 0x2e00000, 0x2e00400, 0x1ad400} } },/* 46: RPMX5 */ + {{{1, 0x2f00000, 0x2f00400, 0x1ad800} } },/* 47: RPMX6 */ + {{{1, 0x3000000, 0x3000400, 0x1adc00} } },/* 48: RPMX7 */ + {{{0, 0x3100000, 0x3104000, 0x1a8000} } },/* 49: XDMA */ + {{{1, 0x3200000, 0x3204000, 0x1d4000} } },/* 50: I2Q */ + {{{1, 0x3300000, 0x3304000, 0x1a0000} } },/* 51: ROMUSB */ + {{{0} } }, /* 52: */ + {{{1, 0x3500000, 0x3500400, 0x1ac000} } },/* 53: RPMX0 */ + {{{1, 0x3600000, 0x3600400, 0x1ae000} } },/* 54: RPMX8 */ + {{{1, 0x3700000, 0x3700400, 0x1ae400} } },/* 55: RPMX9 */ + {{{1, 0x3800000, 0x3804000, 0x1d0000} } },/* 56: OCM0 */ + {{{1, 0x3900000, 0x3904000, 0x1b4000} } },/* 57: CRYPTO */ + {{{1, 0x3a00000, 0x3a04000, 0x1d8000} } },/* 58: SMB */ + {{{0} } }, /* 59: I2C0 */ + {{{0} } }, /* 60: I2C1 */ + {{{1, 0x3d00000, 0x3d04000, 0x1d8000} } },/* 61: LPC */ + {{{1, 0x3e00000, 0x3e01000, 0x167000} } },/* 62: P2NC */ + {{{1, 0x3f00000, 0x3f01000, 0x168000} } } /* 63: P2NR0 */ +}; + +/* + * top 12 bits of crb internal address (hub, agent) + */ +static unsigned crb_hub_agt[64] = +{ + 0, + NETXEN_HW_CRB_HUB_AGT_ADR_PS, + NETXEN_HW_CRB_HUB_AGT_ADR_MN, + NETXEN_HW_CRB_HUB_AGT_ADR_MS, + 0, + NETXEN_HW_CRB_HUB_AGT_ADR_SRE, + NETXEN_HW_CRB_HUB_AGT_ADR_NIU, + NETXEN_HW_CRB_HUB_AGT_ADR_QMN, + NETXEN_HW_CRB_HUB_AGT_ADR_SQN0, + NETXEN_HW_CRB_HUB_AGT_ADR_SQN1, + NETXEN_HW_CRB_HUB_AGT_ADR_SQN2, + NETXEN_HW_CRB_HUB_AGT_ADR_SQN3, + NETXEN_HW_CRB_HUB_AGT_ADR_I2Q, + NETXEN_HW_CRB_HUB_AGT_ADR_TIMR, + NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB, + NETXEN_HW_CRB_HUB_AGT_ADR_PGN4, + NETXEN_HW_CRB_HUB_AGT_ADR_XDMA, + NETXEN_HW_CRB_HUB_AGT_ADR_PGN0, + NETXEN_HW_CRB_HUB_AGT_ADR_PGN1, + NETXEN_HW_CRB_HUB_AGT_ADR_PGN2, + NETXEN_HW_CRB_HUB_AGT_ADR_PGN3, + NETXEN_HW_CRB_HUB_AGT_ADR_PGND, + NETXEN_HW_CRB_HUB_AGT_ADR_PGNI, + NETXEN_HW_CRB_HUB_AGT_ADR_PGS0, + NETXEN_HW_CRB_HUB_AGT_ADR_PGS1, + NETXEN_HW_CRB_HUB_AGT_ADR_PGS2, + NETXEN_HW_CRB_HUB_AGT_ADR_PGS3, + 0, + NETXEN_HW_CRB_HUB_AGT_ADR_PGSI, + NETXEN_HW_CRB_HUB_AGT_ADR_SN, + 0, + NETXEN_HW_CRB_HUB_AGT_ADR_EG, + 0, + NETXEN_HW_CRB_HUB_AGT_ADR_PS, + NETXEN_HW_CRB_HUB_AGT_ADR_CAM, + 0, + 0, + 0, + 0, + 0, + NETXEN_HW_CRB_HUB_AGT_ADR_TIMR, + 0, + NETXEN_HW_CRB_HUB_AGT_ADR_RPMX1, + NETXEN_HW_CRB_HUB_AGT_ADR_RPMX2, + NETXEN_HW_CRB_HUB_AGT_ADR_RPMX3, + NETXEN_HW_CRB_HUB_AGT_ADR_RPMX4, + NETXEN_HW_CRB_HUB_AGT_ADR_RPMX5, + NETXEN_HW_CRB_HUB_AGT_ADR_RPMX6, + NETXEN_HW_CRB_HUB_AGT_ADR_RPMX7, + NETXEN_HW_CRB_HUB_AGT_ADR_XDMA, + NETXEN_HW_CRB_HUB_AGT_ADR_I2Q, + NETXEN_HW_CRB_HUB_AGT_ADR_ROMUSB, + 0, + NETXEN_HW_CRB_HUB_AGT_ADR_RPMX0, + NETXEN_HW_CRB_HUB_AGT_ADR_RPMX8, + NETXEN_HW_CRB_HUB_AGT_ADR_RPMX9, + NETXEN_HW_CRB_HUB_AGT_ADR_OCM0, + 0, + NETXEN_HW_CRB_HUB_AGT_ADR_SMB, + NETXEN_HW_CRB_HUB_AGT_ADR_I2C0, + NETXEN_HW_CRB_HUB_AGT_ADR_I2C1, + 0, + NETXEN_HW_CRB_HUB_AGT_ADR_PGNC, + 0, +}; + struct netxen_recv_crb recv_crb_registers[] = { /* * Instance 0. @@ -123,7 +365,7 @@ static u64 ctx_addr_sig_regs[][3] = { #define NETXEN_MIN_MTU 64 #define NETXEN_ETH_FCS_SIZE 4 #define NETXEN_ENET_HEADER_SIZE 14 -#define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ +#define NETXEN_WINDOW_ONE 0x2000000 /*CRB Window: bit 25 of CRB address */ #define NETXEN_FIRMWARE_LEN ((16 * 1024) / 4) #define NETXEN_NIU_HDRSIZE (0x1 << 6) #define NETXEN_NIU_TLRSIZE (0x1 << 5) @@ -139,8 +381,6 @@ static u64 ctx_addr_sig_regs[][3] = { #define NETXEN_NIC_WINDOW_MARGIN 0x100000 -static unsigned long netxen_nic_pci_set_window(struct netxen_adapter *adapter, - unsigned long long addr); void netxen_free_hw_resources(struct netxen_adapter *adapter); int netxen_nic_set_mac(struct net_device *netdev, void *p) @@ -181,9 +421,9 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter) if (adapter->mc_enabled) return 0; - netxen_nic_hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); + adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); val |= (1UL << (28+port)); - netxen_nic_hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); + adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); /* add broadcast addr to filter */ val = 0xffffff; @@ -212,9 +452,9 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter) if (!adapter->mc_enabled) return 0; - netxen_nic_hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); + adapter->hw_read_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); val &= ~(1UL << (28+port)); - netxen_nic_hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); + adapter->hw_write_wx(adapter, NETXEN_MAC_ADDR_CNTL_REG, &val, 4); val = MAC_HI(addr); netxen_crb_writelit_adapter(adapter, NETXEN_UNICAST_ADDR(port, 0), val); @@ -344,18 +584,15 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) { - DPRINTK(INFO, "Command Peg ready..waiting for rcv peg\n"); loops = 0; state = 0; - /* Window 1 call */ - state = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_RCVPEG_STATE)); - while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) { - msleep(1); + do { /* Window 1 call */ - state = readl(NETXEN_CRB_NORMALIZE(adapter, - CRB_RCVPEG_STATE)); + state = adapter->pci_read_normalize(adapter, + CRB_RCVPEG_STATE); + msleep(1); loops++; - } + } while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20); if (loops >= 20) { printk(KERN_ERR "Rcv Peg initialization not complete:" "%x.\n", state); @@ -363,10 +600,10 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) return err; } } - adapter->intr_scheme = readl( - NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); - adapter->msi_mode = readl( - NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_FW)); + adapter->intr_scheme = adapter->pci_read_normalize(adapter, + CRB_NIC_CAPABILITIES_FW); + adapter->msi_mode = adapter->pci_read_normalize(adapter, + CRB_NIC_MSI_MODE_FW); addr = pci_alloc_consistent(adapter->pdev, sizeof(struct netxen_ring_ctx) + sizeof(uint32_t), @@ -449,12 +686,12 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) } /* Window = 1 */ - writel(lower32(adapter->ctx_desc_phys_addr), - NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_LO(func_id))); - writel(upper32(adapter->ctx_desc_phys_addr), - NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_ADDR_REG_HI(func_id))); - writel(NETXEN_CTX_SIGNATURE | func_id, - NETXEN_CRB_NORMALIZE(adapter, CRB_CTX_SIGNATURE_REG(func_id))); + adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_LO(func_id), + lower32(adapter->ctx_desc_phys_addr)); + adapter->pci_write_normalize(adapter, CRB_CTX_ADDR_REG_HI(func_id), + upper32(adapter->ctx_desc_phys_addr)); + adapter->pci_write_normalize(adapter, CRB_CTX_SIGNATURE_REG(func_id), + NETXEN_CTX_SIGNATURE | func_id); return err; } @@ -601,10 +838,41 @@ int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[]) return 0; } +#define CRB_WIN_LOCK_TIMEOUT 100000000 + +static int crb_win_lock(struct netxen_adapter *adapter) +{ + int done = 0, timeout = 0; + + while (!done) { + /* acquire semaphore3 from PCI HW block */ + adapter->hw_read_wx(adapter, + NETXEN_PCIE_REG(PCIE_SEM7_LOCK), &done, 4); + if (done == 1) + break; + if (timeout >= CRB_WIN_LOCK_TIMEOUT) + return -1; + timeout++; + udelay(1); + } + netxen_crb_writelit_adapter(adapter, + NETXEN_CRB_WIN_LOCK_ID, adapter->portnum); + return 0; +} + +static void crb_win_unlock(struct netxen_adapter *adapter) +{ + int val; + + adapter->hw_read_wx(adapter, + NETXEN_PCIE_REG(PCIE_SEM7_UNLOCK), &val, 4); +} + /* * Changes the CRB window to the specified window. */ -void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) +void +netxen_nic_pci_change_crbwindow_128M(struct netxen_adapter *adapter, u32 wndw) { void __iomem *offset; u32 tmp; @@ -633,7 +901,7 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) while ((tmp = readl(offset)) != wndw) { printk(KERN_WARNING "%s: %s WARNING: CRB window value not " "registered properly: 0x%08x.\n", - netxen_nic_driver_name, __FUNCTION__, tmp); + netxen_nic_driver_name, __func__, tmp); mdelay(1); if (count >= 10) break; @@ -646,51 +914,112 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) adapter->curr_window = 0; } +/* + * Return -1 if off is not valid, + * 1 if window access is needed. 'off' is set to offset from + * CRB space in 128M pci map + * 0 if no window access is needed. 'off' is set to 2M addr + * In: 'off' is offset from base in 128M pci map + */ +static int +netxen_nic_pci_get_crb_addr_2M(struct netxen_adapter *adapter, + ulong *off, int len) +{ + unsigned long end = *off + len; + crb_128M_2M_sub_block_map_t *m; + + + if (*off >= NETXEN_CRB_MAX) + return -1; + + if (*off >= NETXEN_PCI_CAMQM && (end <= NETXEN_PCI_CAMQM_2M_END)) { + *off = (*off - NETXEN_PCI_CAMQM) + NETXEN_PCI_CAMQM_2M_BASE + + (ulong)adapter->ahw.pci_base0; + return 0; + } + + if (*off < NETXEN_PCI_CRBSPACE) + return -1; + + *off -= NETXEN_PCI_CRBSPACE; + end = *off + len; + + /* + * Try direct map + */ + m = &crb_128M_2M_map[CRB_BLK(*off)].sub_block[CRB_SUBBLK(*off)]; + + if (m->valid && (m->start_128M <= *off) && (m->end_128M >= end)) { + *off = *off + m->start_2M - m->start_128M + + (ulong)adapter->ahw.pci_base0; + return 0; + } + + /* + * Not in direct map, use crb window + */ + return 1; +} + +/* + * In: 'off' is offset from CRB space in 128M pci map + * Out: 'off' is 2M pci map addr + * side effect: lock crb window + */ +static void +netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong *off) +{ + u32 win_read; + + adapter->crb_win = CRB_HI(*off); + writel(adapter->crb_win, (void *)(CRB_WINDOW_2M + + adapter->ahw.pci_base0)); + /* + * Read back value to make sure write has gone through before trying + * to use it. + */ + win_read = readl((void *)(CRB_WINDOW_2M + adapter->ahw.pci_base0)); + if (win_read != adapter->crb_win) { + printk(KERN_ERR "%s: Written crbwin (0x%x) != " + "Read crbwin (0x%x), off=0x%lx\n", + __func__, adapter->crb_win, win_read, *off); + } + *off = (*off & MASK(16)) + CRB_INDIRECT_2M + + (ulong)adapter->ahw.pci_base0; +} + int netxen_load_firmware(struct netxen_adapter *adapter) { int i; u32 data, size = 0; u32 flashaddr = NETXEN_FLASH_BASE, memaddr = NETXEN_PHANTOM_MEM_BASE; - u64 off; - void __iomem *addr; size = NETXEN_FIRMWARE_LEN; - writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); + adapter->pci_write_normalize(adapter, + NETXEN_ROMUSB_GLB_CAS_RST, 1); for (i = 0; i < size; i++) { - int retries = 10; if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) return -EIO; - off = netxen_nic_pci_set_window(adapter, memaddr); - addr = pci_base_offset(adapter, off); - writel(data, addr); - do { - if (readl(addr) == data) - break; - msleep(100); - writel(data, addr); - } while (--retries); - if (!retries) { - printk(KERN_ERR "%s: firmware load aborted, write failed at 0x%x\n", - netxen_nic_driver_name, memaddr); - return -EIO; - } + adapter->pci_mem_write(adapter, memaddr, &data, 4); flashaddr += 4; memaddr += 4; + cond_resched(); } udelay(100); /* make sure Casper is powered on */ - writel(0x3fff, - NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL)); - writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); + adapter->pci_write_normalize(adapter, + NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL, 0x3fff); + adapter->pci_write_normalize(adapter, + NETXEN_ROMUSB_GLB_CAS_RST, 0); return 0; } int -netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, - int len) +netxen_nic_hw_write_wx_128M(struct netxen_adapter *adapter, + ulong off, void *data, int len) { void __iomem *addr; @@ -698,7 +1027,7 @@ netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, addr = NETXEN_CRB_NORMALIZE(adapter, off); } else { /* Window 0 */ addr = pci_base_offset(adapter, off); - netxen_nic_pci_change_crbwindow(adapter, 0); + netxen_nic_pci_change_crbwindow_128M(adapter, 0); } DPRINTK(INFO, "writing to base %lx offset %llx addr %p" @@ -706,7 +1035,7 @@ netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, pci_base(adapter, off), off, addr, *(unsigned long long *)data, len); if (!addr) { - netxen_nic_pci_change_crbwindow(adapter, 1); + netxen_nic_pci_change_crbwindow_128M(adapter, 1); return 1; } @@ -733,14 +1062,14 @@ netxen_nic_hw_write_wx(struct netxen_adapter *adapter, u64 off, void *data, break; } if (!ADDR_IN_WINDOW1(off)) - netxen_nic_pci_change_crbwindow(adapter, 1); + netxen_nic_pci_change_crbwindow_128M(adapter, 1); return 0; } int -netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, - int len) +netxen_nic_hw_read_wx_128M(struct netxen_adapter *adapter, + ulong off, void *data, int len) { void __iomem *addr; @@ -748,13 +1077,13 @@ netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, addr = NETXEN_CRB_NORMALIZE(adapter, off); } else { /* Window 0 */ addr = pci_base_offset(adapter, off); - netxen_nic_pci_change_crbwindow(adapter, 0); + netxen_nic_pci_change_crbwindow_128M(adapter, 0); } DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n", pci_base(adapter, off), off, addr); if (!addr) { - netxen_nic_pci_change_crbwindow(adapter, 1); + netxen_nic_pci_change_crbwindow_128M(adapter, 1); return 1; } switch (len) { @@ -778,76 +1107,190 @@ netxen_nic_hw_read_wx(struct netxen_adapter *adapter, u64 off, void *data, DPRINTK(INFO, "read %lx\n", *(unsigned long *)data); if (!ADDR_IN_WINDOW1(off)) - netxen_nic_pci_change_crbwindow(adapter, 1); + netxen_nic_pci_change_crbwindow_128M(adapter, 1); return 0; } -void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val) -{ /* Only for window 1 */ - void __iomem *addr; +int +netxen_nic_hw_write_wx_2M(struct netxen_adapter *adapter, + ulong off, void *data, int len) +{ + unsigned long flags = 0; + int rv; - addr = NETXEN_CRB_NORMALIZE(adapter, off); - DPRINTK(INFO, "writing to base %lx offset %llx addr %p data %x\n", - pci_base(adapter, off), off, addr, val); - writel(val, addr); + rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len); + if (rv == -1) { + printk(KERN_ERR "%s: invalid offset: 0x%016lx\n", + __func__, off); + dump_stack(); + return -1; + } + + if (rv == 1) { + write_lock_irqsave(&adapter->adapter_lock, flags); + crb_win_lock(adapter); + netxen_nic_pci_set_crbwindow_2M(adapter, &off); + } + + DPRINTK(1, INFO, "write data %lx to offset %llx, len=%d\n", + *(unsigned long *)data, off, len); + + switch (len) { + case 1: + writeb(*(uint8_t *)data, (void *)off); + break; + case 2: + writew(*(uint16_t *)data, (void *)off); + break; + case 4: + writel(*(uint32_t *)data, (void *)off); + break; + case 8: + writeq(*(uint64_t *)data, (void *)off); + break; + default: + DPRINTK(1, INFO, + "writing data %lx to offset %llx, num words=%d\n", + *(unsigned long *)data, off, (len>>3)); + break; + } + if (rv == 1) { + crb_win_unlock(adapter); + write_unlock_irqrestore(&adapter->adapter_lock, flags); + } + + return 0; } -int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off) -{ /* Only for window 1 */ - void __iomem *addr; - int val; +int +netxen_nic_hw_read_wx_2M(struct netxen_adapter *adapter, + ulong off, void *data, int len) +{ + unsigned long flags = 0; + int rv; - addr = NETXEN_CRB_NORMALIZE(adapter, off); - DPRINTK(INFO, "reading from base %lx offset %llx addr %p\n", - pci_base(adapter, off), off, addr); - val = readl(addr); - writel(val, addr); + rv = netxen_nic_pci_get_crb_addr_2M(adapter, &off, len); + + if (rv == -1) { + printk(KERN_ERR "%s: invalid offset: 0x%016lx\n", + __func__, off); + dump_stack(); + return -1; + } + + if (rv == 1) { + write_lock_irqsave(&adapter->adapter_lock, flags); + crb_win_lock(adapter); + netxen_nic_pci_set_crbwindow_2M(adapter, &off); + } + + DPRINTK(1, INFO, "read from offset %lx, len=%d\n", off, len); + + switch (len) { + case 1: + *(uint8_t *)data = readb((void *)off); + break; + case 2: + *(uint16_t *)data = readw((void *)off); + break; + case 4: + *(uint32_t *)data = readl((void *)off); + break; + case 8: + *(uint64_t *)data = readq((void *)off); + break; + default: + break; + } + + DPRINTK(1, INFO, "read %lx\n", *(unsigned long *)data); + if (rv == 1) { + crb_win_unlock(adapter); + write_unlock_irqrestore(&adapter->adapter_lock, flags); + } + + return 0; +} + +void netxen_nic_reg_write(struct netxen_adapter *adapter, u64 off, u32 val) +{ + adapter->hw_write_wx(adapter, off, &val, 4); +} + +int netxen_nic_reg_read(struct netxen_adapter *adapter, u64 off) +{ + int val; + adapter->hw_read_wx(adapter, off, &val, 4); return val; } /* Change the window to 0, write and change back to window 1. */ void netxen_nic_write_w0(struct netxen_adapter *adapter, u32 index, u32 value) { - void __iomem *addr; - - netxen_nic_pci_change_crbwindow(adapter, 0); - addr = pci_base_offset(adapter, index); - writel(value, addr); - netxen_nic_pci_change_crbwindow(adapter, 1); + adapter->hw_write_wx(adapter, index, &value, 4); < |