Commit fcb7ad31 authored by Chien Tung's avatar Chien Tung Committed by Roland Dreier

RDMA/nes: Add support for 4-port 1G HP blade card

Add support for NetEffect 4 port 1G HP blade card.  The mapping
between physical port and MAC is different from the standup card.
Signed-off-by: default avatarChien Tung <ctung@neteffect.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 54c86a8c
...@@ -562,7 +562,26 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i ...@@ -562,7 +562,26 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i
nesdev->nesadapter->pd_config_base[PCI_FUNC(nesdev->pcidev->devfn)]; */ nesdev->nesadapter->pd_config_base[PCI_FUNC(nesdev->pcidev->devfn)]; */
nesdev->base_doorbell_index = 1; nesdev->base_doorbell_index = 1;
nesdev->doorbell_start = nesdev->nesadapter->doorbell_start; nesdev->doorbell_start = nesdev->nesadapter->doorbell_start;
nesdev->mac_index = PCI_FUNC(nesdev->pcidev->devfn) % nesdev->nesadapter->port_count; if (nesdev->nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
switch (PCI_FUNC(nesdev->pcidev->devfn) %
nesdev->nesadapter->port_count) {
case 1:
nesdev->mac_index = 2;
break;
case 2:
nesdev->mac_index = 1;
break;
case 3:
nesdev->mac_index = 3;
break;
case 0:
default:
nesdev->mac_index = 0;
}
} else {
nesdev->mac_index = PCI_FUNC(nesdev->pcidev->devfn) %
nesdev->nesadapter->port_count;
}
tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev); tasklet_init(&nesdev->dpc_tasklet, nes_dpc, (unsigned long)nesdev);
...@@ -581,7 +600,7 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i ...@@ -581,7 +600,7 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i
nesdev->int_req = (0x101 << PCI_FUNC(nesdev->pcidev->devfn)) | nesdev->int_req = (0x101 << PCI_FUNC(nesdev->pcidev->devfn)) |
(1 << (PCI_FUNC(nesdev->pcidev->devfn)+16)); (1 << (PCI_FUNC(nesdev->pcidev->devfn)+16));
if (PCI_FUNC(nesdev->pcidev->devfn) < 4) { if (PCI_FUNC(nesdev->pcidev->devfn) < 4) {
nesdev->int_req |= (1 << (PCI_FUNC(nesdev->pcidev->devfn)+24)); nesdev->int_req |= (1 << (PCI_FUNC(nesdev->mac_index)+24));
} }
/* TODO: This really should be the first driver to load, not function 0 */ /* TODO: This really should be the first driver to load, not function 0 */
...@@ -772,14 +791,14 @@ static ssize_t nes_show_adapter(struct device_driver *ddp, char *buf) ...@@ -772,14 +791,14 @@ static ssize_t nes_show_adapter(struct device_driver *ddp, char *buf)
list_for_each_entry(nesdev, &nes_dev_list, list) { list_for_each_entry(nesdev, &nes_dev_list, list) {
if (i == ee_flsh_adapter) { if (i == ee_flsh_adapter) {
devfn = nesdev->nesadapter->devfn; devfn = nesdev->pcidev->devfn;
bus_number = nesdev->nesadapter->bus_number; bus_number = nesdev->pcidev->bus->number;
break; break;
} }
i++; i++;
} }
return snprintf(buf, PAGE_SIZE, "%x:%x", bus_number, devfn); return snprintf(buf, PAGE_SIZE, "%x:%x\n", bus_number, devfn);
} }
static ssize_t nes_store_adapter(struct device_driver *ddp, static ssize_t nes_store_adapter(struct device_driver *ddp,
......
...@@ -61,7 +61,7 @@ u32 int_mod_cq_depth_1; ...@@ -61,7 +61,7 @@ u32 int_mod_cq_depth_1;
static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq); static void nes_cqp_ce_handler(struct nes_device *nesdev, struct nes_hw_cq *cq);
static void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_count); static void nes_init_csr_ne020(struct nes_device *nesdev, u8 hw_rev, u8 port_count);
static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count, static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count,
u8 OneG_Mode); struct nes_adapter *nesadapter, u8 OneG_Mode);
static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq); static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq);
static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq); static void nes_process_aeq(struct nes_device *nesdev, struct nes_hw_aeq *aeq);
static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq); static void nes_process_ceq(struct nes_device *nesdev, struct nes_hw_ceq *ceq);
...@@ -292,9 +292,6 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { ...@@ -292,9 +292,6 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
if ((port_count = nes_reset_adapter_ne020(nesdev, &OneG_Mode)) == 0) if ((port_count = nes_reset_adapter_ne020(nesdev, &OneG_Mode)) == 0)
return NULL; return NULL;
if (nes_init_serdes(nesdev, hw_rev, port_count, OneG_Mode))
return NULL;
nes_init_csr_ne020(nesdev, hw_rev, port_count);
max_qp = nes_read_indexed(nesdev, NES_IDX_QP_CTX_SIZE); max_qp = nes_read_indexed(nesdev, NES_IDX_QP_CTX_SIZE);
nes_debug(NES_DBG_INIT, "QP_CTX_SIZE=%u\n", max_qp); nes_debug(NES_DBG_INIT, "QP_CTX_SIZE=%u\n", max_qp);
...@@ -353,6 +350,19 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { ...@@ -353,6 +350,19 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
nes_debug(NES_DBG_INIT, "Allocating new nesadapter @ %p, size = %u (actual size = %u).\n", nes_debug(NES_DBG_INIT, "Allocating new nesadapter @ %p, size = %u (actual size = %u).\n",
nesadapter, (u32)sizeof(struct nes_adapter), adapter_size); nesadapter, (u32)sizeof(struct nes_adapter), adapter_size);
if (nes_read_eeprom_values(nesdev, nesadapter)) {
printk(KERN_ERR PFX "Unable to read EEPROM data.\n");
kfree(nesadapter);
return NULL;
}
if (nes_init_serdes(nesdev, hw_rev, port_count, nesadapter,
OneG_Mode)) {
kfree(nesadapter);
return NULL;
}
nes_init_csr_ne020(nesdev, hw_rev, port_count);
/* populate the new nesadapter */ /* populate the new nesadapter */
nesadapter->devfn = nesdev->pcidev->devfn; nesadapter->devfn = nesdev->pcidev->devfn;
nesadapter->bus_number = nesdev->pcidev->bus->number; nesadapter->bus_number = nesdev->pcidev->bus->number;
...@@ -468,20 +478,25 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { ...@@ -468,20 +478,25 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
/* setup port configuration */ /* setup port configuration */
if (nesadapter->port_count == 1) { if (nesadapter->port_count == 1) {
u32temp = 0x00000000; nesadapter->log_port = 0x00000000;
if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT) if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT)
nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000002); nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000002);
else else
nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003); nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003);
} else { } else {
if (nesadapter->port_count == 2) if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
u32temp = 0x00000044; nesadapter->log_port = 0x000000D8;
else } else {
u32temp = 0x000000e4; if (nesadapter->port_count == 2)
nesadapter->log_port = 0x00000044;
else
nesadapter->log_port = 0x000000e4;
}
nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003); nes_write_indexed(nesdev, NES_IDX_TX_POOL_SIZE, 0x00000003);
} }
nes_write_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT, u32temp); nes_write_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT,
nesadapter->log_port);
nes_debug(NES_DBG_INIT, "Probe time, LOG2PHY=%u\n", nes_debug(NES_DBG_INIT, "Probe time, LOG2PHY=%u\n",
nes_read_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT)); nes_read_indexed(nesdev, NES_IDX_NIC_LOGPORT_TO_PHYPORT));
...@@ -706,23 +721,43 @@ static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_ ...@@ -706,23 +721,43 @@ static unsigned int nes_reset_adapter_ne020(struct nes_device *nesdev, u8 *OneG_
* nes_init_serdes * nes_init_serdes
*/ */
static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count, static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count,
u8 OneG_Mode) struct nes_adapter *nesadapter, u8 OneG_Mode)
{ {
int i; int i;
u32 u32temp; u32 u32temp;
u32 serdes_common_control;
if (hw_rev != NE020_REV) { if (hw_rev != NE020_REV) {
/* init serdes 0 */ /* init serdes 0 */
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF);
if (!OneG_Mode) if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
serdes_common_control = nes_read_indexed(nesdev,
NES_IDX_ETH_SERDES_COMMON_CONTROL0);
serdes_common_control |= 0x000000100;
nes_write_indexed(nesdev,
NES_IDX_ETH_SERDES_COMMON_CONTROL0,
serdes_common_control);
} else if (!OneG_Mode) {
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000); nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000);
if (port_count > 1) { }
if (((port_count > 1) &&
(nesadapter->phy_type[0] != NES_PHY_TYPE_PUMA_1G)) ||
((port_count > 2) &&
(nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G))) {
/* init serdes 1 */ /* init serdes 1 */
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF); nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000000FF);
if (!OneG_Mode) if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) {
serdes_common_control = nes_read_indexed(nesdev,
NES_IDX_ETH_SERDES_COMMON_CONTROL1);
serdes_common_control |= 0x000000100;
nes_write_indexed(nesdev,
NES_IDX_ETH_SERDES_COMMON_CONTROL1,
serdes_common_control);
} else if (!OneG_Mode) {
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000); nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE1, 0x11110000);
} }
}
} else { } else {
/* init serdes 0 */ /* init serdes 0 */
nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, 0x00000008); nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, 0x00000008);
...@@ -2258,7 +2293,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) ...@@ -2258,7 +2293,8 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number)
spin_unlock_irqrestore(&nesadapter->phy_lock, flags); spin_unlock_irqrestore(&nesadapter->phy_lock, flags);
} }
/* read the PHY interrupt status register */ /* read the PHY interrupt status register */
if (nesadapter->OneG_Mode) { if ((nesadapter->OneG_Mode) &&
(nesadapter->phy_type[mac_index] != NES_PHY_TYPE_PUMA_1G)) {
do { do {
nes_read_1G_phy_reg(nesdev, 0x1a, nes_read_1G_phy_reg(nesdev, 0x1a,
nesadapter->phy_index[mac_index], &phy_data); nesadapter->phy_index[mac_index], &phy_data);
......
...@@ -1100,6 +1100,7 @@ struct nes_adapter { ...@@ -1100,6 +1100,7 @@ struct nes_adapter {
u8 mac_sw_state[4]; u8 mac_sw_state[4];
u8 mac_link_down[4]; u8 mac_link_down[4];
u8 phy_type[4]; u8 phy_type[4];
u8 log_port;
/* PCI information */ /* PCI information */
unsigned int devfn; unsigned int devfn;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment