diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 61 |
1 files changed, 56 insertions, 5 deletions
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 614981c02264..09b625e0fdaa 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | |||
@@ -4318,7 +4318,7 @@ static int bnx2x_queue_comp_cmd(struct bnx2x *bp, | |||
4318 | 4318 | ||
4319 | if (o->next_tx_only >= o->max_cos) | 4319 | if (o->next_tx_only >= o->max_cos) |
4320 | /* >= becuase tx only must always be smaller than cos since the | 4320 | /* >= becuase tx only must always be smaller than cos since the |
4321 | * primary connection suports COS 0 | 4321 | * primary connection supports COS 0 |
4322 | */ | 4322 | */ |
4323 | BNX2X_ERR("illegal value for next tx_only: %d. max cos was %d", | 4323 | BNX2X_ERR("illegal value for next tx_only: %d. max cos was %d", |
4324 | o->next_tx_only, o->max_cos); | 4324 | o->next_tx_only, o->max_cos); |
@@ -5350,12 +5350,24 @@ static int bnx2x_func_chk_transition(struct bnx2x *bp, | |||
5350 | else if ((cmd == BNX2X_F_CMD_AFEX_VIFLISTS) && | 5350 | else if ((cmd == BNX2X_F_CMD_AFEX_VIFLISTS) && |
5351 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) | 5351 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) |
5352 | next_state = BNX2X_F_STATE_STARTED; | 5352 | next_state = BNX2X_F_STATE_STARTED; |
5353 | |||
5354 | /* Switch_update ramrod can be sent in either started or | ||
5355 | * tx_stopped state, and it doesn't change the state. | ||
5356 | */ | ||
5357 | else if ((cmd == BNX2X_F_CMD_SWITCH_UPDATE) && | ||
5358 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) | ||
5359 | next_state = BNX2X_F_STATE_STARTED; | ||
5360 | |||
5353 | else if (cmd == BNX2X_F_CMD_TX_STOP) | 5361 | else if (cmd == BNX2X_F_CMD_TX_STOP) |
5354 | next_state = BNX2X_F_STATE_TX_STOPPED; | 5362 | next_state = BNX2X_F_STATE_TX_STOPPED; |
5355 | 5363 | ||
5356 | break; | 5364 | break; |
5357 | case BNX2X_F_STATE_TX_STOPPED: | 5365 | case BNX2X_F_STATE_TX_STOPPED: |
5358 | if (cmd == BNX2X_F_CMD_TX_START) | 5366 | if ((cmd == BNX2X_F_CMD_SWITCH_UPDATE) && |
5367 | (!test_bit(BNX2X_F_CMD_STOP, &o->pending))) | ||
5368 | next_state = BNX2X_F_STATE_TX_STOPPED; | ||
5369 | |||
5370 | else if (cmd == BNX2X_F_CMD_TX_START) | ||
5359 | next_state = BNX2X_F_STATE_STARTED; | 5371 | next_state = BNX2X_F_STATE_STARTED; |
5360 | 5372 | ||
5361 | break; | 5373 | break; |
@@ -5637,6 +5649,28 @@ static inline int bnx2x_func_send_start(struct bnx2x *bp, | |||
5637 | U64_LO(data_mapping), NONE_CONNECTION_TYPE); | 5649 | U64_LO(data_mapping), NONE_CONNECTION_TYPE); |
5638 | } | 5650 | } |
5639 | 5651 | ||
5652 | static inline int bnx2x_func_send_switch_update(struct bnx2x *bp, | ||
5653 | struct bnx2x_func_state_params *params) | ||
5654 | { | ||
5655 | struct bnx2x_func_sp_obj *o = params->f_obj; | ||
5656 | struct function_update_data *rdata = | ||
5657 | (struct function_update_data *)o->rdata; | ||
5658 | dma_addr_t data_mapping = o->rdata_mapping; | ||
5659 | struct bnx2x_func_switch_update_params *switch_update_params = | ||
5660 | ¶ms->params.switch_update; | ||
5661 | |||
5662 | memset(rdata, 0, sizeof(*rdata)); | ||
5663 | |||
5664 | /* Fill the ramrod data with provided parameters */ | ||
5665 | rdata->tx_switch_suspend_change_flg = 1; | ||
5666 | rdata->tx_switch_suspend = switch_update_params->suspend; | ||
5667 | rdata->echo = SWITCH_UPDATE; | ||
5668 | |||
5669 | return bnx2x_sp_post(bp, RAMROD_CMD_ID_COMMON_FUNCTION_UPDATE, 0, | ||
5670 | U64_HI(data_mapping), | ||
5671 | U64_LO(data_mapping), NONE_CONNECTION_TYPE); | ||
5672 | } | ||
5673 | |||
5640 | static inline int bnx2x_func_send_afex_update(struct bnx2x *bp, | 5674 | static inline int bnx2x_func_send_afex_update(struct bnx2x *bp, |
5641 | struct bnx2x_func_state_params *params) | 5675 | struct bnx2x_func_state_params *params) |
5642 | { | 5676 | { |
@@ -5657,6 +5691,7 @@ static inline int bnx2x_func_send_afex_update(struct bnx2x *bp, | |||
5657 | cpu_to_le16(afex_update_params->afex_default_vlan); | 5691 | cpu_to_le16(afex_update_params->afex_default_vlan); |
5658 | rdata->allowed_priorities_change_flg = 1; | 5692 | rdata->allowed_priorities_change_flg = 1; |
5659 | rdata->allowed_priorities = afex_update_params->allowed_priorities; | 5693 | rdata->allowed_priorities = afex_update_params->allowed_priorities; |
5694 | rdata->echo = AFEX_UPDATE; | ||
5660 | 5695 | ||
5661 | /* No need for an explicit memory barrier here as long we would | 5696 | /* No need for an explicit memory barrier here as long we would |
5662 | * need to ensure the ordering of writing to the SPQ element | 5697 | * need to ensure the ordering of writing to the SPQ element |
@@ -5773,6 +5808,8 @@ static int bnx2x_func_send_cmd(struct bnx2x *bp, | |||
5773 | return bnx2x_func_send_tx_stop(bp, params); | 5808 | return bnx2x_func_send_tx_stop(bp, params); |
5774 | case BNX2X_F_CMD_TX_START: | 5809 | case BNX2X_F_CMD_TX_START: |
5775 | return bnx2x_func_send_tx_start(bp, params); | 5810 | return bnx2x_func_send_tx_start(bp, params); |
5811 | case BNX2X_F_CMD_SWITCH_UPDATE: | ||
5812 | return bnx2x_func_send_switch_update(bp, params); | ||
5776 | default: | 5813 | default: |
5777 | BNX2X_ERR("Unknown command: %d\n", params->cmd); | 5814 | BNX2X_ERR("Unknown command: %d\n", params->cmd); |
5778 | return -EINVAL; | 5815 | return -EINVAL; |
@@ -5818,16 +5855,30 @@ int bnx2x_func_state_change(struct bnx2x *bp, | |||
5818 | struct bnx2x_func_state_params *params) | 5855 | struct bnx2x_func_state_params *params) |
5819 | { | 5856 | { |
5820 | struct bnx2x_func_sp_obj *o = params->f_obj; | 5857 | struct bnx2x_func_sp_obj *o = params->f_obj; |
5821 | int rc; | 5858 | int rc, cnt = 300; |
5822 | enum bnx2x_func_cmd cmd = params->cmd; | 5859 | enum bnx2x_func_cmd cmd = params->cmd; |
5823 | unsigned long *pending = &o->pending; | 5860 | unsigned long *pending = &o->pending; |
5824 | 5861 | ||
5825 | mutex_lock(&o->one_pending_mutex); | 5862 | mutex_lock(&o->one_pending_mutex); |
5826 | 5863 | ||
5827 | /* Check that the requested transition is legal */ | 5864 | /* Check that the requested transition is legal */ |
5828 | if (o->check_transition(bp, o, params)) { | 5865 | rc = o->check_transition(bp, o, params); |
5866 | if ((rc == -EBUSY) && | ||
5867 | (test_bit(RAMROD_RETRY, ¶ms->ramrod_flags))) { | ||
5868 | while ((rc == -EBUSY) && (--cnt > 0)) { | ||
5869 | mutex_unlock(&o->one_pending_mutex); | ||
5870 | msleep(10); | ||
5871 | mutex_lock(&o->one_pending_mutex); | ||
5872 | rc = o->check_transition(bp, o, params); | ||
5873 | } | ||
5874 | if (rc == -EBUSY) { | ||
5875 | mutex_unlock(&o->one_pending_mutex); | ||
5876 | BNX2X_ERR("timeout waiting for previous ramrod completion\n"); | ||
5877 | return rc; | ||
5878 | } | ||
5879 | } else if (rc) { | ||
5829 | mutex_unlock(&o->one_pending_mutex); | 5880 | mutex_unlock(&o->one_pending_mutex); |
5830 | return -EINVAL; | 5881 | return rc; |
5831 | } | 5882 | } |
5832 | 5883 | ||
5833 | /* Set "pending" bit */ | 5884 | /* Set "pending" bit */ |