mirror of
https://github.com/opnsense/src.git
synced 2026-06-10 17:22:46 -04:00
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
This commit is contained in:
parent
bac9ff3446
commit
0bbdea7776
6 changed files with 177 additions and 183 deletions
|
|
@ -1156,6 +1156,7 @@ static int get_module_type(struct cphy *phy)
|
|||
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 *phy, int wait)
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -701,7 +701,6 @@ int t3_slow_intr_handler(adapter_t *adapter);
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -1285,6 +1285,49 @@ static void t3_open_rx_traffic(struct cmac *mac, u32 rx_cfg,
|
|||
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 cmac *mac, u32 rx_cfg,
|
|||
*/
|
||||
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))) {
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
/* 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);
|
||||
|
||||
if (force_link_down) {
|
||||
t3_os_link_fault_handler(adapter, port_id);
|
||||
return;
|
||||
pi->link_fault = LF_NO;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1336,77 +1392,67 @@ void t3_link_changed(adapter_t *adapter, int port_id)
|
|||
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) {
|
||||
|
||||
/* down -> up, or up -> up with changed settings */
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
t3_clear_faults(adapter, port_id);
|
||||
|
||||
} else {
|
||||
|
||||
/* up -> down */
|
||||
|
||||
if (adapter->params.rev > 0 && uses_xaui(adapter)) {
|
||||
t3_write_reg(adapter,
|
||||
A_XGM_XAUI_ACT_CTRL + mac->offset, 0);
|
||||
}
|
||||
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (!pi->link_fault)
|
||||
return; /* nothing to do */
|
||||
|
||||
t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low);
|
||||
|
||||
if (adapter->params.rev > 0 && uses_xaui(adapter))
|
||||
t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, 0);
|
||||
|
||||
t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0);
|
||||
t3_mac_enable(mac, MAC_DIRECTION_RX);
|
||||
|
||||
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);
|
||||
link_fault &= F_LINKFAULTCHANGE;
|
||||
|
||||
phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* t3_link_start - apply link configuration to MAC/PHY
|
||||
* @phy: the PHY to setup
|
||||
|
|
@ -1901,10 +1947,12 @@ static void mc7_intr_handler(struct mc7 *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 *adap, unsigned int idx)
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -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 adapter *adapter);
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
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 +
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue