/*****************************************************************************
* *
* File: subr.c *
- * $Revision: 1.12 $ *
- * $Date: 2005/03/23 07:41:27 $ *
+ * $Revision: 1.27 $ *
+ * $Date: 2005/06/22 01:08:36 $ *
* Description: *
* Various subroutines (intr,pio,etc.) used by Chelsio 10G Ethernet driver. *
* part of the Chelsio 10Gb Ethernet Driver. *
#include "common.h"
#include "elmer0.h"
#include "regs.h"
-
#include "gmac.h"
#include "cphy.h"
#include "sge.h"
* otherwise.
*/
static int t1_wait_op_done(adapter_t *adapter, int reg, u32 mask, int polarity,
- int attempts, int delay)
+ int attempts, int delay)
{
while (1) {
- u32 val = t1_read_reg_4(adapter, reg) & mask;
+ u32 val = readl(adapter->regs + reg) & mask;
if (!!val == polarity)
return 0;
/*
* Write a register over the TPI interface (unlocked and locked versions).
*/
-static int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value)
+int __t1_tpi_write(adapter_t *adapter, u32 addr, u32 value)
{
int tpi_busy;
- t1_write_reg_4(adapter, A_TPI_ADDR, addr);
- t1_write_reg_4(adapter, A_TPI_WR_DATA, value);
- t1_write_reg_4(adapter, A_TPI_CSR, F_TPIWR);
+ writel(addr, adapter->regs + A_TPI_ADDR);
+ writel(value, adapter->regs + A_TPI_WR_DATA);
+ writel(F_TPIWR, adapter->regs + A_TPI_CSR);
tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1,
TPI_ATTEMPTS, 3);
{
int ret;
- TPI_LOCK(adapter);
+ spin_lock(&adapter->tpi_lock);
ret = __t1_tpi_write(adapter, addr, value);
- TPI_UNLOCK(adapter);
+ spin_unlock(&adapter->tpi_lock);
return ret;
}
/*
* Read a register over the TPI interface (unlocked and locked versions).
*/
-static int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp)
+int __t1_tpi_read(adapter_t *adapter, u32 addr, u32 *valp)
{
int tpi_busy;
- t1_write_reg_4(adapter, A_TPI_ADDR, addr);
- t1_write_reg_4(adapter, A_TPI_CSR, 0);
+ writel(addr, adapter->regs + A_TPI_ADDR);
+ writel(0, adapter->regs + A_TPI_CSR);
tpi_busy = t1_wait_op_done(adapter, A_TPI_CSR, F_TPIRDY, 1,
TPI_ATTEMPTS, 3);
CH_ALERT("%s: TPI read from 0x%x failed\n",
adapter->name, addr);
else
- *valp = t1_read_reg_4(adapter, A_TPI_RD_DATA);
+ *valp = readl(adapter->regs + A_TPI_RD_DATA);
return tpi_busy;
}
{
int ret;
- TPI_LOCK(adapter);
+ spin_lock(&adapter->tpi_lock);
ret = __t1_tpi_read(adapter, addr, valp);
- TPI_UNLOCK(adapter);
+ spin_unlock(&adapter->tpi_lock);
return ret;
}
*/
static void t1_tpi_par(adapter_t *adapter, u32 value)
{
- t1_write_reg_4(adapter, A_TPI_PAR, V_TPIPAR(value));
+ writel(V_TPIPAR(value), adapter->regs + A_TPI_PAR);
}
/*
* associated PHY and MAC. After performing the common tasks it invokes an
* OS-specific handler.
*/
-/* static */ void link_changed(adapter_t *adapter, int port_id)
+void t1_link_changed(adapter_t *adapter, int port_id)
{
int link_ok, speed, duplex, fc;
struct cphy *phy = adapter->port[port_id].phy;
mac->ops->set_speed_duplex_fc(mac, speed, duplex, fc);
lc->fc = (unsigned char)fc;
}
- t1_link_changed(adapter, port_id, link_ok, speed, duplex, fc);
+ t1_link_negotiated(adapter, port_id, link_ok, speed, duplex, fc);
}
static int t1_pci_intr_handler(adapter_t *adapter)
{
u32 pcix_cause;
- pci_read_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, &pcix_cause);
+ pci_read_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE, &pcix_cause);
if (pcix_cause) {
pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_CAUSE,
- pcix_cause);
+ pcix_cause);
t1_fatal_err(adapter); /* PCI errors are fatal */
}
return 0;
}
+#ifdef CONFIG_CHELSIO_T1_COUGAR
+#include "cspi.h"
+#endif
+#ifdef CONFIG_CHELSIO_T1_1G
+#include "fpga_defs.h"
+
+/*
+ * PHY interrupt handler for FPGA boards.
+ */
+static int fpga_phy_intr_handler(adapter_t *adapter)
+{
+ int p;
+ u32 cause = readl(adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_CAUSE);
+
+ for_each_port(adapter, p)
+ if (cause & (1 << p)) {
+ struct cphy *phy = adapter->port[p].phy;
+ int phy_cause = phy->ops->interrupt_handler(phy);
+
+ if (phy_cause & cphy_cause_link_change)
+ t1_link_changed(adapter, p);
+ }
+ writel(cause, adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_CAUSE);
+ return 0;
+}
+
+/*
+ * Slow path interrupt handler for FPGAs.
+ */
+static int fpga_slow_intr(adapter_t *adapter)
+{
+ u32 cause = readl(adapter->regs + A_PL_CAUSE);
+
+ cause &= ~F_PL_INTR_SGE_DATA;
+ if (cause & F_PL_INTR_SGE_ERR)
+ t1_sge_intr_error_handler(adapter->sge);
+
+ if (cause & FPGA_PCIX_INTERRUPT_GMAC)
+ fpga_phy_intr_handler(adapter);
+
+ if (cause & FPGA_PCIX_INTERRUPT_TP) {
+ /*
+ * FPGA doesn't support MC4 interrupts and it requires
+ * this odd layer of indirection for MC5.
+ */
+ u32 tp_cause = readl(adapter->regs + FPGA_TP_ADDR_INTERRUPT_CAUSE);
+
+ /* Clear TP interrupt */
+ writel(tp_cause, adapter->regs + FPGA_TP_ADDR_INTERRUPT_CAUSE);
+ }
+ if (cause & FPGA_PCIX_INTERRUPT_PCIX)
+ t1_pci_intr_handler(adapter);
+
+ /* Clear the interrupts just processed. */
+ if (cause)
+ writel(cause, adapter->regs + A_PL_CAUSE);
+
+ return cause != 0;
+}
+#endif
/*
* Wait until Elmer's MI1 interface is ready for new operations.
udelay(10);
} while (busy && --attempts);
if (busy)
- CH_ALERT("%s: MDIO operation timed out\n",
- adapter->name);
+ CH_ALERT("%s: MDIO operation timed out\n", adapter->name);
return busy;
}
t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_CFG, val);
}
+#if defined(CONFIG_CHELSIO_T1_1G) || defined(CONFIG_CHELSIO_T1_COUGAR)
+/*
+ * Elmer MI1 MDIO read/write operations.
+ */
+static int mi1_mdio_read(adapter_t *adapter, int phy_addr, int mmd_addr,
+ int reg_addr, unsigned int *valp)
+{
+ u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
+
+ if (mmd_addr)
+ return -EINVAL;
+
+ spin_lock(&adapter->tpi_lock);
+ __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
+ __t1_tpi_write(adapter,
+ A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_READ);
+ mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
+ __t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
+ spin_unlock(&adapter->tpi_lock);
+ return 0;
+}
+
+static int mi1_mdio_write(adapter_t *adapter, int phy_addr, int mmd_addr,
+ int reg_addr, unsigned int val)
+{
+ u32 addr = V_MI1_REG_ADDR(reg_addr) | V_MI1_PHY_ADDR(phy_addr);
+
+ if (mmd_addr)
+ return -EINVAL;
+
+ spin_lock(&adapter->tpi_lock);
+ __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
+ __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
+ __t1_tpi_write(adapter,
+ A_ELMER0_PORT0_MI1_OP, MI1_OP_DIRECT_WRITE);
+ mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
+ spin_unlock(&adapter->tpi_lock);
+ return 0;
+}
+
+#if defined(CONFIG_CHELSIO_T1_1G) || defined(CONFIG_CHELSIO_T1_COUGAR)
+static const struct mdio_ops mi1_mdio_ops = {
+ .init = mi1_mdio_init,
+ .read = mi1_mdio_read,
+ .write = mi1_mdio_write
+};
+#endif
+
+#endif
+
static int mi1_mdio_ext_read(adapter_t *adapter, int phy_addr, int mmd_addr,
int reg_addr, unsigned int *valp)
{
u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
- TPI_LOCK(adapter);
+ spin_lock(&adapter->tpi_lock);
/* Write the address we want. */
__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
/* Write the operation we want. */
- __t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_READ);
+ __t1_tpi_write(adapter,
+ A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_READ);
mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
/* Read the data. */
__t1_tpi_read(adapter, A_ELMER0_PORT0_MI1_DATA, valp);
- TPI_UNLOCK(adapter);
+ spin_unlock(&adapter->tpi_lock);
return 0;
}
{
u32 addr = V_MI1_REG_ADDR(mmd_addr) | V_MI1_PHY_ADDR(phy_addr);
- TPI_LOCK(adapter);
+ spin_lock(&adapter->tpi_lock);
/* Write the address we want. */
__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_ADDR, addr);
__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_DATA, val);
__t1_tpi_write(adapter, A_ELMER0_PORT0_MI1_OP, MI1_OP_INDIRECT_WRITE);
mi1_wait_until_ready(adapter, A_ELMER0_PORT0_MI1_OP);
- TPI_UNLOCK(adapter);
+ spin_unlock(&adapter->tpi_lock);
return 0;
}
-static struct mdio_ops mi1_mdio_ext_ops = {
- mi1_mdio_init,
- mi1_mdio_ext_read,
- mi1_mdio_ext_write
+static const struct mdio_ops mi1_mdio_ext_ops = {
+ .init = mi1_mdio_init,
+ .read = mi1_mdio_ext_read,
+ .write = mi1_mdio_ext_write
};
enum {
+ CH_BRD_T110_1CU,
CH_BRD_N110_1F,
CH_BRD_N210_1F,
CH_BRD_T210_1F,
+ CH_BRD_T210_1CU,
+ CH_BRD_N204_4CU,
};
-static struct board_info t1_board[] = {
-
-{ CHBT_BOARD_N110, 1/*ports#*/,
- SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T1,
- CHBT_MAC_PM3393, CHBT_PHY_88X2010,
- 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/,
- 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/,
- 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops,
- &t1_mv88x201x_ops, &mi1_mdio_ext_ops,
- "Chelsio N110 1x10GBaseX NIC" },
-
-{ CHBT_BOARD_N210, 1/*ports#*/,
- SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE /*caps*/, CHBT_TERM_T2,
- CHBT_MAC_PM3393, CHBT_PHY_88X2010,
- 125000000/*clk-core*/, 0/*clk-mc3*/, 0/*clk-mc4*/,
- 1/*espi-ports*/, 0/*clk-cspi*/, 44/*clk-elmer0*/, 0/*mdien*/,
- 0/*mdiinv*/, 1/*mdc*/, 0/*phybaseaddr*/, &t1_pm3393_ops,
- &t1_mv88x201x_ops, &mi1_mdio_ext_ops,
- "Chelsio N210 1x10GBaseX NIC" },
+static const struct board_info t1_board[] = {
+ {
+ .board = CHBT_BOARD_CHT110,
+ .port_number = 1,
+ .caps = SUPPORTED_10000baseT_Full,
+ .chip_term = CHBT_TERM_T1,
+ .chip_mac = CHBT_MAC_PM3393,
+ .chip_phy = CHBT_PHY_MY3126,
+ .clock_core = 125000000,
+ .clock_mc3 = 150000000,
+ .clock_mc4 = 125000000,
+ .espi_nports = 1,
+ .clock_elmer0 = 44,
+ .mdio_mdien = 1,
+ .mdio_mdiinv = 1,
+ .mdio_mdc = 1,
+ .mdio_phybaseaddr = 1,
+ .gmac = &t1_pm3393_ops,
+ .gphy = &t1_my3126_ops,
+ .mdio_ops = &mi1_mdio_ext_ops,
+ .desc = "Chelsio T110 1x10GBase-CX4 TOE",
+ },
+
+ {
+ .board = CHBT_BOARD_N110,
+ .port_number = 1,
+ .caps = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE,
+ .chip_term = CHBT_TERM_T1,
+ .chip_mac = CHBT_MAC_PM3393,
+ .chip_phy = CHBT_PHY_88X2010,
+ .clock_core = 125000000,
+ .espi_nports = 1,
+ .clock_elmer0 = 44,
+ .mdio_mdien = 0,
+ .mdio_mdiinv = 0,
+ .mdio_mdc = 1,
+ .mdio_phybaseaddr = 0,
+ .gmac = &t1_pm3393_ops,
+ .gphy = &t1_mv88x201x_ops,
+ .mdio_ops = &mi1_mdio_ext_ops,
+ .desc = "Chelsio N110 1x10GBaseX NIC",
+ },
+
+ {
+ .board = CHBT_BOARD_N210,
+ .port_number = 1,
+ .caps = SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE,
+ .chip_term = CHBT_TERM_T2,
+ .chip_mac = CHBT_MAC_PM3393,
+ .chip_phy = CHBT_PHY_88X2010,
+ .clock_core = 125000000,
+ .espi_nports = 1,
+ .clock_elmer0 = 44,
+ .mdio_mdien = 0,
+ .mdio_mdiinv = 0,
+ .mdio_mdc = 1,
+ .mdio_phybaseaddr = 0,
+ .gmac = &t1_pm3393_ops,
+ .gphy = &t1_mv88x201x_ops,
+ .mdio_ops = &mi1_mdio_ext_ops,
+ .desc = "Chelsio N210 1x10GBaseX NIC",
+ },
+
+ {
+ .board = CHBT_BOARD_CHT210,
+ .port_number = 1,
+ .caps = SUPPORTED_10000baseT_Full,
+ .chip_term = CHBT_TERM_T2,
+ .chip_mac = CHBT_MAC_PM3393,
+ .chip_phy = CHBT_PHY_88X2010,
+ .clock_core = 125000000,
+ .clock_mc3 = 133000000,
+ .clock_mc4 = 125000000,
+ .espi_nports = 1,
+ .clock_elmer0 = 44,
+ .mdio_mdien = 0,
+ .mdio_mdiinv = 0,
+ .mdio_mdc = 1,
+ .mdio_phybaseaddr = 0,
+ .gmac = &t1_pm3393_ops,
+ .gphy = &t1_mv88x201x_ops,
+ .mdio_ops = &mi1_mdio_ext_ops,
+ .desc = "Chelsio T210 1x10GBaseX TOE",
+ },
+
+ {
+ .board = CHBT_BOARD_CHT210,
+ .port_number = 1,
+ .caps = SUPPORTED_10000baseT_Full,
+ .chip_term = CHBT_TERM_T2,
+ .chip_mac = CHBT_MAC_PM3393,
+ .chip_phy = CHBT_PHY_MY3126,
+ .clock_core = 125000000,
+ .clock_mc3 = 133000000,
+ .clock_mc4 = 125000000,
+ .espi_nports = 1,
+ .clock_elmer0 = 44,
+ .mdio_mdien = 1,
+ .mdio_mdiinv = 1,
+ .mdio_mdc = 1,
+ .mdio_phybaseaddr = 1,
+ .gmac = &t1_pm3393_ops,
+ .gphy = &t1_my3126_ops,
+ .mdio_ops = &mi1_mdio_ext_ops,
+ .desc = "Chelsio T210 1x10GBase-CX4 TOE",
+ },
+
+#ifdef CONFIG_CHELSIO_T1_1G
+ {
+ .board = CHBT_BOARD_CHN204,
+ .port_number = 4,
+ .caps = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full
+ | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full
+ | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg |
+ SUPPORTED_PAUSE | SUPPORTED_TP,
+ .chip_term = CHBT_TERM_T2,
+ .chip_mac = CHBT_MAC_VSC7321,
+ .chip_phy = CHBT_PHY_88E1111,
+ .clock_core = 100000000,
+ .espi_nports = 4,
+ .clock_elmer0 = 44,
+ .mdio_mdien = 0,
+ .mdio_mdiinv = 0,
+ .mdio_mdc = 0,
+ .mdio_phybaseaddr = 4,
+ .gmac = &t1_vsc7326_ops,
+ .gphy = &t1_mv88e1xxx_ops,
+ .mdio_ops = &mi1_mdio_ops,
+ .desc = "Chelsio N204 4x100/1000BaseT NIC",
+ },
+#endif
};
struct pci_device_id t1_pci_tbl[] = {
+ CH_DEVICE(8, 0, CH_BRD_T110_1CU),
+ CH_DEVICE(8, 1, CH_BRD_T110_1CU),
CH_DEVICE(7, 0, CH_BRD_N110_1F),
CH_DEVICE(10, 1, CH_BRD_N210_1F),
- { 0, }
+ CH_DEVICE(11, 1, CH_BRD_T210_1F),
+ CH_DEVICE(14, 1, CH_BRD_T210_1CU),
+ CH_DEVICE(16, 1, CH_BRD_N204_4CU),
+ { 0 }
};
+MODULE_DEVICE_TABLE(pci, t1_pci_tbl);
+
/*
* Return the board_info structure with a given index. Out-of-range indices
* return NULL.
*/
const struct board_info *t1_get_board_info(unsigned int board_id)
{
- return board_id < DIMOF(t1_board) ? &t1_board[board_id] : NULL;
+ return board_id < ARRAY_SIZE(t1_board) ? &t1_board[board_id] : NULL;
}
struct chelsio_vpd_t {
* written to the Control register. The hardware device will set the flag to a
* one when 4B have been transferred to the Data register.
*/
-int t1_seeprom_read(adapter_t *adapter, u32 addr, u32 *data)
+int t1_seeprom_read(adapter_t *adapter, u32 addr, __le32 *data)
{
int i = EEPROM_MAX_POLL;
u16 val;
+ u32 v;
if (addr >= EEPROMSIZE || (addr & 3))
return -EINVAL;
adapter->name, addr);
return -EIO;
}
- pci_read_config_dword(adapter->pdev, A_PCICFG_VPD_DATA, data);
- *data = le32_to_cpu(*data);
+ pci_read_config_dword(adapter->pdev, A_PCICFG_VPD_DATA, &v);
+ *data = cpu_to_le32(v);
return 0;
}
for (addr = 0; !ret && addr < sizeof(*vpd); addr += sizeof(u32))
ret = t1_seeprom_read(adapter, addr,
- (u32 *)((u8 *)vpd + addr));
+ (__le32 *)((u8 *)vpd + addr));
return ret;
}
if (lc->supported & SUPPORTED_Autoneg) {
lc->advertising &= ~(ADVERTISED_ASYM_PAUSE | ADVERTISED_PAUSE);
if (fc) {
- lc->advertising |= ADVERTISED_ASYM_PAUSE;
- if (fc == (PAUSE_RX | PAUSE_TX))
+ if (fc == ((PAUSE_RX | PAUSE_TX) &
+ (mac->adapter->params.nports < 2)))
lc->advertising |= ADVERTISED_PAUSE;
+ else {
+ lc->advertising |= ADVERTISED_ASYM_PAUSE;
+ if (fc == PAUSE_RX)
+ lc->advertising |= ADVERTISED_PAUSE;
+ }
}
phy->ops->advertise(phy, lc->advertising);
mac->ops->set_speed_duplex_fc(mac, lc->speed,
lc->duplex, fc);
/* Also disables autoneg */
+ phy->state = PHY_AUTONEG_RDY;
phy->ops->set_speed_duplex(phy, lc->speed, lc->duplex);
phy->ops->reset(phy, 0);
- } else
+ } else {
+ phy->state = PHY_AUTONEG_EN;
phy->ops->autoneg_enable(phy); /* also resets PHY */
+ }
} else {
+ phy->state = PHY_AUTONEG_RDY;
mac->ops->set_speed_duplex_fc(mac, -1, -1, fc);
lc->fc = (unsigned char)fc;
phy->ops->reset(phy, 0);
/*
* External interrupt handler for boards using elmer0.
*/
-int elmer0_ext_intr_handler(adapter_t *adapter)
+int t1_elmer0_ext_intr_handler(adapter_t *adapter)
{
- struct cphy *phy;
+ struct cphy *phy;
int phy_cause;
- u32 cause;
+ u32 cause;
t1_tpi_read(adapter, A_ELMER0_INT_CAUSE, &cause);
switch (board_info(adapter)->board) {
+#ifdef CONFIG_CHELSIO_T1_1G
+ case CHBT_BOARD_CHT204:
+ case CHBT_BOARD_CHT204E:
+ case CHBT_BOARD_CHN204:
+ case CHBT_BOARD_CHT204V: {
+ int i, port_bit;
+ for_each_port(adapter, i) {
+ port_bit = i + 1;
+ if (!(cause & (1 << port_bit)))
+ continue;
+
+ phy = adapter->port[i].phy;
+ phy_cause = phy->ops->interrupt_handler(phy);
+ if (phy_cause & cphy_cause_link_change)
+ t1_link_changed(adapter, i);
+ }
+ break;
+ }
+ case CHBT_BOARD_CHT101:
+ if (cause & ELMER0_GP_BIT1) { /* Marvell 88E1111 interrupt */
+ phy = adapter->port[0].phy;
+ phy_cause = phy->ops->interrupt_handler(phy);
+ if (phy_cause & cphy_cause_link_change)
+ t1_link_changed(adapter, 0);
+ }
+ break;
+ case CHBT_BOARD_7500: {
+ int p;
+ /*
+ * Elmer0's interrupt cause isn't useful here because there is
+ * only one bit that can be set for all 4 ports. This means
+ * we are forced to check every PHY's interrupt status
+ * register to see who initiated the interrupt.
+ */
+ for_each_port(adapter, p) {
+ phy = adapter->port[p].phy;
+ phy_cause = phy->ops->interrupt_handler(phy);
+ if (phy_cause & cphy_cause_link_change)
+ t1_link_changed(adapter, p);
+ }
+ break;
+ }
+#endif
case CHBT_BOARD_CHT210:
case CHBT_BOARD_N210:
case CHBT_BOARD_N110:
phy = adapter->port[0].phy;
phy_cause = phy->ops->interrupt_handler(phy);
if (phy_cause & cphy_cause_link_change)
- link_changed(adapter, 0);
+ t1_link_changed(adapter, 0);
}
break;
case CHBT_BOARD_8000:
case CHBT_BOARD_CHT110:
- CH_DBG(adapter, INTR, "External interrupt cause 0x%x\n",
+ CH_DBG(adapter, INTR, "External interrupt cause 0x%x\n",
cause);
if (cause & ELMER0_GP_BIT1) { /* PMC3393 INTB */
struct cmac *mac = adapter->port[0].mac;
if (cause & ELMER0_GP_BIT5) { /* XPAK MOD_DETECT */
u32 mod_detect;
- t1_tpi_read(adapter, A_ELMER0_GPI_STAT, &mod_detect);
- CH_MSG(adapter, INFO, LINK, "XPAK %s\n",
+ t1_tpi_read(adapter,
+ A_ELMER0_GPI_STAT, &mod_detect);
+ CH_MSG(adapter, INFO, LINK, "XPAK %s\n",
mod_detect ? "removed" : "inserted");
- }
+ }
break;
+#ifdef CONFIG_CHELSIO_T1_COUGAR
+ case CHBT_BOARD_COUGAR:
+ if (adapter->params.nports == 1) {
+ if (cause & ELMER0_GP_BIT1) { /* Vitesse MAC */
+ struct cmac *mac = adapter->port[0].mac;
+ mac->ops->interrupt_handler(mac);
+ }
+ if (cause & ELMER0_GP_BIT5) { /* XPAK MOD_DETECT */
+ }
+ } else {
+ int i, port_bit;
+
+ for_each_port(adapter, i) {
+ port_bit = i ? i + 1 : 0;
+ if (!(cause & (1 << port_bit)))
+ continue;
+
+ phy = adapter->port[i].phy;
+ phy_cause = phy->ops->interrupt_handler(phy);
+ if (phy_cause & cphy_cause_link_change)
+ t1_link_changed(adapter, i);
+ }
+ }
+ break;
+#endif
}
t1_tpi_write(adapter, A_ELMER0_INT_CAUSE, cause);
return 0;
/* Enable PCIX & external chip interrupts on ASIC boards. */
if (t1_is_asic(adapter)) {
- u32 pl_intr = t1_read_reg_4(adapter, A_PL_ENABLE);
+ u32 pl_intr = readl(adapter->regs + A_PL_ENABLE);
/* PCI-X interrupts */
pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE,
- 0xffffffff);
+ 0xffffffff);
adapter->slow_intr_mask |= F_PL_INTR_EXT | F_PL_INTR_PCIX;
pl_intr |= F_PL_INTR_EXT | F_PL_INTR_PCIX;
- t1_write_reg_4(adapter, A_PL_ENABLE, pl_intr);
+ writel(pl_intr, adapter->regs + A_PL_ENABLE);
}
}
/* Disable PCIX & external chip interrupts. */
if (t1_is_asic(adapter))
- t1_write_reg_4(adapter, A_PL_ENABLE, 0);
+ writel(0, adapter->regs + A_PL_ENABLE);
/* PCI-X interrupts */
pci_write_config_dword(adapter->pdev, A_PCICFG_INTR_ENABLE, 0);
/* Enable interrupts for external devices. */
if (t1_is_asic(adapter)) {
- u32 pl_intr = t1_read_reg_4(adapter, A_PL_CAUSE);
+ u32 pl_intr = readl(adapter->regs + A_PL_CAUSE);
- t1_write_reg_4(adapter, A_PL_CAUSE,
- pl_intr | F_PL_INTR_EXT | F_PL_INTR_PCIX);
+ writel(pl_intr | F_PL_INTR_EXT | F_PL_INTR_PCIX,
+ adapter->regs + A_PL_CAUSE);
}
/* PCI-X interrupts */
*/
static int asic_slow_intr(adapter_t *adapter)
{
- u32 cause = t1_read_reg_4(adapter, A_PL_CAUSE);
+ u32 cause = readl(adapter->regs + A_PL_CAUSE);
cause &= adapter->slow_intr_mask;
if (!cause)
t1_elmer0_ext_intr(adapter);
/* Clear the interrupts just processed. */
- t1_write_reg_4(adapter, A_PL_CAUSE, cause);
- (void)t1_read_reg_4(adapter, A_PL_CAUSE); /* flush writes */
+ writel(cause, adapter->regs + A_PL_CAUSE);
+ readl(adapter->regs + A_PL_CAUSE); /* flush writes */
return 1;
}
int t1_slow_intr_handler(adapter_t *adapter)
{
+#ifdef CONFIG_CHELSIO_T1_1G
+ if (!t1_is_asic(adapter))
+ return fpga_slow_intr(adapter);
+#endif
return asic_slow_intr(adapter);
}
/* Power sequencing is a work-around for Intel's XPAKs. */
static void power_sequence_xpak(adapter_t* adapter)
{
- u32 mod_detect;
- u32 gpo;
+ u32 mod_detect;
+ u32 gpo;
- /* Check for XPAK */
- t1_tpi_read(adapter, A_ELMER0_GPI_STAT, &mod_detect);
+ /* Check for XPAK */
+ t1_tpi_read(adapter, A_ELMER0_GPI_STAT, &mod_detect);
if (!(ELMER0_GP_BIT5 & mod_detect)) {
/* XPAK is present */
t1_tpi_read(adapter, A_ELMER0_GPO, &gpo);
if (p->chip_version == CHBT_TERM_T1 ||
p->chip_version == CHBT_TERM_T2 ||
p->chip_version == CHBT_TERM_FPGA) {
- u32 val = t1_read_reg_4(adapter, A_TP_PC_CONFIG);
+ u32 val = readl(adapter->regs + A_TP_PC_CONFIG);
val = G_TP_PC_REV(val);
if (val == 2)
case CHBT_BOARD_N210:
case CHBT_BOARD_CHT210:
case CHBT_BOARD_COUGAR:
- t1_tpi_par(adapter, 0xf);
- t1_tpi_write(adapter, A_ELMER0_GPO, 0x800);
+ t1_tpi_par(adapter, 0xf);
+ t1_tpi_write(adapter, A_ELMER0_GPO, 0x800);
break;
case CHBT_BOARD_CHT110:
- t1_tpi_par(adapter, 0xf);
- t1_tpi_write(adapter, A_ELMER0_GPO, 0x1800);
+ t1_tpi_par(adapter, 0xf);
+ t1_tpi_write(adapter, A_ELMER0_GPO, 0x1800);
- /* TBD XXX Might not need. This fixes a problem
- * described in the Intel SR XPAK errata.
- */
- power_sequence_xpak(adapter);
+ /* TBD XXX Might not need. This fixes a problem
+ * described in the Intel SR XPAK errata.
+ */
+ power_sequence_xpak(adapter);
+ break;
+#ifdef CONFIG_CHELSIO_T1_1G
+ case CHBT_BOARD_CHT204E:
+ /* add config space write here */
+ case CHBT_BOARD_CHT204:
+ case CHBT_BOARD_CHT204V:
+ case CHBT_BOARD_CHN204:
+ t1_tpi_par(adapter, 0xf);
+ t1_tpi_write(adapter, A_ELMER0_GPO, 0x804);
break;
+ case CHBT_BOARD_CHT101:
+ case CHBT_BOARD_7500:
+ t1_tpi_par(adapter, 0xf);
+ t1_tpi_write(adapter, A_ELMER0_GPO, 0x1804);
+ break;
+#endif
}
return 0;
}
int err = -EIO;
const struct board_info *bi = board_info(adapter);
- if (!adapter->mc4) {
- u32 val = t1_read_reg_4(adapter, A_MC4_CFG);
+ if (!bi->clock_mc4) {
+ u32 val = readl(adapter->regs + A_MC4_CFG);
- t1_write_reg_4(adapter, A_MC4_CFG, val | F_READY | F_MC4_SLOW);
- t1_write_reg_4(adapter, A_MC5_CONFIG,
- F_M_BUS_ENABLE | F_TCAM_RESET);
+ writel(val | F_READY | F_MC4_SLOW, adapter->regs + A_MC4_CFG);
+ writel(F_M_BUS_ENABLE | F_TCAM_RESET,
+ adapter->regs + A_MC5_CONFIG);
}
+#ifdef CONFIG_CHELSIO_T1_COUGAR
+ if (adapter->cspi && t1_cspi_init(adapter->cspi))
+ goto out_err;
+#endif
if (adapter->espi && t1_espi_init(adapter->espi, bi->chip_mac,
bi->espi_nports))
goto out_err;
goto out_err;
err = 0;
- out_err:
+out_err:
return err;
}
/*
* Determine a card's PCI mode.
*/
-static void __devinit get_pci_mode(adapter_t *adapter, struct pci_params *p)
+static void __devinit get_pci_mode(adapter_t *adapter, struct chelsio_pci_params *p)
{
- static unsigned short speed_map[] = { 33, 66, 100, 133 };
+ static const unsigned short speed_map[] = { 33, 66, 100, 133 };
u32 pci_mode;
pci_read_config_dword(adapter->pdev, A_PCICFG_MODE, &pci_mode);
t1_tp_destroy(adapter->tp);
if (adapter->espi)
t1_espi_destroy(adapter->espi);
+#ifdef CONFIG_CHELSIO_T1_COUGAR
+ if (adapter->cspi)
+ t1_cspi_destroy(adapter->cspi);
+#endif
}
static void __devinit init_link_config(struct link_config *lc,
}
}
+#ifdef CONFIG_CHELSIO_T1_COUGAR
+ if (bi->clock_cspi && !(adapter->cspi = t1_cspi_create(adapter))) {
+ CH_ERR("%s: CSPI initialization failed\n",
+ adapter->name);
+ goto error;
+ }
+#endif
/*
* Allocate and initialize the data structures that hold the SW state of
goto error;
}
-
-
if (bi->espi_nports && !(adapter->espi = t1_espi_create(adapter))) {
CH_ERR("%s: ESPI initialization failed\n",
adapter->name);
mac->ops->macaddress_get(mac, hw_addr);
else if (vpd_macaddress_get(adapter, i, hw_addr)) {
CH_ERR("%s: could not read MAC address from VPD ROM\n",
- port_name(adapter, i));
+ adapter->port[i].dev->name);
goto error;
}
- t1_set_hw_addr(adapter, i, hw_addr);
+ memcpy(adapter->port[i].dev->dev_addr, hw_addr, ETH_ALEN);
init_link_config(&adapter->port[i].link_config, bi);
}
t1_interrupts_clear(adapter);
return 0;
- error:
+error:
t1_free_sw_modules(adapter);
return -1;
}