Skip to content

Commit

Permalink
bnx2x: NAPI and interrupts enable/disable
Browse files Browse the repository at this point in the history
Fixing the order of enabling and disabling NAPI and the interrupts

Signed-off-by: Yitchak Gertner <gertner@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Yitchak Gertner authored and David S. Miller committed Aug 25, 2008
1 parent d101463 commit 65abd74
Showing 1 changed file with 73 additions and 76 deletions.
149 changes: 73 additions & 76 deletions drivers/net/bnx2x_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6058,6 +6058,44 @@ static int bnx2x_req_irq(struct bnx2x *bp)
return rc;
}

static void bnx2x_napi_enable(struct bnx2x *bp)
{
int i;

for_each_queue(bp, i)
napi_enable(&bnx2x_fp(bp, i, napi));
}

static void bnx2x_napi_disable(struct bnx2x *bp)
{
int i;

for_each_queue(bp, i)
napi_disable(&bnx2x_fp(bp, i, napi));
}

static void bnx2x_netif_start(struct bnx2x *bp)
{
if (atomic_dec_and_test(&bp->intr_sem)) {
if (netif_running(bp->dev)) {
if (bp->state == BNX2X_STATE_OPEN)
netif_wake_queue(bp->dev);
bnx2x_napi_enable(bp);
bnx2x_int_enable(bp);
}
}
}

static void bnx2x_netif_stop(struct bnx2x *bp)
{
bnx2x_int_disable_sync(bp);
if (netif_running(bp->dev)) {
bnx2x_napi_disable(bp);
netif_tx_disable(bp->dev);
bp->dev->trans_start = jiffies; /* prevent tx timeout */
}
}

/*
* Init service functions
*/
Expand Down Expand Up @@ -6363,8 +6401,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)

/* Enable Rx interrupt handling before sending the ramrod
as it's completed on Rx FP queue */
for_each_queue(bp, i)
napi_enable(&bnx2x_fp(bp, i, napi));
bnx2x_napi_enable(bp);

/* Enable interrupt handling */
atomic_set(&bp->intr_sem, 0);
Expand Down Expand Up @@ -6431,8 +6468,7 @@ static int bnx2x_nic_load(struct bnx2x *bp, int load_mode)
return 0;

load_netif_stop:
for_each_queue(bp, i)
napi_disable(&bnx2x_fp(bp, i, napi));
bnx2x_napi_disable(bp);
load_rings_free:
/* Free SKBs, SGEs, TPA pool and driver internals */
bnx2x_free_skbs(bp);
Expand Down Expand Up @@ -6614,11 +6650,9 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
bp->rx_mode = BNX2X_RX_MODE_NONE;
bnx2x_set_storm_rx_mode(bp);

if (netif_running(bp->dev)) {
netif_tx_disable(bp->dev);
bp->dev->trans_start = jiffies; /* prevent tx timeout */
}

bnx2x_netif_stop(bp);
if (!netif_running(bp->dev))
bnx2x_napi_disable(bp);
del_timer_sync(&bp->timer);
SHMEM_WR(bp, func_mb[BP_FUNC(bp)].drv_pulse_mb,
(DRV_PULSE_ALWAYS_ALIVE | bp->fw_drv_pulse_wr_seq));
Expand All @@ -6632,9 +6666,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
smp_rmb();
while (BNX2X_HAS_TX_WORK(fp)) {

if (!netif_running(bp->dev))
bnx2x_tx_int(fp, 1000);

bnx2x_tx_int(fp, 1000);
if (!cnt) {
BNX2X_ERR("timeout waiting for queue[%d]\n",
i);
Expand All @@ -6650,46 +6682,12 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
smp_rmb();
}
}

/* Give HW time to discard old tx messages */
msleep(1);

for_each_queue(bp, i)
napi_disable(&bnx2x_fp(bp, i, napi));
/* Disable interrupts after Tx and Rx are disabled on stack level */
bnx2x_int_disable_sync(bp);

/* Release IRQs */
bnx2x_free_irq(bp);

if (unload_mode == UNLOAD_NORMAL)
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;

else if (bp->flags & NO_WOL_FLAG) {
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP;
if (CHIP_IS_E1H(bp))
REG_WR(bp, MISC_REG_E1HMF_MODE, 0);

} else if (bp->wol) {
u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
u8 *mac_addr = bp->dev->dev_addr;
u32 val;
/* The mac address is written to entries 1-4 to
preserve entry 0 which is used by the PMF */
u8 entry = (BP_E1HVN(bp) + 1)*8;

val = (mac_addr[0] << 8) | mac_addr[1];
EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry, val);

val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
(mac_addr[4] << 8) | mac_addr[5];
EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry + 4, val);

reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN;

} else
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;

if (CHIP_IS_E1(bp)) {
struct mac_configuration_cmd *config =
bnx2x_sp(bp, mcast_config);
Expand All @@ -6712,14 +6710,41 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
U64_LO(bnx2x_sp_mapping(bp, mcast_config)), 0);

} else { /* E1H */
REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);

bnx2x_set_mac_addr_e1h(bp, 0);

for (i = 0; i < MC_HASH_SIZE; i++)
REG_WR(bp, MC_HASH_OFFSET(bp, i), 0);
}

if (CHIP_IS_E1H(bp))
REG_WR(bp, NIG_REG_LLH0_FUNC_EN + port*8, 0);
if (unload_mode == UNLOAD_NORMAL)
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;

else if (bp->flags & NO_WOL_FLAG) {
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP;
if (CHIP_IS_E1H(bp))
REG_WR(bp, MISC_REG_E1HMF_MODE, 0);

} else if (bp->wol) {
u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
u8 *mac_addr = bp->dev->dev_addr;
u32 val;
/* The mac address is written to entries 1-4 to
preserve entry 0 which is used by the PMF */
u8 entry = (BP_E1HVN(bp) + 1)*8;

val = (mac_addr[0] << 8) | mac_addr[1];
EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry, val);

val = (mac_addr[2] << 24) | (mac_addr[3] << 16) |
(mac_addr[4] << 8) | mac_addr[5];
EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + entry + 4, val);

reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_EN;

} else
reset_code = DRV_MSG_CODE_UNLOAD_REQ_WOL_DIS;

/* Close multi and leading connections
Completions for ramrods are collected in a synchronous way */
Expand Down Expand Up @@ -8621,34 +8646,6 @@ static int bnx2x_test_memory(struct bnx2x *bp)
return rc;
}

static void bnx2x_netif_start(struct bnx2x *bp)
{
int i;

if (atomic_dec_and_test(&bp->intr_sem)) {
if (netif_running(bp->dev)) {
bnx2x_int_enable(bp);
for_each_queue(bp, i)
napi_enable(&bnx2x_fp(bp, i, napi));
if (bp->state == BNX2X_STATE_OPEN)
netif_wake_queue(bp->dev);
}
}
}

static void bnx2x_netif_stop(struct bnx2x *bp)
{
int i;

if (netif_running(bp->dev)) {
netif_tx_disable(bp->dev);
bp->dev->trans_start = jiffies; /* prevent tx timeout */
for_each_queue(bp, i)
napi_disable(&bnx2x_fp(bp, i, napi));
}
bnx2x_int_disable_sync(bp);
}

static void bnx2x_wait_for_link(struct bnx2x *bp, u8 link_up)
{
int cnt = 1000;
Expand Down

0 comments on commit 65abd74

Please sign in to comment.