static int aq100x_reset(struct cphy *phy, int wait) { int err = t3_phy_reset(phy, MDIO_MMD_VEND1, 3000); if (err) CH_WARN(phy->adapter, "PHY%d: reset failed (0x%x).\n", phy->mdio.prtad, err); return err; }
static int aq100x_reset(struct cphy *phy, int wait) { /* * Ignore the caller specified wait time; always wait for the reset to * complete. Can take up to 3s. */ int err = t3_phy_reset(phy, MDIO_DEV_VEND1, 3000); if (err) CH_WARN(phy->adapter, "PHY%d: reset failed (0x%x).\n", phy->addr, err); return err; }
int t1_mc4_intr_handler(struct pemc4 *mc4) { adapter_t *adapter = mc4->adapter; u32 cause = t1_read_reg_4(adapter, A_MC4_INT_CAUSE); if (cause & F_MC4_CORR_ERR) { mc4->intr_cnt.corr_err++; CH_WARN("%s: MC4 correctable error at addr 0x%x, " "data 0x%x 0x%x 0x%x 0x%x 0x%x\n", adapter_name(adapter), G_MC4_CE_ADDR(t1_read_reg_4(adapter, A_MC4_CE_ADDR)), t1_read_reg_4(adapter, A_MC4_CE_DATA0), t1_read_reg_4(adapter, A_MC4_CE_DATA1), t1_read_reg_4(adapter, A_MC4_CE_DATA2), t1_read_reg_4(adapter, A_MC4_CE_DATA3), t1_read_reg_4(adapter, A_MC4_CE_DATA4)); } if (cause & F_MC4_UNCORR_ERR) { mc4->intr_cnt.uncorr_err++; CH_ALERT("%s: MC4 uncorrectable error at addr 0x%x, " "data 0x%x 0x%x 0x%x 0x%x 0x%x\n", adapter_name(adapter), G_MC4_UE_ADDR(t1_read_reg_4(adapter, A_MC4_UE_ADDR)), t1_read_reg_4(adapter, A_MC4_UE_DATA0), t1_read_reg_4(adapter, A_MC4_UE_DATA1), t1_read_reg_4(adapter, A_MC4_UE_DATA2), t1_read_reg_4(adapter, A_MC4_UE_DATA3), t1_read_reg_4(adapter, A_MC4_UE_DATA4)); } if (cause & F_MC4_ADDR_ERR) { mc4->intr_cnt.addr_err++; CH_ALERT("%s: MC4 address error\n", adapter_name(adapter)); } if (cause & MC4_INT_FATAL) t1_fatal_err(adapter); t1_write_reg_4(mc4->adapter, A_MC4_INT_CAUSE, cause); return 0; }
static int __devinit init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static int version_printed; int i, err, pci_using_dac = 0; unsigned long mmio_start, mmio_len; const struct board_info *bi; struct adapter *adapter = NULL; struct port_info *pi; if (!version_printed) { printk(KERN_INFO "%s - version %s\n", DRV_DESCRIPTION, DRV_VERSION); ++version_printed; } err = pci_enable_device(pdev); if (err) return err; if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { CH_ERR("%s: cannot find PCI device memory base address\n", pci_name(pdev)); err = -ENODEV; goto out_disable_pdev; } if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { pci_using_dac = 1; if (pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) { CH_ERR("%s: unable to obtain 64-bit DMA for" "consistent allocations\n", pci_name(pdev)); err = -ENODEV; goto out_disable_pdev; } } else if ((err = pci_set_dma_mask(pdev, DMA_32BIT_MASK)) != 0) { CH_ERR("%s: no usable DMA configuration\n", pci_name(pdev)); goto out_disable_pdev; } err = pci_request_regions(pdev, DRV_NAME); if (err) { CH_ERR("%s: cannot obtain PCI resources\n", pci_name(pdev)); goto out_disable_pdev; } pci_set_master(pdev); mmio_start = pci_resource_start(pdev, 0); mmio_len = pci_resource_len(pdev, 0); bi = t1_get_board_info(ent->driver_data); for (i = 0; i < bi->port_number; ++i) { struct net_device *netdev; netdev = alloc_etherdev(adapter ? 0 : sizeof(*adapter)); if (!netdev) { err = -ENOMEM; goto out_free_dev; } SET_MODULE_OWNER(netdev); SET_NETDEV_DEV(netdev, &pdev->dev); if (!adapter) { adapter = netdev->priv; adapter->pdev = pdev; adapter->port[0].dev = netdev; /* so we don't leak it */ adapter->regs = ioremap(mmio_start, mmio_len); if (!adapter->regs) { CH_ERR("%s: cannot map device registers\n", pci_name(pdev)); err = -ENOMEM; goto out_free_dev; } if (t1_get_board_rev(adapter, bi, &adapter->params)) { err = -ENODEV; /* Can't handle this chip rev */ goto out_free_dev; } adapter->name = pci_name(pdev); adapter->msg_enable = dflt_msg_enable; adapter->mmio_len = mmio_len; init_MUTEX(&adapter->mib_mutex); spin_lock_init(&adapter->tpi_lock); spin_lock_init(&adapter->work_lock); spin_lock_init(&adapter->async_lock); INIT_WORK(&adapter->ext_intr_handler_task, ext_intr_task, adapter); INIT_WORK(&adapter->stats_update_task, mac_stats_task, adapter); #ifdef work_struct init_timer(&adapter->stats_update_timer); adapter->stats_update_timer.function = mac_stats_timer; adapter->stats_update_timer.data = (unsigned long)adapter; #endif pci_set_drvdata(pdev, netdev); } pi = &adapter->port[i]; pi->dev = netdev; netif_carrier_off(netdev); netdev->irq = pdev->irq; netdev->if_port = i; netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len - 1; netdev->priv = adapter; netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; netdev->features |= NETIF_F_LLTX; adapter->flags |= RX_CSUM_ENABLED | TCP_CSUM_CAPABLE; if (pci_using_dac) netdev->features |= NETIF_F_HIGHDMA; if (vlan_tso_capable(adapter)) { #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) adapter->flags |= VLAN_ACCEL_CAPABLE; netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; netdev->vlan_rx_register = vlan_rx_register; netdev->vlan_rx_kill_vid = vlan_rx_kill_vid; #endif adapter->flags |= TSO_CAPABLE; netdev->features |= NETIF_F_TSO; } netdev->open = cxgb_open; netdev->stop = cxgb_close; netdev->hard_start_xmit = t1_start_xmit; netdev->hard_header_len += (adapter->flags & TSO_CAPABLE) ? sizeof(struct cpl_tx_pkt_lso) : sizeof(struct cpl_tx_pkt); netdev->get_stats = t1_get_stats; netdev->set_multicast_list = t1_set_rxmode; netdev->do_ioctl = t1_ioctl; netdev->change_mtu = t1_change_mtu; netdev->set_mac_address = t1_set_mac_addr; #ifdef CONFIG_NET_POLL_CONTROLLER netdev->poll_controller = t1_netpoll; #endif netdev->weight = 64; SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops); } if (t1_init_sw_modules(adapter, bi) < 0) { err = -ENODEV; goto out_free_dev; } /* * The card is now ready to go. If any errors occur during device * registration we do not fail the whole card but rather proceed only * with the ports we manage to register successfully. However we must * register at least one net device. */ for (i = 0; i < bi->port_number; ++i) { err = register_netdev(adapter->port[i].dev); if (err) CH_WARN("%s: cannot register net device %s, skipping\n", pci_name(pdev), adapter->port[i].dev->name); else { /* * Change the name we use for messages to the name of * the first successfully registered interface. */ if (!adapter->registered_device_map) adapter->name = adapter->port[i].dev->name; __set_bit(i, &adapter->registered_device_map); } } if (!adapter->registered_device_map) { CH_ERR("%s: could not register any net devices\n", pci_name(pdev)); goto out_release_adapter_res; } printk(KERN_INFO "%s: %s (rev %d), %s %dMHz/%d-bit\n", adapter->name, bi->desc, adapter->params.chip_revision, adapter->params.pci.is_pcix ? "PCIX" : "PCI", adapter->params.pci.speed, adapter->params.pci.width); return 0; out_release_adapter_res: t1_free_sw_modules(adapter); out_free_dev: if (adapter) { if (adapter->regs) iounmap(adapter->regs); for (i = bi->port_number - 1; i >= 0; --i) if (adapter->port[i].dev) { cxgb_proc_cleanup(adapter, proc_root_driver); kfree(adapter->port[i].dev); } } pci_release_regions(pdev); out_disable_pdev: pci_disable_device(pdev); pci_set_drvdata(pdev, NULL); return err; }
int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { unsigned int v, v2, gpio, wait; int err; cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops, SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full | SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_AUI, "1000/10GBASE-T"); /* * The PHY has been out of reset ever since the system powered up. So * we do a hard reset over here. */ gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL; t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0); msleep(1); t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio); /* * Give it enough time to load the firmware and get ready for mdio. */ msleep(1000); wait = 500; /* in 10ms increments */ do { err = mdio_read(phy, MDIO_DEV_VEND1, MII_BMCR, &v); if (err || v == 0xffff) { /* Allow prep_adapter to succeed when ffff is read */ CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n", phy_addr, err, v); goto done; } v &= AQ_RESET; if (v) msleep(10); } while (v && --wait); if (v) { CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n", phy_addr, v); goto done; /* let prep_adapter succeed */ } /* Datasheet says 3s max but this has been observed */ wait = (500 - wait) * 10 + 1000; if (wait > 3000) CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait); /* Firmware version check. */ (void) mdio_read(phy, MDIO_DEV_VEND1, AQ_FW_VERSION, &v); if (v != 101) CH_WARN(adapter, "PHY%d: unsupported firmware %d\n", phy_addr, v); /* * The PHY should start in really-low-power mode. Prepare it for normal * operations. */ err = mdio_read(phy, MDIO_DEV_VEND1, MII_BMCR, &v); if (err) return err; if (v & AQ_LOWPOWER) { err = t3_mdio_change_bits(phy, MDIO_DEV_VEND1, MII_BMCR, AQ_LOWPOWER, 0); if (err) return err; msleep(10); } else CH_WARN(adapter, "PHY%d does not start in low power mode.\n", phy_addr); /* * Verify XAUI settings, but let prep succeed no matter what. */ v = v2 = 0; mdio_read(phy, MDIO_DEV_XGXS, AQ_XAUI_RX_CFG, &v); mdio_read(phy, MDIO_DEV_XGXS, AQ_XAUI_TX_CFG, &v2); if (v != 0x1b || v2 != 0x1b) CH_WARN(adapter, "PHY%d: incorrect XAUI settings (0x%x, 0x%x).\n", phy_addr, v, v2); done: return err; }
/** * t4vf_get_sge_params - retrieve adapter Scatter gather Engine parameters * @adapter: the adapter * * Retrieves various core SGE parameters in the form of hardware SGE * register values. The caller is responsible for decoding these as * needed. The SGE parameters are stored in @adapter->params.sge. */ int t4vf_get_sge_params(struct adapter *adapter) { struct sge_params *sp = &adapter->params.sge; u32 params[7], vals[7]; u32 whoami; unsigned int pf, s_hps; int i, v; params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | V_FW_PARAMS_PARAM_XYZ(A_SGE_CONTROL)); params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | V_FW_PARAMS_PARAM_XYZ(A_SGE_HOST_PAGE_SIZE)); params[2] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_0_AND_1)); params[3] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_2_AND_3)); params[4] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | V_FW_PARAMS_PARAM_XYZ(A_SGE_TIMER_VALUE_4_AND_5)); params[5] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | V_FW_PARAMS_PARAM_XYZ(A_SGE_CONM_CTRL)); params[6] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | V_FW_PARAMS_PARAM_XYZ(A_SGE_INGRESS_RX_THRESHOLD)); v = t4vf_query_params(adapter, 7, params, vals); if (v != FW_SUCCESS) return v; sp->sge_control = vals[0]; sp->counter_val[0] = G_THRESHOLD_0(vals[6]); sp->counter_val[1] = G_THRESHOLD_1(vals[6]); sp->counter_val[2] = G_THRESHOLD_2(vals[6]); sp->counter_val[3] = G_THRESHOLD_3(vals[6]); sp->timer_val[0] = core_ticks_to_us(adapter, G_TIMERVALUE0(vals[2])); sp->timer_val[1] = core_ticks_to_us(adapter, G_TIMERVALUE1(vals[2])); sp->timer_val[2] = core_ticks_to_us(adapter, G_TIMERVALUE2(vals[3])); sp->timer_val[3] = core_ticks_to_us(adapter, G_TIMERVALUE3(vals[3])); sp->timer_val[4] = core_ticks_to_us(adapter, G_TIMERVALUE4(vals[4])); sp->timer_val[5] = core_ticks_to_us(adapter, G_TIMERVALUE5(vals[4])); sp->fl_starve_threshold = G_EGRTHRESHOLD(vals[5]) * 2 + 1; if (is_t4(adapter)) sp->fl_starve_threshold2 = sp->fl_starve_threshold; else sp->fl_starve_threshold2 = G_EGRTHRESHOLDPACKING(vals[5]) * 2 + 1; /* * We need the Queues/Page and Host Page Size for our VF. * This is based on the PF from which we're instantiated. */ whoami = t4_read_reg(adapter, VF_PL_REG(A_PL_VF_WHOAMI)); pf = G_SOURCEPF(whoami); s_hps = (S_HOSTPAGESIZEPF0 + (S_HOSTPAGESIZEPF1 - S_HOSTPAGESIZEPF0) * pf); sp->page_shift = ((vals[1] >> s_hps) & M_HOSTPAGESIZEPF0) + 10; for (i = 0; i < SGE_FLBUF_SIZES; i++) { params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | V_FW_PARAMS_PARAM_XYZ(A_SGE_FL_BUFFER_SIZE0 + (4 * i))); v = t4vf_query_params(adapter, 1, params, vals); if (v != FW_SUCCESS) return v; sp->sge_fl_buffer_size[i] = vals[0]; } /* * T4 uses a single control field to specify both the PCIe Padding and * Packing Boundary. T5 introduced the ability to specify these * separately with the Padding Boundary in SGE_CONTROL and and Packing * Boundary in SGE_CONTROL2. So for T5 and later we need to grab * SGE_CONTROL in order to determine how ingress packet data will be * laid out in Packed Buffer Mode. Unfortunately, older versions of * the firmware won't let us retrieve SGE_CONTROL2 so if we get a * failure grabbing it we throw an error since we can't figure out the * right value. */ sp->spg_len = sp->sge_control & F_EGRSTATUSPAGESIZE ? 128 : 64; sp->fl_pktshift = G_PKTSHIFT(sp->sge_control); sp->pad_boundary = 1 << (G_INGPADBOUNDARY(sp->sge_control) + 5); if (is_t4(adapter)) sp->pack_boundary = sp->pad_boundary; else { params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | V_FW_PARAMS_PARAM_XYZ(A_SGE_CONTROL2)); v = t4vf_query_params(adapter, 1, params, vals); if (v != FW_SUCCESS) { CH_ERR(adapter, "Unable to get SGE Control2; " "probably old firmware.\n"); return v; } if (G_INGPACKBOUNDARY(vals[0]) == 0) sp->pack_boundary = 16; else sp->pack_boundary = 1 << (G_INGPACKBOUNDARY(vals[0]) + 5); } /* * For T5 and later we want to use the new BAR2 Doorbells. * Unfortunately, older firmware didn't allow the this register to be * read. */ if (!is_t4(adapter)) { unsigned int s_qpp; params[0] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | V_FW_PARAMS_PARAM_XYZ(A_SGE_EGRESS_QUEUES_PER_PAGE_VF)); params[1] = (V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | V_FW_PARAMS_PARAM_XYZ(A_SGE_INGRESS_QUEUES_PER_PAGE_VF)); v = t4vf_query_params(adapter, 2, params, vals); if (v != FW_SUCCESS) { CH_WARN(adapter, "Unable to get VF SGE Queues/Page; " "probably old firmware.\n"); return v; } s_qpp = (S_QUEUESPERPAGEPF0 + (S_QUEUESPERPAGEPF1 - S_QUEUESPERPAGEPF0) * pf); sp->eq_s_qpp = ((vals[0] >> s_qpp) & M_QUEUESPERPAGEPF0); sp->iq_s_qpp = ((vals[1] >> s_qpp) & M_QUEUESPERPAGEPF0); }
int t3_aq100x_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, const struct mdio_ops *mdio_ops) { unsigned int v, v2, gpio, wait; int err; cphy_init(phy, adapter, phy_addr, &aq100x_ops, mdio_ops, SUPPORTED_1000baseT_Full | SUPPORTED_10000baseT_Full | SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_AUI, "1000/10GBASE-T"); gpio = phy_addr ? F_GPIO10_OUT_VAL : F_GPIO6_OUT_VAL; t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, 0); msleep(1); t3_set_reg_field(adapter, A_T3DBG_GPIO_EN, gpio, gpio); msleep(1000); wait = 500; do { err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v); if (err || v == 0xffff) { CH_WARN(adapter, "PHY%d: reset failed (0x%x, 0x%x).\n", phy_addr, err, v); goto done; } v &= AQ_RESET; if (v) msleep(10); } while (v && --wait); if (v) { CH_WARN(adapter, "PHY%d: reset timed out (0x%x).\n", phy_addr, v); goto done; } wait = (500 - wait) * 10 + 1000; if (wait > 3000) CH_WARN(adapter, "PHY%d: reset took %ums\n", phy_addr, wait); t3_mdio_read(phy, MDIO_MMD_VEND1, AQ_FW_VERSION, &v); if (v != 101) CH_WARN(adapter, "PHY%d: unsupported firmware %d\n", phy_addr, v); err = t3_mdio_read(phy, MDIO_MMD_VEND1, MDIO_CTRL1, &v); if (err) return err; if (v & AQ_LOWPOWER) { err = t3_mdio_change_bits(phy, MDIO_MMD_VEND1, MDIO_CTRL1, AQ_LOWPOWER, 0); if (err) return err; msleep(10); } else CH_WARN(adapter, "PHY%d does not start in low power mode.\n", phy_addr); v = v2 = 0; t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_RX_CFG, &v); t3_mdio_read(phy, MDIO_MMD_PHYXS, AQ_XAUI_TX_CFG, &v2); if (v != 0x1b || v2 != 0x1b) CH_WARN(adapter, "PHY%d: incorrect XAUI settings (0x%x, 0x%x).\n", phy_addr, v, v2); done: return err; }
int t1_mc3_intr_handler(struct pemc3 *mc3) { adapter_t *adapter = mc3->adapter; int cause_reg = A_MC3_INT_CAUSE; u32 cause; #ifdef CONFIG_CHELSIO_T1_1G if (!t1_is_asic(adapter)) cause_reg = FPGA_MC3_REG_INTRCAUSE; #endif cause = t1_read_reg_4(adapter, cause_reg); if (cause & F_MC3_CORR_ERR) { mc3->intr_cnt.corr_err++; CH_WARN("%s: MC3 correctable error at addr 0x%x, " "data 0x%x 0x%x 0x%x 0x%x 0x%x\n", adapter_name(adapter), G_MC3_CE_ADDR(t1_read_reg_4(adapter, A_MC3_CE_ADDR)), t1_read_reg_4(adapter, A_MC3_CE_DATA0), t1_read_reg_4(adapter, A_MC3_CE_DATA1), t1_read_reg_4(adapter, A_MC3_CE_DATA2), t1_read_reg_4(adapter, A_MC3_CE_DATA3), t1_read_reg_4(adapter, A_MC3_CE_DATA4)); } if (cause & F_MC3_UNCORR_ERR) { mc3->intr_cnt.uncorr_err++; CH_ALERT("%s: MC3 uncorrectable error at addr 0x%x, " "data 0x%x 0x%x 0x%x 0x%x 0x%x\n", adapter_name(adapter), G_MC3_UE_ADDR(t1_read_reg_4(adapter, A_MC3_UE_ADDR)), t1_read_reg_4(adapter, A_MC3_UE_DATA0), t1_read_reg_4(adapter, A_MC3_UE_DATA1), t1_read_reg_4(adapter, A_MC3_UE_DATA2), t1_read_reg_4(adapter, A_MC3_UE_DATA3), t1_read_reg_4(adapter, A_MC3_UE_DATA4)); } if (G_MC3_PARITY_ERR(cause)) { mc3->intr_cnt.parity_err++; CH_ALERT("%s: MC3 parity error 0x%x\n", adapter_name(adapter), G_MC3_PARITY_ERR(cause)); } if (cause & F_MC3_ADDR_ERR) { mc3->intr_cnt.addr_err++; CH_ALERT("%s: MC3 address error\n", adapter_name(adapter)); } if (cause & MC3_INTR_FATAL) t1_fatal_err(adapter); if (t1_is_T1B(adapter)) { /* * Workaround for T1B bug: we must write to enable register to * clear interrupts. */ t1_write_reg_4(adapter, A_MC3_INT_ENABLE, cause); /* restore enable */ t1_write_reg_4(adapter, A_MC3_INT_ENABLE, MC3_INTR_MASK); } else t1_write_reg_4(adapter, cause_reg, cause); return 0; }