int falcon_xmac_set_pause(struct efx_nic *efx, enum efx_fc_type flow_control) { bool reset; if (flow_control & EFX_FC_AUTO) { EFX_LOG(efx, "10G does not support flow control " "autonegotiation\n"); return -EINVAL; } if ((flow_control & EFX_FC_TX) && !(flow_control & EFX_FC_RX)) return -EINVAL; /* TX flow control may automatically turn itself off if the * link partner (intermittently) stops responding to pause * frames. There isn't any indication that this has happened, * so the best we do is leave it up to the user to spot this * and fix it be cycling transmit flow control on this end. */ reset = ((flow_control & EFX_FC_TX) && !(efx->flow_control & EFX_FC_TX)); if (EFX_WORKAROUND_11482(efx) && reset) { if (falcon_rev(efx) >= FALCON_REV_B0) { /* Recover by resetting the EM block */ if (efx->link_up) falcon_drain_tx_fifo(efx); } else { /* Schedule a reset to recover */ efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); } } efx->flow_control = flow_control; return 0; }
static void falcon_mask_status_intr(struct efx_nic *efx, bool enable) { efx_oword_t reg; if ((falcon_rev(efx) != FALCON_REV_B0) || LOOPBACK_INTERNAL(efx)) return; /* We expect xgmii faults if the wireside link is up */ if (!EFX_WORKAROUND_5147(efx) || !efx->link_up) return; /* We can only use this interrupt to signal the negative edge of * xaui_align [we have to poll the positive edge]. */ if (!efx->mac_up) return; /* Flush the ISR */ if (enable) falcon_read(efx, ®, XM_MGT_INT_REG_B0); EFX_POPULATE_OWORD_2(reg, XM_MSK_RMTFLT, !enable, XM_MSK_LCLFLT, !enable); falcon_write(efx, ®, XM_MGT_INT_MSK_REG_B0); }
static void falcon_mask_status_intr(struct efx_nic *efx, bool enable) { efx_oword_t reg; if ((falcon_rev(efx) < FALCON_REV_B0) || LOOPBACK_INTERNAL(efx)) return; /* Flush the ISR */ if (enable) falcon_read(efx, ®, XM_MGT_INT_REG_B0); EFX_POPULATE_OWORD_2(reg, XM_MSK_RMTFLT, !enable, XM_MSK_LCLFLT, !enable); falcon_write(efx, ®, XM_MGT_INT_MSK_REG_B0); }
static bool falcon_xgmii_status(struct efx_nic *efx) { efx_oword_t reg; if (falcon_rev(efx) < FALCON_REV_B0) return true; /* The ISR latches, so clear it and re-read */ falcon_read(efx, ®, XM_MGT_INT_REG_B0); falcon_read(efx, ®, XM_MGT_INT_REG_B0); if (EFX_OWORD_FIELD(reg, XM_LCLFLT) || EFX_OWORD_FIELD(reg, XM_RMTFLT)) { EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg)); return false; } return true; }
static void falcon_mask_status_intr(struct efx_nic *efx, bool enable) { efx_oword_t reg; if ((falcon_rev(efx) != FALCON_REV_B0) || LOOPBACK_INTERNAL(efx)) return; if (!EFX_WORKAROUND_5147(efx) || !efx->link_up) return; if (!efx->mac_up) return; if (enable) falcon_read(efx, ®, XM_MGT_INT_REG_B0); EFX_POPULATE_OWORD_2(reg, XM_MSK_RMTFLT, !enable, XM_MSK_LCLFLT, !enable); falcon_write(efx, ®, XM_MGT_INT_MSK_REG_B0); }