PHY LOCK acquires the hardware lock via bxe_acquire_phy_lock() and releases it via bxe_release_phy_lock(). It was simply acquiring a mutex earlier which can cause the PHY to use bogus values. Fixes intermittent link failures.
bxe_ioctl() completes all functions within its context as opposed to a taskqueue earlier. bxe_handle_rx_mode_tq() no longer required. bxe_set_rx_mode() handles the functionality within its context Submitted by:gary.zambrano@qlogic.com MFC after:5 days
This commit is contained in:
parent
73adf3b3f8
commit
04e9541d02
@ -726,7 +726,6 @@ static __noinline int bxe_nic_unload(struct bxe_softc *sc,
|
||||
uint8_t keep_link);
|
||||
|
||||
static void bxe_handle_sp_tq(void *context, int pending);
|
||||
static void bxe_handle_rx_mode_tq(void *context, int pending);
|
||||
static void bxe_handle_fp_tq(void *context, int pending);
|
||||
|
||||
|
||||
@ -1174,7 +1173,17 @@ bxe_release_hw_lock(struct bxe_softc *sc,
|
||||
REG_WR(sc, hw_lock_control_reg, resource_bit);
|
||||
return (0);
|
||||
}
|
||||
static void bxe_acquire_phy_lock(struct bxe_softc *sc)
|
||||
{
|
||||
BXE_PHY_LOCK(sc);
|
||||
bxe_acquire_hw_lock(sc,HW_LOCK_RESOURCE_MDIO);
|
||||
}
|
||||
|
||||
static void bxe_release_phy_lock(struct bxe_softc *sc)
|
||||
{
|
||||
bxe_release_hw_lock(sc,HW_LOCK_RESOURCE_MDIO);
|
||||
BXE_PHY_UNLOCK(sc);
|
||||
}
|
||||
/*
|
||||
* Per pf misc lock must be acquired before the per port mcp lock. Otherwise,
|
||||
* had we done things the other way around, if two pfs from the same port
|
||||
@ -4764,28 +4773,6 @@ bxe_handle_chip_tq(void *context,
|
||||
|
||||
switch (work)
|
||||
{
|
||||
case CHIP_TQ_START:
|
||||
if ((if_getflags(sc->ifp) & IFF_UP) &&
|
||||
!(if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING)) {
|
||||
/* start the interface */
|
||||
BLOGD(sc, DBG_LOAD, "Starting the interface...\n");
|
||||
BXE_CORE_LOCK(sc);
|
||||
bxe_init_locked(sc);
|
||||
BXE_CORE_UNLOCK(sc);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHIP_TQ_STOP:
|
||||
if (!(if_getflags(sc->ifp) & IFF_UP) &&
|
||||
(if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING)) {
|
||||
/* bring down the interface */
|
||||
BLOGD(sc, DBG_LOAD, "Stopping the interface...\n");
|
||||
bxe_periodic_stop(sc);
|
||||
BXE_CORE_LOCK(sc);
|
||||
bxe_stop_locked(sc);
|
||||
BXE_CORE_UNLOCK(sc);
|
||||
}
|
||||
break;
|
||||
|
||||
case CHIP_TQ_REINIT:
|
||||
if (if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) {
|
||||
@ -4859,21 +4846,22 @@ bxe_ioctl(if_t ifp,
|
||||
/* toggle the interface state up or down */
|
||||
BLOGD(sc, DBG_IOCTL, "Received SIOCSIFFLAGS ioctl\n");
|
||||
|
||||
BXE_CORE_LOCK(sc);
|
||||
/* check if the interface is up */
|
||||
if (if_getflags(ifp) & IFF_UP) {
|
||||
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
|
||||
/* set the receive mode flags */
|
||||
bxe_set_rx_mode(sc);
|
||||
} else {
|
||||
atomic_store_rel_long(&sc->chip_tq_flags, CHIP_TQ_START);
|
||||
taskqueue_enqueue(sc->chip_tq, &sc->chip_tq_task);
|
||||
bxe_init_locked(sc);
|
||||
}
|
||||
} else {
|
||||
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
|
||||
atomic_store_rel_long(&sc->chip_tq_flags, CHIP_TQ_STOP);
|
||||
taskqueue_enqueue(sc->chip_tq, &sc->chip_tq_task);
|
||||
bxe_periodic_stop(sc);
|
||||
bxe_stop_locked(sc);
|
||||
}
|
||||
}
|
||||
BXE_CORE_UNLOCK(sc);
|
||||
|
||||
break;
|
||||
|
||||
@ -4885,7 +4873,9 @@ bxe_ioctl(if_t ifp,
|
||||
/* check if the interface is up */
|
||||
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
|
||||
/* set the receive mode flags */
|
||||
BXE_CORE_LOCK(sc);
|
||||
bxe_set_rx_mode(sc);
|
||||
BXE_CORE_UNLOCK(sc);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -5044,8 +5034,11 @@ bxe_ioctl(if_t ifp,
|
||||
if (reinit && (if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING)) {
|
||||
BLOGD(sc, DBG_LOAD | DBG_IOCTL,
|
||||
"Re-initializing hardware from IOCTL change\n");
|
||||
atomic_store_rel_long(&sc->chip_tq_flags, CHIP_TQ_REINIT);
|
||||
taskqueue_enqueue(sc->chip_tq, &sc->chip_tq_task);
|
||||
bxe_periodic_stop(sc);
|
||||
BXE_CORE_LOCK(sc);
|
||||
bxe_stop_locked(sc);
|
||||
bxe_init_locked(sc);
|
||||
BXE_CORE_UNLOCK(sc);
|
||||
}
|
||||
|
||||
return (error);
|
||||
@ -7487,8 +7480,7 @@ bxe_attn_int_asserted(struct bxe_softc *sc,
|
||||
if (asserted & ATTN_HARD_WIRED_MASK) {
|
||||
if (asserted & ATTN_NIG_FOR_FUNC) {
|
||||
|
||||
BXE_PHY_LOCK(sc);
|
||||
|
||||
bxe_acquire_phy_lock(sc);
|
||||
/* save nig interrupt mask */
|
||||
nig_mask = REG_RD(sc, nig_int_mask_addr);
|
||||
|
||||
@ -7581,7 +7573,7 @@ bxe_attn_int_asserted(struct bxe_softc *sc,
|
||||
|
||||
REG_WR(sc, nig_int_mask_addr, nig_mask);
|
||||
|
||||
BXE_PHY_UNLOCK(sc);
|
||||
bxe_release_phy_lock(sc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -8339,10 +8331,10 @@ bxe_attn_int_deasserted3(struct bxe_softc *sc,
|
||||
if (sc->link_vars.periodic_flags &
|
||||
ELINK_PERIODIC_FLAGS_LINK_EVENT) {
|
||||
/* sync with link */
|
||||
BXE_PHY_LOCK(sc);
|
||||
bxe_acquire_phy_lock(sc);
|
||||
sc->link_vars.periodic_flags &=
|
||||
~ELINK_PERIODIC_FLAGS_LINK_EVENT;
|
||||
BXE_PHY_UNLOCK(sc);
|
||||
bxe_release_phy_lock(sc);
|
||||
if (IS_MF(sc))
|
||||
; // XXX bxe_link_sync_notify(sc);
|
||||
bxe_link_report(sc);
|
||||
@ -8535,9 +8527,9 @@ bxe_attn_int_deasserted0(struct bxe_softc *sc,
|
||||
}
|
||||
|
||||
if ((attn & sc->link_vars.aeu_int_mask) && sc->port.pmf) {
|
||||
BXE_PHY_LOCK(sc);
|
||||
bxe_acquire_phy_lock(sc);
|
||||
elink_handle_module_detect_int(&sc->link_params);
|
||||
BXE_PHY_UNLOCK(sc);
|
||||
bxe_release_phy_lock(sc);
|
||||
}
|
||||
|
||||
if (attn & HW_INTERRUT_ASSERT_SET_0) {
|
||||
@ -9564,11 +9556,6 @@ bxe_interrupt_detach(struct bxe_softc *sc)
|
||||
}
|
||||
}
|
||||
|
||||
if (sc->rx_mode_tq) {
|
||||
taskqueue_drain(sc->rx_mode_tq, &sc->rx_mode_tq_task);
|
||||
taskqueue_free(sc->rx_mode_tq);
|
||||
sc->rx_mode_tq = NULL;
|
||||
}
|
||||
|
||||
if (sc->sp_tq) {
|
||||
taskqueue_drain(sc->sp_tq, &sc->sp_tq_task);
|
||||
@ -9602,14 +9589,6 @@ bxe_interrupt_attach(struct bxe_softc *sc)
|
||||
taskqueue_start_threads(&sc->sp_tq, 1, PWAIT, /* lower priority */
|
||||
"%s", sc->sp_tq_name);
|
||||
|
||||
snprintf(sc->rx_mode_tq_name, sizeof(sc->rx_mode_tq_name),
|
||||
"bxe%d_rx_mode_tq", sc->unit);
|
||||
TASK_INIT(&sc->rx_mode_tq_task, 0, bxe_handle_rx_mode_tq, sc);
|
||||
sc->rx_mode_tq = taskqueue_create_fast(sc->rx_mode_tq_name, M_NOWAIT,
|
||||
taskqueue_thread_enqueue,
|
||||
&sc->rx_mode_tq);
|
||||
taskqueue_start_threads(&sc->rx_mode_tq, 1, PWAIT, /* lower priority */
|
||||
"%s", sc->rx_mode_tq_name);
|
||||
|
||||
for (i = 0; i < sc->num_queues; i++) {
|
||||
fp = &sc->fp[i];
|
||||
@ -12363,9 +12342,9 @@ bxe_link_report_locked(struct bxe_softc *sc)
|
||||
static void
|
||||
bxe_link_report(struct bxe_softc *sc)
|
||||
{
|
||||
BXE_PHY_LOCK(sc);
|
||||
bxe_acquire_phy_lock(sc);
|
||||
bxe_link_report_locked(sc);
|
||||
BXE_PHY_UNLOCK(sc);
|
||||
bxe_release_phy_lock(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -12481,7 +12460,7 @@ bxe_initial_phy_init(struct bxe_softc *sc,
|
||||
sc->link_params.feature_config_flags |= feat;
|
||||
}
|
||||
|
||||
BXE_PHY_LOCK(sc);
|
||||
bxe_acquire_phy_lock(sc);
|
||||
|
||||
if (load_mode == LOAD_DIAG) {
|
||||
lp->loopback_mode = ELINK_LOOPBACK_XGXS;
|
||||
@ -12502,7 +12481,7 @@ bxe_initial_phy_init(struct bxe_softc *sc,
|
||||
|
||||
rc = elink_phy_init(&sc->link_params, &sc->link_vars);
|
||||
|
||||
BXE_PHY_UNLOCK(sc);
|
||||
bxe_release_phy_lock(sc);
|
||||
|
||||
bxe_calc_fc_adv(sc);
|
||||
|
||||
@ -12694,18 +12673,13 @@ bxe_set_uc_list(struct bxe_softc *sc)
|
||||
}
|
||||
|
||||
static void
|
||||
bxe_handle_rx_mode_tq(void *context,
|
||||
int pending)
|
||||
bxe_set_rx_mode(struct bxe_softc *sc)
|
||||
{
|
||||
struct bxe_softc *sc = (struct bxe_softc *)context;
|
||||
if_t ifp = sc->ifp;
|
||||
uint32_t rx_mode = BXE_RX_MODE_NORMAL;
|
||||
|
||||
BXE_CORE_LOCK(sc);
|
||||
|
||||
if (sc->state != BXE_STATE_OPEN) {
|
||||
BLOGD(sc, DBG_SP, "state is %x, returning\n", sc->state);
|
||||
BXE_CORE_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -12747,7 +12721,6 @@ bxe_handle_rx_mode_tq(void *context,
|
||||
if (bxe_test_bit(ECORE_FILTER_RX_MODE_PENDING, &sc->sp_state)) {
|
||||
BLOGD(sc, DBG_LOAD, "Scheduled setting rx_mode with ECORE...\n");
|
||||
bxe_set_bit(ECORE_FILTER_RX_MODE_SCHED, &sc->sp_state);
|
||||
BXE_CORE_UNLOCK(sc);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -12767,14 +12740,8 @@ bxe_handle_rx_mode_tq(void *context,
|
||||
}
|
||||
#endif
|
||||
|
||||
BXE_CORE_UNLOCK(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
bxe_set_rx_mode(struct bxe_softc *sc)
|
||||
{
|
||||
taskqueue_enqueue(sc->rx_mode_tq, &sc->rx_mode_tq_task);
|
||||
}
|
||||
|
||||
/* update flags in shmem */
|
||||
static void
|
||||
@ -12845,13 +12812,13 @@ bxe_periodic_callout_func(void *xsc)
|
||||
*/
|
||||
mb();
|
||||
if (sc->port.pmf) {
|
||||
BXE_PHY_LOCK(sc);
|
||||
bxe_acquire_phy_lock(sc);
|
||||
elink_period_func(&sc->link_params, &sc->link_vars);
|
||||
BXE_PHY_UNLOCK(sc);
|
||||
bxe_release_phy_lock(sc);
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_PF(sc) && !BXE_NOMCP(sc)) {
|
||||
if (IS_PF(sc) && !(sc->flags & BXE_NO_PULSE)) {
|
||||
int mb_idx = SC_FW_MB_IDX(sc);
|
||||
uint32_t drv_pulse;
|
||||
uint32_t mcp_pulse;
|
||||
@ -12995,6 +12962,11 @@ bxe_nic_load(struct bxe_softc *sc,
|
||||
}
|
||||
}
|
||||
|
||||
/* set ALWAYS_ALIVE bit in shmem */
|
||||
sc->fw_drv_pulse_wr_seq |= DRV_PULSE_ALWAYS_ALIVE;
|
||||
bxe_drv_pulse(sc);
|
||||
sc->flags |= BXE_NO_PULSE;
|
||||
|
||||
/* attach interrupts */
|
||||
if (bxe_interrupt_attach(sc) != 0) {
|
||||
sc->state = BXE_STATE_CLOSED;
|
||||
@ -16750,10 +16722,10 @@ bxe_common_init_phy(struct bxe_softc *sc)
|
||||
shmem2_base[1] = SHMEM2_RD(sc, other_shmem2_base_addr);
|
||||
}
|
||||
|
||||
BXE_PHY_LOCK(sc);
|
||||
bxe_acquire_phy_lock(sc);
|
||||
elink_common_init_phy(sc, shmem_base, shmem2_base,
|
||||
sc->devinfo.chip_id, 0);
|
||||
BXE_PHY_UNLOCK(sc);
|
||||
bxe_release_phy_lock(sc);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -18630,9 +18602,9 @@ static void
|
||||
bxe_link_reset(struct bxe_softc *sc)
|
||||
{
|
||||
if (!BXE_NOMCP(sc)) {
|
||||
BXE_PHY_LOCK(sc);
|
||||
bxe_acquire_phy_lock(sc);
|
||||
elink_lfa_reset(&sc->link_params, &sc->link_vars);
|
||||
BXE_PHY_UNLOCK(sc);
|
||||
bxe_release_phy_lock(sc);
|
||||
} else {
|
||||
if (!CHIP_REV_IS_SLOW(sc)) {
|
||||
BLOGW(sc, "Bootcode is missing - cannot reset link\n");
|
||||
|
@ -1400,6 +1400,7 @@ struct bxe_softc {
|
||||
//#define BXE_SAFC_TX_FLAG 0x00000400
|
||||
#define BXE_MF_FUNC_DIS 0x00000800
|
||||
#define BXE_TX_SWITCHING 0x00001000
|
||||
#define BXE_NO_PULSE 0x00002000
|
||||
|
||||
unsigned long debug; /* per-instance debug logging config */
|
||||
|
||||
@ -1429,11 +1430,6 @@ struct bxe_softc {
|
||||
struct taskqueue *sp_tq;
|
||||
char sp_tq_name[32];
|
||||
|
||||
/* set rx_mode asynchronous taskqueue */
|
||||
struct task rx_mode_tq_task;
|
||||
struct taskqueue *rx_mode_tq;
|
||||
char rx_mode_tq_name[32];
|
||||
|
||||
struct bxe_fastpath fp[MAX_RSS_CHAINS];
|
||||
struct bxe_sp_objs sp_objs[MAX_RSS_CHAINS];
|
||||
|
||||
|
@ -1965,6 +1965,7 @@ __FBSDID("$FreeBSD$");
|
||||
#define MISC_SPIO_SPIO5 0x20
|
||||
#define HW_LOCK_MAX_RESOURCE_VALUE 31
|
||||
#define HW_LOCK_RESOURCE_DRV_FLAGS 10
|
||||
#define HW_LOCK_RESOURCE_MDIO 0
|
||||
#define HW_LOCK_RESOURCE_GPIO 1
|
||||
#define HW_LOCK_RESOURCE_NVRAM 12
|
||||
#define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3
|
||||
|
Loading…
Reference in New Issue
Block a user