diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_controlq.c')
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_controlq.c | 29 | 
1 files changed, 20 insertions, 9 deletions
| diff --git a/drivers/net/ethernet/intel/ice/ice_controlq.c b/drivers/net/ethernet/intel/ice/ice_controlq.c index 7c511f144ed6..62be72fdc8f3 100644 --- a/drivers/net/ethernet/intel/ice/ice_controlq.c +++ b/drivers/net/ethernet/intel/ice/ice_controlq.c @@ -597,10 +597,14 @@ static enum ice_status ice_init_check_adminq(struct ice_hw *hw)  	return 0;  init_ctrlq_free_rq: -	ice_shutdown_rq(hw, cq); -	ice_shutdown_sq(hw, cq); -	mutex_destroy(&cq->sq_lock); -	mutex_destroy(&cq->rq_lock); +	if (cq->rq.head) { +		ice_shutdown_rq(hw, cq); +		mutex_destroy(&cq->rq_lock); +	} +	if (cq->sq.head) { +		ice_shutdown_sq(hw, cq); +		mutex_destroy(&cq->sq_lock); +	}  	return status;  } @@ -706,10 +710,14 @@ static void ice_shutdown_ctrlq(struct ice_hw *hw, enum ice_ctl_q q_type)  		return;  	} -	ice_shutdown_sq(hw, cq); -	ice_shutdown_rq(hw, cq); -	mutex_destroy(&cq->sq_lock); -	mutex_destroy(&cq->rq_lock); +	if (cq->sq.head) { +		ice_shutdown_sq(hw, cq); +		mutex_destroy(&cq->sq_lock); +	} +	if (cq->rq.head) { +		ice_shutdown_rq(hw, cq); +		mutex_destroy(&cq->rq_lock); +	}  }  /** @@ -1057,8 +1065,11 @@ ice_clean_rq_elem(struct ice_hw *hw, struct ice_ctl_q_info *cq,  clean_rq_elem_out:  	/* Set pending if needed, unlock and return */ -	if (pending) +	if (pending) { +		/* re-read HW head to calculate actual pending messages */ +		ntu = (u16)(rd32(hw, cq->rq.head) & cq->rq.head_mask);  		*pending = (u16)((ntc > ntu ? cq->rq.count : 0) + (ntu - ntc)); +	}  clean_rq_elem_err:  	mutex_unlock(&cq->rq_lock); |