/* Called from falcon_process_eventq for MCDI events */ void efx_mcdi_process_event(struct efx_channel *channel, efx_qword_t *event) { struct efx_nic *efx = channel->efx; int code = EFX_QWORD_FIELD(*event, MCDI_EVENT_CODE); u32 data = EFX_QWORD_FIELD(*event, MCDI_EVENT_DATA); switch (code) { case MCDI_EVENT_CODE_BADSSERT: netif_err(efx, hw, efx->net_dev, "MC watchdog or assertion failure at 0x%x\n", data); efx_mcdi_ev_death(efx, EINTR); break; case MCDI_EVENT_CODE_PMNOTICE: netif_info(efx, wol, efx->net_dev, "MCDI PM event.\n"); break; case MCDI_EVENT_CODE_CMDDONE: efx_mcdi_ev_cpl(efx, MCDI_EVENT_FIELD(*event, CMDDONE_SEQ), MCDI_EVENT_FIELD(*event, CMDDONE_DATALEN), MCDI_EVENT_FIELD(*event, CMDDONE_ERRNO)); break; case MCDI_EVENT_CODE_LINKCHANGE: efx_mcdi_process_link_change(efx, event); break; case MCDI_EVENT_CODE_SENSOREVT: efx_mcdi_sensor_event(efx, event); break; case MCDI_EVENT_CODE_SCHEDERR: netif_info(efx, hw, efx->net_dev, "MC Scheduler error address=0x%x\n", data); break; case MCDI_EVENT_CODE_REBOOT: netif_info(efx, hw, efx->net_dev, "MC Reboot\n"); efx_mcdi_ev_death(efx, EIO); break; case MCDI_EVENT_CODE_MAC_STATS_DMA: /* MAC stats are gather lazily. We can ignore this. */ break; default: netif_err(efx, hw, efx->net_dev, "Unknown MCDI event 0x%x\n", code); } }
static void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev) { unsigned int monitor, state, value; const char *name, *state_txt; monitor = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR); state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE); value = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_VALUE); /* Deal gracefully with the board having more drivers than we * know about, but do not expect new sensor states. */ name = (monitor >= ARRAY_SIZE(sensor_names)) ? "No sensor name available" : sensor_names[monitor]; EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names)); state_txt = sensor_status_names[state]; netif_err(efx, hw, efx->net_dev, "Sensor %d (%s) reports condition '%s' for raw value %d\n", monitor, name, state_txt, value); }
void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev) { unsigned int type, state, value; const char *name = NULL, *state_txt; type = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR); state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE); value = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_VALUE); if (type < ARRAY_SIZE(efx_mcdi_sensor_type)) name = efx_mcdi_sensor_type[type].label; if (!name) name = "No sensor name available"; EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names)); state_txt = sensor_status_names[state]; netif_err(efx, hw, efx->net_dev, "Sensor %d (%s) reports condition '%s' for raw value %d\n", type, name, state_txt, value); }
static bool falcon_handle_global_event(struct efx_channel *channel, efx_qword_t *event) { struct efx_nic *efx = channel->efx; struct falcon_nic_data *nic_data = efx->nic_data; if (EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_G_PHY0_INTR) || EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XG_PHY0_INTR) || EFX_QWORD_FIELD(*event, FSF_AB_GLB_EV_XFP_PHY0_INTR)) return true; if ((efx_nic_rev(efx) == EFX_REV_FALCON_B0) && EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) { nic_data->xmac_poll_required = true; return true; } if (efx_nic_rev(efx) <= EFX_REV_FALCON_A1 ? EFX_QWORD_FIELD(*event, FSF_AA_GLB_EV_RX_RECOVERY) : EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_RX_RECOVERY)) { netif_err(efx, rx_err, efx->net_dev, "channel %d seen global RX_RESET event. Resetting.\n", channel->channel); atomic_inc(&efx->rx_reset); efx_schedule_reset(efx, EFX_WORKAROUND_6555(efx) ? RESET_TYPE_RX_RECOVERY : RESET_TYPE_DISABLE); return true; } return false; }
static void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev) { u32 flags, fcntl, speed, lpa; speed = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_SPEED); EFX_BUG_ON_PARANOID(speed >= ARRAY_SIZE(efx_mcdi_event_link_speed)); speed = efx_mcdi_event_link_speed[speed]; flags = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LINK_FLAGS); fcntl = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_FCNTL); lpa = EFX_QWORD_FIELD(*ev, MCDI_EVENT_LINKCHANGE_LP_CAP); /* efx->link_state is only modified by efx_mcdi_phy_get_link(), * which is only run after flushing the event queues. Therefore, it * is safe to modify the link state outside of the mac_lock here. */ efx_mcdi_phy_decode_link(efx, &efx->link_state, speed, flags, fcntl); efx_mcdi_phy_check_fcntl(efx, lpa); efx_link_status_changed(efx); }