From owner-svn-src-all@FreeBSD.ORG Thu May 21 15:08:03 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8636B10656B6; Thu, 21 May 2009 15:08:03 +0000 (UTC) (envelope-from gnn@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 719188FC0A; Thu, 21 May 2009 15:08:03 +0000 (UTC) (envelope-from gnn@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n4LF835g070228; Thu, 21 May 2009 15:08:03 GMT (envelope-from gnn@svn.freebsd.org) Received: (from gnn@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n4LF83lV070222; Thu, 21 May 2009 15:08:03 GMT (envelope-from gnn@svn.freebsd.org) Message-Id: <200905211508.n4LF83lV070222@svn.freebsd.org> From: "George V. Neville-Neil" Date: Thu, 21 May 2009 15:08:03 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r192540 - in head/sys/dev/cxgb: . common X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 May 2009 15:08:04 -0000 Author: gnn Date: Thu May 21 15:08:03 2009 New Revision: 192540 URL: http://svn.freebsd.org/changeset/base/192540 Log: 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 Modified: head/sys/dev/cxgb/common/cxgb_ael1002.c head/sys/dev/cxgb/common/cxgb_common.h head/sys/dev/cxgb/common/cxgb_t3_hw.c head/sys/dev/cxgb/cxgb_adapter.h head/sys/dev/cxgb/cxgb_main.c head/sys/dev/cxgb/cxgb_sge.c Modified: head/sys/dev/cxgb/common/cxgb_ael1002.c ============================================================================== --- head/sys/dev/cxgb/common/cxgb_ael1002.c Thu May 21 14:52:36 2009 (r192539) +++ head/sys/dev/cxgb/common/cxgb_ael1002.c Thu May 21 15:08:03 2009 (r192540) @@ -1156,6 +1156,7 @@ static int get_module_type(struct cphy * v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 131); if (v < 0) return v; + v &= 0xf0; if (v == 0x10) return phy_modtype_lrm; if (v == 0x40) @@ -1245,7 +1246,9 @@ static int ael2005_reset(struct cphy *ph return err; phy->modtype = (u8)err; - if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) + if (err == phy_modtype_none || err == phy_modtype_unknown) + err = 0; + else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) err = ael2005_setup_twinax_edc(phy, err); else err = ael2005_setup_sr_edc(phy); Modified: head/sys/dev/cxgb/common/cxgb_common.h ============================================================================== --- head/sys/dev/cxgb/common/cxgb_common.h Thu May 21 14:52:36 2009 (r192539) +++ head/sys/dev/cxgb/common/cxgb_common.h Thu May 21 15:08:03 2009 (r192540) @@ -701,7 +701,6 @@ int t3_slow_intr_handler(adapter_t *adap int t3_phy_intr_handler(adapter_t *adapter); void t3_link_changed(adapter_t *adapter, int port_id); -void t3_link_fault(adapter_t *adapter, int port_id); int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc); const struct adapter_info *t3_get_adapter_info(unsigned int board_id); int t3_seeprom_read(adapter_t *adapter, u32 addr, u32 *data); Modified: head/sys/dev/cxgb/common/cxgb_t3_hw.c ============================================================================== --- head/sys/dev/cxgb/common/cxgb_t3_hw.c Thu May 21 14:52:36 2009 (r192539) +++ head/sys/dev/cxgb/common/cxgb_t3_hw.c Thu May 21 15:08:03 2009 (r192540) @@ -1285,6 +1285,49 @@ static void t3_open_rx_traffic(struct cm t3_write_reg(mac->adapter, A_XGM_RX_HASH_LOW, rx_hash_low); } +static int t3_detect_link_fault(adapter_t *adapter, int port_id) +{ + struct port_info *pi = adap2pinfo(adapter, port_id); + struct cmac *mac = &pi->mac; + uint32_t rx_cfg, rx_hash_high, rx_hash_low; + int link_fault; + + /* stop rx */ + t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low); + t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0); + + /* clear status and make sure intr is enabled */ + (void) t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset); + t3_xgm_intr_enable(adapter, port_id); + + /* restart rx */ + t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, F_RXEN); + t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low); + + link_fault = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset); + return (link_fault & F_LINKFAULTCHANGE ? 1 : 0); +} + +static void t3_clear_faults(adapter_t *adapter, int port_id) +{ + struct port_info *pi = adap2pinfo(adapter, port_id); + struct cmac *mac = &pi->mac; + + t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + mac->offset, + F_ENDROPPKT, 0); + t3_mac_enable(mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX); + t3_set_reg_field(adapter, A_XGM_STAT_CTRL + mac->offset, F_CLRSTATS, 1); + + if (adapter->params.nports <= 2) { + t3_xgm_intr_disable(adapter, pi->port_id); + t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset); + t3_write_reg(adapter, A_XGM_INT_CAUSE + mac->offset, F_XGM_INT); + t3_set_reg_field(adapter, A_XGM_INT_ENABLE + mac->offset, + F_XGM_INT, F_XGM_INT); + t3_xgm_intr_enable(adapter, pi->port_id); + } +} + /** * t3_link_changed - handle interface link changes * @adapter: the adapter @@ -1296,34 +1339,47 @@ static void t3_open_rx_traffic(struct cm */ void t3_link_changed(adapter_t *adapter, int port_id) { - int link_ok, speed, duplex, fc; + int link_ok, speed, duplex, fc, link_fault, link_change; struct port_info *pi = adap2pinfo(adapter, port_id); struct cphy *phy = &pi->phy; struct cmac *mac = &pi->mac; struct link_config *lc = &pi->link_config; - int force_link_down = 0; + + link_ok = lc->link_ok; + speed = lc->speed; + duplex = lc->duplex; + fc = lc->fc; + link_fault = 0; phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); - if (!lc->link_ok && link_ok && adapter->params.nports <= 2) { - u32 rx_cfg, rx_hash_high, rx_hash_low; - u32 status; + /* + * Check for link faults if any of these is true: + * a) A link fault is suspected, and PHY says link ok + * b) PHY link transitioned from down -> up + */ + if (adapter->params.nports <= 2 && + ((pi->link_fault && link_ok) || (!lc->link_ok && link_ok))) { + + link_fault = t3_detect_link_fault(adapter, port_id); + if (link_fault) { + if (pi->link_fault != LF_YES) { + mac->stats.link_faults++; + pi->link_fault = LF_YES; + } - t3_xgm_intr_enable(adapter, port_id); - t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low); - t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0); - t3_mac_enable(mac, MAC_DIRECTION_RX); + /* Don't report link up or any other change */ + link_ok = 0; + speed = lc->speed; + duplex = lc->duplex; + fc = lc->fc; + } else { + /* clear faults here if this was a false alarm. */ + if (pi->link_fault == LF_MAYBE && + link_ok && lc->link_ok) + t3_clear_faults(adapter, port_id); - status = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset); - if (status & F_LINKFAULTCHANGE) { - mac->stats.link_faults++; - force_link_down = 1; - } - t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low); - - if (force_link_down) { - t3_os_link_fault_handler(adapter, port_id); - return; + pi->link_fault = LF_NO; } } @@ -1336,75 +1392,65 @@ void t3_link_changed(adapter_t *adapter, duplex == lc->duplex && fc == lc->fc) return; /* nothing changed */ - if (link_ok != lc->link_ok && adapter->params.rev > 0 && - uses_xaui(adapter)) { - if (link_ok) - t3b_pcs_reset(mac); - t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, - link_ok ? F_TXACTENABLE | F_RXEN : 0); - } + link_change = link_ok != lc->link_ok; lc->link_ok = (unsigned char)link_ok; lc->speed = speed < 0 ? SPEED_INVALID : speed; lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex; - if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) { - /* Set MAC speed, duplex, and flow control to match PHY. */ - t3_mac_set_speed_duplex_fc(mac, speed, duplex, fc); - lc->fc = (unsigned char)fc; - } + if (link_ok) { - t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc); -} - -void t3_link_fault(adapter_t *adapter, int port_id) -{ - struct port_info *pi = adap2pinfo(adapter, port_id); - struct cmac *mac = &pi->mac; - struct cphy *phy = &pi->phy; - struct link_config *lc = &pi->link_config; - int link_ok, speed, duplex, fc, link_fault; - u32 rx_cfg, rx_hash_high, rx_hash_low; + /* down -> up, or up -> up with changed settings */ - if (!pi->link_fault) - return; /* nothing to do */ + if (link_change && adapter->params.rev > 0 && + uses_xaui(adapter)) { + t3b_pcs_reset(mac); + t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, + F_TXACTENABLE | F_RXEN); + } - t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low); + if (speed >= 0 && lc->autoneg == AUTONEG_ENABLE) { + /* Set MAC settings to match PHY. */ + t3_mac_set_speed_duplex_fc(mac, speed, duplex, fc); + lc->fc = (unsigned char)fc; + } - if (adapter->params.rev > 0 && uses_xaui(adapter)) - t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, 0); + t3_clear_faults(adapter, port_id); - t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0); - t3_mac_enable(mac, MAC_DIRECTION_RX); + } else { - t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low); + /* up -> down */ - link_fault = t3_read_reg(adapter, - A_XGM_INT_STATUS + mac->offset); - link_fault &= F_LINKFAULTCHANGE; + if (adapter->params.rev > 0 && uses_xaui(adapter)) { + t3_write_reg(adapter, + A_XGM_XAUI_ACT_CTRL + mac->offset, 0); + } - phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); + t3_xgm_intr_disable(adapter, pi->port_id); + if (adapter->params.nports <= 2) { + t3_set_reg_field(adapter, + A_XGM_INT_ENABLE + mac->offset, + F_XGM_INT, 0); + } - if (link_fault) { - lc->link_ok = 0; - lc->speed = SPEED_INVALID; - lc->duplex = DUPLEX_INVALID; - - t3_os_link_fault(adapter, port_id, 0); - - /* Account link faults only when the phy reports a link up */ - if (link_ok) - mac->stats.link_faults++; - } else { - if (link_ok) - t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, - F_TXACTENABLE | F_RXEN); + if (!link_fault) { + if (is_10G(adapter)) + pi->phy.ops->power_down(&pi->phy, 1); + t3_mac_disable(mac, MAC_DIRECTION_RX); + t3_link_start(phy, mac, lc); + } - pi->link_fault = 0; - lc->link_ok = (unsigned char)link_ok; - lc->speed = speed < 0 ? SPEED_INVALID : speed; - lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex; - t3_os_link_fault(adapter, port_id, link_ok); + /* + * Make sure Tx FIFO continues to drain, even as rxen is left + * high to help detect and indicate remote faults. + */ + t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + mac->offset, 0, + F_ENDROPPKT); + t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0); + t3_write_reg(adapter, A_XGM_TX_CTRL + mac->offset, F_TXEN); + t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, F_RXEN); } + + t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc); } /** @@ -1901,10 +1947,12 @@ static void mc7_intr_handler(struct mc7 static int mac_intr_handler(adapter_t *adap, unsigned int idx) { u32 cause; + struct port_info *pi; struct cmac *mac; idx = idx == 0 ? 0 : adapter_info(adap)->nports0; /* MAC idx -> port */ - mac = &adap2pinfo(adap, idx)->mac; + pi = adap2pinfo(adap, idx); + mac = &pi->mac; /* * We mask out interrupt causes for which we're not taking interrupts. @@ -1937,9 +1985,9 @@ static int mac_intr_handler(adapter_t *a t3_set_reg_field(adap, A_XGM_INT_ENABLE + mac->offset, F_XGM_INT, 0); - mac->stats.link_faults++; - t3_os_link_fault_handler(adap, idx); + /* link fault suspected */ + pi->link_fault = LF_MAYBE; } t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause); Modified: head/sys/dev/cxgb/cxgb_adapter.h ============================================================================== --- head/sys/dev/cxgb/cxgb_adapter.h Thu May 21 14:52:36 2009 (r192539) +++ head/sys/dev/cxgb/cxgb_adapter.h Thu May 21 15:08:03 2009 (r192540) @@ -100,6 +100,12 @@ extern int cxgb_debug; #define SX_DESTROY sx_destroy #endif +enum { + LF_NO = 0, + LF_MAYBE, + LF_YES +}; + struct port_info { struct adapter *adapter; struct ifnet *ifp; @@ -123,7 +129,6 @@ struct port_info { uint8_t hw_addr[ETHER_ADDR_LEN]; struct task timer_reclaim_task; - struct task link_fault_task; struct cdev *port_cdev; #define PORT_LOCK_NAME_LEN 32 @@ -393,6 +398,7 @@ struct adapter { device_t portdev[MAX_NPORTS]; struct t3cdev tdev; char fw_version[64]; + char port_types[MAX_NPORTS + 1]; uint32_t open_device_map; uint32_t registered_device_map; #ifdef USE_SX @@ -435,6 +441,7 @@ struct t3_rx_mode { #define ADAPTER_LOCK_INIT(adap, name) SX_INIT(&(adap)->lock, name) #define ADAPTER_LOCK_DEINIT(adap) SX_DESTROY(&(adap)->lock) #define ADAPTER_LOCK_ASSERT_NOTOWNED(adap) sx_assert(&(adap)->lock, SA_UNLOCKED) +#define ADAPTER_LOCK_ASSERT_OWNED(adap) sx_assert(&(adap)->lock, SA_LOCKED) #else #define PORT_LOCK(port) mtx_lock(&(port)->lock); #define PORT_UNLOCK(port) mtx_unlock(&(port)->lock); @@ -446,7 +453,8 @@ struct t3_rx_mode { #define ADAPTER_UNLOCK(adap) mtx_unlock(&(adap)->lock); #define ADAPTER_LOCK_INIT(adap, name) mtx_init(&(adap)->lock, name, 0, MTX_DEF) #define ADAPTER_LOCK_DEINIT(adap) mtx_destroy(&(adap)->lock) -#define ADAPTER_LOCK_ASSERT_NOTOWNED(adap) mtx_assert(&(adap)->lock, MO_NOTOWNED) +#define ADAPTER_LOCK_ASSERT_NOTOWNED(adap) mtx_assert(&(adap)->lock, MA_NOTOWNED) +#define ADAPTER_LOCK_ASSERT_OWNED(adap) mtx_assert(&(adap)->lock, MA_OWNED) #endif @@ -530,8 +538,6 @@ int t3_os_pci_restore_state(struct adapt void t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, int speed, int duplex, int fc); void t3_os_phymod_changed(struct adapter *adap, int port_id); -void t3_os_link_fault(adapter_t *adapter, int port_id, int state); -void t3_os_link_fault_handler(adapter_t *adapter, int port_id); void t3_sge_err_intr_handler(adapter_t *adapter); int t3_offload_tx(struct t3cdev *, struct mbuf *); void t3_os_ext_intr_handler(adapter_t *adapter); Modified: head/sys/dev/cxgb/cxgb_main.c ============================================================================== --- head/sys/dev/cxgb/cxgb_main.c Thu May 21 14:52:36 2009 (r192539) +++ head/sys/dev/cxgb/cxgb_main.c Thu May 21 15:08:03 2009 (r192540) @@ -115,7 +115,7 @@ static int offload_open(struct port_info 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 * 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, i 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]; + struct link_config *lc = &p->link_config; - if (!(p->phy.caps & SUPPORTED_IRQ)) + 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 + Modified: head/sys/dev/cxgb/cxgb_sge.c ============================================================================== --- head/sys/dev/cxgb/cxgb_sge.c Thu May 21 14:52:36 2009 (r192539) +++ head/sys/dev/cxgb/cxgb_sge.c Thu May 21 15:08:03 2009 (r192540) @@ -3349,6 +3349,10 @@ t3_add_attach_sysctls(adapter_t *sc) "hw_revision", CTLFLAG_RD, &sc->params.rev, 0, "chip model"); + SYSCTL_ADD_STRING(ctx, children, OID_AUTO, + "port_types", + CTLFLAG_RD, &sc->port_types, + 0, "type of ports"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "enable_debug", CTLFLAG_RW, &cxgb_debug, @@ -3680,6 +3684,7 @@ t3_add_configured_sysctls(adapter_t *sc) CXGB_SYSCTL_ADD_ULONG(xaui_pcs_align_change); CXGB_SYSCTL_ADD_ULONG(num_toggled); CXGB_SYSCTL_ADD_ULONG(num_resets); + CXGB_SYSCTL_ADD_ULONG(link_faults); #undef CXGB_SYSCTL_ADD_ULONG } }