diff options
Diffstat (limited to 'drivers/net/ethernet/qlogic')
| -rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed.h | 10 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_dcbx.c | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_dev.c | 91 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_int.c | 96 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_int.h | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_main.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_spq.c | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qed/qed_sriov.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede.h | 3 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede_ethtool.c | 32 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede_fp.c | 17 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qede/qede_ptp.c | 7 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qla3xxx.c | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic.h | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlge/qlge.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/qlogic/qlge/qlge_main.c | 1 | 
17 files changed, 144 insertions, 134 deletions
| diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h index 43a57ec296fd..c5e96ce20f59 100644 --- a/drivers/net/ethernet/qlogic/qed/qed.h +++ b/drivers/net/ethernet/qlogic/qed/qed.h @@ -431,12 +431,16 @@ struct qed_qm_info {  	u8 num_pf_rls;  }; +#define QED_OVERFLOW_BIT	1 +  struct qed_db_recovery_info {  	struct list_head list;  	/* Lock to protect the doorbell recovery mechanism list */  	spinlock_t lock; +	bool dorq_attn;  	u32 db_recovery_counter; +	unsigned long overflow;  };  struct storm_stats { @@ -492,6 +496,9 @@ enum qed_mf_mode_bit {  	/* Allow DSCP to TC mapping */  	QED_MF_DSCP_TO_TC_MAP, + +	/* Do not insert a vlan tag with id 0 */ +	QED_MF_DONT_ADD_VLAN0_TAG,  };  enum qed_ufp_mode { @@ -920,8 +927,7 @@ u16 qed_get_cm_pq_idx_llt_mtc(struct qed_hwfn *p_hwfn, u8 tc);  /* doorbell recovery mechanism */  void qed_db_recovery_dp(struct qed_hwfn *p_hwfn); -void qed_db_recovery_execute(struct qed_hwfn *p_hwfn, -			     enum qed_db_rec_exec db_exec); +void qed_db_recovery_execute(struct qed_hwfn *p_hwfn);  bool qed_edpm_enabled(struct qed_hwfn *p_hwfn);  /* Other Linux specific common definitions */ diff --git a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c index 69966dfc6e3d..5c6a276f69ac 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dcbx.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dcbx.c @@ -204,9 +204,7 @@ qed_dcbx_set_params(struct qed_dcbx_results *p_data,  	else  		p_data->arr[type].update = DONT_UPDATE_DCB_DSCP; -	/* Do not add vlan tag 0 when DCB is enabled and port in UFP/OV mode */ -	if ((test_bit(QED_MF_8021Q_TAGGING, &p_hwfn->cdev->mf_bits) || -	     test_bit(QED_MF_8021AD_TAGGING, &p_hwfn->cdev->mf_bits))) +	if (test_bit(QED_MF_DONT_ADD_VLAN0_TAG, &p_hwfn->cdev->mf_bits))  		p_data->arr[type].dont_add_vlan0 = true;  	/* QM reconf data */ diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index 9df8c4b3b54e..fccdb06fc5c5 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -102,11 +102,15 @@ static void qed_db_recovery_dp_entry(struct qed_hwfn *p_hwfn,  /* Doorbell address sanity (address within doorbell bar range) */  static bool qed_db_rec_sanity(struct qed_dev *cdev, -			      void __iomem *db_addr, void *db_data) +			      void __iomem *db_addr, +			      enum qed_db_rec_width db_width, +			      void *db_data)  { +	u32 width = (db_width == DB_REC_WIDTH_32B) ? 32 : 64; +  	/* Make sure doorbell address is within the doorbell bar */  	if (db_addr < cdev->doorbells || -	    (u8 __iomem *)db_addr > +	    (u8 __iomem *)db_addr + width >  	    (u8 __iomem *)cdev->doorbells + cdev->db_size) {  		WARN(true,  		     "Illegal doorbell address: %p. Legal range for doorbell addresses is [%p..%p]\n", @@ -159,7 +163,7 @@ int qed_db_recovery_add(struct qed_dev *cdev,  	}  	/* Sanitize doorbell address */ -	if (!qed_db_rec_sanity(cdev, db_addr, db_data)) +	if (!qed_db_rec_sanity(cdev, db_addr, db_width, db_data))  		return -EINVAL;  	/* Obtain hwfn from doorbell address */ @@ -205,10 +209,6 @@ int qed_db_recovery_del(struct qed_dev *cdev,  		return 0;  	} -	/* Sanitize doorbell address */ -	if (!qed_db_rec_sanity(cdev, db_addr, db_data)) -		return -EINVAL; -  	/* Obtain hwfn from doorbell address */  	p_hwfn = qed_db_rec_find_hwfn(cdev, db_addr); @@ -300,31 +300,24 @@ void qed_db_recovery_dp(struct qed_hwfn *p_hwfn)  /* Ring the doorbell of a single doorbell recovery entry */  static void qed_db_recovery_ring(struct qed_hwfn *p_hwfn, -				 struct qed_db_recovery_entry *db_entry, -				 enum qed_db_rec_exec db_exec) -{ -	if (db_exec != DB_REC_ONCE) { -		/* Print according to width */ -		if (db_entry->db_width == DB_REC_WIDTH_32B) { -			DP_VERBOSE(p_hwfn, QED_MSG_SPQ, -				   "%s doorbell address %p data %x\n", -				   db_exec == DB_REC_DRY_RUN ? -				   "would have rung" : "ringing", -				   db_entry->db_addr, -				   *(u32 *)db_entry->db_data); -		} else { -			DP_VERBOSE(p_hwfn, QED_MSG_SPQ, -				   "%s doorbell address %p data %llx\n", -				   db_exec == DB_REC_DRY_RUN ? -				   "would have rung" : "ringing", -				   db_entry->db_addr, -				   *(u64 *)(db_entry->db_data)); -		} +				 struct qed_db_recovery_entry *db_entry) +{ +	/* Print according to width */ +	if (db_entry->db_width == DB_REC_WIDTH_32B) { +		DP_VERBOSE(p_hwfn, QED_MSG_SPQ, +			   "ringing doorbell address %p data %x\n", +			   db_entry->db_addr, +			   *(u32 *)db_entry->db_data); +	} else { +		DP_VERBOSE(p_hwfn, QED_MSG_SPQ, +			   "ringing doorbell address %p data %llx\n", +			   db_entry->db_addr, +			   *(u64 *)(db_entry->db_data));  	}  	/* Sanity */  	if (!qed_db_rec_sanity(p_hwfn->cdev, db_entry->db_addr, -			       db_entry->db_data)) +			       db_entry->db_width, db_entry->db_data))  		return;  	/* Flush the write combined buffer. Since there are multiple doorbelling @@ -334,14 +327,12 @@ static void qed_db_recovery_ring(struct qed_hwfn *p_hwfn,  	wmb();  	/* Ring the doorbell */ -	if (db_exec == DB_REC_REAL_DEAL || db_exec == DB_REC_ONCE) { -		if (db_entry->db_width == DB_REC_WIDTH_32B) -			DIRECT_REG_WR(db_entry->db_addr, -				      *(u32 *)(db_entry->db_data)); -		else -			DIRECT_REG_WR64(db_entry->db_addr, -					*(u64 *)(db_entry->db_data)); -	} +	if (db_entry->db_width == DB_REC_WIDTH_32B) +		DIRECT_REG_WR(db_entry->db_addr, +			      *(u32 *)(db_entry->db_data)); +	else +		DIRECT_REG_WR64(db_entry->db_addr, +				*(u64 *)(db_entry->db_data));  	/* Flush the write combined buffer. Next doorbell may come from a  	 * different entity to the same address... @@ -350,29 +341,21 @@ static void qed_db_recovery_ring(struct qed_hwfn *p_hwfn,  }  /* Traverse the doorbell recovery entry list and ring all the doorbells */ -void qed_db_recovery_execute(struct qed_hwfn *p_hwfn, -			     enum qed_db_rec_exec db_exec) +void qed_db_recovery_execute(struct qed_hwfn *p_hwfn)  {  	struct qed_db_recovery_entry *db_entry = NULL; -	if (db_exec != DB_REC_ONCE) { -		DP_NOTICE(p_hwfn, -			  "Executing doorbell recovery. Counter was %d\n", -			  p_hwfn->db_recovery_info.db_recovery_counter); +	DP_NOTICE(p_hwfn, "Executing doorbell recovery. Counter was %d\n", +		  p_hwfn->db_recovery_info.db_recovery_counter); -		/* Track amount of times recovery was executed */ -		p_hwfn->db_recovery_info.db_recovery_counter++; -	} +	/* Track amount of times recovery was executed */ +	p_hwfn->db_recovery_info.db_recovery_counter++;  	/* Protect the list */  	spin_lock_bh(&p_hwfn->db_recovery_info.lock);  	list_for_each_entry(db_entry, -			    &p_hwfn->db_recovery_info.list, list_entry) { -		qed_db_recovery_ring(p_hwfn, db_entry, db_exec); -		if (db_exec == DB_REC_ONCE) -			break; -	} - +			    &p_hwfn->db_recovery_info.list, list_entry) +		qed_db_recovery_ring(p_hwfn, db_entry);  	spin_unlock_bh(&p_hwfn->db_recovery_info.lock);  } @@ -3157,12 +3140,14 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)  			cdev->mf_bits = BIT(QED_MF_OVLAN_CLSS) |  					BIT(QED_MF_LLH_PROTO_CLSS) |  					BIT(QED_MF_UFP_SPECIFIC) | -					BIT(QED_MF_8021Q_TAGGING); +					BIT(QED_MF_8021Q_TAGGING) | +					BIT(QED_MF_DONT_ADD_VLAN0_TAG);  			break;  		case NVM_CFG1_GLOB_MF_MODE_BD:  			cdev->mf_bits = BIT(QED_MF_OVLAN_CLSS) |  					BIT(QED_MF_LLH_PROTO_CLSS) | -					BIT(QED_MF_8021AD_TAGGING); +					BIT(QED_MF_8021AD_TAGGING) | +					BIT(QED_MF_DONT_ADD_VLAN0_TAG);  			break;  		case NVM_CFG1_GLOB_MF_MODE_NPAR1_0:  			cdev->mf_bits = BIT(QED_MF_LLH_MAC_CLSS) | diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.c b/drivers/net/ethernet/qlogic/qed/qed_int.c index e23980e301b6..fdfedbc8e431 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_int.c +++ b/drivers/net/ethernet/qlogic/qed/qed_int.c @@ -378,6 +378,9 @@ static int qed_db_rec_flush_queue(struct qed_hwfn *p_hwfn,  	u32 count = QED_DB_REC_COUNT;  	u32 usage = 1; +	/* Flush any pending (e)dpms as they may never arrive */ +	qed_wr(p_hwfn, p_ptt, DORQ_REG_DPM_FORCE_ABORT, 0x1); +  	/* wait for usage to zero or count to run out. This is necessary since  	 * EDPM doorbell transactions can take multiple 64b cycles, and as such  	 * can "split" over the pci. Possibly, the doorbell drop can happen with @@ -406,51 +409,74 @@ static int qed_db_rec_flush_queue(struct qed_hwfn *p_hwfn,  int qed_db_rec_handler(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)  { -	u32 overflow; +	u32 attn_ovfl, cur_ovfl;  	int rc; -	overflow = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY); -	DP_NOTICE(p_hwfn, "PF Overflow sticky 0x%x\n", overflow); -	if (!overflow) { -		qed_db_recovery_execute(p_hwfn, DB_REC_ONCE); +	attn_ovfl = test_and_clear_bit(QED_OVERFLOW_BIT, +				       &p_hwfn->db_recovery_info.overflow); +	cur_ovfl = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY); +	if (!cur_ovfl && !attn_ovfl)  		return 0; -	} -	if (qed_edpm_enabled(p_hwfn)) { +	DP_NOTICE(p_hwfn, "PF Overflow sticky: attn %u current %u\n", +		  attn_ovfl, cur_ovfl); + +	if (cur_ovfl && !p_hwfn->db_bar_no_edpm) {  		rc = qed_db_rec_flush_queue(p_hwfn, p_ptt);  		if (rc)  			return rc;  	} -	/* Flush any pending (e)dpm as they may never arrive */ -	qed_wr(p_hwfn, p_ptt, DORQ_REG_DPM_FORCE_ABORT, 0x1); -  	/* Release overflow sticky indication (stop silently dropping everything) */  	qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0);  	/* Repeat all last doorbells (doorbell drop recovery) */ -	qed_db_recovery_execute(p_hwfn, DB_REC_REAL_DEAL); +	qed_db_recovery_execute(p_hwfn);  	return 0;  } -static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn) +static void qed_dorq_attn_overflow(struct qed_hwfn *p_hwfn)  { -	u32 int_sts, first_drop_reason, details, address, all_drops_reason;  	struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt; +	u32 overflow;  	int rc; -	int_sts = qed_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS); -	DP_NOTICE(p_hwfn->cdev, "DORQ attention. int_sts was %x\n", int_sts); +	overflow = qed_rd(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY); +	if (!overflow) +		goto out; + +	/* Run PF doorbell recovery in next periodic handler */ +	set_bit(QED_OVERFLOW_BIT, &p_hwfn->db_recovery_info.overflow); + +	if (!p_hwfn->db_bar_no_edpm) { +		rc = qed_db_rec_flush_queue(p_hwfn, p_ptt); +		if (rc) +			goto out; +	} + +	qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_OVFL_STICKY, 0x0); +out: +	/* Schedule the handler even if overflow was not detected */ +	qed_periodic_db_rec_start(p_hwfn); +} + +static int qed_dorq_attn_int_sts(struct qed_hwfn *p_hwfn) +{ +	u32 int_sts, first_drop_reason, details, address, all_drops_reason; +	struct qed_ptt *p_ptt = p_hwfn->p_dpc_ptt;  	/* int_sts may be zero since all PFs were interrupted for doorbell  	 * overflow but another one already handled it. Can abort here. If  	 * This PF also requires overflow recovery we will be interrupted again.  	 * The masked almost full indication may also be set. Ignoring.  	 */ +	int_sts = qed_rd(p_hwfn, p_ptt, DORQ_REG_INT_STS);  	if (!(int_sts & ~DORQ_REG_INT_STS_DORQ_FIFO_AFULL))  		return 0; +	DP_NOTICE(p_hwfn->cdev, "DORQ attention. int_sts was %x\n", int_sts); +  	/* check if db_drop or overflow happened */  	if (int_sts & (DORQ_REG_INT_STS_DB_DROP |  		       DORQ_REG_INT_STS_DORQ_FIFO_OVFL_ERR)) { @@ -477,11 +503,6 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)  			  GET_FIELD(details, QED_DORQ_ATTENTION_SIZE) * 4,  			  first_drop_reason, all_drops_reason); -		rc = qed_db_rec_handler(p_hwfn, p_ptt); -		qed_periodic_db_rec_start(p_hwfn); -		if (rc) -			return rc; -  		/* Clear the doorbell drop details and prepare for next drop */  		qed_wr(p_hwfn, p_ptt, DORQ_REG_DB_DROP_DETAILS_REL, 0); @@ -507,6 +528,25 @@ static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn)  	return -EINVAL;  } +static int qed_dorq_attn_cb(struct qed_hwfn *p_hwfn) +{ +	p_hwfn->db_recovery_info.dorq_attn = true; +	qed_dorq_attn_overflow(p_hwfn); + +	return qed_dorq_attn_int_sts(p_hwfn); +} + +static void qed_dorq_attn_handler(struct qed_hwfn *p_hwfn) +{ +	if (p_hwfn->db_recovery_info.dorq_attn) +		goto out; + +	/* Call DORQ callback if the attention was missed */ +	qed_dorq_attn_cb(p_hwfn); +out: +	p_hwfn->db_recovery_info.dorq_attn = false; +} +  /* Instead of major changes to the data-structure, we have a some 'special'   * identifiers for sources that changed meaning between adapters.   */ @@ -774,18 +814,12 @@ static inline u16 qed_attn_update_idx(struct qed_hwfn *p_hwfn,  {  	u16 rc = 0, index; -	/* Make certain HW write took affect */ -	mmiowb(); -  	index = le16_to_cpu(p_sb_desc->sb_attn->sb_index);  	if (p_sb_desc->index != index) {  		p_sb_desc->index	= index;  		rc		      = QED_SB_ATT_IDX;  	} -	/* Make certain we got a consistent view with HW */ -	mmiowb(); -  	return rc;  } @@ -1080,6 +1114,9 @@ static int qed_int_deassertion(struct qed_hwfn  *p_hwfn,  		}  	} +	/* Handle missed DORQ attention */ +	qed_dorq_attn_handler(p_hwfn); +  	/* Clear IGU indication for the deasserted bits */  	DIRECT_REG_WR((u8 __iomem *)p_hwfn->regview +  				    GTT_BAR0_MAP_REG_IGU_CMD + @@ -1170,7 +1207,6 @@ static void qed_sb_ack_attn(struct qed_hwfn *p_hwfn,  	/* Both segments (interrupts & acks) are written to same place address;  	 * Need to guarantee all commands will be received (in-order) by HW.  	 */ -	mmiowb();  	barrier();  } @@ -1805,9 +1841,6 @@ static void qed_int_igu_enable_attn(struct qed_hwfn *p_hwfn,  	qed_wr(p_hwfn, p_ptt, IGU_REG_TRAILING_EDGE_LATCH, 0xfff);  	qed_wr(p_hwfn, p_ptt, IGU_REG_ATTENTION_ENABLE, 0xfff); -	/* Flush the writes to IGU */ -	mmiowb(); -  	/* Unmask AEU signals toward IGU */  	qed_wr(p_hwfn, p_ptt, MISC_REG_AEU_MASK_ATTN_IGU, 0xff);  } @@ -1871,9 +1904,6 @@ static void qed_int_igu_cleanup_sb(struct qed_hwfn *p_hwfn,  	qed_wr(p_hwfn, p_ptt, IGU_REG_COMMAND_REG_CTRL, cmd_ctrl); -	/* Flush the write to IGU */ -	mmiowb(); -  	/* calculate where to read the status bit from */  	sb_bit = 1 << (igu_sb_id % 32);  	sb_bit_addr = igu_sb_id / 32 * sizeof(u32); diff --git a/drivers/net/ethernet/qlogic/qed/qed_int.h b/drivers/net/ethernet/qlogic/qed/qed_int.h index 1f356ed4f761..d473b522afc5 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_int.h +++ b/drivers/net/ethernet/qlogic/qed/qed_int.h @@ -192,8 +192,8 @@ void qed_int_disable_post_isr_release(struct qed_dev *cdev);  /**   * @brief - Doorbell Recovery handler. - *          Run DB_REAL_DEAL doorbell recovery in case of PF overflow - *          (and flush DORQ if needed), otherwise run DB_REC_ONCE. + *          Run doorbell recovery in case of PF overflow (and flush DORQ if + *          needed).   *   * @param p_hwfn   * @param p_ptt diff --git a/drivers/net/ethernet/qlogic/qed/qed_main.c b/drivers/net/ethernet/qlogic/qed/qed_main.c index f164d4acebcb..6de23b56b294 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_main.c +++ b/drivers/net/ethernet/qlogic/qed/qed_main.c @@ -970,7 +970,7 @@ static void qed_update_pf_params(struct qed_dev *cdev,  	}  } -#define QED_PERIODIC_DB_REC_COUNT		100 +#define QED_PERIODIC_DB_REC_COUNT		10  #define QED_PERIODIC_DB_REC_INTERVAL_MS		100  #define QED_PERIODIC_DB_REC_INTERVAL \  	msecs_to_jiffies(QED_PERIODIC_DB_REC_INTERVAL_MS) diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c index 79b311b86f66..f5f3c03b9dd2 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_spq.c +++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c @@ -341,9 +341,6 @@ void qed_eq_prod_update(struct qed_hwfn *p_hwfn, u16 prod)  		   USTORM_EQE_CONS_OFFSET(p_hwfn->rel_pf_id);  	REG_WR16(p_hwfn, addr, prod); - -	/* keep prod updates ordered */ -	mmiowb();  }  int qed_eq_completion(struct qed_hwfn *p_hwfn, void *cookie) diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c b/drivers/net/ethernet/qlogic/qed/qed_sriov.c index 9faaa6df78ed..2f318aaf2b05 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c +++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c @@ -1591,7 +1591,7 @@ static void qed_iov_vf_mbx_acquire(struct qed_hwfn *p_hwfn,  			p_vfdev->eth_fp_hsi_minor = ETH_HSI_VER_NO_PKT_LEN_TUNN;  		} else {  			DP_INFO(p_hwfn, -				"VF[%d] needs fastpath HSI %02x.%02x, which is incompatible with loaded FW's faspath HSI %02x.%02x\n", +				"VF[%d] needs fastpath HSI %02x.%02x, which is incompatible with loaded FW's fastpath HSI %02x.%02x\n",  				vf->abs_vf_id,  				req->vfdev_info.eth_fp_hsi_major,  				req->vfdev_info.eth_fp_hsi_minor, diff --git a/drivers/net/ethernet/qlogic/qede/qede.h b/drivers/net/ethernet/qlogic/qede/qede.h index 63a78162cfaf..92fe226980fd 100644 --- a/drivers/net/ethernet/qlogic/qede/qede.h +++ b/drivers/net/ethernet/qlogic/qede/qede.h @@ -498,8 +498,7 @@ struct qede_reload_args {  /* Datapath functions definition */  netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev);  u16 qede_select_queue(struct net_device *dev, struct sk_buff *skb, -		      struct net_device *sb_dev, -		      select_queue_fallback_t fallback); +		      struct net_device *sb_dev);  netdev_features_t qede_features_check(struct sk_buff *skb,  				      struct net_device *dev,  				      netdev_features_t features); diff --git a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c index b4c8949933f1..8911a97ab0ca 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ethtool.c +++ b/drivers/net/ethernet/qlogic/qede/qede_ethtool.c @@ -652,9 +652,9 @@ static void qede_get_drvinfo(struct net_device *ndev,  {  	char mfw[ETHTOOL_FWVERS_LEN], storm[ETHTOOL_FWVERS_LEN];  	struct qede_dev *edev = netdev_priv(ndev); +	char mbi[ETHTOOL_FWVERS_LEN];  	strlcpy(info->driver, "qede", sizeof(info->driver)); -	strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));  	snprintf(storm, ETHTOOL_FWVERS_LEN, "%d.%d.%d.%d",  		 edev->dev_info.common.fw_major, @@ -668,13 +668,27 @@ static void qede_get_drvinfo(struct net_device *ndev,  		 (edev->dev_info.common.mfw_rev >> 8) & 0xFF,  		 edev->dev_info.common.mfw_rev & 0xFF); -	if ((strlen(storm) + strlen(mfw) + strlen("mfw storm  ")) < -	    sizeof(info->fw_version)) { +	if ((strlen(storm) + strlen(DRV_MODULE_VERSION) + strlen("[storm]  ")) < +	    sizeof(info->version)) +		snprintf(info->version, sizeof(info->version), +			 "%s [storm %s]", DRV_MODULE_VERSION, storm); +	else +		snprintf(info->version, sizeof(info->version), +			 "%s %s", DRV_MODULE_VERSION, storm); + +	if (edev->dev_info.common.mbi_version) { +		snprintf(mbi, ETHTOOL_FWVERS_LEN, "%d.%d.%d", +			 (edev->dev_info.common.mbi_version & +			  QED_MBI_VERSION_2_MASK) >> QED_MBI_VERSION_2_OFFSET, +			 (edev->dev_info.common.mbi_version & +			  QED_MBI_VERSION_1_MASK) >> QED_MBI_VERSION_1_OFFSET, +			 (edev->dev_info.common.mbi_version & +			  QED_MBI_VERSION_0_MASK) >> QED_MBI_VERSION_0_OFFSET);  		snprintf(info->fw_version, sizeof(info->fw_version), -			 "mfw %s storm %s", mfw, storm); +			 "mbi %s [mfw %s]", mbi, mfw);  	} else {  		snprintf(info->fw_version, sizeof(info->fw_version), -			 "%s %s", mfw, storm); +			 "mfw %s", mfw);  	}  	strlcpy(info->bus_info, pci_name(edev->pdev), sizeof(info->bus_info)); @@ -1526,14 +1540,6 @@ static int qede_selftest_transmit_traffic(struct qede_dev *edev,  	barrier();  	writel(txq->tx_db.raw, txq->doorbell_addr); -	/* mmiowb is needed to synchronize doorbell writes from more than one -	 * processor. It guarantees that the write arrives to the device before -	 * the queue lock is released and another start_xmit is called (possibly -	 * on another CPU). Without this barrier, the next doorbell can bypass -	 * this doorbell. This is applicable to IA64/Altix systems. -	 */ -	mmiowb(); -  	for (i = 0; i < QEDE_SELFTEST_POLL_COUNT; i++) {  		if (qede_txq_has_work(txq))  			break; diff --git a/drivers/net/ethernet/qlogic/qede/qede_fp.c b/drivers/net/ethernet/qlogic/qede/qede_fp.c index 31b046e24565..0ae28f0d2523 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_fp.c +++ b/drivers/net/ethernet/qlogic/qede/qede_fp.c @@ -580,14 +580,6 @@ void qede_update_rx_prod(struct qede_dev *edev, struct qede_rx_queue *rxq)  	internal_ram_wr(rxq->hw_rxq_prod_addr, sizeof(rx_prods),  			(u32 *)&rx_prods); - -	/* mmiowb is needed to synchronize doorbell writes from more than one -	 * processor. It guarantees that the write arrives to the device before -	 * the napi lock is released and another qede_poll is called (possibly -	 * on another CPU). Without this barrier, the next doorbell can bypass -	 * this doorbell. This is applicable to IA64/Altix systems. -	 */ -	mmiowb();  }  static void qede_get_rxhash(struct sk_buff *skb, u8 bitfields, __le32 rss_hash) @@ -1665,12 +1657,12 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev)  	txq->tx_db.data.bd_prod =  		cpu_to_le16(qed_chain_get_prod_idx(&txq->tx_pbl)); -	if (!skb->xmit_more || netif_xmit_stopped(netdev_txq)) +	if (!netdev_xmit_more() || netif_xmit_stopped(netdev_txq))  		qede_update_tx_producer(txq);  	if (unlikely(qed_chain_get_elem_left(&txq->tx_pbl)  		      < (MAX_SKB_FRAGS + 1))) { -		if (skb->xmit_more) +		if (netdev_xmit_more())  			qede_update_tx_producer(txq);  		netif_tx_stop_queue(netdev_txq); @@ -1696,8 +1688,7 @@ netdev_tx_t qede_start_xmit(struct sk_buff *skb, struct net_device *ndev)  }  u16 qede_select_queue(struct net_device *dev, struct sk_buff *skb, -		      struct net_device *sb_dev, -		      select_queue_fallback_t fallback) +		      struct net_device *sb_dev)  {  	struct qede_dev *edev = netdev_priv(dev);  	int total_txq; @@ -1705,7 +1696,7 @@ u16 qede_select_queue(struct net_device *dev, struct sk_buff *skb,  	total_txq = QEDE_TSS_COUNT(edev) * edev->dev_info.num_tc;  	return QEDE_TSS_COUNT(edev) ? -		fallback(dev, skb, NULL) % total_txq :  0; +		netdev_pick_tx(dev, skb, NULL) % total_txq :  0;  }  /* 8B udp header + 8B base tunnel header + 32B option length */ diff --git a/drivers/net/ethernet/qlogic/qede/qede_ptp.c b/drivers/net/ethernet/qlogic/qede/qede_ptp.c index 5f3f42a25361..bddb2b5982dc 100644 --- a/drivers/net/ethernet/qlogic/qede/qede_ptp.c +++ b/drivers/net/ethernet/qlogic/qede/qede_ptp.c @@ -490,18 +490,17 @@ int qede_ptp_enable(struct qede_dev *edev, bool init_tc)  	ptp->clock = ptp_clock_register(&ptp->clock_info, &edev->pdev->dev);  	if (IS_ERR(ptp->clock)) { -		rc = -EINVAL;  		DP_ERR(edev, "PTP clock registration failed\n"); +		qede_ptp_disable(edev); +		rc = -EINVAL;  		goto err2;  	}  	return 0; -err2: -	qede_ptp_disable(edev); -	ptp->clock = NULL;  err1:  	kfree(ptp); +err2:  	edev->ptp = NULL;  	return rc; diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index b61b88cbc0c7..457444894d80 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c @@ -1858,7 +1858,6 @@ static void ql_update_small_bufq_prod_index(struct ql3_adapter *qdev)  		wmb();  		writel_relaxed(qdev->small_buf_q_producer_index,  			       &port_regs->CommonRegs.rxSmallQProducerIndex); -		mmiowb();  	}  } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h index 0c443ea98479..374a4d4371f9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h @@ -497,7 +497,7 @@ struct qlcnic_hardware_context {  	u16 board_type;  	u16 supported_type; -	u16 link_speed; +	u32 link_speed;  	u16 link_duplex;  	u16 link_autoneg;  	u16 module_type; diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c index 3b0adda7cc9c..a4cd6f2cfb86 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ethtool.c @@ -1048,6 +1048,8 @@ int qlcnic_do_lb_test(struct qlcnic_adapter *adapter, u8 mode)  	for (i = 0; i < QLCNIC_NUM_ILB_PKT; i++) {  		skb = netdev_alloc_skb(adapter->netdev, QLCNIC_ILB_PKT_SIZE); +		if (!skb) +			break;  		qlcnic_create_loopback_buff(skb->data, adapter->mac_addr);  		skb_put(skb, QLCNIC_ILB_PKT_SIZE);  		adapter->ahw->diag_cnt = 0; diff --git a/drivers/net/ethernet/qlogic/qlge/qlge.h b/drivers/net/ethernet/qlogic/qlge/qlge.h index 3e71b65a9546..ad7c5eb8a3b6 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge.h +++ b/drivers/net/ethernet/qlogic/qlge/qlge.h @@ -2181,7 +2181,6 @@ static inline void ql_write32(const struct ql_adapter *qdev, int reg, u32 val)  static inline void ql_write_db_reg(u32 val, void __iomem *addr)  {  	writel(val, addr); -	mmiowb();  }  /* diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c index 07e1c623048e..6cae33072496 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c @@ -2695,7 +2695,6 @@ static netdev_tx_t qlge_send(struct sk_buff *skb, struct net_device *ndev)  	wmb();  	ql_write_db_reg_relaxed(tx_ring->prod_idx, tx_ring->prod_idx_db_reg); -	mmiowb();  	netif_printk(qdev, tx_queued, KERN_DEBUG, qdev->ndev,  		     "tx queued, slot %d, len %d\n",  		     tx_ring->prod_idx, skb->len); |