struct efx_nic *efx = container_of(data, struct efx_nic, mac_work);
mutex_lock(&efx->mac_lock);
- if (efx->port_enabled)
- efx->mac_op->irq(efx);
mutex_unlock(&efx->mac_lock);
}
mutex_lock(&efx->mac_lock);
efx->port_enabled = true;
__efx_reconfigure_port(efx);
- efx->mac_op->irq(efx);
mutex_unlock(&efx->mac_lock);
}
static struct efx_mac_operations efx_dummy_mac_operations = {
.reconfigure = efx_port_dummy_op_void,
- .poll = efx_port_dummy_op_void,
- .irq = efx_port_dummy_op_void,
};
static struct efx_phy_operations efx_dummy_phy_operations = {
if ((falcon_rev(efx) >= FALCON_REV_B0) &&
EFX_QWORD_FIELD(*event, FSF_BB_GLB_EV_XG_MGT_INTR)) {
- queue_work(efx->workqueue, &efx->mac_work);
+ efx->xmac_poll_required = true;
handled = true;
}
EFX_LOG(efx, "selected %cMAC\n", EFX_IS10G(efx) ? 'X' : 'G');
/* Not all macs support a mac-level link state */
- efx->mac_up = true;
+ efx->xmac_poll_required = false;
rc = falcon_reset_macs(efx);
out:
falcon_sim_phy_event(efx);
}
efx->phy_op->poll(efx);
- efx->mac_op->poll(efx);
+ if (EFX_IS10G(efx))
+ falcon_poll_xmac(efx);
}
/* Zeroes out the SRAM contents. This routine must be called in
extern void falcon_generate_event(struct efx_channel *channel,
efx_qword_t *event);
+extern void falcon_poll_xmac(struct efx_nic *efx);
+
#endif /* EFX_FALCON_H */
s32 status;
/* If XAUI link is up then do not monitor */
- if (EFX_WORKAROUND_7884(efx) && efx->mac_up)
+ if (EFX_WORKAROUND_7884(efx) && !efx->xmac_poll_required)
return 0;
/* Check the powered status of the PHY. Lack of power implies that
s32 status;
/* If XAUI link is up then do not monitor */
- if (EFX_WORKAROUND_7884(efx) && efx->mac_up)
+ if (EFX_WORKAROUND_7884(efx) && !efx->xmac_poll_required)
return 0;
/* Test LHIGH, RHIGH, FAULT, EOT and IOT alarms */
mac_stats->rx_lt64 = mac_stats->rx_good_lt64 + mac_stats->rx_bad_lt64;
}
+static bool falcon_gmac_check_fault(struct efx_nic *efx)
+{
+ return false;
+}
+
struct efx_mac_operations falcon_gmac_operations = {
.reconfigure = falcon_reconfigure_gmac,
.update_stats = falcon_update_stats_gmac,
- .irq = efx_port_dummy_op_void,
- .poll = efx_port_dummy_op_void,
+ .check_fault = falcon_gmac_check_fault,
};
/* 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)
+ if (efx->xmac_poll_required)
return;
/* Flush the ISR */
}
-/* Try and bring the Falcon side of the Falcon-Phy XAUI link fails
- * to come back up. Bash it until it comes back up */
-static void falcon_check_xaui_link_up(struct efx_nic *efx, int tries)
+/* Try to bring up the Falcon side of the Falcon-Phy XAUI link */
+static bool falcon_check_xaui_link_up(struct efx_nic *efx, int tries)
{
- efx->mac_up = falcon_xaui_link_ok(efx);
+ bool mac_up = falcon_xaui_link_ok(efx);
if ((efx->loopback_mode == LOOPBACK_NETWORK) ||
efx_phy_mode_disabled(efx->phy_mode))
/* XAUI link is expected to be down */
- return;
+ return mac_up;
falcon_stop_nic_stats(efx);
- while (!efx->mac_up && tries) {
+ while (!mac_up && tries) {
EFX_LOG(efx, "bashing xaui\n");
falcon_reset_xaui(efx);
udelay(200);
- efx->mac_up = falcon_xaui_link_ok(efx);
+ mac_up = falcon_xaui_link_ok(efx);
--tries;
}
falcon_start_nic_stats(efx);
+
+ return mac_up;
+}
+
+static bool falcon_xmac_check_fault(struct efx_nic *efx)
+{
+ return !falcon_check_xaui_link_up(efx, 5);
}
static void falcon_reconfigure_xmac(struct efx_nic *efx)
falcon_reconfigure_mac_wrapper(efx);
- falcon_check_xaui_link_up(efx, 5);
+ efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 5);
falcon_mask_status_intr(efx, true);
}
mac_stats->rx_control * 64);
}
-static void falcon_xmac_irq(struct efx_nic *efx)
-{
- /* The XGMII link has a transient fault, which indicates either:
- * - there's a transient xgmii fault
- * - falcon's end of the xaui link may need a kick
- * - the wire-side link may have gone down, but the lasi/poll()
- * hasn't noticed yet.
- *
- * We only want to even bother polling XAUI if we're confident it's
- * not (1) or (3). In both cases, the only reliable way to spot this
- * is to wait a bit. We do this here by forcing the mac link state
- * to down, and waiting for the mac poll to come round and check
- */
- efx->mac_up = false;
-}
-
-static void falcon_poll_xmac(struct efx_nic *efx)
+void falcon_poll_xmac(struct efx_nic *efx)
{
- if (!EFX_WORKAROUND_5147(efx) || !efx->link_state.up || efx->mac_up)
+ if (!EFX_WORKAROUND_5147(efx) || !efx->link_state.up ||
+ !efx->xmac_poll_required)
return;
falcon_mask_status_intr(efx, false);
- falcon_check_xaui_link_up(efx, 1);
+ efx->xmac_poll_required = !falcon_check_xaui_link_up(efx, 1);
falcon_mask_status_intr(efx, true);
}
struct efx_mac_operations falcon_xmac_operations = {
.reconfigure = falcon_reconfigure_xmac,
.update_stats = falcon_update_stats_xmac,
- .irq = falcon_xmac_irq,
- .poll = falcon_poll_xmac,
+ .check_fault = falcon_xmac_check_fault,
};
* struct efx_mac_operations - Efx MAC operations table
* @reconfigure: Reconfigure MAC. Serialised by the mac_lock
* @update_stats: Update statistics
- * @irq: Hardware MAC event callback. Serialised by the mac_lock
- * @poll: Poll for hardware state. Serialised by the mac_lock
+ * @check_fault: Check fault state. True if fault present.
*/
struct efx_mac_operations {
void (*reconfigure) (struct efx_nic *efx);
void (*update_stats) (struct efx_nic *efx);
- void (*irq) (struct efx_nic *efx);
- void (*poll) (struct efx_nic *efx);
+ bool (*check_fault)(struct efx_nic *efx);
};
/**
* @phy_data: PHY private data (including PHY-specific stats)
* @mdio: PHY MDIO interface
* @phy_mode: PHY operating mode. Serialised by @mac_lock.
- * @mac_up: MAC link state
+ * @xmac_poll_required: XMAC link state needs polling
* @link_state: Current state of the link
* @n_link_state_changes: Number of times the link has changed state
* @promiscuous: Promiscuous flag. Protected by netif_tx_lock.
struct mdio_if_info mdio;
enum efx_phy_mode phy_mode;
- bool mac_up;
+ bool xmac_poll_required;
struct efx_link_state link_state;
unsigned int n_link_state_changes;
flush_workqueue(efx->workqueue);
rmb();
- /* We need both the phy and xaui links to be ok.
- * rather than relying on the falcon_xmac irq/poll
- * regime, just poll xaui directly */
+ /* We need both the PHY and MAC-PHY links to be OK */
link_up = efx->link_state.up;
- if (link_up && EFX_IS10G(efx) &&
- !falcon_xaui_link_ok(efx))
- link_up = false;
+ if (link_up)
+ link_up = !efx->mac_op->check_fault(efx);
} while ((++count < 20) && !link_up);