diff options
author | gnn <gnn@FreeBSD.org> | 2009-05-21 15:08:03 +0000 |
---|---|---|
committer | gnn <gnn@FreeBSD.org> | 2009-05-21 15:08:03 +0000 |
commit | 9857e6abfd3b8b04176b92943bed84e968b24098 (patch) | |
tree | 4c6c6def26c4adc8ee5dccdcc679c5bca51c3f2b /sys/dev/cxgb/cxgb_main.c | |
parent | 44027bf4b716cbbccf8c18757c92214f42dde171 (diff) | |
download | FreeBSD-src-9857e6abfd3b8b04176b92943bed84e968b24098.zip FreeBSD-src-9857e6abfd3b8b04176b92943bed84e968b24098.tar.gz |
Integrate three changes from Chelsio.
1) Add a sysctl that will say what type of PHYs exist on the card.
2) Fix a bug that occurs when an AEL 2005 PHY resets without a transciever
in the card.
3) Unify the PHY link detection code.
Obtained from: Navdeep Parhar
MFC after: 10 days
Diffstat (limited to 'sys/dev/cxgb/cxgb_main.c')
-rw-r--r-- | sys/dev/cxgb/cxgb_main.c | 123 |
1 files changed, 28 insertions, 95 deletions
diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index 9639037..e510025 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -115,7 +115,7 @@ static int offload_open(struct port_info *pi); static void touch_bars(device_t dev); static int offload_close(struct t3cdev *tdev); static void cxgb_link_start(struct port_info *p); -static void cxgb_link_fault(void *arg, int ncount); +int t3_detect_link_fault(adapter_t *adapter, int port_id); static device_method_t cxgb_controller_methods[] = { DEVMETHOD(device_probe, cxgb_controller_probe), @@ -650,6 +650,10 @@ cxgb_controller_attach(device_t dev) sc->params.vpd.ec, sc->params.vpd.sn); device_set_desc_copy(dev, buf); + snprintf(&sc->port_types[0], sizeof(sc->port_types), "%x%x%x%x", + sc->params.vpd.port_type[0], sc->params.vpd.port_type[1], + sc->params.vpd.port_type[2], sc->params.vpd.port_type[3]); + device_printf(sc->dev, "Firmware Version %s\n", &sc->fw_version[0]); callout_reset(&sc->cxgb_tick_ch, CXGB_TICKS(sc), cxgb_tick, sc); t3_add_attach_sysctls(sc); @@ -1069,8 +1073,6 @@ cxgb_port_attach(device_t dev) bcopy(IF_LLADDR(p->ifp), p->hw_addr, ETHER_ADDR_LEN); t3_sge_init_port(p); - TASK_INIT(&p->link_fault_task, 0, cxgb_link_fault, p); - /* If it's MSI or INTx, allocate a single interrupt for everything */ if ((sc->flags & USING_MSIX) == 0) { if ((sc->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, @@ -1257,32 +1259,6 @@ t3_os_pci_restore_state(struct adapter *sc) return (0); } -void t3_os_link_fault(struct adapter *adap, int port_id, int state) -{ - struct port_info *pi = &adap->port[port_id]; - - if (!state) { - if_link_state_change(pi->ifp, LINK_STATE_DOWN); - return; - } - - if (adap->params.nports <= 2) { - struct cmac *mac = &pi->mac; - - /* Clear local faults */ - t3_xgm_intr_disable(adap, port_id); - t3_read_reg(adap, A_XGM_INT_STATUS + pi->mac.offset); - t3_write_reg(adap, A_XGM_INT_CAUSE + pi->mac.offset, F_XGM_INT); - - t3_set_reg_field(adap, A_XGM_INT_ENABLE + pi->mac.offset, - F_XGM_INT, F_XGM_INT); - t3_xgm_intr_enable(adap, pi->port_id); - t3_mac_enable(mac, MAC_DIRECTION_TX); - } - - if_link_state_change(pi->ifp, LINK_STATE_UP); -} - /** * t3_os_link_changed - handle link status changes * @adapter: the adapter associated with the link change @@ -1301,48 +1277,12 @@ t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, int speed, int duplex, int fc) { struct port_info *pi = &adapter->port[port_id]; - struct cmac *mac = &adapter->port[port_id].mac; if (link_status) { - DELAY(10); - t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX); - /* Clear errors created by MAC enable */ - t3_set_reg_field(adapter, A_XGM_STAT_CTRL + pi->mac.offset, - F_CLRSTATS, 1); - - if (adapter->params.nports <= 2) { - /* Clear local faults */ - t3_xgm_intr_disable(adapter, pi->port_id); - t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset); - t3_write_reg(adapter, A_XGM_INT_CAUSE + pi->mac.offset, - F_XGM_INT); - - t3_set_reg_field(adapter, - A_XGM_INT_ENABLE + pi->mac.offset, - F_XGM_INT, F_XGM_INT); - t3_xgm_intr_enable(adapter, pi->port_id); - } - + pi->ifp->if_baudrate = IF_Mbps(speed); if_link_state_change(pi->ifp, LINK_STATE_UP); - } else { - t3_xgm_intr_disable(adapter, pi->port_id); - t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset); - if (adapter->params.nports <= 2) { - t3_set_reg_field(adapter, - A_XGM_INT_ENABLE + pi->mac.offset, - F_XGM_INT, 0); - } - - /* PR 5666. We shouldn't power down 1G phys */ - if (is_10G(adapter)) - pi->phy.ops->power_down(&pi->phy, 1); - - t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset); - t3_mac_disable(mac, MAC_DIRECTION_RX); - t3_link_start(&pi->phy, mac, &pi->link_config); - + } else if_link_state_change(pi->ifp, LINK_STATE_DOWN); - } } /** @@ -1395,22 +1335,6 @@ t3_os_ext_intr_handler(adapter_t *sc) ADAPTER_UNLOCK(sc); } -static void -cxgb_link_fault(void *arg, int ncount) -{ - struct port_info *pi = arg; - - t3_link_fault(pi->adapter, pi->port_id); -} - -void t3_os_link_fault_handler(struct adapter *sc, int port_id) -{ - struct port_info *pi = &sc->port[port_id]; - - pi->link_fault = 1; - taskqueue_enqueue(sc->tq, &pi->link_fault_task); -} - void t3_os_set_hw_addr(adapter_t *adapter, int port_idx, u8 hw_addr[]) { @@ -1966,15 +1890,16 @@ cxgb_init_locked(struct port_info *p) log(LOG_WARNING, "Could not initialize offload capabilities\n"); } + + device_printf(sc->dev, "enabling interrupts on port=%d\n", p->port_id); + t3_port_intr_enable(sc, p->port_id); + #if !defined(LINK_ATTACH) cxgb_link_start(p); t3_link_changed(sc, p->port_id); #endif ifp->if_baudrate = IF_Mbps(p->link_config.speed); - device_printf(sc->dev, "enabling interrupts on port=%d\n", p->port_id); - t3_port_intr_enable(sc, p->port_id); - callout_reset(&sc->cxgb_tick_ch, CXGB_TICKS(sc), cxgb_tick, sc); t3_sge_reset_adapter(sc); @@ -2338,12 +2263,23 @@ check_link_status(adapter_t *sc) { int i; + /* For synchronized access to open_device_map */ + ADAPTER_LOCK_ASSERT_OWNED(sc); + for (i = 0; i < (sc)->params.nports; ++i) { struct port_info *p = &sc->port[i]; - - if (!(p->phy.caps & SUPPORTED_IRQ)) + struct link_config *lc = &p->link_config; + + if (!isset(&sc->open_device_map, p->port_id)) { + /* + * port is down, report link down too. Note + * that we do this for IRQ based PHYs too. + */ + lc->link_ok = 0; + t3_os_link_changed(sc, i, lc->link_ok, lc->speed, + lc->duplex, lc->fc); + } else if (p->link_fault || !(p->phy.caps & SUPPORTED_IRQ)) t3_link_changed(sc, i); - p->ifp->if_baudrate = IF_Mbps(p->link_config.speed); } } @@ -2410,12 +2346,12 @@ cxgb_tick_handler(void *arg, int count) int i; uint32_t cause, reset; - if(sc->flags & CXGB_SHUTDOWN) + if(sc->flags & CXGB_SHUTDOWN || !(sc->flags & FULL_INIT_DONE)) return; ADAPTER_LOCK(sc); - if (p->linkpoll_period) - check_link_status(sc); + + check_link_status(sc); sc->check_task_cnt++; @@ -2457,9 +2393,6 @@ cxgb_tick_handler(void *arg, int count) t3_mac_update_stats(mac); PORT_UNLOCK(pi); - if (pi->link_fault) - taskqueue_enqueue(sc->tq, &pi->link_fault_task); - ifp->if_opackets = mstats->tx_frames_64 + mstats->tx_frames_65_127 + |