mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts: drivers/net/wireless/libertas/if_cs.c drivers/net/wireless/rtlwifi/pci.c net/bluetooth/l2cap_sock.c
This commit is contained in:
		
						commit
						a70171dce9
					
				
					 244 changed files with 12302 additions and 6509 deletions
				
			
		|  | @ -158,6 +158,11 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah) | |||
| 	txlat = AR5K_REG_MS(usec_reg, AR5K_USEC_TX_LATENCY_5211); | ||||
| 	rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Set default Tx frame to Tx data start delay | ||||
| 	 */ | ||||
| 	txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * 5210 initvals don't include usec settings | ||||
| 	 * so we need to use magic values here for | ||||
|  |  | |||
|  | @ -21,11 +21,15 @@ | |||
| #include <linux/ath9k_platform.h> | ||||
| #include "ath9k.h" | ||||
| 
 | ||||
| const struct platform_device_id ath9k_platform_id_table[] = { | ||||
| static const struct platform_device_id ath9k_platform_id_table[] = { | ||||
| 	{ | ||||
| 		.name = "ath9k", | ||||
| 		.driver_data = AR5416_AR9100_DEVID, | ||||
| 	}, | ||||
| 	{ | ||||
| 		.name = "ar934x_wmac", | ||||
| 		.driver_data = AR9300_DEVID_AR9340, | ||||
| 	}, | ||||
| 	{}, | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -899,12 +899,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah) | |||
| 	 * check here default level should not modify INI setting. | ||||
| 	 */ | ||||
| 	if (use_new_ani(ah)) { | ||||
| 		const struct ani_ofdm_level_entry *entry_ofdm; | ||||
| 		const struct ani_cck_level_entry *entry_cck; | ||||
| 
 | ||||
| 		entry_ofdm = &ofdm_level_table[ATH9K_ANI_OFDM_DEF_LEVEL]; | ||||
| 		entry_cck = &cck_level_table[ATH9K_ANI_CCK_DEF_LEVEL]; | ||||
| 
 | ||||
| 		ah->aniperiod = ATH9K_ANI_PERIOD_NEW; | ||||
| 		ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW; | ||||
| 	} else { | ||||
|  |  | |||
|  | @ -18,13 +18,13 @@ | |||
| #include "hw-ops.h" | ||||
| #include "ar9003_phy.h" | ||||
| 
 | ||||
| #define MPASS	3 | ||||
| #define MAX_MEASUREMENT	8 | ||||
| #define MAX_DIFFERENCE	10 | ||||
| #define MAX_MAG_DELTA	11 | ||||
| #define MAX_PHS_DELTA	10 | ||||
| 
 | ||||
| struct coeff { | ||||
| 	int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS]; | ||||
| 	int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS]; | ||||
| 	int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT]; | ||||
| 	int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT]; | ||||
| 	int iqc_coeff[2]; | ||||
| }; | ||||
| 
 | ||||
|  | @ -185,17 +185,19 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah) | |||
| 
 | ||||
| 	/* Accumulate IQ cal measures for active chains */ | ||||
| 	for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||||
| 		ah->totalPowerMeasI[i] += | ||||
| 			REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||||
| 		ah->totalPowerMeasQ[i] += | ||||
| 			REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||||
| 		ah->totalIqCorrMeas[i] += | ||||
| 			(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||||
| 		ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | ||||
| 			"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", | ||||
| 			ah->cal_samples, i, ah->totalPowerMeasI[i], | ||||
| 			ah->totalPowerMeasQ[i], | ||||
| 			ah->totalIqCorrMeas[i]); | ||||
| 		if (ah->txchainmask & BIT(i)) { | ||||
| 			ah->totalPowerMeasI[i] += | ||||
| 				REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||||
| 			ah->totalPowerMeasQ[i] += | ||||
| 				REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||||
| 			ah->totalIqCorrMeas[i] += | ||||
| 				(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||||
| 			ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | ||||
| 				"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", | ||||
| 				ah->cal_samples, i, ah->totalPowerMeasI[i], | ||||
| 				ah->totalPowerMeasQ[i], | ||||
| 				ah->totalIqCorrMeas[i]); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -608,36 +610,48 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | |||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg) | ||||
| static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement, | ||||
| 				     int max_delta) | ||||
| { | ||||
| 	int diff[MPASS]; | ||||
| 	int mp_max = -64, max_idx = 0; | ||||
| 	int mp_min = 63, min_idx = 0; | ||||
| 	int mp_avg = 0, i, outlier_idx = 0; | ||||
| 
 | ||||
| 	diff[0] = abs(mp_coeff[0] - mp_coeff[1]); | ||||
| 	diff[1] = abs(mp_coeff[1] - mp_coeff[2]); | ||||
| 	diff[2] = abs(mp_coeff[2] - mp_coeff[0]); | ||||
| 	/* find min/max mismatch across all calibrated gains */ | ||||
| 	for (i = 0; i < nmeasurement; i++) { | ||||
| 		mp_avg += mp_coeff[i]; | ||||
| 		if (mp_coeff[i] > mp_max) { | ||||
| 			mp_max = mp_coeff[i]; | ||||
| 			max_idx = i; | ||||
| 		} else if (mp_coeff[i] < mp_min) { | ||||
| 			mp_min = mp_coeff[i]; | ||||
| 			min_idx = i; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (diff[0] > MAX_DIFFERENCE && | ||||
| 	    diff[1] > MAX_DIFFERENCE && | ||||
| 	    diff[2] > MAX_DIFFERENCE) | ||||
| 		return false; | ||||
| 	/* find average (exclude max abs value) */ | ||||
| 	for (i = 0; i < nmeasurement; i++) { | ||||
| 		if ((abs(mp_coeff[i]) < abs(mp_max)) || | ||||
| 		    (abs(mp_coeff[i]) < abs(mp_min))) | ||||
| 			mp_avg += mp_coeff[i]; | ||||
| 	} | ||||
| 	mp_avg /= (nmeasurement - 1); | ||||
| 
 | ||||
| 	if (diff[0] <= diff[1] && diff[0] <= diff[2]) | ||||
| 		*mp_avg = (mp_coeff[0] + mp_coeff[1]) / 2; | ||||
| 	else if (diff[1] <= diff[2]) | ||||
| 		*mp_avg = (mp_coeff[1] + mp_coeff[2]) / 2; | ||||
| 	else | ||||
| 		*mp_avg = (mp_coeff[2] + mp_coeff[0]) / 2; | ||||
| 
 | ||||
| 	return true; | ||||
| 	/* detect outlier */ | ||||
| 	if (abs(mp_max - mp_min) > max_delta) { | ||||
| 		if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg)) | ||||
| 			outlier_idx = max_idx; | ||||
| 		else | ||||
| 			outlier_idx = min_idx; | ||||
| 	} | ||||
| 	mp_coeff[outlier_idx] = mp_avg; | ||||
| } | ||||
| 
 | ||||
| static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | ||||
| 						 u8 num_chains, | ||||
| 						 struct coeff *coeff) | ||||
| { | ||||
| 	struct ath_common *common = ath9k_hw_common(ah); | ||||
| 	int i, im, nmeasurement; | ||||
| 	int magnitude, phase; | ||||
| 	u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS]; | ||||
| 
 | ||||
| 	memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff)); | ||||
|  | @ -657,37 +671,28 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | |||
| 
 | ||||
| 	/* Load the average of 2 passes */ | ||||
| 	for (i = 0; i < num_chains; i++) { | ||||
| 		if (AR_SREV_9485(ah)) | ||||
| 			nmeasurement = REG_READ_FIELD(ah, | ||||
| 					AR_PHY_TX_IQCAL_STATUS_B0_9485, | ||||
| 					AR_PHY_CALIBRATED_GAINS_0); | ||||
| 		else | ||||
| 			nmeasurement = REG_READ_FIELD(ah, | ||||
| 					AR_PHY_TX_IQCAL_STATUS_B0, | ||||
| 					AR_PHY_CALIBRATED_GAINS_0); | ||||
| 		nmeasurement = REG_READ_FIELD(ah, | ||||
| 				AR_PHY_TX_IQCAL_STATUS_B0, | ||||
| 				AR_PHY_CALIBRATED_GAINS_0); | ||||
| 
 | ||||
| 		if (nmeasurement > MAX_MEASUREMENT) | ||||
| 			nmeasurement = MAX_MEASUREMENT; | ||||
| 
 | ||||
| 		/* detect outlier only if nmeasurement > 1 */ | ||||
| 		if (nmeasurement > 1) { | ||||
| 			/* Detect magnitude outlier */ | ||||
| 			ar9003_hw_detect_outlier(coeff->mag_coeff[i], | ||||
| 					nmeasurement, MAX_MAG_DELTA); | ||||
| 
 | ||||
| 			/* Detect phase outlier */ | ||||
| 			ar9003_hw_detect_outlier(coeff->phs_coeff[i], | ||||
| 					nmeasurement, MAX_PHS_DELTA); | ||||
| 		} | ||||
| 
 | ||||
| 		for (im = 0; im < nmeasurement; im++) { | ||||
| 			/*
 | ||||
| 			 * Determine which 2 passes are closest and compute avg | ||||
| 			 * magnitude | ||||
| 			 */ | ||||
| 			if (!ar9003_hw_compute_closest_pass_and_avg(coeff->mag_coeff[i][im], | ||||
| 								    &magnitude)) | ||||
| 				goto disable_txiqcal; | ||||
| 
 | ||||
| 			/*
 | ||||
| 			 * Determine which 2 passes are closest and compute avg | ||||
| 			 * phase | ||||
| 			 */ | ||||
| 			if (!ar9003_hw_compute_closest_pass_and_avg(coeff->phs_coeff[i][im], | ||||
| 								    &phase)) | ||||
| 				goto disable_txiqcal; | ||||
| 
 | ||||
| 			coeff->iqc_coeff[0] = (magnitude & 0x7f) | | ||||
| 					      ((phase & 0x7f) << 7); | ||||
| 			coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) | | ||||
| 				((coeff->phs_coeff[i][im] & 0x7f) << 7); | ||||
| 
 | ||||
| 			if ((im % 2) == 0) | ||||
| 				REG_RMW_FIELD(ah, tx_corr_coeff[im][i], | ||||
|  | @ -707,141 +712,37 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah, | |||
| 
 | ||||
| 	return; | ||||
| 
 | ||||
| disable_txiqcal: | ||||
| 	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, | ||||
| 		      AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x0); | ||||
| 	REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, | ||||
| 		      AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x0); | ||||
| 
 | ||||
| 	ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n"); | ||||
| } | ||||
| 
 | ||||
| static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) | ||||
| static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) | ||||
| { | ||||
| 	struct ath_common *common = ath9k_hw_common(ah); | ||||
| 	static const u32 txiqcal_status[AR9300_MAX_CHAINS] = { | ||||
| 		AR_PHY_TX_IQCAL_STATUS_B0, | ||||
| 		AR_PHY_TX_IQCAL_STATUS_B1, | ||||
| 		AR_PHY_TX_IQCAL_STATUS_B2, | ||||
| 	}; | ||||
| 	static const u32 chan_info_tab[] = { | ||||
| 		AR_PHY_CHAN_INFO_TAB_0, | ||||
| 		AR_PHY_CHAN_INFO_TAB_1, | ||||
| 		AR_PHY_CHAN_INFO_TAB_2, | ||||
| 	}; | ||||
| 	struct coeff coeff; | ||||
| 	s32 iq_res[6]; | ||||
| 	s32 i, j, ip, im, nmeasurement; | ||||
| 	u8 nchains = get_streams(common->tx_chainmask); | ||||
| 
 | ||||
| 	for (ip = 0; ip < MPASS; ip++) { | ||||
| 		REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, | ||||
| 			      AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, | ||||
| 			      DELPT); | ||||
| 		REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START, | ||||
| 			      AR_PHY_TX_IQCAL_START_DO_CAL, | ||||
| 			      AR_PHY_TX_IQCAL_START_DO_CAL); | ||||
| 
 | ||||
| 		if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START, | ||||
| 				   AR_PHY_TX_IQCAL_START_DO_CAL, | ||||
| 				   0, AH_WAIT_TIMEOUT)) { | ||||
| 			ath_dbg(common, ATH_DBG_CALIBRATE, | ||||
| 				"Tx IQ Cal not complete.\n"); | ||||
| 			goto TX_IQ_CAL_FAILED; | ||||
| 		} | ||||
| 
 | ||||
| 		nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0, | ||||
| 					      AR_PHY_CALIBRATED_GAINS_0); | ||||
| 			if (nmeasurement > MAX_MEASUREMENT) | ||||
| 				nmeasurement = MAX_MEASUREMENT; | ||||
| 
 | ||||
| 		for (i = 0; i < nchains; i++) { | ||||
| 			ath_dbg(common, ATH_DBG_CALIBRATE, | ||||
| 				"Doing Tx IQ Cal for chain %d.\n", i); | ||||
| 			for (im = 0; im < nmeasurement; im++) { | ||||
| 				if (REG_READ(ah, txiqcal_status[i]) & | ||||
| 					     AR_PHY_TX_IQCAL_STATUS_FAILED) { | ||||
| 					ath_dbg(common, ATH_DBG_CALIBRATE, | ||||
| 						"Tx IQ Cal failed for chain %d.\n", i); | ||||
| 					goto TX_IQ_CAL_FAILED; | ||||
| 				} | ||||
| 
 | ||||
| 				for (j = 0; j < 3; j++) { | ||||
| 					u8 idx = 2 * j, | ||||
| 					   offset = 4 * (3 * im + j); | ||||
| 
 | ||||
| 					REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, | ||||
| 						      AR_PHY_CHAN_INFO_TAB_S2_READ, | ||||
| 						      0); | ||||
| 
 | ||||
| 					/* 32 bits */ | ||||
| 					iq_res[idx] = REG_READ(ah, | ||||
| 							chan_info_tab[i] + | ||||
| 							offset); | ||||
| 
 | ||||
| 					REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, | ||||
| 						      AR_PHY_CHAN_INFO_TAB_S2_READ, | ||||
| 						      1); | ||||
| 
 | ||||
| 					/* 16 bits */ | ||||
| 					iq_res[idx+1] = 0xffff & REG_READ(ah, | ||||
| 								chan_info_tab[i] + | ||||
| 								offset); | ||||
| 
 | ||||
| 					ath_dbg(common, ATH_DBG_CALIBRATE, | ||||
| 						"IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n", | ||||
| 						idx, iq_res[idx], idx+1, iq_res[idx+1]); | ||||
| 				} | ||||
| 
 | ||||
| 				if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, | ||||
| 							    coeff.iqc_coeff)) { | ||||
| 					ath_dbg(common, ATH_DBG_CALIBRATE, | ||||
| 						"Failed in calculation of IQ correction.\n"); | ||||
| 					goto TX_IQ_CAL_FAILED; | ||||
| 				} | ||||
| 				coeff.mag_coeff[i][im][ip] = | ||||
| 						coeff.iqc_coeff[0] & 0x7f; | ||||
| 				coeff.phs_coeff[i][im][ip] = | ||||
| 						(coeff.iqc_coeff[0] >> 7) & 0x7f; | ||||
| 
 | ||||
| 				if (coeff.mag_coeff[i][im][ip] > 63) | ||||
| 					coeff.mag_coeff[i][im][ip] -= 128; | ||||
| 				if (coeff.phs_coeff[i][im][ip] > 63) | ||||
| 					coeff.phs_coeff[i][im][ip] -= 128; | ||||
| 
 | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff); | ||||
| 
 | ||||
| 	return; | ||||
| 
 | ||||
| TX_IQ_CAL_FAILED: | ||||
| 	ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); | ||||
| } | ||||
| 
 | ||||
| static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah) | ||||
| { | ||||
| 	u8 tx_gain_forced; | ||||
| 
 | ||||
| 	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1_9485, | ||||
| 		      AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT); | ||||
| 	tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN, | ||||
| 					AR_PHY_TXGAIN_FORCE); | ||||
| 	if (tx_gain_forced) | ||||
| 		REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, | ||||
| 			      AR_PHY_TXGAIN_FORCE, 0); | ||||
| 
 | ||||
| 	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START_9485, | ||||
| 		      AR_PHY_TX_IQCAL_START_DO_CAL_9485, 1); | ||||
| 	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START, | ||||
| 		      AR_PHY_TX_IQCAL_START_DO_CAL, 1); | ||||
| 
 | ||||
| 	if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START, | ||||
| 			AR_PHY_TX_IQCAL_START_DO_CAL, 0, | ||||
| 			AH_WAIT_TIMEOUT)) { | ||||
| 		ath_dbg(common, ATH_DBG_CALIBRATE, | ||||
| 			"Tx IQ Cal is not completed.\n"); | ||||
| 		return false; | ||||
| 	} | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) | ||||
| { | ||||
| 	struct ath_common *common = ath9k_hw_common(ah); | ||||
| 	const u32 txiqcal_status[AR9300_MAX_CHAINS] = { | ||||
| 		AR_PHY_TX_IQCAL_STATUS_B0_9485, | ||||
| 		AR_PHY_TX_IQCAL_STATUS_B0, | ||||
| 		AR_PHY_TX_IQCAL_STATUS_B1, | ||||
| 		AR_PHY_TX_IQCAL_STATUS_B2, | ||||
| 	}; | ||||
|  | @ -853,7 +754,7 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) | |||
| 	struct coeff coeff; | ||||
| 	s32 iq_res[6]; | ||||
| 	u8 num_chains = 0; | ||||
| 	int i, ip, im, j; | ||||
| 	int i, im, j; | ||||
| 	int nmeasurement; | ||||
| 
 | ||||
| 	for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||||
|  | @ -861,71 +762,69 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah) | |||
| 			num_chains++; | ||||
| 	} | ||||
| 
 | ||||
| 	for (ip = 0; ip < MPASS; ip++) { | ||||
| 		for (i = 0; i < num_chains; i++) { | ||||
| 			nmeasurement = REG_READ_FIELD(ah, | ||||
| 					AR_PHY_TX_IQCAL_STATUS_B0_9485, | ||||
| 					AR_PHY_CALIBRATED_GAINS_0); | ||||
| 			if (nmeasurement > MAX_MEASUREMENT) | ||||
| 				nmeasurement = MAX_MEASUREMENT; | ||||
| 	for (i = 0; i < num_chains; i++) { | ||||
| 		nmeasurement = REG_READ_FIELD(ah, | ||||
| 				AR_PHY_TX_IQCAL_STATUS_B0, | ||||
| 				AR_PHY_CALIBRATED_GAINS_0); | ||||
| 		if (nmeasurement > MAX_MEASUREMENT) | ||||
| 			nmeasurement = MAX_MEASUREMENT; | ||||
| 
 | ||||
| 			for (im = 0; im < nmeasurement; im++) { | ||||
| 		for (im = 0; im < nmeasurement; im++) { | ||||
| 			ath_dbg(common, ATH_DBG_CALIBRATE, | ||||
| 				"Doing Tx IQ Cal for chain %d.\n", i); | ||||
| 
 | ||||
| 			if (REG_READ(ah, txiqcal_status[i]) & | ||||
| 					AR_PHY_TX_IQCAL_STATUS_FAILED) { | ||||
| 				ath_dbg(common, ATH_DBG_CALIBRATE, | ||||
| 					"Doing Tx IQ Cal for chain %d.\n", i); | ||||
| 
 | ||||
| 				if (REG_READ(ah, txiqcal_status[i]) & | ||||
| 				    AR_PHY_TX_IQCAL_STATUS_FAILED) { | ||||
| 					ath_dbg(common, ATH_DBG_CALIBRATE, | ||||
| 					"Tx IQ Cal failed for chain %d.\n", i); | ||||
| 					goto tx_iqcal_fail; | ||||
| 				} | ||||
| 				goto tx_iqcal_fail; | ||||
| 			} | ||||
| 
 | ||||
| 				for (j = 0; j < 3; j++) { | ||||
| 					u32 idx = 2 * j, offset = 4 * (3 * im + j); | ||||
| 			for (j = 0; j < 3; j++) { | ||||
| 				u32 idx = 2 * j, offset = 4 * (3 * im + j); | ||||
| 
 | ||||
| 					REG_RMW_FIELD(ah, | ||||
| 				REG_RMW_FIELD(ah, | ||||
| 						AR_PHY_CHAN_INFO_MEMORY, | ||||
| 						AR_PHY_CHAN_INFO_TAB_S2_READ, | ||||
| 						0); | ||||
| 
 | ||||
| 					/* 32 bits */ | ||||
| 					iq_res[idx] = REG_READ(ah, | ||||
| 							chan_info_tab[i] + | ||||
| 							offset); | ||||
| 				/* 32 bits */ | ||||
| 				iq_res[idx] = REG_READ(ah, | ||||
| 						chan_info_tab[i] + | ||||
| 						offset); | ||||
| 
 | ||||
| 					REG_RMW_FIELD(ah, | ||||
| 				REG_RMW_FIELD(ah, | ||||
| 						AR_PHY_CHAN_INFO_MEMORY, | ||||
| 						AR_PHY_CHAN_INFO_TAB_S2_READ, | ||||
| 						1); | ||||
| 
 | ||||
| 					/* 16 bits */ | ||||
| 					iq_res[idx + 1] = 0xffff & REG_READ(ah, | ||||
| 							  chan_info_tab[i] + offset); | ||||
| 				/* 16 bits */ | ||||
| 				iq_res[idx + 1] = 0xffff & REG_READ(ah, | ||||
| 						chan_info_tab[i] + offset); | ||||
| 
 | ||||
| 					ath_dbg(common, ATH_DBG_CALIBRATE, | ||||
| 						"IQ RES[%d]=0x%x" | ||||
| 						"IQ_RES[%d]=0x%x\n", | ||||
| 						idx, iq_res[idx], idx + 1, | ||||
| 						iq_res[idx + 1]); | ||||
| 				} | ||||
| 
 | ||||
| 				if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, | ||||
| 							    coeff.iqc_coeff)) { | ||||
| 					ath_dbg(common, ATH_DBG_CALIBRATE, | ||||
| 					 "Failed in calculation of IQ correction.\n"); | ||||
| 					goto tx_iqcal_fail; | ||||
| 				} | ||||
| 
 | ||||
| 				coeff.mag_coeff[i][im][ip] = | ||||
| 						coeff.iqc_coeff[0] & 0x7f; | ||||
| 				coeff.phs_coeff[i][im][ip] = | ||||
| 						(coeff.iqc_coeff[0] >> 7) & 0x7f; | ||||
| 
 | ||||
| 				if (coeff.mag_coeff[i][im][ip] > 63) | ||||
| 					coeff.mag_coeff[i][im][ip] -= 128; | ||||
| 				if (coeff.phs_coeff[i][im][ip] > 63) | ||||
| 					coeff.phs_coeff[i][im][ip] -= 128; | ||||
| 				ath_dbg(common, ATH_DBG_CALIBRATE, | ||||
| 					"IQ RES[%d]=0x%x" | ||||
| 					"IQ_RES[%d]=0x%x\n", | ||||
| 					idx, iq_res[idx], idx + 1, | ||||
| 					iq_res[idx + 1]); | ||||
| 			} | ||||
| 
 | ||||
| 			if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, | ||||
| 						coeff.iqc_coeff)) { | ||||
| 				ath_dbg(common, ATH_DBG_CALIBRATE, | ||||
| 					"Failed in calculation of \
 | ||||
| 					IQ correction.\n"); | ||||
| 				goto tx_iqcal_fail; | ||||
| 			} | ||||
| 
 | ||||
| 			coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f; | ||||
| 			coeff.phs_coeff[i][im] = | ||||
| 				(coeff.iqc_coeff[0] >> 7) & 0x7f; | ||||
| 
 | ||||
| 			if (coeff.mag_coeff[i][im] > 63) | ||||
| 				coeff.mag_coeff[i][im] -= 128; | ||||
| 			if (coeff.phs_coeff[i][im] > 63) | ||||
| 				coeff.phs_coeff[i][im] -= 128; | ||||
| 		} | ||||
| 	} | ||||
| 	ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff); | ||||
|  | @ -940,31 +839,37 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
| 			       struct ath9k_channel *chan) | ||||
| { | ||||
| 	struct ath_common *common = ath9k_hw_common(ah); | ||||
| 	struct ath9k_hw_capabilities *pCap = &ah->caps; | ||||
| 	int val; | ||||
| 	bool txiqcal_done = false; | ||||
| 
 | ||||
| 	val = REG_READ(ah, AR_ENT_OTP); | ||||
| 	ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val); | ||||
| 
 | ||||
| 	if (AR_SREV_9485(ah)) | ||||
| 		ar9003_hw_set_chain_masks(ah, 0x1, 0x1); | ||||
| 	else if (val & AR_ENT_OTP_CHAIN2_DISABLE) | ||||
| 	/* Configure rx/tx chains before running AGC/TxiQ cals */ | ||||
| 	if (val & AR_ENT_OTP_CHAIN2_DISABLE) | ||||
| 		ar9003_hw_set_chain_masks(ah, 0x3, 0x3); | ||||
| 	else | ||||
| 		/*
 | ||||
| 		 * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain | ||||
| 		 * mode before running AGC/TxIQ cals | ||||
| 		 */ | ||||
| 		ar9003_hw_set_chain_masks(ah, 0x7, 0x7); | ||||
| 		ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask, | ||||
| 					  pCap->tx_chainmask); | ||||
| 
 | ||||
| 	/* Do Tx IQ Calibration */ | ||||
| 	if (AR_SREV_9485(ah)) | ||||
| 		ar9003_hw_tx_iq_cal_run(ah); | ||||
| 	else | ||||
| 		ar9003_hw_tx_iq_cal(ah); | ||||
| 	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, | ||||
| 		      AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, | ||||
| 		      DELPT); | ||||
| 
 | ||||
| 	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); | ||||
| 	udelay(5); | ||||
| 	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | ||||
| 	/*
 | ||||
| 	 * For AR9485 or later chips, TxIQ cal runs as part of | ||||
| 	 * AGC calibration | ||||
| 	 */ | ||||
| 	if (AR_SREV_9485_OR_LATER(ah)) | ||||
| 		txiqcal_done = true; | ||||
| 	else { | ||||
| 		txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); | ||||
| 		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); | ||||
| 		udelay(5); | ||||
| 		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Calibrate the AGC */ | ||||
| 	REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||||
|  | @ -979,7 +884,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, | |||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	if (AR_SREV_9485(ah)) | ||||
| 	if (txiqcal_done) | ||||
| 		ar9003_hw_tx_iq_cal_post_proc(ah); | ||||
| 
 | ||||
| 	/* Revert chainmasks to their original values before NF cal */ | ||||
|  |  | |||
|  | @ -3217,7 +3217,6 @@ static int ar9300_compress_decision(struct ath_hw *ah, | |||
| 				    u8 *word, int length, int mdata_size) | ||||
| { | ||||
| 	struct ath_common *common = ath9k_hw_common(ah); | ||||
| 	u8 *dptr; | ||||
| 	const struct ar9300_eeprom *eep = NULL; | ||||
| 
 | ||||
| 	switch (code) { | ||||
|  | @ -3235,7 +3234,6 @@ static int ar9300_compress_decision(struct ath_hw *ah, | |||
| 		break; | ||||
| 	case _CompressBlock: | ||||
| 		if (reference == 0) { | ||||
| 			dptr = mptr; | ||||
| 		} else { | ||||
| 			eep = ar9003_eeprom_struct_find_by_id(reference); | ||||
| 			if (eep == NULL) { | ||||
|  | @ -3448,9 +3446,13 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) | |||
| 		REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); | ||||
| 	else { | ||||
| 		REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); | ||||
| 		REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB, | ||||
| 			      bias >> 2); | ||||
| 		REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1); | ||||
| 		if (!AR_SREV_9340(ah)) { | ||||
| 			REG_RMW_FIELD(ah, AR_CH0_THERM, | ||||
| 				      AR_CH0_THERM_XPABIASLVL_MSB, | ||||
| 				      bias >> 2); | ||||
| 			REG_RMW_FIELD(ah, AR_CH0_THERM, | ||||
| 				      AR_CH0_THERM_XPASHORT2GND, 1); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -3497,23 +3499,28 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, | |||
| 
 | ||||
| static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) | ||||
| { | ||||
| 	int chain; | ||||
| 	static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = { | ||||
| 			AR_PHY_SWITCH_CHAIN_0, | ||||
| 			AR_PHY_SWITCH_CHAIN_1, | ||||
| 			AR_PHY_SWITCH_CHAIN_2, | ||||
| 	}; | ||||
| 
 | ||||
| 	u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz); | ||||
| 
 | ||||
| 	REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value); | ||||
| 
 | ||||
| 	value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); | ||||
| 	REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); | ||||
| 
 | ||||
| 	value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz); | ||||
| 	REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value); | ||||
| 
 | ||||
| 	if (!AR_SREV_9485(ah)) { | ||||
| 		value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz); | ||||
| 		REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, | ||||
| 			      value); | ||||
| 
 | ||||
| 		value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz); | ||||
| 		REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, | ||||
| 			      value); | ||||
| 	for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { | ||||
| 		if ((ah->rxchainmask & BIT(chain)) || | ||||
| 		    (ah->txchainmask & BIT(chain))) { | ||||
| 			value = ar9003_hw_ant_ctrl_chain_get(ah, chain, | ||||
| 							     is2ghz); | ||||
| 			REG_RMW_FIELD(ah, switch_chain_reg[chain], | ||||
| 				      AR_SWITCH_TABLE_ALL, value); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (AR_SREV_9485(ah)) { | ||||
|  | @ -3634,13 +3641,16 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan) | |||
| 
 | ||||
| 	/* Test value. if 0 then attenuation is unused. Don't load anything. */ | ||||
| 	for (i = 0; i < 3; i++) { | ||||
| 		value = ar9003_hw_atten_chain_get(ah, i, chan); | ||||
| 		REG_RMW_FIELD(ah, ext_atten_reg[i], | ||||
| 			      AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); | ||||
| 		if (ah->txchainmask & BIT(i)) { | ||||
| 			value = ar9003_hw_atten_chain_get(ah, i, chan); | ||||
| 			REG_RMW_FIELD(ah, ext_atten_reg[i], | ||||
| 				      AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value); | ||||
| 
 | ||||
| 		value = ar9003_hw_atten_chain_get_margin(ah, i, chan); | ||||
| 		REG_RMW_FIELD(ah, ext_atten_reg[i], | ||||
| 			      AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value); | ||||
| 			value = ar9003_hw_atten_chain_get_margin(ah, i, chan); | ||||
| 			REG_RMW_FIELD(ah, ext_atten_reg[i], | ||||
| 				      AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, | ||||
| 				      value); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -3749,8 +3759,9 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, | |||
| 	ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); | ||||
| 	ar9003_hw_drive_strength_apply(ah); | ||||
| 	ar9003_hw_atten_apply(ah, chan); | ||||
| 	ar9003_hw_internal_regulator_apply(ah); | ||||
| 	if (AR_SREV_9485(ah)) | ||||
| 	if (!AR_SREV_9340(ah)) | ||||
| 		ar9003_hw_internal_regulator_apply(ah); | ||||
| 	if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) | ||||
| 		ar9003_hw_apply_tuning_caps(ah); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ | |||
| #include "ar9003_mac.h" | ||||
| #include "ar9003_2p2_initvals.h" | ||||
| #include "ar9485_initvals.h" | ||||
| #include "ar9340_initvals.h" | ||||
| 
 | ||||
| /* General hardware code for the AR9003 hadware family */ | ||||
| 
 | ||||
|  | @ -28,7 +29,63 @@ | |||
|  */ | ||||
| static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | ||||
| { | ||||
| 	if (AR_SREV_9485_11(ah)) { | ||||
| 	if (AR_SREV_9340(ah)) { | ||||
| 		/* mac */ | ||||
| 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||||
| 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | ||||
| 				ar9340_1p0_mac_core, | ||||
| 				ARRAY_SIZE(ar9340_1p0_mac_core), 2); | ||||
| 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | ||||
| 				ar9340_1p0_mac_postamble, | ||||
| 				ARRAY_SIZE(ar9340_1p0_mac_postamble), 5); | ||||
| 
 | ||||
| 		/* bb */ | ||||
| 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); | ||||
| 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | ||||
| 				ar9340_1p0_baseband_core, | ||||
| 				ARRAY_SIZE(ar9340_1p0_baseband_core), 2); | ||||
| 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | ||||
| 				ar9340_1p0_baseband_postamble, | ||||
| 				ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5); | ||||
| 
 | ||||
| 		/* radio */ | ||||
| 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||||
| 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | ||||
| 				ar9340_1p0_radio_core, | ||||
| 				ARRAY_SIZE(ar9340_1p0_radio_core), 2); | ||||
| 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | ||||
| 				ar9340_1p0_radio_postamble, | ||||
| 				ARRAY_SIZE(ar9340_1p0_radio_postamble), 5); | ||||
| 
 | ||||
| 		/* soc */ | ||||
| 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | ||||
| 				ar9340_1p0_soc_preamble, | ||||
| 				ARRAY_SIZE(ar9340_1p0_soc_preamble), 2); | ||||
| 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||||
| 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | ||||
| 				ar9340_1p0_soc_postamble, | ||||
| 				ARRAY_SIZE(ar9340_1p0_soc_postamble), 5); | ||||
| 
 | ||||
| 		/* rx/tx gain */ | ||||
| 		INIT_INI_ARRAY(&ah->iniModesRxGain, | ||||
| 				ar9340Common_wo_xlna_rx_gain_table_1p0, | ||||
| 				ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0), | ||||
| 				5); | ||||
| 		INIT_INI_ARRAY(&ah->iniModesTxGain, | ||||
| 				ar9340Modes_high_ob_db_tx_gain_table_1p0, | ||||
| 				ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0), | ||||
| 				5); | ||||
| 
 | ||||
| 		INIT_INI_ARRAY(&ah->iniModesAdditional, | ||||
| 				ar9340Modes_fast_clock_1p0, | ||||
| 				ARRAY_SIZE(ar9340Modes_fast_clock_1p0), | ||||
| 				3); | ||||
| 
 | ||||
| 		INIT_INI_ARRAY(&ah->iniModesAdditional_40M, | ||||
| 				ar9340_1p0_radio_core_40M, | ||||
| 				ARRAY_SIZE(ar9340_1p0_radio_core_40M), | ||||
| 				2); | ||||
| 	} else if (AR_SREV_9485_11(ah)) { | ||||
| 		/* mac */ | ||||
| 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||||
| 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | ||||
|  | @ -163,7 +220,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
| 	switch (ar9003_hw_get_tx_gain_idx(ah)) { | ||||
| 	case 0: | ||||
| 	default: | ||||
| 		if (AR_SREV_9485_11(ah)) | ||||
| 		if (AR_SREV_9340(ah)) | ||||
| 			INIT_INI_ARRAY(&ah->iniModesTxGain, | ||||
| 					ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | ||||
| 				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | ||||
| 				       5); | ||||
| 		else if (AR_SREV_9485_11(ah)) | ||||
| 			INIT_INI_ARRAY(&ah->iniModesTxGain, | ||||
| 				       ar9485_modes_lowest_ob_db_tx_gain_1_1, | ||||
| 				       ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1), | ||||
|  | @ -175,7 +237,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
| 				       5); | ||||
| 		break; | ||||
| 	case 1: | ||||
| 		if (AR_SREV_9485_11(ah)) | ||||
| 		if (AR_SREV_9340(ah)) | ||||
| 			INIT_INI_ARRAY(&ah->iniModesTxGain, | ||||
| 					ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | ||||
| 				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | ||||
| 				       5); | ||||
| 		else if (AR_SREV_9485_11(ah)) | ||||
| 			INIT_INI_ARRAY(&ah->iniModesTxGain, | ||||
| 				       ar9485Modes_high_ob_db_tx_gain_1_1, | ||||
| 				       ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1), | ||||
|  | @ -187,7 +254,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
| 				       5); | ||||
| 		break; | ||||
| 	case 2: | ||||
| 		if (AR_SREV_9485_11(ah)) | ||||
| 		if (AR_SREV_9340(ah)) | ||||
| 			INIT_INI_ARRAY(&ah->iniModesTxGain, | ||||
| 					ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | ||||
| 				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | ||||
| 				       5); | ||||
| 		else if (AR_SREV_9485_11(ah)) | ||||
| 			INIT_INI_ARRAY(&ah->iniModesTxGain, | ||||
| 				       ar9485Modes_low_ob_db_tx_gain_1_1, | ||||
| 				       ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1), | ||||
|  | @ -199,7 +271,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | |||
| 				       5); | ||||
| 		break; | ||||
| 	case 3: | ||||
| 		if (AR_SREV_9485_11(ah)) | ||||
| 		if (AR_SREV_9340(ah)) | ||||
| 			INIT_INI_ARRAY(&ah->iniModesTxGain, | ||||
| 					ar9340Modes_lowest_ob_db_tx_gain_table_1p0, | ||||
| 				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0), | ||||
| 				       5); | ||||
| 		else if (AR_SREV_9485_11(ah)) | ||||
| 			INIT_INI_ARRAY(&ah->iniModesTxGain, | ||||
| 				       ar9485Modes_high_power_tx_gain_1_1, | ||||
| 				       ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1), | ||||
|  | @ -218,7 +295,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) | |||
| 	switch (ar9003_hw_get_rx_gain_idx(ah)) { | ||||
| 	case 0: | ||||
| 	default: | ||||
| 		if (AR_SREV_9485_11(ah)) | ||||
| 		if (AR_SREV_9340(ah)) | ||||
| 			INIT_INI_ARRAY(&ah->iniModesRxGain, | ||||
| 				       ar9340Common_rx_gain_table_1p0, | ||||
| 				       ARRAY_SIZE(ar9340Common_rx_gain_table_1p0), | ||||
| 				       2); | ||||
| 		else if (AR_SREV_9485_11(ah)) | ||||
| 			INIT_INI_ARRAY(&ah->iniModesRxGain, | ||||
| 				       ar9485Common_wo_xlna_rx_gain_1_1, | ||||
| 				       ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), | ||||
|  | @ -230,7 +312,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah) | |||
| 				       2); | ||||
| 		break; | ||||
| 	case 1: | ||||
| 		if (AR_SREV_9485_11(ah)) | ||||
| 		if (AR_SREV_9340(ah)) | ||||
| 			INIT_INI_ARRAY(&ah->iniModesRxGain, | ||||
| 				       ar9340Common_wo_xlna_rx_gain_table_1p0, | ||||
| 				       ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0), | ||||
| 				       2); | ||||
| 		else if (AR_SREV_9485_11(ah)) | ||||
| 			INIT_INI_ARRAY(&ah->iniModesRxGain, | ||||
| 				       ar9485Common_wo_xlna_rx_gain_1_1, | ||||
| 				       ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), | ||||
|  |  | |||
|  | @ -86,14 +86,31 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | |||
| 			channelSel = (freq * 4) / 120; | ||||
| 			chan_frac = (((freq * 4) % 120) * 0x20000) / 120; | ||||
| 			channelSel = (channelSel << 17) | chan_frac; | ||||
| 		} else if (AR_SREV_9340(ah)) { | ||||
| 			if (ah->is_clk_25mhz) { | ||||
| 				u32 chan_frac; | ||||
| 
 | ||||
| 				channelSel = (freq * 2) / 75; | ||||
| 				chan_frac = (((freq * 2) % 75) * 0x20000) / 75; | ||||
| 				channelSel = (channelSel << 17) | chan_frac; | ||||
| 			} else | ||||
| 				channelSel = CHANSEL_2G(freq) >> 1; | ||||
| 		} else | ||||
| 			channelSel = CHANSEL_2G(freq); | ||||
| 		/* Set to 2G mode */ | ||||
| 		bMode = 1; | ||||
| 	} else { | ||||
| 		channelSel = CHANSEL_5G(freq); | ||||
| 		/* Doubler is ON, so, divide channelSel by 2. */ | ||||
| 		channelSel >>= 1; | ||||
| 		if (AR_SREV_9340(ah) && ah->is_clk_25mhz) { | ||||
| 			u32 chan_frac; | ||||
| 
 | ||||
| 			channelSel = (freq * 2) / 75; | ||||
| 			chan_frac = ((freq % 75) * 0x20000) / 75; | ||||
| 			channelSel = (channelSel << 17) | chan_frac; | ||||
| 		} else { | ||||
| 			channelSel = CHANSEL_5G(freq); | ||||
| 			/* Doubler is ON, so, divide channelSel by 2. */ | ||||
| 			channelSel >>= 1; | ||||
| 		} | ||||
| 		/* Set to 5G mode */ | ||||
| 		bMode = 0; | ||||
| 	} | ||||
|  | @ -151,7 +168,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, | |||
| 	 * is out-of-band and can be ignored. | ||||
| 	 */ | ||||
| 
 | ||||
| 	if (AR_SREV_9485(ah)) { | ||||
| 	if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) { | ||||
| 		spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah, | ||||
| 							 IS_CHAN_2GHZ(chan)); | ||||
| 		if (spur_fbin_ptr[0] == 0) /* No spur */ | ||||
|  | @ -176,7 +193,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, | |||
| 
 | ||||
| 	for (i = 0; i < max_spur_cnts; i++) { | ||||
| 		negative = 0; | ||||
| 		if (AR_SREV_9485(ah)) | ||||
| 		if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) | ||||
| 			cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i], | ||||
| 					IS_CHAN_2GHZ(chan)) - synth_freq; | ||||
| 		else | ||||
|  | @ -599,29 +616,25 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
| 	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | ||||
| 	unsigned int regWrites = 0, i; | ||||
| 	struct ieee80211_channel *channel = chan->chan; | ||||
| 	u32 modesIndex, freqIndex; | ||||
| 	u32 modesIndex; | ||||
| 
 | ||||
| 	switch (chan->chanmode) { | ||||
| 	case CHANNEL_A: | ||||
| 	case CHANNEL_A_HT20: | ||||
| 		modesIndex = 1; | ||||
| 		freqIndex = 1; | ||||
| 		break; | ||||
| 	case CHANNEL_A_HT40PLUS: | ||||
| 	case CHANNEL_A_HT40MINUS: | ||||
| 		modesIndex = 2; | ||||
| 		freqIndex = 1; | ||||
| 		break; | ||||
| 	case CHANNEL_G: | ||||
| 	case CHANNEL_G_HT20: | ||||
| 	case CHANNEL_B: | ||||
| 		modesIndex = 4; | ||||
| 		freqIndex = 2; | ||||
| 		break; | ||||
| 	case CHANNEL_G_HT40PLUS: | ||||
| 	case CHANNEL_G_HT40MINUS: | ||||
| 		modesIndex = 3; | ||||
| 		freqIndex = 2; | ||||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
|  | @ -646,6 +659,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, | |||
| 		REG_WRITE_ARRAY(&ah->iniModesAdditional, | ||||
| 				modesIndex, regWrites); | ||||
| 
 | ||||
| 	if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) | ||||
| 		REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); | ||||
| 
 | ||||
| 	ar9003_hw_override_ini(ah); | ||||
| 	ar9003_hw_set_channel_regs(ah, chan); | ||||
| 	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); | ||||
|  |  | |||
|  | @ -548,15 +548,12 @@ | |||
| 
 | ||||
| #define AR_PHY_TXGAIN_TABLE      (AR_SM_BASE + 0x300) | ||||
| 
 | ||||
| #define AR_PHY_TX_IQCAL_START_9485		(AR_SM_BASE + 0x3c4) | ||||
| #define AR_PHY_TX_IQCAL_START_DO_CAL_9485	0x80000000 | ||||
| #define AR_PHY_TX_IQCAL_START_DO_CAL_9485_S	31 | ||||
| #define AR_PHY_TX_IQCAL_CONTROL_1_9485		(AR_SM_BASE + 0x3c8) | ||||
| #define AR_PHY_TX_IQCAL_STATUS_B0_9485		(AR_SM_BASE + 0x3f0) | ||||
| 
 | ||||
| #define AR_PHY_TX_IQCAL_CONTROL_1   (AR_SM_BASE + 0x448) | ||||
| #define AR_PHY_TX_IQCAL_START       (AR_SM_BASE + 0x440) | ||||
| #define AR_PHY_TX_IQCAL_STATUS_B0   (AR_SM_BASE + 0x48c) | ||||
| #define AR_PHY_TX_IQCAL_CONTROL_1   (AR_SM_BASE + AR_SREV_9485(ah) ? \ | ||||
| 						 0x3c8 : 0x448) | ||||
| #define AR_PHY_TX_IQCAL_START       (AR_SM_BASE + AR_SREV_9485(ah) ? \ | ||||
| 						 0x3c4 : 0x440) | ||||
| #define AR_PHY_TX_IQCAL_STATUS_B0   (AR_SM_BASE + AR_SREV_9485(ah) ? \ | ||||
| 						 0x3f0 : 0x48c) | ||||
| #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i)    (AR_SM_BASE + \ | ||||
| 					     (AR_SREV_9485(ah) ? \ | ||||
| 					      0x3d0 : 0x450) + ((_i) << 2)) | ||||
|  | @ -588,7 +585,7 @@ | |||
| #define AR_PHY_65NM_CH0_BIAS2       0x160c4 | ||||
| #define AR_PHY_65NM_CH0_BIAS4       0x160cc | ||||
| #define AR_PHY_65NM_CH0_RXTX4       0x1610c | ||||
| #define AR_PHY_65NM_CH0_THERM       (AR_SREV_9485(ah) ? 0x1628c : 0x16290) | ||||
| #define AR_PHY_65NM_CH0_THERM       (AR_SREV_9300(ah) ? 0x16290 : 0x1628c) | ||||
| 
 | ||||
| #define AR_PHY_65NM_CH0_THERM_LOCAL   0x80000000 | ||||
| #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 | ||||
|  | @ -758,10 +755,10 @@ | |||
| #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT   0x01000000 | ||||
| #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 | ||||
| #define AR_PHY_CHANNEL_STATUS_RX_CLEAR      0x00000004 | ||||
| #define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT             0x01fc0000 | ||||
| #define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S                   18 | ||||
| #define AR_PHY_TX_IQCAL_START_DO_CAL        0x00000001 | ||||
| #define AR_PHY_TX_IQCAL_START_DO_CAL_S      0 | ||||
| #define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT             0x01fc0000 | ||||
| #define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S                   18 | ||||
| #define AR_PHY_TX_IQCAL_START_DO_CAL	    0x00000001 | ||||
| #define AR_PHY_TX_IQCAL_START_DO_CAL_S	    0 | ||||
| 
 | ||||
| #define AR_PHY_TX_IQCAL_STATUS_FAILED    0x00000001 | ||||
| #define AR_PHY_CALIBRATED_GAINS_0	 0x3e | ||||
|  |  | |||
							
								
								
									
										1525
									
								
								drivers/net/wireless/ath/ath9k/ar9340_initvals.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1525
									
								
								drivers/net/wireless/ath/ath9k/ar9340_initvals.h
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -423,6 +423,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); | |||
| #define ATH_PAPRD_TIMEOUT	100 /* msecs */ | ||||
| 
 | ||||
| void ath_hw_check(struct work_struct *work); | ||||
| void ath_hw_pll_work(struct work_struct *work); | ||||
| void ath_paprd_calibrate(struct work_struct *work); | ||||
| void ath_ani_calibrate(unsigned long data); | ||||
| 
 | ||||
|  | @ -453,6 +454,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc); | |||
| 
 | ||||
| #define ATH_LED_PIN_DEF 		1 | ||||
| #define ATH_LED_PIN_9287		8 | ||||
| #define ATH_LED_PIN_9300		10 | ||||
| #define ATH_LED_PIN_9485		6 | ||||
| 
 | ||||
| #ifdef CONFIG_MAC80211_LEDS | ||||
|  |  | |||
|  | @ -781,12 +781,6 @@ void ath_set_beacon(struct ath_softc *sc) | |||
| 		break; | ||||
| 	case NL80211_IFTYPE_STATION: | ||||
| 		ath_beacon_config_sta(sc, cur_conf); | ||||
| 		/*
 | ||||
| 		 * Request a re-configuration of Beacon related timers | ||||
| 		 * on the receipt of the first Beacon frame (i.e., | ||||
| 		 * after time sync with the AP). | ||||
| 		 */ | ||||
| 		sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||||
| 		break; | ||||
| 	default: | ||||
| 		ath_dbg(common, ATH_DBG_CONFIG, | ||||
|  |  | |||
|  | @ -51,6 +51,10 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) | |||
| 		.bt_hold_rx_clear = true, | ||||
| 	}; | ||||
| 	u32 i; | ||||
| 	bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity; | ||||
| 
 | ||||
| 	if (AR_SREV_9300_20_OR_LATER(ah)) | ||||
| 		rxclear_polarity = !ath_bt_config.bt_rxclear_polarity; | ||||
| 
 | ||||
| 	btcoex_hw->bt_coex_mode = | ||||
| 		(btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) | | ||||
|  | @ -59,7 +63,7 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) | |||
| 		SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) | | ||||
| 		SM(ath_bt_config.bt_mode, AR_BT_MODE) | | ||||
| 		SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) | | ||||
| 		SM(ath_bt_config.bt_rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) | | ||||
| 		SM(rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) | | ||||
| 		SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) | | ||||
| 		SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) | | ||||
| 		SM(qnum, AR_BT_QCU_THRESH); | ||||
|  | @ -142,6 +146,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, | |||
| } | ||||
| EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); | ||||
| 
 | ||||
| 
 | ||||
| static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) | ||||
| { | ||||
| 	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | ||||
|  | @ -152,9 +157,22 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) | |||
| 	 * enable coex 3-wire | ||||
| 	 */ | ||||
| 	REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_hw->bt_coex_mode); | ||||
| 	REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights); | ||||
| 	REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2); | ||||
| 
 | ||||
| 
 | ||||
| 	if (AR_SREV_9300_20_OR_LATER(ah)) { | ||||
| 		REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, ah->bt_coex_wlan_weight[0]); | ||||
| 		REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, ah->bt_coex_wlan_weight[1]); | ||||
| 		REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, ah->bt_coex_bt_weight[0]); | ||||
| 		REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, ah->bt_coex_bt_weight[1]); | ||||
| 		REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, ah->bt_coex_bt_weight[2]); | ||||
| 		REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, ah->bt_coex_bt_weight[3]); | ||||
| 
 | ||||
| 	} else | ||||
| 		REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	if (AR_SREV_9271(ah)) { | ||||
| 		val = REG_READ(ah, 0x50040); | ||||
| 		val &= 0xFFFFFEFF; | ||||
|  | @ -202,10 +220,86 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah) | |||
| 
 | ||||
| 	if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) { | ||||
| 		REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE); | ||||
| 		REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0); | ||||
| 		REG_WRITE(ah, AR_BT_COEX_MODE2, 0); | ||||
| 
 | ||||
| 		if (AR_SREV_9300_20_OR_LATER(ah)) { | ||||
| 			REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, 0); | ||||
| 			REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, 0); | ||||
| 			REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, 0); | ||||
| 			REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, 0); | ||||
| 			REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, 0); | ||||
| 			REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, 0); | ||||
| 		} else | ||||
| 			REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	ah->btcoex_hw.enabled = false; | ||||
| } | ||||
| EXPORT_SYMBOL(ath9k_hw_btcoex_disable); | ||||
| 
 | ||||
| static void ar9003_btcoex_bt_stomp(struct ath_hw *ah, | ||||
| 			 enum ath_stomp_type stomp_type) | ||||
| { | ||||
| 	ah->bt_coex_bt_weight[0] = AR9300_BT_WGHT; | ||||
| 	ah->bt_coex_bt_weight[1] = AR9300_BT_WGHT; | ||||
| 	ah->bt_coex_bt_weight[2] = AR9300_BT_WGHT; | ||||
| 	ah->bt_coex_bt_weight[3] = AR9300_BT_WGHT; | ||||
| 
 | ||||
| 
 | ||||
| 	switch (stomp_type) { | ||||
| 	case ATH_BTCOEX_STOMP_ALL: | ||||
| 		ah->bt_coex_wlan_weight[0] = AR9300_STOMP_ALL_WLAN_WGHT0; | ||||
| 		ah->bt_coex_wlan_weight[1] = AR9300_STOMP_ALL_WLAN_WGHT1; | ||||
| 		break; | ||||
| 	case ATH_BTCOEX_STOMP_LOW: | ||||
| 		ah->bt_coex_wlan_weight[0] = AR9300_STOMP_LOW_WLAN_WGHT0; | ||||
| 		ah->bt_coex_wlan_weight[1] = AR9300_STOMP_LOW_WLAN_WGHT1; | ||||
| 		break; | ||||
| 	case ATH_BTCOEX_STOMP_NONE: | ||||
| 		ah->bt_coex_wlan_weight[0] = AR9300_STOMP_NONE_WLAN_WGHT0; | ||||
| 		ah->bt_coex_wlan_weight[1] = AR9300_STOMP_NONE_WLAN_WGHT1; | ||||
| 		break; | ||||
| 
 | ||||
| 	default: | ||||
| 		ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||||
| 				"Invalid Stomptype\n"); | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	ath9k_hw_btcoex_enable(ah); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Configures appropriate weight based on stomp type. | ||||
|  */ | ||||
| void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, | ||||
| 			      enum ath_stomp_type stomp_type) | ||||
| { | ||||
| 	if (AR_SREV_9300_20_OR_LATER(ah)) { | ||||
| 		ar9003_btcoex_bt_stomp(ah, stomp_type); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	switch (stomp_type) { | ||||
| 	case ATH_BTCOEX_STOMP_ALL: | ||||
| 		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||||
| 				AR_STOMP_ALL_WLAN_WGHT); | ||||
| 		break; | ||||
| 	case ATH_BTCOEX_STOMP_LOW: | ||||
| 		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||||
| 				AR_STOMP_LOW_WLAN_WGHT); | ||||
| 		break; | ||||
| 	case ATH_BTCOEX_STOMP_NONE: | ||||
| 		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||||
| 				AR_STOMP_NONE_WLAN_WGHT); | ||||
| 		break; | ||||
| 	default: | ||||
| 		ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | ||||
| 				"Invalid Stomptype\n"); | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	ath9k_hw_btcoex_enable(ah); | ||||
| } | ||||
| EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp); | ||||
|  |  | |||
|  | @ -19,9 +19,13 @@ | |||
| 
 | ||||
| #include "hw.h" | ||||
| 
 | ||||
| #define ATH_WLANACTIVE_GPIO	5 | ||||
| #define ATH_BTACTIVE_GPIO	6 | ||||
| #define ATH_BTPRIORITY_GPIO	7 | ||||
| #define ATH_WLANACTIVE_GPIO_9280     5 | ||||
| #define ATH_BTACTIVE_GPIO_9280       6 | ||||
| #define ATH_BTPRIORITY_GPIO_9285     7 | ||||
| 
 | ||||
| #define ATH_WLANACTIVE_GPIO_9300     5 | ||||
| #define ATH_BTACTIVE_GPIO_9300       4 | ||||
| #define ATH_BTPRIORITY_GPIO_9300     8 | ||||
| 
 | ||||
| #define ATH_BTCOEX_DEF_BT_PERIOD  45 | ||||
| #define ATH_BTCOEX_DEF_DUTY_CYCLE 55 | ||||
|  | @ -32,6 +36,14 @@ | |||
| #define ATH_BT_CNT_THRESHOLD	       3 | ||||
| #define ATH_BT_CNT_SCAN_THRESHOLD      15 | ||||
| 
 | ||||
| /* Defines the BT AR_BT_COEX_WGHT used */ | ||||
| enum ath_stomp_type { | ||||
| 	ATH_BTCOEX_NO_STOMP, | ||||
| 	ATH_BTCOEX_STOMP_ALL, | ||||
| 	ATH_BTCOEX_STOMP_LOW, | ||||
| 	ATH_BTCOEX_STOMP_NONE | ||||
| }; | ||||
| 
 | ||||
| enum ath_btcoex_scheme { | ||||
| 	ATH_BTCOEX_CFG_NONE, | ||||
| 	ATH_BTCOEX_CFG_2WIRE, | ||||
|  | @ -57,5 +69,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, | |||
| 				u32 wlan_weight); | ||||
| void ath9k_hw_btcoex_enable(struct ath_hw *ah); | ||||
| void ath9k_hw_btcoex_disable(struct ath_hw *ah); | ||||
| void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, | ||||
| 			      enum ath_stomp_type stomp_type); | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -158,37 +158,6 @@ int ath9k_cmn_count_streams(unsigned int chainmask, int max) | |||
| } | ||||
| EXPORT_SYMBOL(ath9k_cmn_count_streams); | ||||
| 
 | ||||
| /*
 | ||||
|  * Configures appropriate weight based on stomp type. | ||||
|  */ | ||||
| void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common, | ||||
| 				  enum ath_stomp_type stomp_type) | ||||
| { | ||||
| 	struct ath_hw *ah = common->ah; | ||||
| 
 | ||||
| 	switch (stomp_type) { | ||||
| 	case ATH_BTCOEX_STOMP_ALL: | ||||
| 		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||||
| 					   AR_STOMP_ALL_WLAN_WGHT); | ||||
| 		break; | ||||
| 	case ATH_BTCOEX_STOMP_LOW: | ||||
| 		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||||
| 					   AR_STOMP_LOW_WLAN_WGHT); | ||||
| 		break; | ||||
| 	case ATH_BTCOEX_STOMP_NONE: | ||||
| 		ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, | ||||
| 					   AR_STOMP_NONE_WLAN_WGHT); | ||||
| 		break; | ||||
| 	default: | ||||
| 		ath_dbg(common, ATH_DBG_BTCOEX, | ||||
| 			"Invalid Stomptype\n"); | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	ath9k_hw_btcoex_enable(ah); | ||||
| } | ||||
| EXPORT_SYMBOL(ath9k_cmn_btcoex_bt_stomp); | ||||
| 
 | ||||
| void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow, | ||||
| 			    u16 new_txpow, u16 *txpower) | ||||
| { | ||||
|  |  | |||
|  | @ -50,14 +50,6 @@ | |||
| #define ATH_EP_RND(x, mul) 						\ | ||||
| 	((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) | ||||
| 
 | ||||
| /* Defines the BT AR_BT_COEX_WGHT used */ | ||||
| enum ath_stomp_type { | ||||
| 	ATH_BTCOEX_NO_STOMP, | ||||
| 	ATH_BTCOEX_STOMP_ALL, | ||||
| 	ATH_BTCOEX_STOMP_LOW, | ||||
| 	ATH_BTCOEX_STOMP_NONE | ||||
| }; | ||||
| 
 | ||||
| int ath9k_cmn_padpos(__le16 frame_control); | ||||
| int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); | ||||
| void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan, | ||||
|  |  | |||
|  | @ -326,6 +326,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) | |||
| 		sc->debug.stats.istats.dtimsync++; | ||||
| 	if (status & ATH9K_INT_DTIM) | ||||
| 		sc->debug.stats.istats.dtim++; | ||||
| 	if (status & ATH9K_INT_TSFOOR) | ||||
| 		sc->debug.stats.istats.tsfoor++; | ||||
| } | ||||
| 
 | ||||
| static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, | ||||
|  | @ -379,9 +381,12 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, | |||
| 		"%8s: %10u\n", "DTIMSYNC", sc->debug.stats.istats.dtimsync); | ||||
| 	len += snprintf(buf + len, sizeof(buf) - len, | ||||
| 		"%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim); | ||||
| 	len += snprintf(buf + len, sizeof(buf) - len, | ||||
| 		"%8s: %10u\n", "TSFOOR", sc->debug.stats.istats.tsfoor); | ||||
| 	len += snprintf(buf + len, sizeof(buf) - len, | ||||
| 		"%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total); | ||||
| 
 | ||||
| 
 | ||||
| 	if (len > sizeof(buf)) | ||||
| 		len = sizeof(buf); | ||||
| 
 | ||||
|  |  | |||
|  | @ -54,6 +54,9 @@ struct ath_buf; | |||
|  * @dtimsync: DTIM sync lossage | ||||
|  * @dtim: RX Beacon with DTIM | ||||
|  * @bb_watchdog: Baseband watchdog | ||||
|  * @tsfoor: TSF out of range, indicates that the corrected TSF received | ||||
|  * from a beacon differs from the PCU's internal TSF by more than a | ||||
|  * (programmable) threshold | ||||
|  */ | ||||
| struct ath_interrupt_stats { | ||||
| 	u32 total; | ||||
|  | @ -78,6 +81,7 @@ struct ath_interrupt_stats { | |||
| 	u32 dtimsync; | ||||
| 	u32 dtim; | ||||
| 	u32 bb_watchdog; | ||||
| 	u32 tsfoor; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  |  | |||
|  | @ -319,10 +319,9 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah, | |||
| 	u16 numXpdGain, xpdMask; | ||||
| 	u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0}; | ||||
| 	u32 reg32, regOffset, regChainOffset, regval; | ||||
| 	int16_t modalIdx, diff = 0; | ||||
| 	int16_t diff = 0; | ||||
| 	struct ar9287_eeprom *pEepData = &ah->eeprom.map9287; | ||||
| 
 | ||||
| 	modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; | ||||
| 	xpdMask = pEepData->modalHeader.xpdGain; | ||||
| 
 | ||||
| 	if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= | ||||
|  |  | |||
|  | @ -231,6 +231,10 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | |||
| 				integer = swab32(pModal->antCtrlChain[i]); | ||||
| 				pModal->antCtrlChain[i] = integer; | ||||
| 			} | ||||
| 			for (i = 0; i < 3; i++) { | ||||
| 				word = swab16(pModal->xpaBiasLvlFreq[i]); | ||||
| 				pModal->xpaBiasLvlFreq[i] = word; | ||||
| 			} | ||||
| 
 | ||||
| 			for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | ||||
| 				word = swab16(pModal->spurChans[i].spurChan); | ||||
|  |  | |||
|  | @ -46,6 +46,8 @@ void ath_init_leds(struct ath_softc *sc) | |||
| 			sc->sc_ah->led_pin = ATH_LED_PIN_9287; | ||||
| 		else if (AR_SREV_9485(sc->sc_ah)) | ||||
| 			sc->sc_ah->led_pin = ATH_LED_PIN_9485; | ||||
| 		else if (AR_SREV_9300(sc->sc_ah)) | ||||
| 			sc->sc_ah->led_pin = ATH_LED_PIN_9300; | ||||
| 		else | ||||
| 			sc->sc_ah->led_pin = ATH_LED_PIN_DEF; | ||||
| 	} | ||||
|  | @ -138,10 +140,10 @@ static void ath_detect_bt_priority(struct ath_softc *sc) | |||
| 
 | ||||
| static void ath9k_gen_timer_start(struct ath_hw *ah, | ||||
| 				  struct ath_gen_timer *timer, | ||||
| 				  u32 timer_next, | ||||
| 				  u32 trig_timeout, | ||||
| 				  u32 timer_period) | ||||
| { | ||||
| 	ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); | ||||
| 	ath9k_hw_gen_timer_start(ah, timer, trig_timeout, timer_period); | ||||
| 
 | ||||
| 	if ((ah->imask & ATH9K_INT_GENTIMER) == 0) { | ||||
| 		ath9k_hw_disable_interrupts(ah); | ||||
|  | @ -174,17 +176,17 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
| 	struct ath_softc *sc = (struct ath_softc *) data; | ||||
| 	struct ath_hw *ah = sc->sc_ah; | ||||
| 	struct ath_btcoex *btcoex = &sc->btcoex; | ||||
| 	struct ath_common *common = ath9k_hw_common(ah); | ||||
| 	u32 timer_period; | ||||
| 	bool is_btscan; | ||||
| 
 | ||||
| 	ath9k_ps_wakeup(sc); | ||||
| 	ath_detect_bt_priority(sc); | ||||
| 
 | ||||
| 	is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | ||||
| 
 | ||||
| 	spin_lock_bh(&btcoex->btcoex_lock); | ||||
| 
 | ||||
| 	ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL : | ||||
| 	ath9k_hw_btcoex_bt_stomp(ah, is_btscan ? ATH_BTCOEX_STOMP_ALL : | ||||
| 			      btcoex->bt_stomp_type); | ||||
| 
 | ||||
| 	spin_unlock_bh(&btcoex->btcoex_lock); | ||||
|  | @ -195,11 +197,12 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
| 
 | ||||
| 		timer_period = is_btscan ? btcoex->btscan_no_stomp : | ||||
| 					   btcoex->btcoex_no_stomp; | ||||
| 		ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, 0, | ||||
| 		ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period, | ||||
| 				      timer_period * 10); | ||||
| 		btcoex->hw_timer_enabled = true; | ||||
| 	} | ||||
| 
 | ||||
| 	ath9k_ps_restore(sc); | ||||
| 	mod_timer(&btcoex->period_timer, jiffies + | ||||
| 				  msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD)); | ||||
| } | ||||
|  | @ -219,14 +222,16 @@ static void ath_btcoex_no_stomp_timer(void *arg) | |||
| 	ath_dbg(common, ATH_DBG_BTCOEX, | ||||
| 		"no stomp timer running\n"); | ||||
| 
 | ||||
| 	ath9k_ps_wakeup(sc); | ||||
| 	spin_lock_bh(&btcoex->btcoex_lock); | ||||
| 
 | ||||
| 	if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) | ||||
| 		ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE); | ||||
| 		ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); | ||||
| 	 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | ||||
| 		ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW); | ||||
| 		ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); | ||||
| 
 | ||||
| 	spin_unlock_bh(&btcoex->btcoex_lock); | ||||
| 	ath9k_ps_restore(sc); | ||||
| } | ||||
| 
 | ||||
| int ath_init_btcoex_timer(struct ath_softc *sc) | ||||
|  |  | |||
|  | @ -17,6 +17,9 @@ | |||
| #ifndef HTC_USB_H | ||||
| #define HTC_USB_H | ||||
| 
 | ||||
| #define MAJOR_VERSION_REQ 1 | ||||
| #define MINOR_VERSION_REQ 2 | ||||
| 
 | ||||
| #define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB)) | ||||
| 
 | ||||
| #define AR9271_FIRMWARE       0x501000 | ||||
|  |  | |||
|  | @ -66,8 +66,6 @@ enum htc_opmode { | |||
| 	HTC_M_WDS	= 2 | ||||
| }; | ||||
| 
 | ||||
| #define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr) | ||||
| 
 | ||||
| #define ATH9K_HTC_AMPDU  1 | ||||
| #define ATH9K_HTC_NORMAL 2 | ||||
| #define ATH9K_HTC_BEACON 3 | ||||
|  | @ -75,7 +73,6 @@ enum htc_opmode { | |||
| 
 | ||||
| #define ATH9K_HTC_TX_CTSONLY      0x1 | ||||
| #define ATH9K_HTC_TX_RTSCTS       0x2 | ||||
| #define ATH9K_HTC_TX_USE_MIN_RATE 0x100 | ||||
| 
 | ||||
| struct tx_frame_hdr { | ||||
| 	u8 data_type; | ||||
|  | @ -106,15 +103,14 @@ struct tx_beacon_header { | |||
| 	u16 rev; | ||||
| } __packed; | ||||
| 
 | ||||
| #define MAX_TX_AMPDU_SUBFRAMES_9271 17 | ||||
| #define MAX_TX_AMPDU_SUBFRAMES_7010 22 | ||||
| 
 | ||||
| struct ath9k_htc_cap_target { | ||||
| 	u32 flags; | ||||
| 	u32 flags_ext; | ||||
| 	u32 ampdu_limit; | ||||
| 	__be32 ampdu_limit; | ||||
| 	u8 ampdu_subframes; | ||||
| 	u8 enable_coex; | ||||
| 	u8 tx_chainmask; | ||||
| 	u8 tx_chainmask_legacy; | ||||
| 	u8 rtscts_ratecode; | ||||
| 	u8 protmode; | ||||
| 	u8 pad; | ||||
| } __packed; | ||||
| 
 | ||||
|  | @ -175,6 +171,13 @@ struct ath9k_htc_target_rate { | |||
| 	struct ath9k_htc_rate rates; | ||||
| }; | ||||
| 
 | ||||
| struct ath9k_htc_target_rate_mask { | ||||
| 	u8 vif_index; | ||||
| 	u8 band; | ||||
| 	__be32 mask; | ||||
| 	u16 pad; | ||||
| } __packed; | ||||
| 
 | ||||
| struct ath9k_htc_target_int_stats { | ||||
| 	__be32 rx; | ||||
| 	__be32 rxorn; | ||||
|  | @ -382,25 +385,6 @@ static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, | |||
| #define ATH_LED_PIN_9287            10 | ||||
| #define ATH_LED_PIN_9271            15 | ||||
| #define ATH_LED_PIN_7010            12 | ||||
| #define ATH_LED_ON_DURATION_IDLE    350	/* in msecs */ | ||||
| #define ATH_LED_OFF_DURATION_IDLE   250	/* in msecs */ | ||||
| 
 | ||||
| enum ath_led_type { | ||||
| 	ATH_LED_RADIO, | ||||
| 	ATH_LED_ASSOC, | ||||
| 	ATH_LED_TX, | ||||
| 	ATH_LED_RX | ||||
| }; | ||||
| 
 | ||||
| struct ath_led { | ||||
| 	struct ath9k_htc_priv *priv; | ||||
| 	struct led_classdev led_cdev; | ||||
| 	enum ath_led_type led_type; | ||||
| 	struct delayed_work brightness_work; | ||||
| 	char name[32]; | ||||
| 	bool registered; | ||||
| 	int brightness; | ||||
| }; | ||||
| 
 | ||||
| #define BSTUCK_THRESHOLD 10 | ||||
| 
 | ||||
|  | @ -434,14 +418,11 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv); | |||
| 
 | ||||
| #define OP_INVALID		   BIT(0) | ||||
| #define OP_SCANNING		   BIT(1) | ||||
| #define OP_LED_ASSOCIATED	   BIT(2) | ||||
| #define OP_LED_ON		   BIT(3) | ||||
| #define OP_ENABLE_BEACON	   BIT(4) | ||||
| #define OP_LED_DEINIT		   BIT(5) | ||||
| #define OP_BT_PRIORITY_DETECTED    BIT(6) | ||||
| #define OP_BT_SCAN                 BIT(7) | ||||
| #define OP_ANI_RUNNING             BIT(8) | ||||
| #define OP_TSF_RESET               BIT(9) | ||||
| #define OP_ENABLE_BEACON           BIT(2) | ||||
| #define OP_BT_PRIORITY_DETECTED    BIT(3) | ||||
| #define OP_BT_SCAN                 BIT(4) | ||||
| #define OP_ANI_RUNNING             BIT(5) | ||||
| #define OP_TSF_RESET               BIT(6) | ||||
| 
 | ||||
| struct ath9k_htc_priv { | ||||
| 	struct device *dev; | ||||
|  | @ -501,15 +482,13 @@ struct ath9k_htc_priv { | |||
| 	bool ps_enabled; | ||||
| 	bool ps_idle; | ||||
| 
 | ||||
| 	struct ath_led radio_led; | ||||
| 	struct ath_led assoc_led; | ||||
| 	struct ath_led tx_led; | ||||
| 	struct ath_led rx_led; | ||||
| 	struct delayed_work ath9k_led_blink_work; | ||||
| 	int led_on_duration; | ||||
| 	int led_off_duration; | ||||
| 	int led_on_cnt; | ||||
| 	int led_off_cnt; | ||||
| #ifdef CONFIG_MAC80211_LEDS | ||||
| 	enum led_brightness brightness; | ||||
| 	bool led_registered; | ||||
| 	char led_name[32]; | ||||
| 	struct led_classdev led_cdev; | ||||
| 	struct work_struct led_work; | ||||
| #endif | ||||
| 
 | ||||
| 	int beaconq; | ||||
| 	int cabq; | ||||
|  | @ -551,7 +530,8 @@ void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id, | |||
| void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, | ||||
| 			enum htc_endpoint_id ep_id, bool txok); | ||||
| 
 | ||||
| int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv); | ||||
| int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv, | ||||
| 				u8 enable_coex); | ||||
| void ath9k_htc_station_work(struct work_struct *work); | ||||
| void ath9k_htc_aggr_work(struct work_struct *work); | ||||
| void ath9k_htc_ani_work(struct work_struct *work); | ||||
|  | @ -593,9 +573,24 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); | |||
| void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); | ||||
| void ath9k_htc_radio_enable(struct ieee80211_hw *hw); | ||||
| void ath9k_htc_radio_disable(struct ieee80211_hw *hw); | ||||
| void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv); | ||||
| 
 | ||||
| #ifdef CONFIG_MAC80211_LEDS | ||||
| void ath9k_init_leds(struct ath9k_htc_priv *priv); | ||||
| void ath9k_deinit_leds(struct ath9k_htc_priv *priv); | ||||
| void ath9k_led_work(struct work_struct *work); | ||||
| #else | ||||
| static inline void ath9k_init_leds(struct ath9k_htc_priv *priv) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| static inline void ath9k_deinit_leds(struct ath9k_htc_priv *priv) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| static inline void ath9k_led_work(struct work_struct *work) | ||||
| { | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, | ||||
| 			   u16 devid, char *product, u32 drv_info); | ||||
|  |  | |||
|  | @ -74,7 +74,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, | |||
| 	__be32 htc_imask = 0; | ||||
| 	u64 tsf; | ||||
| 	int num_beacons, offset, dtim_dec_count, cfp_dec_count; | ||||
| 	int ret; | ||||
| 	int ret __attribute__ ((unused)); | ||||
| 	u8 cmd_rsp; | ||||
| 
 | ||||
| 	memset(&bs, 0, sizeof(bs)); | ||||
|  | @ -190,7 +190,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv, | |||
| 	enum ath9k_int imask = 0; | ||||
| 	u32 nexttbtt, intval, tsftu; | ||||
| 	__be32 htc_imask = 0; | ||||
| 	int ret; | ||||
| 	int ret __attribute__ ((unused)); | ||||
| 	u8 cmd_rsp; | ||||
| 	u64 tsf; | ||||
| 
 | ||||
|  | @ -246,7 +246,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, | |||
| 	enum ath9k_int imask = 0; | ||||
| 	u32 nexttbtt, intval, tsftu; | ||||
| 	__be32 htc_imask = 0; | ||||
| 	int ret; | ||||
| 	int ret __attribute__ ((unused)); | ||||
| 	u8 cmd_rsp; | ||||
| 	u64 tsf; | ||||
| 
 | ||||
|  |  | |||
|  | @ -33,9 +33,15 @@ static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf, | |||
| 
 | ||||
| 	memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||||
| 
 | ||||
| 	ath9k_htc_ps_wakeup(priv); | ||||
| 
 | ||||
| 	WMI_CMD(WMI_INT_STATS_CMDID); | ||||
| 	if (ret) | ||||
| 	if (ret) { | ||||
| 		ath9k_htc_ps_restore(priv); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	ath9k_htc_ps_restore(priv); | ||||
| 
 | ||||
| 	len += snprintf(buf + len, sizeof(buf) - len, | ||||
| 			"%20s : %10u\n", "RX", | ||||
|  | @ -85,9 +91,15 @@ static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf, | |||
| 
 | ||||
| 	memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||||
| 
 | ||||
| 	ath9k_htc_ps_wakeup(priv); | ||||
| 
 | ||||
| 	WMI_CMD(WMI_TX_STATS_CMDID); | ||||
| 	if (ret) | ||||
| 	if (ret) { | ||||
| 		ath9k_htc_ps_restore(priv); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	ath9k_htc_ps_restore(priv); | ||||
| 
 | ||||
| 	len += snprintf(buf + len, sizeof(buf) - len, | ||||
| 			"%20s : %10u\n", "Xretries", | ||||
|  | @ -149,9 +161,15 @@ static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf, | |||
| 
 | ||||
| 	memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||||
| 
 | ||||
| 	ath9k_htc_ps_wakeup(priv); | ||||
| 
 | ||||
| 	WMI_CMD(WMI_RX_STATS_CMDID); | ||||
| 	if (ret) | ||||
| 	if (ret) { | ||||
| 		ath9k_htc_ps_restore(priv); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	ath9k_htc_ps_restore(priv); | ||||
| 
 | ||||
| 	len += snprintf(buf + len, sizeof(buf) - len, | ||||
| 			"%20s : %10u\n", "NoBuf", | ||||
|  | @ -474,6 +492,439 @@ static const struct file_operations fops_debug = { | |||
| 	.llseek = default_llseek, | ||||
| }; | ||||
| 
 | ||||
| static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf, | ||||
| 				     size_t count, loff_t *ppos) | ||||
| { | ||||
| 	struct ath9k_htc_priv *priv = file->private_data; | ||||
| 	struct ath_common *common = ath9k_hw_common(priv->ah); | ||||
| 	struct base_eep_header *pBase = NULL; | ||||
| 	unsigned int len = 0, size = 1500; | ||||
| 	ssize_t retval = 0; | ||||
| 	char *buf; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * This can be done since all the 3 EEPROM families have the | ||||
| 	 * same base header upto a certain point, and we are interested in | ||||
| 	 * the data only upto that point. | ||||
| 	 */ | ||||
| 
 | ||||
| 	if (AR_SREV_9271(priv->ah)) | ||||
| 		pBase = (struct base_eep_header *) | ||||
| 			&priv->ah->eeprom.map4k.baseEepHeader; | ||||
| 	else if (priv->ah->hw_version.usbdev == AR9280_USB) | ||||
| 		pBase = (struct base_eep_header *) | ||||
| 			&priv->ah->eeprom.def.baseEepHeader; | ||||
| 	else if (priv->ah->hw_version.usbdev == AR9287_USB) | ||||
| 		pBase = (struct base_eep_header *) | ||||
| 			&priv->ah->eeprom.map9287.baseEepHeader; | ||||
| 
 | ||||
| 	if (pBase == NULL) { | ||||
| 		ath_err(common, "Unknown EEPROM type\n"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	buf = kzalloc(size, GFP_KERNEL); | ||||
| 	if (buf == NULL) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", "Major Version", | ||||
| 			pBase->version >> 12); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", "Minor Version", | ||||
| 			pBase->version & 0xFFF); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", "Checksum", | ||||
| 			pBase->checksum); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", "Length", | ||||
| 			pBase->length); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", "RegDomain1", | ||||
| 			pBase->regDmn[0]); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", "RegDomain2", | ||||
| 			pBase->regDmn[1]); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", | ||||
| 			"TX Mask", pBase->txMask); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", | ||||
| 			"RX Mask", pBase->rxMask); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", | ||||
| 			"Allow 5GHz", | ||||
| 			!!(pBase->opCapFlags & AR5416_OPFLAGS_11A)); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", | ||||
| 			"Allow 2GHz", | ||||
| 			!!(pBase->opCapFlags & AR5416_OPFLAGS_11G)); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", | ||||
| 			"Disable 2GHz HT20", | ||||
| 			!!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20)); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", | ||||
| 			"Disable 2GHz HT40", | ||||
| 			!!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40)); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", | ||||
| 			"Disable 5Ghz HT20", | ||||
| 			!!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20)); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", | ||||
| 			"Disable 5Ghz HT40", | ||||
| 			!!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40)); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", | ||||
| 			"Big Endian", | ||||
| 			!!(pBase->eepMisc & 0x01)); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", | ||||
| 			"Cal Bin Major Ver", | ||||
| 			(pBase->binBuildNumber >> 24) & 0xFF); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", | ||||
| 			"Cal Bin Minor Ver", | ||||
| 			(pBase->binBuildNumber >> 16) & 0xFF); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %10d\n", | ||||
| 			"Cal Bin Build", | ||||
| 			(pBase->binBuildNumber >> 8) & 0xFF); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * UB91 specific data. | ||||
| 	 */ | ||||
| 	if (AR_SREV_9271(priv->ah)) { | ||||
| 		struct base_eep_header_4k *pBase4k = | ||||
| 			&priv->ah->eeprom.map4k.baseEepHeader; | ||||
| 
 | ||||
| 		len += snprintf(buf + len, size - len, | ||||
| 				"%20s : %10d\n", | ||||
| 				"TX Gain type", | ||||
| 				pBase4k->txGainType); | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * UB95 specific data. | ||||
| 	 */ | ||||
| 	if (priv->ah->hw_version.usbdev == AR9287_USB) { | ||||
| 		struct base_eep_ar9287_header *pBase9287 = | ||||
| 			&priv->ah->eeprom.map9287.baseEepHeader; | ||||
| 
 | ||||
| 		len += snprintf(buf + len, size - len, | ||||
| 				"%20s : %10ddB\n", | ||||
| 				"Power Table Offset", | ||||
| 				pBase9287->pwrTableOffset); | ||||
| 
 | ||||
| 		len += snprintf(buf + len, size - len, | ||||
| 				"%20s : %10d\n", | ||||
| 				"OpenLoop Power Ctrl", | ||||
| 				pBase9287->openLoopPwrCntl); | ||||
| 	} | ||||
| 
 | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%20s : %02X:%02X:%02X:%02X:%02X:%02X\n", | ||||
| 			"MacAddress", | ||||
| 			pBase->macAddr[0], pBase->macAddr[1], pBase->macAddr[2], | ||||
| 			pBase->macAddr[3], pBase->macAddr[4], pBase->macAddr[5]); | ||||
| 	if (len > size) | ||||
| 		len = size; | ||||
| 
 | ||||
| 	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||||
| 	kfree(buf); | ||||
| 
 | ||||
| 	return retval; | ||||
| } | ||||
| 
 | ||||
| static const struct file_operations fops_base_eeprom = { | ||||
| 	.read = read_file_base_eeprom, | ||||
| 	.open = ath9k_debugfs_open, | ||||
| 	.owner = THIS_MODULE, | ||||
| 	.llseek = default_llseek, | ||||
| }; | ||||
| 
 | ||||
| static ssize_t read_4k_modal_eeprom(struct file *file, | ||||
| 				    char __user *user_buf, | ||||
| 				    size_t count, loff_t *ppos) | ||||
| { | ||||
| #define PR_EEP(_s, _val)						\ | ||||
| 	do {								\ | ||||
| 		len += snprintf(buf + len, size - len, "%20s : %10d\n",	\ | ||||
| 				_s, (_val));				\ | ||||
| 	} while (0) | ||||
| 
 | ||||
| 	struct ath9k_htc_priv *priv = file->private_data; | ||||
| 	struct modal_eep_4k_header *pModal = &priv->ah->eeprom.map4k.modalHeader; | ||||
| 	unsigned int len = 0, size = 2048; | ||||
| 	ssize_t retval = 0; | ||||
| 	char *buf; | ||||
| 
 | ||||
| 	buf = kzalloc(size, GFP_KERNEL); | ||||
| 	if (buf == NULL) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]); | ||||
| 	PR_EEP("Ant. Common Control", pModal->antCtrlCommon); | ||||
| 	PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]); | ||||
| 	PR_EEP("Switch Settle", pModal->switchSettling); | ||||
| 	PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]); | ||||
| 	PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]); | ||||
| 	PR_EEP("ADC Desired size", pModal->adcDesiredSize); | ||||
| 	PR_EEP("PGA Desired size", pModal->pgaDesiredSize); | ||||
| 	PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]); | ||||
| 	PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff); | ||||
| 	PR_EEP("txEndToRxOn", pModal->txEndToRxOn); | ||||
| 	PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn); | ||||
| 	PR_EEP("CCA Threshold)", pModal->thresh62); | ||||
| 	PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]); | ||||
| 	PR_EEP("xpdGain", pModal->xpdGain); | ||||
| 	PR_EEP("External PD", pModal->xpd); | ||||
| 	PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]); | ||||
| 	PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]); | ||||
| 	PR_EEP("pdGainOverlap", pModal->pdGainOverlap); | ||||
| 	PR_EEP("O/D Bias Version", pModal->version); | ||||
| 	PR_EEP("CCK OutputBias", pModal->ob_0); | ||||
| 	PR_EEP("BPSK OutputBias", pModal->ob_1); | ||||
| 	PR_EEP("QPSK OutputBias", pModal->ob_2); | ||||
| 	PR_EEP("16QAM OutputBias", pModal->ob_3); | ||||
| 	PR_EEP("64QAM OutputBias", pModal->ob_4); | ||||
| 	PR_EEP("CCK Driver1_Bias", pModal->db1_0); | ||||
| 	PR_EEP("BPSK Driver1_Bias", pModal->db1_1); | ||||
| 	PR_EEP("QPSK Driver1_Bias", pModal->db1_2); | ||||
| 	PR_EEP("16QAM Driver1_Bias", pModal->db1_3); | ||||
| 	PR_EEP("64QAM Driver1_Bias", pModal->db1_4); | ||||
| 	PR_EEP("CCK Driver2_Bias", pModal->db2_0); | ||||
| 	PR_EEP("BPSK Driver2_Bias", pModal->db2_1); | ||||
| 	PR_EEP("QPSK Driver2_Bias", pModal->db2_2); | ||||
| 	PR_EEP("16QAM Driver2_Bias", pModal->db2_3); | ||||
| 	PR_EEP("64QAM Driver2_Bias", pModal->db2_4); | ||||
| 	PR_EEP("xPA Bias Level", pModal->xpaBiasLvl); | ||||
| 	PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart); | ||||
| 	PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn); | ||||
| 	PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc); | ||||
| 	PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]); | ||||
| 	PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]); | ||||
| 	PR_EEP("HT40 Switch Settle", pModal->swSettleHt40); | ||||
| 	PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]); | ||||
| 	PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]); | ||||
| 	PR_EEP("Ant. Diversity ctl1", pModal->antdiv_ctl1); | ||||
| 	PR_EEP("Ant. Diversity ctl2", pModal->antdiv_ctl2); | ||||
| 	PR_EEP("TX Diversity", pModal->tx_diversity); | ||||
| 
 | ||||
| 	if (len > size) | ||||
| 		len = size; | ||||
| 
 | ||||
| 	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||||
| 	kfree(buf); | ||||
| 
 | ||||
| 	return retval; | ||||
| 
 | ||||
| #undef PR_EEP | ||||
| } | ||||
| 
 | ||||
| static ssize_t read_def_modal_eeprom(struct file *file, | ||||
| 				     char __user *user_buf, | ||||
| 				     size_t count, loff_t *ppos) | ||||
| { | ||||
| #define PR_EEP(_s, _val)						\ | ||||
| 	do {								\ | ||||
| 		if (pBase->opCapFlags & AR5416_OPFLAGS_11G) {		\ | ||||
| 			pModal = &priv->ah->eeprom.def.modalHeader[1];	\ | ||||
| 			len += snprintf(buf + len, size - len, "%20s : %8d%7s", \ | ||||
| 					_s, (_val), "|");		\ | ||||
| 		}							\ | ||||
| 		if (pBase->opCapFlags & AR5416_OPFLAGS_11A) {		\ | ||||
| 			pModal = &priv->ah->eeprom.def.modalHeader[0];	\ | ||||
| 			len += snprintf(buf + len, size - len, "%9d\n", \ | ||||
| 					(_val));			\ | ||||
| 		}							\ | ||||
| 	} while (0) | ||||
| 
 | ||||
| 	struct ath9k_htc_priv *priv = file->private_data; | ||||
| 	struct base_eep_header *pBase = &priv->ah->eeprom.def.baseEepHeader; | ||||
| 	struct modal_eep_header *pModal = NULL; | ||||
| 	unsigned int len = 0, size = 3500; | ||||
| 	ssize_t retval = 0; | ||||
| 	char *buf; | ||||
| 
 | ||||
| 	buf = kzalloc(size, GFP_KERNEL); | ||||
| 	if (buf == NULL) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%31s %15s\n", "2G", "5G"); | ||||
| 	len += snprintf(buf + len, size - len, | ||||
| 			"%32s %16s\n", "====", "====\n"); | ||||
| 
 | ||||
| 	PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]); | ||||
| 	PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]); | ||||
| 	PR_EEP("Chain2 Ant. Control", pModal->antCtrlChain[2]); | ||||
| 	PR_EEP("Ant. Common Control", pModal->antCtrlCommon); | ||||
| 	PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]); | ||||
| 	PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]); | ||||
| 	PR_EEP("Chain2 Ant. Gain", pModal->antennaGainCh[2]); | ||||
| 	PR_EEP("Switch Settle", pModal->switchSettling); | ||||
| 	PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]); | ||||
| 	PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]); | ||||
| 	PR_EEP("Chain2 TxRxAtten", pModal->txRxAttenCh[2]); | ||||
| 	PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]); | ||||
| 	PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]); | ||||
| 	PR_EEP("Chain2 RxTxMargin", pModal->rxTxMarginCh[2]); | ||||
| 	PR_EEP("ADC Desired size", pModal->adcDesiredSize); | ||||
| 	PR_EEP("PGA Desired size", pModal->pgaDesiredSize); | ||||
| 	PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]); | ||||
| 	PR_EEP("Chain1 xlna Gain", pModal->xlnaGainCh[1]); | ||||
| 	PR_EEP("Chain2 xlna Gain", pModal->xlnaGainCh[2]); | ||||
| 	PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff); | ||||
| 	PR_EEP("txEndToRxOn", pModal->txEndToRxOn); | ||||
| 	PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn); | ||||
| 	PR_EEP("CCA Threshold)", pModal->thresh62); | ||||
| 	PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]); | ||||
| 	PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]); | ||||
| 	PR_EEP("Chain2 NF Threshold", pModal->noiseFloorThreshCh[2]); | ||||
| 	PR_EEP("xpdGain", pModal->xpdGain); | ||||
| 	PR_EEP("External PD", pModal->xpd); | ||||
| 	PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]); | ||||
| 	PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]); | ||||
| 	PR_EEP("Chain2 I Coefficient", pModal->iqCalICh[2]); | ||||
| 	PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]); | ||||
| 	PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]); | ||||
| 	PR_EEP("Chain2 Q Coefficient", pModal->iqCalQCh[2]); | ||||
| 	PR_EEP("pdGainOverlap", pModal->pdGainOverlap); | ||||
| 	PR_EEP("Chain0 OutputBias", pModal->ob); | ||||
| 	PR_EEP("Chain0 DriverBias", pModal->db); | ||||
| 	PR_EEP("xPA Bias Level", pModal->xpaBiasLvl); | ||||
| 	PR_EEP("2chain pwr decrease", pModal->pwrDecreaseFor2Chain); | ||||
| 	PR_EEP("3chain pwr decrease", pModal->pwrDecreaseFor3Chain); | ||||
| 	PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart); | ||||
| 	PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn); | ||||
| 	PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc); | ||||
| 	PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]); | ||||
| 	PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]); | ||||
| 	PR_EEP("Chain2 bswAtten", pModal->bswAtten[2]); | ||||
| 	PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]); | ||||
| 	PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]); | ||||
| 	PR_EEP("Chain2 bswMargin", pModal->bswMargin[2]); | ||||
| 	PR_EEP("HT40 Switch Settle", pModal->swSettleHt40); | ||||
| 	PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]); | ||||
| 	PR_EEP("Chain1 xatten2Db", pModal->xatten2Db[1]); | ||||
| 	PR_EEP("Chain2 xatten2Db", pModal->xatten2Db[2]); | ||||
| 	PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]); | ||||
| 	PR_EEP("Chain1 xatten2Margin", pModal->xatten2Margin[1]); | ||||
| 	PR_EEP("Chain2 xatten2Margin", pModal->xatten2Margin[2]); | ||||
| 	PR_EEP("Chain1 OutputBias", pModal->ob_ch1); | ||||
| 	PR_EEP("Chain1 DriverBias", pModal->db_ch1); | ||||
| 	PR_EEP("LNA Control", pModal->lna_ctl); | ||||
| 	PR_EEP("XPA Bias Freq0", pModal->xpaBiasLvlFreq[0]); | ||||
| 	PR_EEP("XPA Bias Freq1", pModal->xpaBiasLvlFreq[1]); | ||||
| 	PR_EEP("XPA Bias Freq2", pModal->xpaBiasLvlFreq[2]); | ||||
| 
 | ||||
| 	if (len > size) | ||||
| 		len = size; | ||||
| 
 | ||||
| 	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||||
| 	kfree(buf); | ||||
| 
 | ||||
| 	return retval; | ||||
| 
 | ||||
| #undef PR_EEP | ||||
| } | ||||
| 
 | ||||
| static ssize_t read_9287_modal_eeprom(struct file *file, | ||||
| 				      char __user *user_buf, | ||||
| 				      size_t count, loff_t *ppos) | ||||
| { | ||||
| #define PR_EEP(_s, _val)						\ | ||||
| 	do {								\ | ||||
| 		len += snprintf(buf + len, size - len, "%20s : %10d\n",	\ | ||||
| 				_s, (_val));				\ | ||||
| 	} while (0) | ||||
| 
 | ||||
| 	struct ath9k_htc_priv *priv = file->private_data; | ||||
| 	struct modal_eep_ar9287_header *pModal = &priv->ah->eeprom.map9287.modalHeader; | ||||
| 	unsigned int len = 0, size = 3000; | ||||
| 	ssize_t retval = 0; | ||||
| 	char *buf; | ||||
| 
 | ||||
| 	buf = kzalloc(size, GFP_KERNEL); | ||||
| 	if (buf == NULL) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]); | ||||
| 	PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]); | ||||
| 	PR_EEP("Ant. Common Control", pModal->antCtrlCommon); | ||||
| 	PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]); | ||||
| 	PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]); | ||||
| 	PR_EEP("Switch Settle", pModal->switchSettling); | ||||
| 	PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]); | ||||
| 	PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]); | ||||
| 	PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]); | ||||
| 	PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]); | ||||
| 	PR_EEP("ADC Desired size", pModal->adcDesiredSize); | ||||
| 	PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff); | ||||
| 	PR_EEP("txEndToRxOn", pModal->txEndToRxOn); | ||||
| 	PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn); | ||||
| 	PR_EEP("CCA Threshold)", pModal->thresh62); | ||||
| 	PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]); | ||||
| 	PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]); | ||||
| 	PR_EEP("xpdGain", pModal->xpdGain); | ||||
| 	PR_EEP("External PD", pModal->xpd); | ||||
| 	PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]); | ||||
| 	PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]); | ||||
| 	PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]); | ||||
| 	PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]); | ||||
| 	PR_EEP("pdGainOverlap", pModal->pdGainOverlap); | ||||
| 	PR_EEP("xPA Bias Level", pModal->xpaBiasLvl); | ||||
| 	PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart); | ||||
| 	PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn); | ||||
| 	PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc); | ||||
| 	PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]); | ||||
| 	PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]); | ||||
| 	PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]); | ||||
| 	PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]); | ||||
| 	PR_EEP("HT40 Switch Settle", pModal->swSettleHt40); | ||||
| 	PR_EEP("AR92x7 Version", pModal->version); | ||||
| 	PR_EEP("DriverBias1", pModal->db1); | ||||
| 	PR_EEP("DriverBias2", pModal->db1); | ||||
| 	PR_EEP("CCK OutputBias", pModal->ob_cck); | ||||
| 	PR_EEP("PSK OutputBias", pModal->ob_psk); | ||||
| 	PR_EEP("QAM OutputBias", pModal->ob_qam); | ||||
| 	PR_EEP("PAL_OFF OutputBias", pModal->ob_pal_off); | ||||
| 
 | ||||
| 	if (len > size) | ||||
| 		len = size; | ||||
| 
 | ||||
| 	retval = simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||||
| 	kfree(buf); | ||||
| 
 | ||||
| 	return retval; | ||||
| 
 | ||||
| #undef PR_EEP | ||||
| } | ||||
| 
 | ||||
| static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf, | ||||
| 				      size_t count, loff_t *ppos) | ||||
| { | ||||
| 	struct ath9k_htc_priv *priv = file->private_data; | ||||
| 
 | ||||
| 	if (AR_SREV_9271(priv->ah)) | ||||
| 		return read_4k_modal_eeprom(file, user_buf, count, ppos); | ||||
| 	else if (priv->ah->hw_version.usbdev == AR9280_USB) | ||||
| 		return read_def_modal_eeprom(file, user_buf, count, ppos); | ||||
| 	else if (priv->ah->hw_version.usbdev == AR9287_USB) | ||||
| 		return read_9287_modal_eeprom(file, user_buf, count, ppos); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static const struct file_operations fops_modal_eeprom = { | ||||
| 	.read = read_file_modal_eeprom, | ||||
| 	.open = ath9k_debugfs_open, | ||||
| 	.owner = THIS_MODULE, | ||||
| 	.llseek = default_llseek, | ||||
| }; | ||||
| 
 | ||||
| int ath9k_htc_init_debug(struct ath_hw *ah) | ||||
| { | ||||
| 	struct ath_common *common = ath9k_hw_common(ah); | ||||
|  | @ -485,21 +936,25 @@ int ath9k_htc_init_debug(struct ath_hw *ah) | |||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy, | ||||
| 				priv, &fops_tgt_int_stats); | ||||
| 			    priv, &fops_tgt_int_stats); | ||||
| 	debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy, | ||||
| 				priv, &fops_tgt_tx_stats); | ||||
| 			    priv, &fops_tgt_tx_stats); | ||||
| 	debugfs_create_file("tgt_rx_stats", S_IRUSR, priv->debug.debugfs_phy, | ||||
| 				priv, &fops_tgt_rx_stats); | ||||
| 			    priv, &fops_tgt_rx_stats); | ||||
| 	debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy, | ||||
| 				priv, &fops_xmit); | ||||
| 			    priv, &fops_xmit); | ||||
| 	debugfs_create_file("recv", S_IRUSR, priv->debug.debugfs_phy, | ||||
| 				priv, &fops_recv); | ||||
| 			    priv, &fops_recv); | ||||
| 	debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy, | ||||
| 				priv, &fops_slot); | ||||
| 			    priv, &fops_slot); | ||||
| 	debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy, | ||||
| 				priv, &fops_queue); | ||||
| 			    priv, &fops_queue); | ||||
| 	debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy, | ||||
| 				priv, &fops_debug); | ||||
| 			    priv, &fops_debug); | ||||
| 	debugfs_create_file("base_eeprom", S_IRUSR, priv->debug.debugfs_phy, | ||||
| 			    priv, &fops_base_eeprom); | ||||
| 	debugfs_create_file("modal_eeprom", S_IRUSR, priv->debug.debugfs_phy, | ||||
| 			    priv, &fops_modal_eeprom); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -65,17 +65,19 @@ static void ath_btcoex_period_work(struct work_struct *work) | |||
| 	u32 timer_period; | ||||
| 	bool is_btscan; | ||||
| 	int ret; | ||||
| 	u8 cmd_rsp, aggr; | ||||
| 
 | ||||
| 	ath_detect_bt_priority(priv); | ||||
| 
 | ||||
| 	is_btscan = !!(priv->op_flags & OP_BT_SCAN); | ||||
| 
 | ||||
| 	aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED; | ||||
| 	ret = ath9k_htc_update_cap_target(priv, | ||||
| 				  !!(priv->op_flags & OP_BT_PRIORITY_DETECTED)); | ||||
| 	if (ret) { | ||||
| 		ath_err(common, "Unable to set BTCOEX parameters\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr); | ||||
| 
 | ||||
| 	ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL : | ||||
| 	ath9k_hw_btcoex_bt_stomp(priv->ah, is_btscan ? ATH_BTCOEX_STOMP_ALL : | ||||
| 			btcoex->bt_stomp_type); | ||||
| 
 | ||||
| 	timer_period = is_btscan ? btcoex->btscan_no_stomp : | ||||
|  | @ -103,9 +105,9 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work) | |||
| 		"time slice work for bt and wlan\n"); | ||||
| 
 | ||||
| 	if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) | ||||
| 		ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE); | ||||
| 		ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); | ||||
| 	else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | ||||
| 		ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW); | ||||
| 		ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); | ||||
| } | ||||
| 
 | ||||
| void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv) | ||||
|  | @ -152,140 +154,41 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv) | |||
| /* LED */ | ||||
| /*******/ | ||||
| 
 | ||||
| static void ath9k_led_blink_work(struct work_struct *work) | ||||
| #ifdef CONFIG_MAC80211_LEDS | ||||
| void ath9k_led_work(struct work_struct *work) | ||||
| { | ||||
| 	struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, | ||||
| 						   ath9k_led_blink_work.work); | ||||
| 	struct ath9k_htc_priv *priv = container_of(work, | ||||
| 						   struct ath9k_htc_priv, | ||||
| 						   led_work); | ||||
| 
 | ||||
| 	if (!(priv->op_flags & OP_LED_ASSOCIATED)) | ||||
| 		return; | ||||
| 
 | ||||
| 	if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) || | ||||
| 	    (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) | ||||
| 		ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); | ||||
| 	else | ||||
| 		ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, | ||||
| 				  (priv->op_flags & OP_LED_ON) ? 1 : 0); | ||||
| 
 | ||||
| 	ieee80211_queue_delayed_work(priv->hw, | ||||
| 				     &priv->ath9k_led_blink_work, | ||||
| 				     (priv->op_flags & OP_LED_ON) ? | ||||
| 				     msecs_to_jiffies(priv->led_off_duration) : | ||||
| 				     msecs_to_jiffies(priv->led_on_duration)); | ||||
| 
 | ||||
| 	priv->led_on_duration = priv->led_on_cnt ? | ||||
| 		max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) : | ||||
| 		ATH_LED_ON_DURATION_IDLE; | ||||
| 	priv->led_off_duration = priv->led_off_cnt ? | ||||
| 		max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) : | ||||
| 		ATH_LED_OFF_DURATION_IDLE; | ||||
| 	priv->led_on_cnt = priv->led_off_cnt = 0; | ||||
| 
 | ||||
| 	if (priv->op_flags & OP_LED_ON) | ||||
| 		priv->op_flags &= ~OP_LED_ON; | ||||
| 	else | ||||
| 		priv->op_flags |= OP_LED_ON; | ||||
| } | ||||
| 
 | ||||
| static void ath9k_led_brightness_work(struct work_struct *work) | ||||
| { | ||||
| 	struct ath_led *led = container_of(work, struct ath_led, | ||||
| 					   brightness_work.work); | ||||
| 	struct ath9k_htc_priv *priv = led->priv; | ||||
| 
 | ||||
| 	switch (led->brightness) { | ||||
| 	case LED_OFF: | ||||
| 		if (led->led_type == ATH_LED_ASSOC || | ||||
| 		    led->led_type == ATH_LED_RADIO) { | ||||
| 			ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, | ||||
| 					  (led->led_type == ATH_LED_RADIO)); | ||||
| 			priv->op_flags &= ~OP_LED_ASSOCIATED; | ||||
| 			if (led->led_type == ATH_LED_RADIO) | ||||
| 				priv->op_flags &= ~OP_LED_ON; | ||||
| 		} else { | ||||
| 			priv->led_off_cnt++; | ||||
| 		} | ||||
| 		break; | ||||
| 	case LED_FULL: | ||||
| 		if (led->led_type == ATH_LED_ASSOC) { | ||||
| 			priv->op_flags |= OP_LED_ASSOCIATED; | ||||
| 			ieee80211_queue_delayed_work(priv->hw, | ||||
| 					     &priv->ath9k_led_blink_work, 0); | ||||
| 		} else if (led->led_type == ATH_LED_RADIO) { | ||||
| 			ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); | ||||
| 			priv->op_flags |= OP_LED_ON; | ||||
| 		} else { | ||||
| 			priv->led_on_cnt++; | ||||
| 		} | ||||
| 		break; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, | ||||
| 			  (priv->brightness == LED_OFF)); | ||||
| } | ||||
| 
 | ||||
| static void ath9k_led_brightness(struct led_classdev *led_cdev, | ||||
| 				 enum led_brightness brightness) | ||||
| { | ||||
| 	struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); | ||||
| 	struct ath9k_htc_priv *priv = led->priv; | ||||
| 	struct ath9k_htc_priv *priv = container_of(led_cdev, | ||||
| 						   struct ath9k_htc_priv, | ||||
| 						   led_cdev); | ||||
| 
 | ||||
| 	led->brightness = brightness; | ||||
| 	if (!(priv->op_flags & OP_LED_DEINIT)) | ||||
| 		ieee80211_queue_delayed_work(priv->hw, | ||||
| 					     &led->brightness_work, 0); | ||||
| } | ||||
| 
 | ||||
| void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv) | ||||
| { | ||||
| 	cancel_delayed_work_sync(&priv->radio_led.brightness_work); | ||||
| 	cancel_delayed_work_sync(&priv->assoc_led.brightness_work); | ||||
| 	cancel_delayed_work_sync(&priv->tx_led.brightness_work); | ||||
| 	cancel_delayed_work_sync(&priv->rx_led.brightness_work); | ||||
| } | ||||
| 
 | ||||
| static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led, | ||||
| 			      char *trigger) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	led->priv = priv; | ||||
| 	led->led_cdev.name = led->name; | ||||
| 	led->led_cdev.default_trigger = trigger; | ||||
| 	led->led_cdev.brightness_set = ath9k_led_brightness; | ||||
| 
 | ||||
| 	ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev); | ||||
| 	if (ret) | ||||
| 		ath_err(ath9k_hw_common(priv->ah), | ||||
| 			"Failed to register led:%s", led->name); | ||||
| 	else | ||||
| 		led->registered = 1; | ||||
| 
 | ||||
| 	INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void ath9k_unregister_led(struct ath_led *led) | ||||
| { | ||||
| 	if (led->registered) { | ||||
| 		led_classdev_unregister(&led->led_cdev); | ||||
| 		led->registered = 0; | ||||
| 	} | ||||
| 	/* Not locked, but it's just a tiny green light..*/ | ||||
| 	priv->brightness = brightness; | ||||
| 	ieee80211_queue_work(priv->hw, &priv->led_work); | ||||
| } | ||||
| 
 | ||||
| void ath9k_deinit_leds(struct ath9k_htc_priv *priv) | ||||
| { | ||||
| 	priv->op_flags |= OP_LED_DEINIT; | ||||
| 	ath9k_unregister_led(&priv->assoc_led); | ||||
| 	priv->op_flags &= ~OP_LED_ASSOCIATED; | ||||
| 	ath9k_unregister_led(&priv->tx_led); | ||||
| 	ath9k_unregister_led(&priv->rx_led); | ||||
| 	ath9k_unregister_led(&priv->radio_led); | ||||
| 	if (!priv->led_registered) | ||||
| 		return; | ||||
| 
 | ||||
| 	ath9k_led_brightness(&priv->led_cdev, LED_OFF); | ||||
| 	led_classdev_unregister(&priv->led_cdev); | ||||
| 	cancel_work_sync(&priv->led_work); | ||||
| } | ||||
| 
 | ||||
| void ath9k_init_leds(struct ath9k_htc_priv *priv) | ||||
| { | ||||
| 	char *trigger; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (AR_SREV_9287(priv->ah)) | ||||
|  | @ -303,48 +206,21 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv) | |||
| 	/* LED off, active low */ | ||||
| 	ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1); | ||||
| 
 | ||||
| 	INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work); | ||||
| 	snprintf(priv->led_name, sizeof(priv->led_name), | ||||
| 		"ath9k_htc-%s", wiphy_name(priv->hw->wiphy)); | ||||
| 	priv->led_cdev.name = priv->led_name; | ||||
| 	priv->led_cdev.brightness_set = ath9k_led_brightness; | ||||
| 
 | ||||
| 	trigger = ieee80211_get_radio_led_name(priv->hw); | ||||
| 	snprintf(priv->radio_led.name, sizeof(priv->radio_led.name), | ||||
| 		"ath9k-%s::radio", wiphy_name(priv->hw->wiphy)); | ||||
| 	ret = ath9k_register_led(priv, &priv->radio_led, trigger); | ||||
| 	priv->radio_led.led_type = ATH_LED_RADIO; | ||||
| 	if (ret) | ||||
| 		goto fail; | ||||
| 	ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &priv->led_cdev); | ||||
| 	if (ret < 0) | ||||
| 		return; | ||||
| 
 | ||||
| 	trigger = ieee80211_get_assoc_led_name(priv->hw); | ||||
| 	snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name), | ||||
| 		"ath9k-%s::assoc", wiphy_name(priv->hw->wiphy)); | ||||
| 	ret = ath9k_register_led(priv, &priv->assoc_led, trigger); | ||||
| 	priv->assoc_led.led_type = ATH_LED_ASSOC; | ||||
| 	if (ret) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	trigger = ieee80211_get_tx_led_name(priv->hw); | ||||
| 	snprintf(priv->tx_led.name, sizeof(priv->tx_led.name), | ||||
| 		"ath9k-%s::tx", wiphy_name(priv->hw->wiphy)); | ||||
| 	ret = ath9k_register_led(priv, &priv->tx_led, trigger); | ||||
| 	priv->tx_led.led_type = ATH_LED_TX; | ||||
| 	if (ret) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	trigger = ieee80211_get_rx_led_name(priv->hw); | ||||
| 	snprintf(priv->rx_led.name, sizeof(priv->rx_led.name), | ||||
| 		"ath9k-%s::rx", wiphy_name(priv->hw->wiphy)); | ||||
| 	ret = ath9k_register_led(priv, &priv->rx_led, trigger); | ||||
| 	priv->rx_led.led_type = ATH_LED_RX; | ||||
| 	if (ret) | ||||
| 		goto fail; | ||||
| 
 | ||||
| 	priv->op_flags &= ~OP_LED_DEINIT; | ||||
| 	INIT_WORK(&priv->led_work, ath9k_led_work); | ||||
| 	priv->led_registered = true; | ||||
| 
 | ||||
| 	return; | ||||
| 
 | ||||
| fail: | ||||
| 	cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | ||||
| 	ath9k_deinit_leds(priv); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /*******************/ | ||||
| /*	Rfkill	   */ | ||||
|  |  | |||
|  | @ -117,6 +117,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = { | |||
| 	RATE(540, 0x0c, 0), | ||||
| }; | ||||
| 
 | ||||
| #ifdef CONFIG_MAC80211_LEDS | ||||
| static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = { | ||||
| 	{ .throughput = 0 * 1024, .blink_time = 334 }, | ||||
| 	{ .throughput = 1 * 1024, .blink_time = 260 }, | ||||
| 	{ .throughput = 5 * 1024, .blink_time = 220 }, | ||||
| 	{ .throughput = 10 * 1024, .blink_time = 190 }, | ||||
| 	{ .throughput = 20 * 1024, .blink_time = 170 }, | ||||
| 	{ .throughput = 50 * 1024, .blink_time = 150 }, | ||||
| 	{ .throughput = 70 * 1024, .blink_time = 130 }, | ||||
| 	{ .throughput = 100 * 1024, .blink_time = 110 }, | ||||
| 	{ .throughput = 200 * 1024, .blink_time = 80 }, | ||||
| 	{ .throughput = 300 * 1024, .blink_time = 50 }, | ||||
| }; | ||||
| #endif | ||||
| 
 | ||||
| static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv) | ||||
| { | ||||
| 	int time_left; | ||||
|  | @ -243,7 +258,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid, | |||
| 	 */ | ||||
| 
 | ||||
| 	if (IS_AR7010_DEVICE(drv_info)) | ||||
| 		priv->htc->credits = 45; | ||||
| 		priv->htc->credits = 48; | ||||
| 	else | ||||
| 		priv->htc->credits = 33; | ||||
| 
 | ||||
|  | @ -753,6 +768,12 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | |||
| 	hw->queues = 4; | ||||
| 	hw->channel_change_time = 5000; | ||||
| 	hw->max_listen_interval = 10; | ||||
| 
 | ||||
| 	if (AR_SREV_9271(priv->ah)) | ||||
| 		hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_9271; | ||||
| 	else | ||||
| 		hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_7010; | ||||
| 
 | ||||
| 	hw->vif_data_size = sizeof(struct ath9k_htc_vif); | ||||
| 	hw->sta_data_size = sizeof(struct ath9k_htc_sta); | ||||
| 
 | ||||
|  | @ -802,6 +823,17 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv) | |||
| 		 priv->fw_version_major, | ||||
| 		 priv->fw_version_minor); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Check if the available FW matches the driver's | ||||
| 	 * required version. | ||||
| 	 */ | ||||
| 	if (priv->fw_version_major != MAJOR_VERSION_REQ || | ||||
| 	    priv->fw_version_minor != MINOR_VERSION_REQ) { | ||||
| 		dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n", | ||||
| 			MAJOR_VERSION_REQ, MINOR_VERSION_REQ); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -846,6 +878,13 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv, | |||
| 	if (error != 0) | ||||
| 		goto err_rx; | ||||
| 
 | ||||
| #ifdef CONFIG_MAC80211_LEDS | ||||
| 	/* must be initialized before ieee80211_register_hw */ | ||||
| 	priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw, | ||||
| 		IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_htc_tpt_blink, | ||||
| 		ARRAY_SIZE(ath9k_htc_tpt_blink)); | ||||
| #endif | ||||
| 
 | ||||
| 	/* Register with mac80211 */ | ||||
| 	error = ieee80211_register_hw(hw); | ||||
| 	if (error) | ||||
|  |  | |||
|  | @ -332,6 +332,11 @@ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) | |||
| 	memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); | ||||
| 	hvif.index = priv->mon_vif_idx; | ||||
| 	WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); | ||||
| 	if (ret) { | ||||
| 		ath_err(common, "Unable to remove monitor interface at idx: %d\n", | ||||
| 			priv->mon_vif_idx); | ||||
| 	} | ||||
| 
 | ||||
| 	priv->nvifs--; | ||||
| 	priv->vif_slot &= ~(1 << priv->mon_vif_idx); | ||||
| } | ||||
|  | @ -462,6 +467,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | |||
| 	struct ath9k_htc_sta *ista; | ||||
| 	int ret, sta_idx; | ||||
| 	u8 cmd_rsp; | ||||
| 	u16 maxampdu; | ||||
| 
 | ||||
| 	if (priv->nstations >= ATH9K_HTC_MAX_STA) | ||||
| 		return -ENOBUFS; | ||||
|  | @ -485,7 +491,15 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | |||
| 
 | ||||
| 	tsta.sta_index = sta_idx; | ||||
| 	tsta.vif_index = avp->index; | ||||
| 	tsta.maxampdu = cpu_to_be16(0xffff); | ||||
| 
 | ||||
| 	if (!sta) { | ||||
| 		tsta.maxampdu = cpu_to_be16(0xffff); | ||||
| 	} else { | ||||
| 		maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + | ||||
| 				 sta->ht_cap.ampdu_factor); | ||||
| 		tsta.maxampdu = cpu_to_be16(maxampdu); | ||||
| 	} | ||||
| 
 | ||||
| 	if (sta && sta->ht_cap.ht_supported) | ||||
| 		tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); | ||||
| 
 | ||||
|  | @ -558,7 +572,8 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv, | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv) | ||||
| int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv, | ||||
| 				u8 enable_coex) | ||||
| { | ||||
| 	struct ath9k_htc_cap_target tcap; | ||||
| 	int ret; | ||||
|  | @ -566,13 +581,9 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv) | |||
| 
 | ||||
| 	memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target)); | ||||
| 
 | ||||
| 	/* FIXME: Values are hardcoded */ | ||||
| 	tcap.flags = 0x240c40; | ||||
| 	tcap.flags_ext = 0x80601000; | ||||
| 	tcap.ampdu_limit = 0xffff0000; | ||||
| 	tcap.ampdu_subframes = 20; | ||||
| 	tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask; | ||||
| 	tcap.protmode = 1; | ||||
| 	tcap.ampdu_limit = cpu_to_be32(0xffff); | ||||
| 	tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes; | ||||
| 	tcap.enable_coex = enable_coex; | ||||
| 	tcap.tx_chainmask = priv->ah->caps.tx_chainmask; | ||||
| 
 | ||||
| 	WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap); | ||||
|  | @ -931,7 +942,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
| 
 | ||||
| 	ath9k_host_rx_init(priv); | ||||
| 
 | ||||
| 	ret = ath9k_htc_update_cap_target(priv); | ||||
| 	ret = ath9k_htc_update_cap_target(priv, 0); | ||||
| 	if (ret) | ||||
| 		ath_dbg(common, ATH_DBG_CONFIG, | ||||
| 			"Failed to update capability in target\n"); | ||||
|  | @ -964,7 +975,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
| 	struct ath9k_htc_priv *priv = hw->priv; | ||||
| 	struct ath_hw *ah = priv->ah; | ||||
| 	struct ath_common *common = ath9k_hw_common(ah); | ||||
| 	int ret = 0; | ||||
| 	int ret __attribute__ ((unused)); | ||||
| 	u8 cmd_rsp; | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
|  | @ -992,9 +1003,11 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
| 	/* Cancel all the running timers/work .. */ | ||||
| 	cancel_work_sync(&priv->fatal_work); | ||||
| 	cancel_work_sync(&priv->ps_work); | ||||
| 	cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | ||||
| 
 | ||||
| #ifdef CONFIG_MAC80211_LEDS | ||||
| 	cancel_work_sync(&priv->led_work); | ||||
| #endif | ||||
| 	ath9k_htc_stop_ani(priv); | ||||
| 	ath9k_led_stop_brightness(priv); | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 
 | ||||
|  | @ -1135,6 +1148,10 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, | |||
| 	memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); | ||||
| 	hvif.index = avp->index; | ||||
| 	WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); | ||||
| 	if (ret) { | ||||
| 		ath_err(common, "Unable to remove interface at idx: %d\n", | ||||
| 			avp->index); | ||||
| 	} | ||||
| 	priv->nvifs--; | ||||
| 	priv->vif_slot &= ~(1 << avp->index); | ||||
| 
 | ||||
|  | @ -1567,6 +1584,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, | |||
| 	int ret = 0; | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 	ath9k_htc_ps_wakeup(priv); | ||||
| 
 | ||||
| 	switch (action) { | ||||
| 	case IEEE80211_AMPDU_RX_START: | ||||
|  | @ -1592,6 +1610,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, | |||
| 		ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	ath9k_htc_ps_restore(priv); | ||||
| 	mutex_unlock(&priv->mutex); | ||||
| 
 | ||||
| 	return ret; | ||||
|  | @ -1642,6 +1661,55 @@ static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw, | |||
| 	mutex_unlock(&priv->mutex); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Currently, this is used only for selecting the minimum rate | ||||
|  * for management frames, rate selection for data frames remain | ||||
|  * unaffected. | ||||
|  */ | ||||
| static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw, | ||||
| 				      struct ieee80211_vif *vif, | ||||
| 				      const struct cfg80211_bitrate_mask *mask) | ||||
| { | ||||
| 	struct ath9k_htc_priv *priv = hw->priv; | ||||
| 	struct ath_common *common = ath9k_hw_common(priv->ah); | ||||
| 	struct ath9k_htc_target_rate_mask tmask; | ||||
| 	struct ath9k_htc_vif *avp = (void *)vif->drv_priv; | ||||
| 	int ret = 0; | ||||
| 	u8 cmd_rsp; | ||||
| 
 | ||||
| 	memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask)); | ||||
| 
 | ||||
| 	tmask.vif_index = avp->index; | ||||
| 	tmask.band = IEEE80211_BAND_2GHZ; | ||||
| 	tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_2GHZ].legacy); | ||||
| 
 | ||||
| 	WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask); | ||||
| 	if (ret) { | ||||
| 		ath_err(common, | ||||
| 			"Unable to set 2G rate mask for " | ||||
| 			"interface at idx: %d\n", avp->index); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	tmask.band = IEEE80211_BAND_5GHZ; | ||||
| 	tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_5GHZ].legacy); | ||||
| 
 | ||||
| 	WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask); | ||||
| 	if (ret) { | ||||
| 		ath_err(common, | ||||
| 			"Unable to set 5G rate mask for " | ||||
| 			"interface at idx: %d\n", avp->index); | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	ath_dbg(common, ATH_DBG_CONFIG, | ||||
| 		"Set bitrate masks: 0x%x, 0x%x\n", | ||||
| 		mask->control[IEEE80211_BAND_2GHZ].legacy, | ||||
| 		mask->control[IEEE80211_BAND_5GHZ].legacy); | ||||
| out: | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| struct ieee80211_ops ath9k_htc_ops = { | ||||
| 	.tx                 = ath9k_htc_tx, | ||||
| 	.start              = ath9k_htc_start, | ||||
|  | @ -1664,4 +1732,5 @@ struct ieee80211_ops ath9k_htc_ops = { | |||
| 	.set_rts_threshold  = ath9k_htc_set_rts_threshold, | ||||
| 	.rfkill_poll        = ath9k_htc_rfkill_poll_state, | ||||
| 	.set_coverage_class = ath9k_htc_set_coverage_class, | ||||
| 	.set_bitrate_mask   = ath9k_htc_set_bitrate_mask, | ||||
| }; | ||||
|  |  | |||
|  | @ -446,7 +446,6 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, | |||
| 	struct ieee80211_tx_info *tx_info; | ||||
| 	struct ieee80211_tx_rate *rate; | ||||
| 	struct ieee80211_conf *cur_conf = &priv->hw->conf; | ||||
| 	struct ieee80211_supported_band *sband; | ||||
| 	bool txok; | ||||
| 	int slot; | ||||
| 
 | ||||
|  | @ -461,7 +460,6 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv, | |||
| 	tx_info = IEEE80211_SKB_CB(skb); | ||||
| 	vif = tx_info->control.vif; | ||||
| 	rate = &tx_info->status.rates[0]; | ||||
| 	sband = priv->hw->wiphy->bands[cur_conf->channel->band]; | ||||
| 
 | ||||
| 	memset(&tx_info->status, 0, sizeof(tx_info->status)); | ||||
| 
 | ||||
|  |  | |||
|  | @ -83,21 +83,10 @@ struct htc_ep_callbacks { | |||
| 	void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id); | ||||
| }; | ||||
| 
 | ||||
| #define HTC_TX_QUEUE_SIZE 256 | ||||
| 
 | ||||
| struct htc_txq { | ||||
| 	struct sk_buff *buf[HTC_TX_QUEUE_SIZE]; | ||||
| 	u32 txqdepth; | ||||
| 	u16 txbuf_cnt; | ||||
| 	u16 txq_head; | ||||
| 	u16 txq_tail; | ||||
| }; | ||||
| 
 | ||||
| struct htc_endpoint { | ||||
| 	u16 service_id; | ||||
| 
 | ||||
| 	struct htc_ep_callbacks ep_callbacks; | ||||
| 	struct htc_txq htc_txq; | ||||
| 	u32 max_txqdepth; | ||||
| 	int max_msglen; | ||||
| 
 | ||||
|  |  | |||
|  | @ -247,6 +247,17 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah) | |||
| { | ||||
| 	u32 val; | ||||
| 
 | ||||
| 	switch (ah->hw_version.devid) { | ||||
| 	case AR5416_AR9100_DEVID: | ||||
| 		ah->hw_version.macVersion = AR_SREV_VERSION_9100; | ||||
| 		break; | ||||
| 	case AR9300_DEVID_AR9340: | ||||
| 		ah->hw_version.macVersion = AR_SREV_VERSION_9340; | ||||
| 		val = REG_READ(ah, AR_SREV); | ||||
| 		ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	val = REG_READ(ah, AR_SREV) & AR_SREV_ID; | ||||
| 
 | ||||
| 	if (val == 0xFF) { | ||||
|  | @ -462,7 +473,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah) | |||
| 		return ecode; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!AR_SREV_9100(ah)) { | ||||
| 	if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) { | ||||
| 		ath9k_hw_ani_setup(ah); | ||||
| 		ath9k_hw_ani_init(ah); | ||||
| 	} | ||||
|  | @ -484,9 +495,6 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
| 	struct ath_common *common = ath9k_hw_common(ah); | ||||
| 	int r = 0; | ||||
| 
 | ||||
| 	if (ah->hw_version.devid == AR5416_AR9100_DEVID) | ||||
| 		ah->hw_version.macVersion = AR_SREV_VERSION_9100; | ||||
| 
 | ||||
| 	ath9k_hw_read_revisions(ah); | ||||
| 
 | ||||
| 	/*
 | ||||
|  | @ -544,6 +552,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
| 	case AR_SREV_VERSION_9271: | ||||
| 	case AR_SREV_VERSION_9300: | ||||
| 	case AR_SREV_VERSION_9485: | ||||
| 	case AR_SREV_VERSION_9340: | ||||
| 		break; | ||||
| 	default: | ||||
| 		ath_err(common, | ||||
|  | @ -552,7 +561,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
| 		return -EOPNOTSUPP; | ||||
| 	} | ||||
| 
 | ||||
| 	if (AR_SREV_9271(ah) || AR_SREV_9100(ah)) | ||||
| 	if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah)) | ||||
| 		ah->is_pciexpress = false; | ||||
| 
 | ||||
| 	ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); | ||||
|  | @ -621,6 +630,7 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
| 	case AR2427_DEVID_PCIE: | ||||
| 	case AR9300_DEVID_PCIE: | ||||
| 	case AR9300_DEVID_AR9485_PCIE: | ||||
| 	case AR9300_DEVID_AR9340: | ||||
| 		break; | ||||
| 	default: | ||||
| 		if (common->bus_ops->ath_bus_type == ATH_USB) | ||||
|  | @ -663,7 +673,7 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) | |||
| 	REGWRITE_BUFFER_FLUSH(ah); | ||||
| } | ||||
| 
 | ||||
| unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) | ||||
| u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) | ||||
| { | ||||
| 	REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK); | ||||
| 	udelay(100); | ||||
|  | @ -676,7 +686,6 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah) | |||
| } | ||||
| EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc); | ||||
| 
 | ||||
| #define DPLL3_PHASE_SHIFT_VAL 0x1 | ||||
| static void ath9k_hw_init_pll(struct ath_hw *ah, | ||||
| 			      struct ath9k_channel *chan) | ||||
| { | ||||
|  | @ -713,16 +722,48 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
| 		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, | ||||
| 			      AR_CH0_BB_DPLL2_PLL_PWD, 0x0); | ||||
| 		udelay(1000); | ||||
| 	} else if (AR_SREV_9340(ah)) { | ||||
| 		u32 regval, pll2_divint, pll2_divfrac, refdiv; | ||||
| 
 | ||||
| 		REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3, | ||||
| 			      AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL); | ||||
| 		REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c); | ||||
| 		udelay(1000); | ||||
| 
 | ||||
| 		REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16); | ||||
| 		udelay(100); | ||||
| 
 | ||||
| 		if (ah->is_clk_25mhz) { | ||||
| 			pll2_divint = 0x54; | ||||
| 			pll2_divfrac = 0x1eb85; | ||||
| 			refdiv = 3; | ||||
| 		} else { | ||||
| 			pll2_divint = 88; | ||||
| 			pll2_divfrac = 0; | ||||
| 			refdiv = 5; | ||||
| 		} | ||||
| 
 | ||||
| 		regval = REG_READ(ah, AR_PHY_PLL_MODE); | ||||
| 		regval |= (0x1 << 16); | ||||
| 		REG_WRITE(ah, AR_PHY_PLL_MODE, regval); | ||||
| 		udelay(100); | ||||
| 
 | ||||
| 		REG_WRITE(ah, AR_PHY_PLL_CONTROL, (refdiv << 27) | | ||||
| 			  (pll2_divint << 18) | pll2_divfrac); | ||||
| 		udelay(100); | ||||
| 
 | ||||
| 		regval = REG_READ(ah, AR_PHY_PLL_MODE); | ||||
| 		regval = (regval & 0x80071fff) | (0x1 << 30) | (0x1 << 13) | | ||||
| 			 (0x4 << 26) | (0x18 << 19); | ||||
| 		REG_WRITE(ah, AR_PHY_PLL_MODE, regval); | ||||
| 		REG_WRITE(ah, AR_PHY_PLL_MODE, | ||||
| 			  REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff); | ||||
| 		udelay(1000); | ||||
| 	} | ||||
| 
 | ||||
| 	pll = ath9k_hw_compute_pll_control(ah, chan); | ||||
| 
 | ||||
| 	REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); | ||||
| 
 | ||||
| 	if (AR_SREV_9485(ah)) | ||||
| 	if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) | ||||
| 		udelay(1000); | ||||
| 
 | ||||
| 	/* Switch the core clock for ar9271 to 117Mhz */ | ||||
|  | @ -734,17 +775,34 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
| 	udelay(RTC_PLL_SETTLE_DELAY); | ||||
| 
 | ||||
| 	REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); | ||||
| 
 | ||||
| 	if (AR_SREV_9340(ah)) { | ||||
| 		if (ah->is_clk_25mhz) { | ||||
| 			REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1); | ||||
| 			REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7); | ||||
| 			REG_WRITE(ah,  AR_SLP32_INC, 0x0001e7ae); | ||||
| 		} else { | ||||
| 			REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1); | ||||
| 			REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400); | ||||
| 			REG_WRITE(ah,  AR_SLP32_INC, 0x0001e800); | ||||
| 		} | ||||
| 		udelay(100); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | ||||
| 					  enum nl80211_iftype opmode) | ||||
| { | ||||
| 	u32 sync_default = AR_INTR_SYNC_DEFAULT; | ||||
| 	u32 imr_reg = AR_IMR_TXERR | | ||||
| 		AR_IMR_TXURN | | ||||
| 		AR_IMR_RXERR | | ||||
| 		AR_IMR_RXORN | | ||||
| 		AR_IMR_BCNMISC; | ||||
| 
 | ||||
| 	if (AR_SREV_9340(ah)) | ||||
| 		sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; | ||||
| 
 | ||||
| 	if (AR_SREV_9300_20_OR_LATER(ah)) { | ||||
| 		imr_reg |= AR_IMR_RXOK_HP; | ||||
| 		if (ah->config.rx_intr_mitigation) | ||||
|  | @ -775,7 +833,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | |||
| 
 | ||||
| 	if (!AR_SREV_9100(ah)) { | ||||
| 		REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); | ||||
| 		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT); | ||||
| 		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default); | ||||
| 		REG_WRITE(ah, AR_INTR_SYNC_MASK, 0); | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1487,7 +1545,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
| 				REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | ||||
| 		} | ||||
| #ifdef __BIG_ENDIAN | ||||
|                 else | ||||
| 		else if (AR_SREV_9340(ah)) | ||||
| 			REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0); | ||||
| 		else | ||||
| 			REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); | ||||
| #endif | ||||
| 	} | ||||
|  | @ -1793,7 +1853,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
| 	struct ath_common *common = ath9k_hw_common(ah); | ||||
| 	struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; | ||||
| 
 | ||||
| 	u16 capField = 0, eeval; | ||||
| 	u16 eeval; | ||||
| 	u8 ant_div_ctl1, tx_chainmask, rx_chainmask; | ||||
| 
 | ||||
| 	eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0); | ||||
|  | @ -1804,8 +1864,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
| 		eeval |= AR9285_RDEXT_DEFAULT; | ||||
| 	regulatory->current_rd_ext = eeval; | ||||
| 
 | ||||
| 	capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP); | ||||
| 
 | ||||
| 	if (ah->opmode != NL80211_IFTYPE_AP && | ||||
| 	    ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) { | ||||
| 		if (regulatory->current_rd == 0x64 || | ||||
|  | @ -1898,15 +1956,23 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
| 	else | ||||
| 		pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS; | ||||
| 
 | ||||
| 	if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) { | ||||
| 		btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO; | ||||
| 		btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO; | ||||
| 
 | ||||
| 		if (AR_SREV_9285(ah)) { | ||||
| 	if (common->btcoex_enabled) { | ||||
| 		if (AR_SREV_9300_20_OR_LATER(ah)) { | ||||
| 			btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; | ||||
| 			btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO; | ||||
| 		} else { | ||||
| 			btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE; | ||||
| 			btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300; | ||||
| 			btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300; | ||||
| 			btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300; | ||||
| 		} else if (AR_SREV_9280_20_OR_LATER(ah)) { | ||||
| 			btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280; | ||||
| 			btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280; | ||||
| 
 | ||||
| 			if (AR_SREV_9285(ah)) { | ||||
| 				btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; | ||||
| 				btcoex_hw->btpriority_gpio = | ||||
| 						ATH_BTPRIORITY_GPIO_9285; | ||||
| 			} else { | ||||
| 				btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE; | ||||
| 			} | ||||
| 		} | ||||
| 	} else { | ||||
| 		btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; | ||||
|  | @ -2359,11 +2425,11 @@ EXPORT_SYMBOL(ath_gen_timer_alloc); | |||
| 
 | ||||
| void ath9k_hw_gen_timer_start(struct ath_hw *ah, | ||||
| 			      struct ath_gen_timer *timer, | ||||
| 			      u32 timer_next, | ||||
| 			      u32 trig_timeout, | ||||
| 			      u32 timer_period) | ||||
| { | ||||
| 	struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; | ||||
| 	u32 tsf; | ||||
| 	u32 tsf, timer_next; | ||||
| 
 | ||||
| 	BUG_ON(!timer_period); | ||||
| 
 | ||||
|  | @ -2371,17 +2437,12 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah, | |||
| 
 | ||||
| 	tsf = ath9k_hw_gettsf32(ah); | ||||
| 
 | ||||
| 	timer_next = tsf + trig_timeout; | ||||
| 
 | ||||
| 	ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER, | ||||
| 		"current tsf %x period %x timer_next %x\n", | ||||
| 		tsf, timer_period, timer_next); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Pull timer_next forward if the current TSF already passed it | ||||
| 	 * because of software latency | ||||
| 	 */ | ||||
| 	if (timer_next < tsf) | ||||
| 		timer_next = tsf + timer_period; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Program generic timer registers | ||||
| 	 */ | ||||
|  |  | |||
|  | @ -43,6 +43,7 @@ | |||
| #define AR9287_DEVID_PCI	0x002d | ||||
| #define AR9287_DEVID_PCIE	0x002e | ||||
| #define AR9300_DEVID_PCIE	0x0030 | ||||
| #define AR9300_DEVID_AR9340	0x0031 | ||||
| #define AR9300_DEVID_AR9485_PCIE 0x0032 | ||||
| 
 | ||||
| #define AR5416_AR9100_DEVID	0x000b | ||||
|  | @ -55,6 +56,9 @@ | |||
| #define AT9285_COEX3WIRE_SA_SUBSYSID	0x30aa | ||||
| #define AT9285_COEX3WIRE_DA_SUBSYSID	0x30ab | ||||
| 
 | ||||
| #define AR9300_NUM_BT_WEIGHTS   4 | ||||
| #define AR9300_NUM_WLAN_WEIGHTS 4 | ||||
| 
 | ||||
| #define ATH_AMPDU_LIMIT_MAX        (64 * 1024 - 1) | ||||
| 
 | ||||
| #define	ATH_DEFAULT_NOISE_FLOOR -95 | ||||
|  | @ -121,7 +125,7 @@ | |||
| #define AR_GPIO_BIT(_gpio)          (1 << (_gpio)) | ||||
| 
 | ||||
| #define BASE_ACTIVATE_DELAY         100 | ||||
| #define RTC_PLL_SETTLE_DELAY        100 | ||||
| #define RTC_PLL_SETTLE_DELAY        (AR_SREV_9340(ah) ? 1000 : 100) | ||||
| #define COEF_SCALE_S                24 | ||||
| #define HT40_CHANNEL_CENTER_SHIFT   10 | ||||
| 
 | ||||
|  | @ -771,6 +775,8 @@ struct ath_hw { | |||
| 
 | ||||
| 	/* Bluetooth coexistance */ | ||||
| 	struct ath_btcoex_hw btcoex_hw; | ||||
| 	u32 bt_coex_bt_weight[AR9300_NUM_BT_WEIGHTS]; | ||||
| 	u32 bt_coex_wlan_weight[AR9300_NUM_WLAN_WEIGHTS]; | ||||
| 
 | ||||
| 	u32 intr_txqs; | ||||
| 	u8 txchainmask; | ||||
|  | @ -799,6 +805,7 @@ struct ath_hw { | |||
| 	struct ar5416IniArray iniPcieSerdes; | ||||
| 	struct ar5416IniArray iniPcieSerdesLowPower; | ||||
| 	struct ar5416IniArray iniModesAdditional; | ||||
| 	struct ar5416IniArray iniModesAdditional_40M; | ||||
| 	struct ar5416IniArray iniModesRxGain; | ||||
| 	struct ar5416IniArray iniModesTxGain; | ||||
| 	struct ar5416IniArray iniModes_9271_1_0_only; | ||||
|  | @ -845,6 +852,8 @@ struct ath_hw { | |||
| 
 | ||||
| 	/* Enterprise mode cap */ | ||||
| 	u32 ent_mode; | ||||
| 
 | ||||
| 	bool is_clk_25mhz; | ||||
| }; | ||||
| 
 | ||||
| struct ath_bus_ops { | ||||
|  | @ -928,7 +937,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64); | |||
| void ath9k_hw_reset_tsf(struct ath_hw *ah); | ||||
| void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); | ||||
| void ath9k_hw_init_global_settings(struct ath_hw *ah); | ||||
| unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); | ||||
| u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah); | ||||
| void ath9k_hw_set11nmac2040(struct ath_hw *ah); | ||||
| void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); | ||||
| void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | ||||
|  |  | |||
|  | @ -574,6 +574,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
| 		sc->sc_ah->gpio_mask = pdata->gpio_mask; | ||||
| 		sc->sc_ah->gpio_val = pdata->gpio_val; | ||||
| 		sc->sc_ah->led_pin = pdata->led_pin; | ||||
| 		ah->is_clk_25mhz = pdata->is_clk_25mhz; | ||||
| 	} | ||||
| 
 | ||||
| 	common = ath9k_hw_common(ah); | ||||
|  | @ -800,6 +801,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
| 
 | ||||
| 	INIT_WORK(&sc->hw_check_work, ath_hw_check); | ||||
| 	INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); | ||||
| 	INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||||
| 	sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||||
| 
 | ||||
| 	ath_init_leds(sc); | ||||
|  |  | |||
|  | @ -812,10 +812,14 @@ EXPORT_SYMBOL(ath9k_hw_disable_interrupts); | |||
| void ath9k_hw_enable_interrupts(struct ath_hw *ah) | ||||
| { | ||||
| 	struct ath_common *common = ath9k_hw_common(ah); | ||||
| 	u32 sync_default = AR_INTR_SYNC_DEFAULT; | ||||
| 
 | ||||
| 	if (!(ah->imask & ATH9K_INT_GLOBAL)) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (AR_SREV_9340(ah)) | ||||
| 		sync_default &= ~AR_INTR_SYNC_HOST1_FATAL; | ||||
| 
 | ||||
| 	ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n"); | ||||
| 	REG_WRITE(ah, AR_IER, AR_IER_ENABLE); | ||||
| 	if (!AR_SREV_9100(ah)) { | ||||
|  | @ -824,10 +828,8 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah) | |||
| 		REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ); | ||||
| 
 | ||||
| 
 | ||||
| 		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, | ||||
| 			  AR_INTR_SYNC_DEFAULT); | ||||
| 		REG_WRITE(ah, AR_INTR_SYNC_MASK, | ||||
| 			  AR_INTR_SYNC_DEFAULT); | ||||
| 		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default); | ||||
| 		REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default); | ||||
| 	} | ||||
| 	ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", | ||||
| 		REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); | ||||
|  | @ -883,6 +885,9 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | |||
| 			mask |= AR_IMR_GENTMR; | ||||
| 	} | ||||
| 
 | ||||
| 	if (ints & ATH9K_INT_GENTIMER) | ||||
| 		mask |= AR_IMR_GENTMR; | ||||
| 
 | ||||
| 	if (ints & (ATH9K_INT_BMISC)) { | ||||
| 		mask |= AR_IMR_BCNMISC; | ||||
| 		if (ints & ATH9K_INT_TIM) | ||||
|  |  | |||
|  | @ -624,6 +624,43 @@ out: | |||
| 	ath9k_ps_restore(sc); | ||||
| } | ||||
| 
 | ||||
| static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum) | ||||
| { | ||||
| 	static int count; | ||||
| 	struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||||
| 
 | ||||
| 	if (pll_sqsum >= 0x40000) { | ||||
| 		count++; | ||||
| 		if (count == 3) { | ||||
| 			/* Rx is hung for more than 500ms. Reset it */ | ||||
| 			ath_dbg(common, ATH_DBG_RESET, | ||||
| 				"Possible RX hang, resetting"); | ||||
| 			ath_reset(sc, true); | ||||
| 			count = 0; | ||||
| 		} | ||||
| 	} else | ||||
| 		count = 0; | ||||
| } | ||||
| 
 | ||||
| void ath_hw_pll_work(struct work_struct *work) | ||||
| { | ||||
| 	struct ath_softc *sc = container_of(work, struct ath_softc, | ||||
| 					    hw_pll_work.work); | ||||
| 	u32 pll_sqsum; | ||||
| 
 | ||||
| 	if (AR_SREV_9485(sc->sc_ah)) { | ||||
| 
 | ||||
| 		ath9k_ps_wakeup(sc); | ||||
| 		pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah); | ||||
| 		ath9k_ps_restore(sc); | ||||
| 
 | ||||
| 		ath_hw_pll_rx_hang_check(sc, pll_sqsum); | ||||
| 
 | ||||
| 		ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void ath9k_tasklet(unsigned long data) | ||||
| { | ||||
| 	struct ath_softc *sc = (struct ath_softc *)data; | ||||
|  | @ -1932,6 +1969,12 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | |||
| 				"Bss Info ASSOC %d, bssid: %pM\n", | ||||
| 				bss_conf->aid, common->curbssid); | ||||
| 			ath_beacon_config(sc, vif); | ||||
| 			/*
 | ||||
| 			 * Request a re-configuration of Beacon related timers | ||||
| 			 * on the receipt of the first Beacon frame (i.e., | ||||
| 			 * after time sync with the AP). | ||||
| 			 */ | ||||
| 			sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; | ||||
| 			/* Reset rssi stats */ | ||||
| 			sc->last_rssi = ATH_RSSI_DUMMY_MARKER; | ||||
| 			sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; | ||||
|  | @ -2219,9 +2262,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | |||
| 	int timeout = 200; /* ms */ | ||||
| 	int i, j; | ||||
| 
 | ||||
| 	ath9k_ps_wakeup(sc); | ||||
| 	mutex_lock(&sc->mutex); | ||||
| 
 | ||||
| 	cancel_delayed_work_sync(&sc->tx_complete_work); | ||||
| 
 | ||||
| 	if (drop) | ||||
|  | @ -2244,15 +2285,15 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop) | |||
| 		    goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	ath9k_ps_wakeup(sc); | ||||
| 	if (!ath_drain_all_txq(sc, false)) | ||||
| 		ath_reset(sc, false); | ||||
| 
 | ||||
| 	ath9k_ps_restore(sc); | ||||
| 	ieee80211_wake_queues(hw); | ||||
| 
 | ||||
| out: | ||||
| 	ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0); | ||||
| 	mutex_unlock(&sc->mutex); | ||||
| 	ath9k_ps_restore(sc); | ||||
| } | ||||
| 
 | ||||
| static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw) | ||||
|  |  | |||
|  | @ -45,4 +45,7 @@ | |||
| #define	AR_PHY_TIMING11_SPUR_FREQ_SD		0x3FF00000 | ||||
| #define	AR_PHY_TIMING11_SPUR_FREQ_SD_S		20 | ||||
| 
 | ||||
| #define AR_PHY_PLL_CONTROL 0x16180 | ||||
| #define AR_PHY_PLL_MODE 0x16184 | ||||
| 
 | ||||
| #endif | ||||
|  |  | |||
|  | @ -854,14 +854,13 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
| 	ath_rc_rate_set_rtscts(sc, rate_table, tx_info); | ||||
| } | ||||
| 
 | ||||
| static bool ath_rc_update_per(struct ath_softc *sc, | ||||
| static void ath_rc_update_per(struct ath_softc *sc, | ||||
| 			      const struct ath_rate_table *rate_table, | ||||
| 			      struct ath_rate_priv *ath_rc_priv, | ||||
| 				  struct ieee80211_tx_info *tx_info, | ||||
| 			      int tx_rate, int xretries, int retries, | ||||
| 			      u32 now_msec) | ||||
| { | ||||
| 	bool state_change = false; | ||||
| 	int count, n_bad_frames; | ||||
| 	u8 last_per; | ||||
| 	static const u32 nretry_to_per_lookup[10] = { | ||||
|  | @ -992,8 +991,6 @@ static bool ath_rc_update_per(struct ath_softc *sc, | |||
| 
 | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return state_change; | ||||
| } | ||||
| 
 | ||||
| static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix, | ||||
|  | @ -1017,7 +1014,6 @@ static void ath_rc_update_ht(struct ath_softc *sc, | |||
| 	u32 now_msec = jiffies_to_msecs(jiffies); | ||||
| 	int rate; | ||||
| 	u8 last_per; | ||||
| 	bool state_change = false; | ||||
| 	const struct ath_rate_table *rate_table = ath_rc_priv->rate_table; | ||||
| 	int size = ath_rc_priv->rate_table_size; | ||||
| 
 | ||||
|  | @ -1027,9 +1023,9 @@ static void ath_rc_update_ht(struct ath_softc *sc, | |||
| 	last_per = ath_rc_priv->per[tx_rate]; | ||||
| 
 | ||||
| 	/* Update PER first */ | ||||
| 	state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv, | ||||
| 					 tx_info, tx_rate, xretries, | ||||
| 					 retries, now_msec); | ||||
| 	ath_rc_update_per(sc, rate_table, ath_rc_priv, | ||||
| 			  tx_info, tx_rate, xretries, | ||||
| 			  retries, now_msec); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * If this rate looks bad (high PER) then stop using it for | ||||
|  |  | |||
|  | @ -1339,7 +1339,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | |||
| 	struct ath_hw_antcomb_conf div_ant_conf; | ||||
| 	struct ath_ant_comb *antcomb = &sc->ant_comb; | ||||
| 	int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set; | ||||
| 	int curr_main_set, curr_bias; | ||||
| 	int curr_main_set; | ||||
| 	int main_rssi = rs->rs_rssi_ctl0; | ||||
| 	int alt_rssi = rs->rs_rssi_ctl1; | ||||
| 	int rx_ant_conf,  main_ant_conf; | ||||
|  | @ -1393,7 +1393,6 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs) | |||
| 	ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf); | ||||
| 	curr_alt_set = div_ant_conf.alt_lna_conf; | ||||
| 	curr_main_set = div_ant_conf.main_lna_conf; | ||||
| 	curr_bias = div_ant_conf.fast_div_bias; | ||||
| 
 | ||||
| 	antcomb->count++; | ||||
| 
 | ||||
|  | @ -1743,7 +1742,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
| 		if ((sc->ps_flags & (PS_WAIT_FOR_BEACON | | ||||
| 					      PS_WAIT_FOR_CAB | | ||||
| 					      PS_WAIT_FOR_PSPOLL_DATA)) || | ||||
| 					unlikely(ath9k_check_auto_sleep(sc))) | ||||
| 						ath9k_check_auto_sleep(sc)) | ||||
| 			ath_rx_ps(sc, skb); | ||||
| 		spin_unlock_irqrestore(&sc->sc_pm_lock, flags); | ||||
| 
 | ||||
|  |  | |||
|  | @ -693,7 +693,7 @@ | |||
| #define AR_RC_APB            0x00000002 | ||||
| #define AR_RC_HOSTIF         0x00000100 | ||||
| 
 | ||||
| #define AR_WA                		0x4004 | ||||
| #define AR_WA			(AR_SREV_9340(ah) ? 0x40c4 : 0x4004) | ||||
| #define AR_WA_BIT6			(1 << 6) | ||||
| #define AR_WA_BIT7			(1 << 7) | ||||
| #define AR_WA_BIT23			(1 << 23) | ||||
|  | @ -712,7 +712,7 @@ | |||
| #define AR_PM_STATE                 0x4008 | ||||
| #define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000 | ||||
| 
 | ||||
| #define AR_HOST_TIMEOUT             0x4018 | ||||
| #define AR_HOST_TIMEOUT             (AR_SREV_9340(ah) ? 0x4008 : 0x4018) | ||||
| #define AR_HOST_TIMEOUT_APB_CNTR    0x0000FFFF | ||||
| #define AR_HOST_TIMEOUT_APB_CNTR_S  0 | ||||
| #define AR_HOST_TIMEOUT_LCL_CNTR    0xFFFF0000 | ||||
|  | @ -742,7 +742,8 @@ | |||
| #define EEPROM_PROTECT_WP_1024_2047   0x8000 | ||||
| 
 | ||||
| #define AR_SREV \ | ||||
| 	((AR_SREV_9100(ah)) ? 0x0600 : 0x4020) | ||||
| 	((AR_SREV_9100(ah)) ? 0x0600 : (AR_SREV_9340(ah) \ | ||||
| 					? 0x400c : 0x4020)) | ||||
| 
 | ||||
| #define AR_SREV_ID \ | ||||
| 	((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF) | ||||
|  | @ -790,6 +791,7 @@ | |||
| #define AR_SREV_VERSION_9485		0x240 | ||||
| #define AR_SREV_REVISION_9485_10	0 | ||||
| #define AR_SREV_REVISION_9485_11        1 | ||||
| #define AR_SREV_VERSION_9340		0x300 | ||||
| 
 | ||||
| #define AR_SREV_5416(_ah) \ | ||||
| 	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ | ||||
|  | @ -868,6 +870,11 @@ | |||
| #define AR_SREV_9485_11(_ah) \ | ||||
| 	(AR_SREV_9485(_ah) && \ | ||||
| 	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11)) | ||||
| #define AR_SREV_9485_OR_LATER(_ah) \ | ||||
| 	(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485)) | ||||
| 
 | ||||
| #define AR_SREV_9340(_ah) \ | ||||
| 	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340)) | ||||
| 
 | ||||
| #define AR_SREV_9285E_20(_ah) \ | ||||
|     (AR_SREV_9285_12_OR_LATER(_ah) && \ | ||||
|  | @ -910,11 +917,11 @@ enum ath_usb_dev { | |||
| #define AR_INTR_SPURIOUS                      0xFFFFFFFF | ||||
| 
 | ||||
| 
 | ||||
| #define AR_INTR_SYNC_CAUSE_CLR                0x4028 | ||||
| #define AR_INTR_SYNC_CAUSE                    (AR_SREV_9340(ah) ? 0x4010 : 0x4028) | ||||
| #define AR_INTR_SYNC_CAUSE_CLR                (AR_SREV_9340(ah) ? 0x4010 : 0x4028) | ||||
| 
 | ||||
| #define AR_INTR_SYNC_CAUSE                    0x4028 | ||||
| 
 | ||||
| #define AR_INTR_SYNC_ENABLE                   0x402c | ||||
| #define AR_INTR_SYNC_ENABLE                   (AR_SREV_9340(ah) ? 0x4014 : 0x402c) | ||||
| #define AR_INTR_SYNC_ENABLE_GPIO              0xFFFC0000 | ||||
| #define AR_INTR_SYNC_ENABLE_GPIO_S            18 | ||||
| 
 | ||||
|  | @ -954,24 +961,24 @@ enum { | |||
| 
 | ||||
| }; | ||||
| 
 | ||||
| #define AR_INTR_ASYNC_MASK                       0x4030 | ||||
| #define AR_INTR_ASYNC_MASK                       (AR_SREV_9340(ah) ? 0x4018 : 0x4030) | ||||
| #define AR_INTR_ASYNC_MASK_GPIO                  0xFFFC0000 | ||||
| #define AR_INTR_ASYNC_MASK_GPIO_S                18 | ||||
| 
 | ||||
| #define AR_INTR_SYNC_MASK                        0x4034 | ||||
| #define AR_INTR_SYNC_MASK                        (AR_SREV_9340(ah) ? 0x401c : 0x4034) | ||||
| #define AR_INTR_SYNC_MASK_GPIO                   0xFFFC0000 | ||||
| #define AR_INTR_SYNC_MASK_GPIO_S                 18 | ||||
| 
 | ||||
| #define AR_INTR_ASYNC_CAUSE_CLR                  0x4038 | ||||
| #define AR_INTR_ASYNC_CAUSE                      0x4038 | ||||
| #define AR_INTR_ASYNC_CAUSE_CLR                  (AR_SREV_9340(ah) ? 0x4020 : 0x4038) | ||||
| #define AR_INTR_ASYNC_CAUSE                      (AR_SREV_9340(ah) ? 0x4020 : 0x4038) | ||||
| 
 | ||||
| #define AR_INTR_ASYNC_ENABLE                     0x403c | ||||
| #define AR_INTR_ASYNC_ENABLE                     (AR_SREV_9340(ah) ? 0x4024 : 0x403c) | ||||
| #define AR_INTR_ASYNC_ENABLE_GPIO                0xFFFC0000 | ||||
| #define AR_INTR_ASYNC_ENABLE_GPIO_S              18 | ||||
| 
 | ||||
| #define AR_PCIE_SERDES                           0x4040 | ||||
| #define AR_PCIE_SERDES2                          0x4044 | ||||
| #define AR_PCIE_PM_CTRL                          0x4014 | ||||
| #define AR_PCIE_PM_CTRL                          (AR_SREV_9340(ah) ? 0x4004 : 0x4014) | ||||
| #define AR_PCIE_PM_CTRL_ENA                      0x00080000 | ||||
| 
 | ||||
| #define AR_NUM_GPIO                              14 | ||||
|  | @ -982,7 +989,7 @@ enum { | |||
| #define AR9300_NUM_GPIO                          17 | ||||
| #define AR7010_NUM_GPIO                          16 | ||||
| 
 | ||||
| #define AR_GPIO_IN_OUT                           0x4048 | ||||
| #define AR_GPIO_IN_OUT                           (AR_SREV_9340(ah) ? 0x4028 : 0x4048) | ||||
| #define AR_GPIO_IN_VAL                           0x0FFFC000 | ||||
| #define AR_GPIO_IN_VAL_S                         14 | ||||
| #define AR928X_GPIO_IN_VAL                       0x000FFC00 | ||||
|  | @ -996,11 +1003,12 @@ enum { | |||
| #define AR7010_GPIO_IN_VAL                       0x0000FFFF | ||||
| #define AR7010_GPIO_IN_VAL_S                     0 | ||||
| 
 | ||||
| #define AR_GPIO_IN				 0x404c | ||||
| #define AR_GPIO_IN				 (AR_SREV_9340(ah) ? 0x402c : 0x404c) | ||||
| #define AR9300_GPIO_IN_VAL                       0x0001FFFF | ||||
| #define AR9300_GPIO_IN_VAL_S                     0 | ||||
| 
 | ||||
| #define AR_GPIO_OE_OUT                           (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c) | ||||
| #define AR_GPIO_OE_OUT                           (AR_SREV_9340(ah) ? 0x4030 : \ | ||||
| 						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)) | ||||
| #define AR_GPIO_OE_OUT_DRV                       0x3 | ||||
| #define AR_GPIO_OE_OUT_DRV_NO                    0x0 | ||||
| #define AR_GPIO_OE_OUT_DRV_LOW                   0x1 | ||||
|  | @ -1022,11 +1030,13 @@ enum { | |||
| #define AR7010_GPIO_INT_MASK                     0x52024 | ||||
| #define AR7010_GPIO_FUNCTION                     0x52028 | ||||
| 
 | ||||
| #define AR_GPIO_INTR_POL                         (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050) | ||||
| #define AR_GPIO_INTR_POL                         (AR_SREV_9340(ah) ? 0x4038 : \ | ||||
| 						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050)) | ||||
| #define AR_GPIO_INTR_POL_VAL                     0x0001FFFF | ||||
| #define AR_GPIO_INTR_POL_VAL_S                   0 | ||||
| 
 | ||||
| #define AR_GPIO_INPUT_EN_VAL                     (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054) | ||||
| #define AR_GPIO_INPUT_EN_VAL                     (AR_SREV_9340(ah) ? 0x403c : \ | ||||
| 						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054)) | ||||
| #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF     0x00000004 | ||||
| #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S       2 | ||||
| #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF    0x00000008 | ||||
|  | @ -1044,13 +1054,15 @@ enum { | |||
| #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE        0x00010000 | ||||
| #define AR_GPIO_JTAG_DISABLE                     0x00020000 | ||||
| 
 | ||||
| #define AR_GPIO_INPUT_MUX1                       (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058) | ||||
| #define AR_GPIO_INPUT_MUX1                       (AR_SREV_9340(ah) ? 0x4040 : \ | ||||
| 						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058)) | ||||
| #define AR_GPIO_INPUT_MUX1_BT_ACTIVE             0x000f0000 | ||||
| #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S           16 | ||||
| #define AR_GPIO_INPUT_MUX1_BT_PRIORITY           0x00000f00 | ||||
| #define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S         8 | ||||
| 
 | ||||
| #define AR_GPIO_INPUT_MUX2                       (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c) | ||||
| #define AR_GPIO_INPUT_MUX2                       (AR_SREV_9340(ah) ? 0x4044 : \ | ||||
| 						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c)) | ||||
| #define AR_GPIO_INPUT_MUX2_CLK25                 0x0000000f | ||||
| #define AR_GPIO_INPUT_MUX2_CLK25_S               0 | ||||
| #define AR_GPIO_INPUT_MUX2_RFSILENT              0x000000f0 | ||||
|  | @ -1058,13 +1070,18 @@ enum { | |||
| #define AR_GPIO_INPUT_MUX2_RTC_RESET             0x00000f00 | ||||
| #define AR_GPIO_INPUT_MUX2_RTC_RESET_S           8 | ||||
| 
 | ||||
| #define AR_GPIO_OUTPUT_MUX1                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060) | ||||
| #define AR_GPIO_OUTPUT_MUX2                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064) | ||||
| #define AR_GPIO_OUTPUT_MUX3                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068) | ||||
| #define AR_GPIO_OUTPUT_MUX1                      (AR_SREV_9340(ah) ? 0x4048 : \ | ||||
| 						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060)) | ||||
| #define AR_GPIO_OUTPUT_MUX2                      (AR_SREV_9340(ah) ? 0x404c : \ | ||||
| 						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064)) | ||||
| #define AR_GPIO_OUTPUT_MUX3                      (AR_SREV_9340(ah) ? 0x4050 : \ | ||||
| 						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068)) | ||||
| 
 | ||||
| #define AR_INPUT_STATE                           (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c) | ||||
| #define AR_INPUT_STATE                           (AR_SREV_9340(ah) ? 0x4054 : \ | ||||
| 						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c)) | ||||
| 
 | ||||
| #define AR_EEPROM_STATUS_DATA                    (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c) | ||||
| #define AR_EEPROM_STATUS_DATA                    (AR_SREV_9340(ah) ? 0x40c8 : \ | ||||
| 						  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c)) | ||||
| #define AR_EEPROM_STATUS_DATA_VAL                0x0000ffff | ||||
| #define AR_EEPROM_STATUS_DATA_VAL_S              0 | ||||
| #define AR_EEPROM_STATUS_DATA_BUSY               0x00010000 | ||||
|  | @ -1072,17 +1089,19 @@ enum { | |||
| #define AR_EEPROM_STATUS_DATA_PROT_ACCESS        0x00040000 | ||||
| #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS      0x00080000 | ||||
| 
 | ||||
| #define AR_OBS                  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080) | ||||
| #define AR_OBS                  (AR_SREV_9340(ah) ? 0x405c : \ | ||||
| 				 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080)) | ||||
| 
 | ||||
| #define AR_GPIO_PDPU                             (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088) | ||||
| 
 | ||||
| #define AR_PCIE_MSI                              (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094) | ||||
| #define AR_PCIE_MSI                             (AR_SREV_9340(ah) ? 0x40d8 : \ | ||||
| 						 (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)) | ||||
| #define AR_PCIE_MSI_ENABLE                       0x00000001 | ||||
| 
 | ||||
| #define AR_INTR_PRIO_SYNC_ENABLE  0x40c4 | ||||
| #define AR_INTR_PRIO_ASYNC_MASK   0x40c8 | ||||
| #define AR_INTR_PRIO_SYNC_MASK    0x40cc | ||||
| #define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4 | ||||
| #define AR_INTR_PRIO_SYNC_ENABLE  (AR_SREV_9340(ah) ? 0x4088 : 0x40c4) | ||||
| #define AR_INTR_PRIO_ASYNC_MASK   (AR_SREV_9340(ah) ? 0x408c : 0x40c8) | ||||
| #define AR_INTR_PRIO_SYNC_MASK    (AR_SREV_9340(ah) ? 0x4090 : 0x40cc) | ||||
| #define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4) | ||||
| #define AR_ENT_OTP		  0x40d8 | ||||
| #define AR_ENT_OTP_CHAIN2_DISABLE               0x00020000 | ||||
| #define AR_ENT_OTP_MPSD		0x00800000 | ||||
|  | @ -1163,6 +1182,7 @@ enum { | |||
| #define AR_RTC_PLL_REFDIV_5     0x000000c0 | ||||
| #define AR_RTC_PLL_CLKSEL       0x00000300 | ||||
| #define AR_RTC_PLL_CLKSEL_S     8 | ||||
| #define AR_RTC_PLL_BYPASS	0x00010000 | ||||
| 
 | ||||
| #define PLL3 0x16188 | ||||
| #define PLL3_DO_MEAS_MASK 0x40000000 | ||||
|  | @ -1209,7 +1229,8 @@ enum { | |||
| 
 | ||||
| /* RTC_DERIVED_* - only for AR9100 */ | ||||
| 
 | ||||
| #define AR_RTC_DERIVED_CLK           (AR_RTC_BASE + 0x0038) | ||||
| #define AR_RTC_DERIVED_CLK \ | ||||
| 	(AR_SREV_9100(ah) ? (AR_RTC_BASE + 0x0038) : 0x7038) | ||||
| #define AR_RTC_DERIVED_CLK_PERIOD    0x0000fffe | ||||
| #define AR_RTC_DERIVED_CLK_PERIOD_S  1 | ||||
| 
 | ||||
|  | @ -1688,6 +1709,22 @@ enum { | |||
| #define AR_BTCOEX_WL_WGHT          0xffff0000 | ||||
| #define AR_BTCOEX_WL_WGHT_S        16 | ||||
| 
 | ||||
| #define AR_BT_COEX_WL_WEIGHTS0     0x8174 | ||||
| #define AR_BT_COEX_WL_WEIGHTS1     0x81c4 | ||||
| 
 | ||||
| #define AR_BT_COEX_BT_WEIGHTS0     0x83ac | ||||
| #define AR_BT_COEX_BT_WEIGHTS1     0x83b0 | ||||
| #define AR_BT_COEX_BT_WEIGHTS2     0x83b4 | ||||
| #define AR_BT_COEX_BT_WEIGHTS3     0x83b8 | ||||
| 
 | ||||
| #define AR9300_BT_WGHT                     0xcccc4444 | ||||
| #define AR9300_STOMP_ALL_WLAN_WGHT0        0xfffffff0 | ||||
| #define AR9300_STOMP_ALL_WLAN_WGHT1        0xfffffff0 | ||||
| #define AR9300_STOMP_LOW_WLAN_WGHT0        0x88888880 | ||||
| #define AR9300_STOMP_LOW_WLAN_WGHT1        0x88888880 | ||||
| #define AR9300_STOMP_NONE_WLAN_WGHT0       0x00000000 | ||||
| #define AR9300_STOMP_NONE_WLAN_WGHT1       0x00000000 | ||||
| 
 | ||||
| #define AR_BT_COEX_MODE2           0x817c | ||||
| #define AR_BT_BCN_MISS_THRESH      0x000000ff | ||||
| #define AR_BT_BCN_MISS_THRESH_S    0 | ||||
|  |  | |||
|  | @ -79,8 +79,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | |||
| 		return "WMI_TX_STATS_CMDID"; | ||||
| 	case WMI_RX_STATS_CMDID: | ||||
| 		return "WMI_RX_STATS_CMDID"; | ||||
| 	case WMI_AGGR_LIMIT_CMD: | ||||
| 		return "WMI_AGGR_LIMIT_CMD"; | ||||
| 	case WMI_BITRATE_MASK_CMDID: | ||||
| 		return "WMI_BITRATE_MASK_CMDID"; | ||||
| 	} | ||||
| 
 | ||||
| 	return "Bogus"; | ||||
|  |  | |||
|  | @ -111,7 +111,7 @@ enum wmi_cmd_id { | |||
| 	WMI_INT_STATS_CMDID, | ||||
| 	WMI_TX_STATS_CMDID, | ||||
| 	WMI_RX_STATS_CMDID, | ||||
| 	WMI_AGGR_LIMIT_CMD = 0x0026, | ||||
| 	WMI_BITRATE_MASK_CMDID, | ||||
| }; | ||||
| 
 | ||||
| enum wmi_event_id { | ||||
|  |  | |||
|  | @ -2180,28 +2180,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void ath_hw_pll_work(struct work_struct *work) | ||||
| { | ||||
| 	struct ath_softc *sc = container_of(work, struct ath_softc, | ||||
| 					    hw_pll_work.work); | ||||
| 	static int count; | ||||
| 
 | ||||
| 	if (AR_SREV_9485(sc->sc_ah)) { | ||||
| 		if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) { | ||||
| 			count++; | ||||
| 
 | ||||
| 			if (count == 3) { | ||||
| 				/* Rx is hung for more than 500ms. Reset it */ | ||||
| 				ath_reset(sc, true); | ||||
| 				count = 0; | ||||
| 			} | ||||
| 		} else | ||||
| 			count = 0; | ||||
| 
 | ||||
| 		ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void ath_tx_complete_poll_work(struct work_struct *work) | ||||
| { | ||||
| 	struct ath_softc *sc = container_of(work, struct ath_softc, | ||||
|  | @ -2396,7 +2374,6 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
| 	} | ||||
| 
 | ||||
| 	INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); | ||||
| 	INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); | ||||
| 
 | ||||
| 	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | ||||
| 		error = ath_tx_edma_init(sc); | ||||
|  |  | |||
|  | @ -448,6 +448,8 @@ struct carl9170_ba_stats { | |||
| 
 | ||||
| struct carl9170_sta_info { | ||||
| 	bool ht_sta; | ||||
| 	bool sleeping; | ||||
| 	atomic_t pending_frames; | ||||
| 	unsigned int ampdu_max_len; | ||||
| 	struct carl9170_sta_tid *agg[CARL9170_NUM_TID]; | ||||
| 	struct carl9170_ba_stats stats[CARL9170_NUM_TID]; | ||||
|  |  | |||
|  | @ -1193,6 +1193,8 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw, | |||
| 	struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; | ||||
| 	unsigned int i; | ||||
| 
 | ||||
| 	atomic_set(&sta_info->pending_frames, 0); | ||||
| 
 | ||||
| 	if (sta->ht_cap.ht_supported) { | ||||
| 		if (sta->ht_cap.ampdu_density > 6) { | ||||
| 			/*
 | ||||
|  | @ -1467,99 +1469,17 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw, | |||
| 				   enum sta_notify_cmd cmd, | ||||
| 				   struct ieee80211_sta *sta) | ||||
| { | ||||
| 	struct ar9170 *ar = hw->priv; | ||||
| 	struct carl9170_sta_info *sta_info = (void *) sta->drv_priv; | ||||
| 	struct sk_buff *skb, *tmp; | ||||
| 	struct sk_buff_head free; | ||||
| 	int i; | ||||
| 
 | ||||
| 	switch (cmd) { | ||||
| 	case STA_NOTIFY_SLEEP: | ||||
| 		/*
 | ||||
| 		 * Since the peer is no longer listening, we have to return | ||||
| 		 * as many SKBs as possible back to the mac80211 stack. | ||||
| 		 * It will deal with the retry procedure, once the peer | ||||
| 		 * has become available again. | ||||
| 		 * | ||||
| 		 * NB: Ideally, the driver should return the all frames in | ||||
| 		 * the correct, ascending order. However, I think that this | ||||
| 		 * functionality should be implemented in the stack and not | ||||
| 		 * here... | ||||
| 		 */ | ||||
| 
 | ||||
| 		__skb_queue_head_init(&free); | ||||
| 
 | ||||
| 		if (sta->ht_cap.ht_supported) { | ||||
| 			rcu_read_lock(); | ||||
| 			for (i = 0; i < CARL9170_NUM_TID; i++) { | ||||
| 				struct carl9170_sta_tid *tid_info; | ||||
| 
 | ||||
| 				tid_info = rcu_dereference(sta_info->agg[i]); | ||||
| 
 | ||||
| 				if (!tid_info) | ||||
| 					continue; | ||||
| 
 | ||||
| 				spin_lock_bh(&ar->tx_ampdu_list_lock); | ||||
| 				if (tid_info->state > | ||||
| 				    CARL9170_TID_STATE_SUSPEND) | ||||
| 					tid_info->state = | ||||
| 						CARL9170_TID_STATE_SUSPEND; | ||||
| 				spin_unlock_bh(&ar->tx_ampdu_list_lock); | ||||
| 
 | ||||
| 				spin_lock_bh(&tid_info->lock); | ||||
| 				while ((skb = __skb_dequeue(&tid_info->queue))) | ||||
| 					__skb_queue_tail(&free, skb); | ||||
| 				spin_unlock_bh(&tid_info->lock); | ||||
| 			} | ||||
| 			rcu_read_unlock(); | ||||
| 		} | ||||
| 
 | ||||
| 		for (i = 0; i < ar->hw->queues; i++) { | ||||
| 			spin_lock_bh(&ar->tx_pending[i].lock); | ||||
| 			skb_queue_walk_safe(&ar->tx_pending[i], skb, tmp) { | ||||
| 				struct _carl9170_tx_superframe *super; | ||||
| 				struct ieee80211_hdr *hdr; | ||||
| 				struct ieee80211_tx_info *info; | ||||
| 
 | ||||
| 				super = (void *) skb->data; | ||||
| 				hdr = (void *) super->frame_data; | ||||
| 
 | ||||
| 				if (compare_ether_addr(hdr->addr1, sta->addr)) | ||||
| 					continue; | ||||
| 
 | ||||
| 				__skb_unlink(skb, &ar->tx_pending[i]); | ||||
| 
 | ||||
| 				info = IEEE80211_SKB_CB(skb); | ||||
| 				if (info->flags & IEEE80211_TX_CTL_AMPDU) | ||||
| 					atomic_dec(&ar->tx_ampdu_upload); | ||||
| 
 | ||||
| 				carl9170_tx_status(ar, skb, false); | ||||
| 			} | ||||
| 			spin_unlock_bh(&ar->tx_pending[i].lock); | ||||
| 		} | ||||
| 
 | ||||
| 		while ((skb = __skb_dequeue(&free))) | ||||
| 			carl9170_tx_status(ar, skb, false); | ||||
| 
 | ||||
| 		sta_info->sleeping = true; | ||||
| 		if (atomic_read(&sta_info->pending_frames)) | ||||
| 			ieee80211_sta_block_awake(hw, sta, true); | ||||
| 		break; | ||||
| 
 | ||||
| 	case STA_NOTIFY_AWAKE: | ||||
| 		if (!sta->ht_cap.ht_supported) | ||||
| 			return; | ||||
| 
 | ||||
| 		rcu_read_lock(); | ||||
| 		for (i = 0; i < CARL9170_NUM_TID; i++) { | ||||
| 			struct carl9170_sta_tid *tid_info; | ||||
| 
 | ||||
| 			tid_info = rcu_dereference(sta_info->agg[i]); | ||||
| 
 | ||||
| 			if (!tid_info) | ||||
| 				continue; | ||||
| 
 | ||||
| 			if ((tid_info->state == CARL9170_TID_STATE_SUSPEND)) | ||||
| 				tid_info->state = CARL9170_TID_STATE_IDLE; | ||||
| 		} | ||||
| 		rcu_read_unlock(); | ||||
| 		sta_info->sleeping = false; | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -104,6 +104,56 @@ static void carl9170_tx_accounting(struct ar9170 *ar, struct sk_buff *skb) | |||
| 	spin_unlock_bh(&ar->tx_stats_lock); | ||||
| } | ||||
| 
 | ||||
| /* needs rcu_read_lock */ | ||||
| static struct ieee80211_sta *__carl9170_get_tx_sta(struct ar9170 *ar, | ||||
| 						   struct sk_buff *skb) | ||||
| { | ||||
| 	struct _carl9170_tx_superframe *super = (void *) skb->data; | ||||
| 	struct ieee80211_hdr *hdr = (void *) super->frame_data; | ||||
| 	struct ieee80211_vif *vif; | ||||
| 	unsigned int vif_id; | ||||
| 
 | ||||
| 	vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >> | ||||
| 		 CARL9170_TX_SUPER_MISC_VIF_ID_S; | ||||
| 
 | ||||
| 	if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC)) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	vif = rcu_dereference(ar->vif_priv[vif_id].vif); | ||||
| 	if (unlikely(!vif)) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Normally we should use wrappers like ieee80211_get_DA to get | ||||
| 	 * the correct peer ieee80211_sta. | ||||
| 	 * | ||||
| 	 * But there is a problem with indirect traffic (broadcasts, or | ||||
| 	 * data which is designated for other stations) in station mode. | ||||
| 	 * The frame will be directed to the AP for distribution and not | ||||
| 	 * to the actual destination. | ||||
| 	 */ | ||||
| 
 | ||||
| 	return ieee80211_find_sta(vif, hdr->addr1); | ||||
| } | ||||
| 
 | ||||
| static void carl9170_tx_ps_unblock(struct ar9170 *ar, struct sk_buff *skb) | ||||
| { | ||||
| 	struct ieee80211_sta *sta; | ||||
| 	struct carl9170_sta_info *sta_info; | ||||
| 
 | ||||
| 	rcu_read_lock(); | ||||
| 	sta = __carl9170_get_tx_sta(ar, skb); | ||||
| 	if (unlikely(!sta)) | ||||
| 		goto out_rcu; | ||||
| 
 | ||||
| 	sta_info = (struct carl9170_sta_info *) sta->drv_priv; | ||||
| 	if (atomic_dec_return(&sta_info->pending_frames) == 0) | ||||
| 		ieee80211_sta_block_awake(ar->hw, sta, false); | ||||
| 
 | ||||
| out_rcu: | ||||
| 	rcu_read_unlock(); | ||||
| } | ||||
| 
 | ||||
| static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) | ||||
| { | ||||
| 	struct ieee80211_tx_info *txinfo; | ||||
|  | @ -135,6 +185,7 @@ static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb) | |||
| 	} | ||||
| 
 | ||||
| 	spin_unlock_bh(&ar->tx_stats_lock); | ||||
| 
 | ||||
| 	if (atomic_dec_and_test(&ar->tx_total_queued)) | ||||
| 		complete(&ar->tx_flush); | ||||
| } | ||||
|  | @ -329,13 +380,10 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, | |||
| { | ||||
| 	struct _carl9170_tx_superframe *super = (void *) skb->data; | ||||
| 	struct ieee80211_hdr *hdr = (void *) super->frame_data; | ||||
| 	struct ieee80211_tx_info *tx_info; | ||||
| 	struct carl9170_tx_info *ar_info; | ||||
| 	struct carl9170_sta_info *sta_info; | ||||
| 	struct ieee80211_sta *sta; | ||||
| 	struct carl9170_sta_info *sta_info; | ||||
| 	struct carl9170_sta_tid *tid_info; | ||||
| 	struct ieee80211_vif *vif; | ||||
| 	unsigned int vif_id; | ||||
| 	u8 tid; | ||||
| 
 | ||||
| 	if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) || | ||||
|  | @ -343,30 +391,10 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar, | |||
| 	   (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR)))) | ||||
| 		return; | ||||
| 
 | ||||
| 	tx_info = IEEE80211_SKB_CB(skb); | ||||
| 	ar_info = (void *) tx_info->rate_driver_data; | ||||
| 
 | ||||
| 	vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >> | ||||
| 		 CARL9170_TX_SUPER_MISC_VIF_ID_S; | ||||
| 
 | ||||
| 	if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC)) | ||||
| 		return; | ||||
| 	ar_info = (void *) txinfo->rate_driver_data; | ||||
| 
 | ||||
| 	rcu_read_lock(); | ||||
| 	vif = rcu_dereference(ar->vif_priv[vif_id].vif); | ||||
| 	if (unlikely(!vif)) | ||||
| 		goto out_rcu; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Normally we should use wrappers like ieee80211_get_DA to get | ||||
| 	 * the correct peer ieee80211_sta. | ||||
| 	 * | ||||
| 	 * But there is a problem with indirect traffic (broadcasts, or | ||||
| 	 * data which is designated for other stations) in station mode. | ||||
| 	 * The frame will be directed to the AP for distribution and not | ||||
| 	 * to the actual destination. | ||||
| 	 */ | ||||
| 	sta = ieee80211_find_sta(vif, hdr->addr1); | ||||
| 	sta = __carl9170_get_tx_sta(ar, skb); | ||||
| 	if (unlikely(!sta)) | ||||
| 		goto out_rcu; | ||||
| 
 | ||||
|  | @ -427,6 +455,7 @@ void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, | |||
| 	if (txinfo->flags & IEEE80211_TX_CTL_AMPDU) | ||||
| 		carl9170_tx_status_process_ampdu(ar, skb, txinfo); | ||||
| 
 | ||||
| 	carl9170_tx_ps_unblock(ar, skb); | ||||
| 	carl9170_tx_put_skb(skb); | ||||
| } | ||||
| 
 | ||||
|  | @ -540,11 +569,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar) | |||
| 	struct sk_buff *skb; | ||||
| 	struct ieee80211_tx_info *txinfo; | ||||
| 	struct carl9170_tx_info *arinfo; | ||||
| 	struct _carl9170_tx_superframe *super; | ||||
| 	struct ieee80211_sta *sta; | ||||
| 	struct ieee80211_vif *vif; | ||||
| 	struct ieee80211_hdr *hdr; | ||||
| 	unsigned int vif_id; | ||||
| 
 | ||||
| 	rcu_read_lock(); | ||||
| 	list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) { | ||||
|  | @ -562,20 +587,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar) | |||
| 		    msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT))) | ||||
| 			goto unlock; | ||||
| 
 | ||||
| 		super = (void *) skb->data; | ||||
| 		hdr = (void *) super->frame_data; | ||||
| 
 | ||||
| 		vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >> | ||||
| 			 CARL9170_TX_SUPER_MISC_VIF_ID_S; | ||||
| 
 | ||||
| 		if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC)) | ||||
| 			goto unlock; | ||||
| 
 | ||||
| 		vif = rcu_dereference(ar->vif_priv[vif_id].vif); | ||||
| 		if (WARN_ON(!vif)) | ||||
| 			goto unlock; | ||||
| 
 | ||||
| 		sta = ieee80211_find_sta(vif, hdr->addr1); | ||||
| 		sta = __carl9170_get_tx_sta(ar, skb); | ||||
| 		if (WARN_ON(!sta)) | ||||
| 			goto unlock; | ||||
| 
 | ||||
|  | @ -1199,15 +1211,6 @@ static struct sk_buff *carl9170_tx_pick_skb(struct ar9170 *ar, | |||
| 	arinfo = (void *) info->rate_driver_data; | ||||
| 
 | ||||
| 	arinfo->timeout = jiffies; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * increase ref count to "2". | ||||
| 	 * Ref counting is the easiest way to solve the race between | ||||
| 	 * the the urb's completion routine: carl9170_tx_callback and | ||||
| 	 * wlan tx status functions: carl9170_tx_status/janitor. | ||||
| 	 */ | ||||
| 	carl9170_tx_get_skb(skb); | ||||
| 
 | ||||
| 	return skb; | ||||
| 
 | ||||
| err_unlock: | ||||
|  | @ -1228,6 +1231,36 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb) | |||
| 	__carl9170_tx_process_status(ar, super->s.cookie, q); | ||||
| } | ||||
| 
 | ||||
| static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb) | ||||
| { | ||||
| 	struct ieee80211_sta *sta; | ||||
| 	struct carl9170_sta_info *sta_info; | ||||
| 
 | ||||
| 	rcu_read_lock(); | ||||
| 	sta = __carl9170_get_tx_sta(ar, skb); | ||||
| 	if (!sta) | ||||
| 		goto out_rcu; | ||||
| 
 | ||||
| 	sta_info = (void *) sta->drv_priv; | ||||
| 	if (unlikely(sta_info->sleeping)) { | ||||
| 		struct ieee80211_tx_info *tx_info; | ||||
| 
 | ||||
| 		rcu_read_unlock(); | ||||
| 
 | ||||
| 		tx_info = IEEE80211_SKB_CB(skb); | ||||
| 		if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) | ||||
| 			atomic_dec(&ar->tx_ampdu_upload); | ||||
| 
 | ||||
| 		tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | ||||
| 		carl9170_tx_status(ar, skb, false); | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| out_rcu: | ||||
| 	rcu_read_unlock(); | ||||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| static void carl9170_tx(struct ar9170 *ar) | ||||
| { | ||||
| 	struct sk_buff *skb; | ||||
|  | @ -1247,6 +1280,9 @@ static void carl9170_tx(struct ar9170 *ar) | |||
| 			if (unlikely(!skb)) | ||||
| 				break; | ||||
| 
 | ||||
| 			if (unlikely(carl9170_tx_ps_drop(ar, skb))) | ||||
| 				continue; | ||||
| 
 | ||||
| 			atomic_inc(&ar->tx_total_pending); | ||||
| 
 | ||||
| 			q = __carl9170_get_queue(ar, i); | ||||
|  | @ -1256,6 +1292,16 @@ static void carl9170_tx(struct ar9170 *ar) | |||
| 			 */ | ||||
| 			skb_queue_tail(&ar->tx_status[q], skb); | ||||
| 
 | ||||
| 			/*
 | ||||
| 			 * increase ref count to "2". | ||||
| 			 * Ref counting is the easiest way to solve the | ||||
| 			 * race between the urb's completion routine: | ||||
| 			 *	carl9170_tx_callback | ||||
| 			 * and wlan tx status functions: | ||||
| 			 *	carl9170_tx_status/janitor. | ||||
| 			 */ | ||||
| 			carl9170_tx_get_skb(skb); | ||||
| 
 | ||||
| 			carl9170_usb_tx(ar, skb); | ||||
| 			schedule_garbagecollector = true; | ||||
| 		} | ||||
|  | @ -1368,6 +1414,11 @@ void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
| 	 * all ressouces which are associated with the frame. | ||||
| 	 */ | ||||
| 
 | ||||
| 	if (sta) { | ||||
| 		struct carl9170_sta_info *stai = (void *) sta->drv_priv; | ||||
| 		atomic_inc(&stai->pending_frames); | ||||
| 	} | ||||
| 
 | ||||
| 	if (info->flags & IEEE80211_TX_CTL_AMPDU) { | ||||
| 		run = carl9170_tx_ampdu_queue(ar, sta, skb); | ||||
| 		if (run) | ||||
|  |  | |||
|  | @ -2281,6 +2281,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, | |||
| 		save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); | ||||
| 		save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); | ||||
| 		save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1); | ||||
| 		save_regs_phy[8] = 0; | ||||
| 	} else { | ||||
| 		save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); | ||||
| 		save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); | ||||
|  | @ -2289,6 +2290,8 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, | |||
| 		save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER); | ||||
| 		save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1); | ||||
| 		save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2); | ||||
| 		save_regs_phy[7] = 0; | ||||
| 		save_regs_phy[8] = 0; | ||||
| 	} | ||||
| 
 | ||||
| 	b43_nphy_rssi_select(dev, 5, type); | ||||
|  | @ -3845,8 +3848,8 @@ static int b43_nphy_set_channel(struct b43_wldev *dev, | |||
| { | ||||
| 	struct b43_phy *phy = &dev->phy; | ||||
| 
 | ||||
| 	const struct b43_nphy_channeltab_entry_rev2 *tabent_r2; | ||||
| 	const struct b43_nphy_channeltab_entry_rev3 *tabent_r3; | ||||
| 	const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL; | ||||
| 	const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL; | ||||
| 
 | ||||
| 	u8 tmp; | ||||
| 
 | ||||
|  |  | |||
|  | @ -955,9 +955,6 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
| 	if (priv->cfg->scan_rx_antennas[band]) | ||||
| 		rx_ant = priv->cfg->scan_rx_antennas[band]; | ||||
| 
 | ||||
| 	if (priv->cfg->scan_tx_antennas[band]) | ||||
| 		scan_tx_antennas = priv->cfg->scan_tx_antennas[band]; | ||||
| 
 | ||||
| 	priv->scan_tx_ant[band] = iwl4965_toggle_tx_ant(priv, | ||||
| 						priv->scan_tx_ant[band], | ||||
| 						    scan_tx_antennas); | ||||
|  |  | |||
|  | @ -211,10 +211,7 @@ int iwl_legacy_init_geos(struct iwl_priv *priv) | |||
| 		if (!iwl_legacy_is_channel_valid(ch)) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (iwl_legacy_is_channel_a_band(ch)) | ||||
| 			sband =  &priv->bands[IEEE80211_BAND_5GHZ]; | ||||
| 		else | ||||
| 			sband =  &priv->bands[IEEE80211_BAND_2GHZ]; | ||||
| 		sband = &priv->bands[ch->band]; | ||||
| 
 | ||||
| 		geo_ch = &sband->channels[sband->n_channels++]; | ||||
| 
 | ||||
|  | @ -2117,10 +2114,9 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed) | |||
| 	IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n", | ||||
| 					channel->hw_value, changed); | ||||
| 
 | ||||
| 	if (unlikely(!priv->cfg->mod_params->disable_hw_scan && | ||||
| 			test_bit(STATUS_SCANNING, &priv->status))) { | ||||
| 	if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) { | ||||
| 		scan_active = 1; | ||||
| 		IWL_DEBUG_MAC80211(priv, "leave - scanning\n"); | ||||
| 		IWL_DEBUG_MAC80211(priv, "scan active\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	if (changed & (IEEE80211_CONF_CHANGE_SMPS | | ||||
|  | @ -2433,11 +2429,13 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw, | |||
| 
 | ||||
| 	IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); | ||||
| 
 | ||||
| 	if (!iwl_legacy_is_alive(priv)) | ||||
| 		return; | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 
 | ||||
| 	if (!iwl_legacy_is_alive(priv)) { | ||||
| 		mutex_unlock(&priv->mutex); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (changes & BSS_CHANGED_QOS) { | ||||
| 		unsigned long flags; | ||||
| 
 | ||||
|  | @ -2646,7 +2644,7 @@ unplugged: | |||
| 
 | ||||
| none: | ||||
| 	/* re-enable interrupts here since we don't have anything to service. */ | ||||
| 	/* only Re-enable if diabled by irq */ | ||||
| 	/* only Re-enable if disabled by irq */ | ||||
| 	if (test_bit(STATUS_INT_ENABLED, &priv->status)) | ||||
| 		iwl_legacy_enable_interrupts(priv); | ||||
| 	spin_unlock_irqrestore(&priv->lock, flags); | ||||
|  |  | |||
|  | @ -287,7 +287,6 @@ struct iwl_cfg { | |||
| 	struct iwl_base_params *base_params; | ||||
| 	/* params likely to change within a device family */ | ||||
| 	u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; | ||||
| 	u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; | ||||
| 	enum iwl_led_mode led_mode; | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -134,7 +134,7 @@ struct iwl_queue { | |||
| 				* space more than this */ | ||||
| 	int high_mark;         /* high watermark, stop queue if free
 | ||||
| 				* space less than this */ | ||||
| } __packed; | ||||
| }; | ||||
| 
 | ||||
| /* One for each TFD */ | ||||
| struct iwl_tx_info { | ||||
|  | @ -290,6 +290,7 @@ enum { | |||
| 	CMD_SIZE_HUGE = (1 << 0), | ||||
| 	CMD_ASYNC = (1 << 1), | ||||
| 	CMD_WANT_SKB = (1 << 2), | ||||
| 	CMD_MAPPED = (1 << 3), | ||||
| }; | ||||
| 
 | ||||
| #define DEF_CMD_PAYLOAD_SIZE 320 | ||||
|  | @ -1076,7 +1077,6 @@ struct iwl_priv { | |||
| 	spinlock_t hcmd_lock;	/* protect hcmd */ | ||||
| 	spinlock_t reg_lock;	/* protect hw register access */ | ||||
| 	struct mutex mutex; | ||||
| 	struct mutex sync_cmd_mutex; /* enable serialization of sync commands */ | ||||
| 
 | ||||
| 	/* basic pci-network driver stuff */ | ||||
| 	struct pci_dev *pci_dev; | ||||
|  |  | |||
|  | @ -145,6 +145,8 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
| 	int cmd_idx; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	lockdep_assert_held(&priv->mutex); | ||||
| 
 | ||||
| 	BUG_ON(cmd->flags & CMD_ASYNC); | ||||
| 
 | ||||
| 	 /* A synchronous command can not have a callback set. */ | ||||
|  | @ -152,7 +154,6 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
| 
 | ||||
| 	IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n", | ||||
| 			iwl_legacy_get_cmd_string(cmd->id)); | ||||
| 	mutex_lock(&priv->sync_cmd_mutex); | ||||
| 
 | ||||
| 	set_bit(STATUS_HCMD_ACTIVE, &priv->status); | ||||
| 	IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n", | ||||
|  | @ -224,7 +225,6 @@ fail: | |||
| 		cmd->reply_page = 0; | ||||
| 	} | ||||
| out: | ||||
| 	mutex_unlock(&priv->sync_cmd_mutex); | ||||
| 	return ret; | ||||
| } | ||||
| EXPORT_SYMBOL(iwl_legacy_send_cmd_sync); | ||||
|  |  | |||
|  | @ -149,6 +149,12 @@ static inline void iwl_legacy_disable_interrupts(struct iwl_priv *priv) | |||
| 	IWL_DEBUG_ISR(priv, "Disabled interrupts\n"); | ||||
| } | ||||
| 
 | ||||
| static inline void iwl_legacy_enable_rfkill_int(struct iwl_priv *priv) | ||||
| { | ||||
| 	IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n"); | ||||
| 	iwl_write32(priv, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); | ||||
| } | ||||
| 
 | ||||
| static inline void iwl_legacy_enable_interrupts(struct iwl_priv *priv) | ||||
| { | ||||
| 	IWL_DEBUG_ISR(priv, "Enabling interrupts\n"); | ||||
|  |  | |||
|  | @ -146,33 +146,32 @@ void iwl_legacy_cmd_queue_unmap(struct iwl_priv *priv) | |||
| { | ||||
| 	struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; | ||||
| 	struct iwl_queue *q = &txq->q; | ||||
| 	bool huge = false; | ||||
| 	int i; | ||||
| 
 | ||||
| 	if (q->n_bd == 0) | ||||
| 		return; | ||||
| 
 | ||||
| 	while (q->read_ptr != q->write_ptr) { | ||||
| 		/* we have no way to tell if it is a huge cmd ATM */ | ||||
| 		i = iwl_legacy_get_cmd_index(q, q->read_ptr, 0); | ||||
| 
 | ||||
| 		if (txq->meta[i].flags & CMD_SIZE_HUGE) | ||||
| 			huge = true; | ||||
| 		else | ||||
| 		if (txq->meta[i].flags & CMD_MAPPED) { | ||||
| 			pci_unmap_single(priv->pci_dev, | ||||
| 					 dma_unmap_addr(&txq->meta[i], mapping), | ||||
| 					 dma_unmap_len(&txq->meta[i], len), | ||||
| 					 PCI_DMA_BIDIRECTIONAL); | ||||
| 			txq->meta[i].flags = 0; | ||||
| 		} | ||||
| 
 | ||||
| 		q->read_ptr = iwl_legacy_queue_inc_wrap(q->read_ptr, q->n_bd); | ||||
| 	} | ||||
| 
 | ||||
| 	if (huge) { | ||||
| 		i = q->n_window; | ||||
| 	i = q->n_window; | ||||
| 	if (txq->meta[i].flags & CMD_MAPPED) { | ||||
| 		pci_unmap_single(priv->pci_dev, | ||||
| 				 dma_unmap_addr(&txq->meta[i], mapping), | ||||
| 				 dma_unmap_len(&txq->meta[i], len), | ||||
| 				 PCI_DMA_BIDIRECTIONAL); | ||||
| 		txq->meta[i].flags = 0; | ||||
| 	} | ||||
| } | ||||
| EXPORT_SYMBOL(iwl_legacy_cmd_queue_unmap); | ||||
|  | @ -467,29 +466,27 @@ int iwl_legacy_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
| 		return -EIO; | ||||
| 	} | ||||
| 
 | ||||
| 	if (iwl_legacy_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { | ||||
| 		IWL_ERR(priv, "No space in command queue\n"); | ||||
| 		IWL_ERR(priv, "Restarting adapter due to queue full\n"); | ||||
| 		queue_work(priv->workqueue, &priv->restart); | ||||
| 		return -ENOSPC; | ||||
| 	} | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->hcmd_lock, flags); | ||||
| 
 | ||||
| 	/* If this is a huge cmd, mark the huge flag also on the meta.flags
 | ||||
| 	 * of the _original_ cmd. This is used for DMA mapping clean up. | ||||
| 	 */ | ||||
| 	if (cmd->flags & CMD_SIZE_HUGE) { | ||||
| 		idx = iwl_legacy_get_cmd_index(q, q->write_ptr, 0); | ||||
| 		txq->meta[idx].flags = CMD_SIZE_HUGE; | ||||
| 	if (iwl_legacy_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) { | ||||
| 		spin_unlock_irqrestore(&priv->hcmd_lock, flags); | ||||
| 
 | ||||
| 		IWL_ERR(priv, "Restarting adapter due to command queue full\n"); | ||||
| 		queue_work(priv->workqueue, &priv->restart); | ||||
| 		return -ENOSPC; | ||||
| 	} | ||||
| 
 | ||||
| 	idx = iwl_legacy_get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE); | ||||
| 	out_cmd = txq->cmd[idx]; | ||||
| 	out_meta = &txq->meta[idx]; | ||||
| 
 | ||||
| 	if (WARN_ON(out_meta->flags & CMD_MAPPED)) { | ||||
| 		spin_unlock_irqrestore(&priv->hcmd_lock, flags); | ||||
| 		return -ENOSPC; | ||||
| 	} | ||||
| 
 | ||||
| 	memset(out_meta, 0, sizeof(*out_meta));	/* re-initialize to NULL */ | ||||
| 	out_meta->flags = cmd->flags; | ||||
| 	out_meta->flags = cmd->flags | CMD_MAPPED; | ||||
| 	if (cmd->flags & CMD_WANT_SKB) | ||||
| 		out_meta->source = cmd; | ||||
| 	if (cmd->flags & CMD_ASYNC) | ||||
|  | @ -610,6 +607,7 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
| 	struct iwl_device_cmd *cmd; | ||||
| 	struct iwl_cmd_meta *meta; | ||||
| 	struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	/* If a Tx command is being handled and it isn't in the actual
 | ||||
| 	 * command queue then there a command routing bug has been introduced | ||||
|  | @ -623,14 +621,6 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	/* If this is a huge cmd, clear the huge flag on the meta.flags
 | ||||
| 	 * of the _original_ cmd. So that iwl_legacy_cmd_queue_free won't unmap | ||||
| 	 * the DMA buffer for the scan (huge) command. | ||||
| 	 */ | ||||
| 	if (huge) { | ||||
| 		cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, 0); | ||||
| 		txq->meta[cmd_index].flags = 0; | ||||
| 	} | ||||
| 	cmd_index = iwl_legacy_get_cmd_index(&txq->q, index, huge); | ||||
| 	cmd = txq->cmd[cmd_index]; | ||||
| 	meta = &txq->meta[cmd_index]; | ||||
|  | @ -647,6 +637,8 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
| 	} else if (meta->callback) | ||||
| 		meta->callback(priv, cmd, pkt); | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->hcmd_lock, flags); | ||||
| 
 | ||||
| 	iwl_legacy_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); | ||||
| 
 | ||||
| 	if (!(meta->flags & CMD_ASYNC)) { | ||||
|  | @ -655,6 +647,10 @@ iwl_legacy_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
| 			       iwl_legacy_get_cmd_string(cmd->hdr.cmd)); | ||||
| 		wake_up_interruptible(&priv->wait_command_queue); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Mark as unmapped */ | ||||
| 	meta->flags = 0; | ||||
| 
 | ||||
| 	spin_unlock_irqrestore(&priv->hcmd_lock, flags); | ||||
| } | ||||
| EXPORT_SYMBOL(iwl_legacy_tx_cmd_complete); | ||||
|  |  | |||
|  | @ -2748,11 +2748,12 @@ static void iwl3945_bg_init_alive_start(struct work_struct *data) | |||
| 	struct iwl_priv *priv = | ||||
| 	    container_of(data, struct iwl_priv, init_alive_start.work); | ||||
| 
 | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 		return; | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	iwl3945_init_alive_start(priv); | ||||
| out: | ||||
| 	mutex_unlock(&priv->mutex); | ||||
| } | ||||
| 
 | ||||
|  | @ -2761,11 +2762,12 @@ static void iwl3945_bg_alive_start(struct work_struct *data) | |||
| 	struct iwl_priv *priv = | ||||
| 	    container_of(data, struct iwl_priv, alive_start.work); | ||||
| 
 | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 		return; | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	iwl3945_alive_start(priv); | ||||
| out: | ||||
| 	mutex_unlock(&priv->mutex); | ||||
| } | ||||
| 
 | ||||
|  | @ -2995,10 +2997,12 @@ static void iwl3945_bg_restart(struct work_struct *data) | |||
| 	} else { | ||||
| 		iwl3945_down(priv); | ||||
| 
 | ||||
| 		if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 			return; | ||||
| 
 | ||||
| 		mutex_lock(&priv->mutex); | ||||
| 		if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||||
| 			mutex_unlock(&priv->mutex); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		__iwl3945_up(priv); | ||||
| 		mutex_unlock(&priv->mutex); | ||||
| 	} | ||||
|  | @ -3009,11 +3013,12 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data) | |||
| 	struct iwl_priv *priv = | ||||
| 	    container_of(data, struct iwl_priv, rx_replenish); | ||||
| 
 | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 		return; | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	iwl3945_rx_replenish(priv); | ||||
| out: | ||||
| 	mutex_unlock(&priv->mutex); | ||||
| } | ||||
| 
 | ||||
|  | @ -3810,7 +3815,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
| 	INIT_LIST_HEAD(&priv->free_frames); | ||||
| 
 | ||||
| 	mutex_init(&priv->mutex); | ||||
| 	mutex_init(&priv->sync_cmd_mutex); | ||||
| 
 | ||||
| 	priv->ieee_channels = NULL; | ||||
| 	priv->ieee_rates = NULL; | ||||
|  |  | |||
|  | @ -1069,9 +1069,12 @@ static void iwl4965_irq_tasklet(struct iwl_priv *priv) | |||
| 	} | ||||
| 
 | ||||
| 	/* Re-enable all interrupts */ | ||||
| 	/* only Re-enable if diabled by irq */ | ||||
| 	/* only Re-enable if disabled by irq */ | ||||
| 	if (test_bit(STATUS_INT_ENABLED, &priv->status)) | ||||
| 		iwl_legacy_enable_interrupts(priv); | ||||
| 	/* Re-enable RF_KILL if it occurred */ | ||||
| 	else if (handled & CSR_INT_BIT_RF_KILL) | ||||
| 		iwl_legacy_enable_rfkill_int(priv); | ||||
| 
 | ||||
| #ifdef CONFIG_IWLWIFI_LEGACY_DEBUG | ||||
| 	if (iwl_legacy_get_debug_level(priv) & (IWL_DL_ISR)) { | ||||
|  | @ -2139,7 +2142,7 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv); | |||
| static void __iwl4965_down(struct iwl_priv *priv) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 	int exit_pending = test_bit(STATUS_EXIT_PENDING, &priv->status); | ||||
| 	int exit_pending; | ||||
| 
 | ||||
| 	IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); | ||||
| 
 | ||||
|  | @ -2401,11 +2404,12 @@ static void iwl4965_bg_init_alive_start(struct work_struct *data) | |||
| 	struct iwl_priv *priv = | ||||
| 	    container_of(data, struct iwl_priv, init_alive_start.work); | ||||
| 
 | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 		return; | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	priv->cfg->ops->lib->init_alive_start(priv); | ||||
| out: | ||||
| 	mutex_unlock(&priv->mutex); | ||||
| } | ||||
| 
 | ||||
|  | @ -2414,11 +2418,12 @@ static void iwl4965_bg_alive_start(struct work_struct *data) | |||
| 	struct iwl_priv *priv = | ||||
| 	    container_of(data, struct iwl_priv, alive_start.work); | ||||
| 
 | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 		return; | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	iwl4965_alive_start(priv); | ||||
| out: | ||||
| 	mutex_unlock(&priv->mutex); | ||||
| } | ||||
| 
 | ||||
|  | @ -2468,10 +2473,12 @@ static void iwl4965_bg_restart(struct work_struct *data) | |||
| 	} else { | ||||
| 		iwl4965_down(priv); | ||||
| 
 | ||||
| 		if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 			return; | ||||
| 
 | ||||
| 		mutex_lock(&priv->mutex); | ||||
| 		if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||||
| 			mutex_unlock(&priv->mutex); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		__iwl4965_up(priv); | ||||
| 		mutex_unlock(&priv->mutex); | ||||
| 	} | ||||
|  | @ -2624,9 +2631,10 @@ void iwl4965_mac_stop(struct ieee80211_hw *hw) | |||
| 
 | ||||
| 	flush_workqueue(priv->workqueue); | ||||
| 
 | ||||
| 	/* enable interrupts again in order to receive rfkill changes */ | ||||
| 	/* User space software may expect getting rfkill changes
 | ||||
| 	 * even if interface is down */ | ||||
| 	iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | ||||
| 	iwl_legacy_enable_interrupts(priv); | ||||
| 	iwl_legacy_enable_rfkill_int(priv); | ||||
| 
 | ||||
| 	IWL_DEBUG_MAC80211(priv, "leave\n"); | ||||
| } | ||||
|  | @ -2847,21 +2855,22 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, | |||
| 
 | ||||
| 	IWL_DEBUG_MAC80211(priv, "enter\n"); | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 
 | ||||
| 	if (iwl_legacy_is_rfkill(priv)) | ||||
| 		goto out_exit; | ||||
| 		goto out; | ||||
| 
 | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status) || | ||||
| 	    test_bit(STATUS_SCANNING, &priv->status)) | ||||
| 		goto out_exit; | ||||
| 		goto out; | ||||
| 
 | ||||
| 	if (!iwl_legacy_is_associated_ctx(ctx)) | ||||
| 		goto out_exit; | ||||
| 		goto out; | ||||
| 
 | ||||
| 	/* channel switch in progress */ | ||||
| 	if (priv->switch_rxon.switch_in_progress == true) | ||||
| 		goto out_exit; | ||||
| 		goto out; | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 	if (priv->cfg->ops->lib->set_channel_switch) { | ||||
| 
 | ||||
| 		ch = channel->hw_value; | ||||
|  | @ -2917,7 +2926,6 @@ void iwl4965_mac_channel_switch(struct ieee80211_hw *hw, | |||
| 	} | ||||
| out: | ||||
| 	mutex_unlock(&priv->mutex); | ||||
| out_exit: | ||||
| 	if (!priv->switch_rxon.switch_in_progress) | ||||
| 		ieee80211_chswitch_done(ctx->vif, false); | ||||
| 	IWL_DEBUG_MAC80211(priv, "leave\n"); | ||||
|  | @ -3116,7 +3124,6 @@ static int iwl4965_init_drv(struct iwl_priv *priv) | |||
| 	INIT_LIST_HEAD(&priv->free_frames); | ||||
| 
 | ||||
| 	mutex_init(&priv->mutex); | ||||
| 	mutex_init(&priv->sync_cmd_mutex); | ||||
| 
 | ||||
| 	priv->ieee_channels = NULL; | ||||
| 	priv->ieee_rates = NULL; | ||||
|  | @ -3406,14 +3413,14 @@ iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 	 * 8. Enable interrupts and read RFKILL state | ||||
| 	 *********************************************/ | ||||
| 
 | ||||
| 	/* enable interrupts if needed: hw bug w/a */ | ||||
| 	/* enable rfkill interrupt: hw bug w/a */ | ||||
| 	pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd); | ||||
| 	if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { | ||||
| 		pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; | ||||
| 		pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd); | ||||
| 	} | ||||
| 
 | ||||
| 	iwl_legacy_enable_interrupts(priv); | ||||
| 	iwl_legacy_enable_rfkill_int(priv); | ||||
| 
 | ||||
| 	/* If platform's RF_KILL switch is NOT set to KILL */ | ||||
| 	if (iwl_read32(priv, CSR_GP_CNTRL) & | ||||
|  |  | |||
|  | @ -14,7 +14,6 @@ iwlagn-objs             += iwl-6000.o | |||
| iwlagn-objs             += iwl-1000.o | ||||
| iwlagn-objs             += iwl-2000.o | ||||
| 
 | ||||
| iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-agn-debugfs.o | ||||
| iwlagn-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | ||||
| iwlagn-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o | ||||
| 
 | ||||
|  |  | |||
|  | @ -45,7 +45,6 @@ | |||
| #include "iwl-agn.h" | ||||
| #include "iwl-helpers.h" | ||||
| #include "iwl-agn-hw.h" | ||||
| #include "iwl-agn-debugfs.h" | ||||
| 
 | ||||
| /* Highest firmware API version supported */ | ||||
| #define IWL1000_UCODE_API_MAX 5 | ||||
|  | @ -121,10 +120,10 @@ static struct iwl_sensitivity_ranges iwl1000_sensitivity = { | |||
| 
 | ||||
| static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) | ||||
| { | ||||
| 	if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && | ||||
| 	    priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) | ||||
| 	if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||||
| 	    iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||||
| 		priv->cfg->base_params->num_of_queues = | ||||
| 			priv->cfg->mod_params->num_of_queues; | ||||
| 			iwlagn_mod_params.num_of_queues; | ||||
| 
 | ||||
| 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; | ||||
| 	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | ||||
|  | @ -197,21 +196,11 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
| 			EEPROM_REG_BAND_24_HT40_CHANNELS, | ||||
| 			EEPROM_REGULATORY_BAND_NO_HT40, | ||||
| 		}, | ||||
| 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||||
| 		.release_semaphore = iwlcore_eeprom_release_semaphore, | ||||
| 		.calib_version	= iwlagn_eeprom_calib_version, | ||||
| 		.query_addr = iwlagn_eeprom_query_addr, | ||||
| 	}, | ||||
| 	.temp_ops = { | ||||
| 		.temperature = iwlagn_temperature, | ||||
| 	 }, | ||||
| 	.debugfs_ops = { | ||||
| 		.rx_stats_read = iwl_ucode_rx_stats_read, | ||||
| 		.tx_stats_read = iwl_ucode_tx_stats_read, | ||||
| 		.general_stats_read = iwl_ucode_general_stats_read, | ||||
| 		.bt_stats_read = iwl_ucode_bt_stats_read, | ||||
| 		.reply_tx_error = iwl_reply_tx_error_read, | ||||
| 	}, | ||||
| 	.txfifo_flush = iwlagn_txfifo_flush, | ||||
| 	.dev_txfifo_flush = iwlagn_dev_txfifo_flush, | ||||
| }; | ||||
|  | @ -249,7 +238,6 @@ static struct iwl_ht_params iwl1000_ht_params = { | |||
| 	.eeprom_ver = EEPROM_1000_EEPROM_VERSION,		\ | ||||
| 	.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,	\ | ||||
| 	.ops = &iwl1000_ops,					\ | ||||
| 	.mod_params = &iwlagn_mod_params,			\ | ||||
| 	.base_params = &iwl1000_base_params,			\ | ||||
| 	.led_mode = IWL_LED_BLINK | ||||
| 
 | ||||
|  | @ -271,7 +259,6 @@ struct iwl_cfg iwl1000_bg_cfg = { | |||
| 	.eeprom_ver = EEPROM_1000_EEPROM_VERSION,		\ | ||||
| 	.eeprom_calib_ver = EEPROM_1000_TX_POWER_VERSION,	\ | ||||
| 	.ops = &iwl1000_ops,					\ | ||||
| 	.mod_params = &iwlagn_mod_params,			\ | ||||
| 	.base_params = &iwl1000_base_params,			\ | ||||
| 	.led_mode = IWL_LED_RF_STATE,				\ | ||||
| 	.rx_with_siso_diversity = true | ||||
|  |  | |||
|  | @ -46,17 +46,16 @@ | |||
| #include "iwl-helpers.h" | ||||
| #include "iwl-agn-hw.h" | ||||
| #include "iwl-6000-hw.h" | ||||
| #include "iwl-agn-debugfs.h" | ||||
| 
 | ||||
| /* Highest firmware API version supported */ | ||||
| #define IWL2030_UCODE_API_MAX 5 | ||||
| #define IWL2000_UCODE_API_MAX 5 | ||||
| #define IWL200_UCODE_API_MAX 5 | ||||
| #define IWL105_UCODE_API_MAX 5 | ||||
| 
 | ||||
| /* Lowest firmware API version supported */ | ||||
| #define IWL2030_UCODE_API_MIN 5 | ||||
| #define IWL2000_UCODE_API_MIN 5 | ||||
| #define IWL200_UCODE_API_MIN 5 | ||||
| #define IWL105_UCODE_API_MIN 5 | ||||
| 
 | ||||
| #define IWL2030_FW_PRE "iwlwifi-2030-" | ||||
| #define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode" | ||||
|  | @ -64,8 +63,8 @@ | |||
| #define IWL2000_FW_PRE "iwlwifi-2000-" | ||||
| #define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode" | ||||
| 
 | ||||
| #define IWL200_FW_PRE "iwlwifi-200-" | ||||
| #define IWL200_MODULE_FIRMWARE(api) IWL200_FW_PRE #api ".ucode" | ||||
| #define IWL105_FW_PRE "iwlwifi-105-" | ||||
| #define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE #api ".ucode" | ||||
| 
 | ||||
| static void iwl2000_set_ct_threshold(struct iwl_priv *priv) | ||||
| { | ||||
|  | @ -128,10 +127,10 @@ static struct iwl_sensitivity_ranges iwl2000_sensitivity = { | |||
| 
 | ||||
| static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) | ||||
| { | ||||
| 	if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && | ||||
| 	    priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) | ||||
| 	if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||||
| 	    iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||||
| 		priv->cfg->base_params->num_of_queues = | ||||
| 			priv->cfg->mod_params->num_of_queues; | ||||
| 			iwlagn_mod_params.num_of_queues; | ||||
| 
 | ||||
| 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; | ||||
| 	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | ||||
|  | @ -280,22 +279,12 @@ static struct iwl_lib_ops iwl2000_lib = { | |||
| 			EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||||
| 			EEPROM_REGULATORY_BAND_NO_HT40, | ||||
| 		}, | ||||
| 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||||
| 		.release_semaphore = iwlcore_eeprom_release_semaphore, | ||||
| 		.calib_version  = iwlagn_eeprom_calib_version, | ||||
| 		.query_addr = iwlagn_eeprom_query_addr, | ||||
| 		.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, | ||||
| 	}, | ||||
| 	.temp_ops = { | ||||
| 		.temperature = iwlagn_temperature, | ||||
| 	}, | ||||
| 	.debugfs_ops = { | ||||
| 		.rx_stats_read = iwl_ucode_rx_stats_read, | ||||
| 		.tx_stats_read = iwl_ucode_tx_stats_read, | ||||
| 		.general_stats_read = iwl_ucode_general_stats_read, | ||||
| 		.bt_stats_read = iwl_ucode_bt_stats_read, | ||||
| 		.reply_tx_error = iwl_reply_tx_error_read, | ||||
| 	}, | ||||
| 	.txfifo_flush = iwlagn_txfifo_flush, | ||||
| 	.dev_txfifo_flush = iwlagn_dev_txfifo_flush, | ||||
| }; | ||||
|  | @ -312,13 +301,13 @@ static const struct iwl_ops iwl2030_ops = { | |||
| 	.utils = &iwlagn_hcmd_utils, | ||||
| }; | ||||
| 
 | ||||
| static const struct iwl_ops iwl200_ops = { | ||||
| static const struct iwl_ops iwl105_ops = { | ||||
| 	.lib = &iwl2000_lib, | ||||
| 	.hcmd = &iwlagn_hcmd, | ||||
| 	.utils = &iwlagn_hcmd_utils, | ||||
| }; | ||||
| 
 | ||||
| static const struct iwl_ops iwl230_ops = { | ||||
| static const struct iwl_ops iwl135_ops = { | ||||
| 	.lib = &iwl2000_lib, | ||||
| 	.hcmd = &iwlagn_bt_hcmd, | ||||
| 	.utils = &iwlagn_hcmd_utils, | ||||
|  | @ -383,7 +372,6 @@ static struct iwl_bt_params iwl2030_bt_params = { | |||
| 	.eeprom_ver = EEPROM_2000_EEPROM_VERSION,		\ | ||||
| 	.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\ | ||||
| 	.ops = &iwl2000_ops,					\ | ||||
| 	.mod_params = &iwlagn_mod_params,			\ | ||||
| 	.base_params = &iwl2000_base_params,			\ | ||||
| 	.need_dc_calib = true,					\ | ||||
| 	.need_temp_offset_calib = true,				\ | ||||
|  | @ -409,7 +397,6 @@ struct iwl_cfg iwl2000_2bg_cfg = { | |||
| 	.eeprom_ver = EEPROM_2000_EEPROM_VERSION,		\ | ||||
| 	.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\ | ||||
| 	.ops = &iwl2030_ops,					\ | ||||
| 	.mod_params = &iwlagn_mod_params,			\ | ||||
| 	.base_params = &iwl2030_base_params,			\ | ||||
| 	.bt_params = &iwl2030_bt_params,			\ | ||||
| 	.need_dc_calib = true,					\ | ||||
|  | @ -429,14 +416,13 @@ struct iwl_cfg iwl2030_2bg_cfg = { | |||
| 	IWL_DEVICE_2030, | ||||
| }; | ||||
| 
 | ||||
| #define IWL_DEVICE_200						\ | ||||
| 	.fw_name_pre = IWL200_FW_PRE,				\ | ||||
| 	.ucode_api_max = IWL200_UCODE_API_MAX,			\ | ||||
| 	.ucode_api_min = IWL200_UCODE_API_MIN,			\ | ||||
| #define IWL_DEVICE_105						\ | ||||
| 	.fw_name_pre = IWL105_FW_PRE,				\ | ||||
| 	.ucode_api_max = IWL105_UCODE_API_MAX,			\ | ||||
| 	.ucode_api_min = IWL105_UCODE_API_MIN,			\ | ||||
| 	.eeprom_ver = EEPROM_2000_EEPROM_VERSION,		\ | ||||
| 	.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\ | ||||
| 	.ops = &iwl200_ops,					\ | ||||
| 	.mod_params = &iwlagn_mod_params,			\ | ||||
| 	.ops = &iwl105_ops,					\ | ||||
| 	.base_params = &iwl2000_base_params,			\ | ||||
| 	.need_dc_calib = true,					\ | ||||
| 	.need_temp_offset_calib = true,				\ | ||||
|  | @ -444,25 +430,24 @@ struct iwl_cfg iwl2030_2bg_cfg = { | |||
| 	.adv_pm = true,						\ | ||||
| 	.rx_with_siso_diversity = true				\ | ||||
| 
 | ||||
| struct iwl_cfg iwl200_bg_cfg = { | ||||
| 	.name = "200 Series 1x1 BG", | ||||
| 	IWL_DEVICE_200, | ||||
| struct iwl_cfg iwl105_bg_cfg = { | ||||
| 	.name = "105 Series 1x1 BG", | ||||
| 	IWL_DEVICE_105, | ||||
| }; | ||||
| 
 | ||||
| struct iwl_cfg iwl200_bgn_cfg = { | ||||
| 	.name = "200 Series 1x1 BGN", | ||||
| 	IWL_DEVICE_200, | ||||
| struct iwl_cfg iwl105_bgn_cfg = { | ||||
| 	.name = "105 Series 1x1 BGN", | ||||
| 	IWL_DEVICE_105, | ||||
| 	.ht_params = &iwl2000_ht_params, | ||||
| }; | ||||
| 
 | ||||
| #define IWL_DEVICE_230						\ | ||||
| 	.fw_name_pre = IWL200_FW_PRE,				\ | ||||
| 	.ucode_api_max = IWL200_UCODE_API_MAX,			\ | ||||
| 	.ucode_api_min = IWL200_UCODE_API_MIN,			\ | ||||
| #define IWL_DEVICE_135						\ | ||||
| 	.fw_name_pre = IWL105_FW_PRE,				\ | ||||
| 	.ucode_api_max = IWL105_UCODE_API_MAX,			\ | ||||
| 	.ucode_api_min = IWL105_UCODE_API_MIN,			\ | ||||
| 	.eeprom_ver = EEPROM_2000_EEPROM_VERSION,		\ | ||||
| 	.eeprom_calib_ver = EEPROM_2000_TX_POWER_VERSION,	\ | ||||
| 	.ops = &iwl230_ops,					\ | ||||
| 	.mod_params = &iwlagn_mod_params,			\ | ||||
| 	.ops = &iwl135_ops,					\ | ||||
| 	.base_params = &iwl2030_base_params,			\ | ||||
| 	.bt_params = &iwl2030_bt_params,			\ | ||||
| 	.need_dc_calib = true,					\ | ||||
|  | @ -471,17 +456,17 @@ struct iwl_cfg iwl200_bgn_cfg = { | |||
| 	.adv_pm = true,						\ | ||||
| 	.rx_with_siso_diversity = true				\ | ||||
| 
 | ||||
| struct iwl_cfg iwl230_bg_cfg = { | ||||
| 	.name = "200 Series 1x1 BG/BT", | ||||
| 	IWL_DEVICE_230, | ||||
| struct iwl_cfg iwl135_bg_cfg = { | ||||
| 	.name = "105 Series 1x1 BG/BT", | ||||
| 	IWL_DEVICE_135, | ||||
| }; | ||||
| 
 | ||||
| struct iwl_cfg iwl230_bgn_cfg = { | ||||
| 	.name = "200 Series 1x1 BGN/BT", | ||||
| 	IWL_DEVICE_230, | ||||
| struct iwl_cfg iwl135_bgn_cfg = { | ||||
| 	.name = "105 Series 1x1 BGN/BT", | ||||
| 	IWL_DEVICE_135, | ||||
| 	.ht_params = &iwl2000_ht_params, | ||||
| }; | ||||
| 
 | ||||
| MODULE_FIRMWARE(IWL2000_MODULE_FIRMWARE(IWL2000_UCODE_API_MAX)); | ||||
| MODULE_FIRMWARE(IWL2030_MODULE_FIRMWARE(IWL2030_UCODE_API_MAX)); | ||||
| MODULE_FIRMWARE(IWL200_MODULE_FIRMWARE(IWL200_UCODE_API_MAX)); | ||||
| MODULE_FIRMWARE(IWL105_MODULE_FIRMWARE(IWL105_UCODE_API_MAX)); | ||||
|  |  | |||
|  | @ -47,7 +47,6 @@ | |||
| #include "iwl-agn.h" | ||||
| #include "iwl-agn-hw.h" | ||||
| #include "iwl-5000-hw.h" | ||||
| #include "iwl-agn-debugfs.h" | ||||
| 
 | ||||
| /* Highest firmware API version supported */ | ||||
| #define IWL5000_UCODE_API_MAX 5 | ||||
|  | @ -165,10 +164,10 @@ static void iwl5000_set_ct_threshold(struct iwl_priv *priv) | |||
| 
 | ||||
| static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | ||||
| { | ||||
| 	if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && | ||||
| 	    priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) | ||||
| 	if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||||
| 	    iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||||
| 		priv->cfg->base_params->num_of_queues = | ||||
| 			priv->cfg->mod_params->num_of_queues; | ||||
| 			iwlagn_mod_params.num_of_queues; | ||||
| 
 | ||||
| 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; | ||||
| 	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | ||||
|  | @ -210,10 +209,10 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | |||
| 
 | ||||
| static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) | ||||
| { | ||||
| 	if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && | ||||
| 	    priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) | ||||
| 	if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||||
| 	    iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||||
| 		priv->cfg->base_params->num_of_queues = | ||||
| 			priv->cfg->mod_params->num_of_queues; | ||||
| 			iwlagn_mod_params.num_of_queues; | ||||
| 
 | ||||
| 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; | ||||
| 	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | ||||
|  | @ -366,21 +365,11 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
| 			EEPROM_REG_BAND_24_HT40_CHANNELS, | ||||
| 			EEPROM_REG_BAND_52_HT40_CHANNELS | ||||
| 		}, | ||||
| 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||||
| 		.release_semaphore = iwlcore_eeprom_release_semaphore, | ||||
| 		.calib_version	= iwlagn_eeprom_calib_version, | ||||
| 		.query_addr = iwlagn_eeprom_query_addr, | ||||
| 	}, | ||||
| 	.temp_ops = { | ||||
| 		.temperature = iwlagn_temperature, | ||||
| 	 }, | ||||
| 	.debugfs_ops = { | ||||
| 		.rx_stats_read = iwl_ucode_rx_stats_read, | ||||
| 		.tx_stats_read = iwl_ucode_tx_stats_read, | ||||
| 		.general_stats_read = iwl_ucode_general_stats_read, | ||||
| 		.bt_stats_read = iwl_ucode_bt_stats_read, | ||||
| 		.reply_tx_error = iwl_reply_tx_error_read, | ||||
| 	}, | ||||
| 	.txfifo_flush = iwlagn_txfifo_flush, | ||||
| 	.dev_txfifo_flush = iwlagn_dev_txfifo_flush, | ||||
| }; | ||||
|  | @ -413,21 +402,11 @@ static struct iwl_lib_ops iwl5150_lib = { | |||
| 			EEPROM_REG_BAND_24_HT40_CHANNELS, | ||||
| 			EEPROM_REG_BAND_52_HT40_CHANNELS | ||||
| 		}, | ||||
| 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||||
| 		.release_semaphore = iwlcore_eeprom_release_semaphore, | ||||
| 		.calib_version	= iwlagn_eeprom_calib_version, | ||||
| 		.query_addr = iwlagn_eeprom_query_addr, | ||||
| 	}, | ||||
| 	.temp_ops = { | ||||
| 		.temperature = iwl5150_temperature, | ||||
| 	 }, | ||||
| 	.debugfs_ops = { | ||||
| 		.rx_stats_read = iwl_ucode_rx_stats_read, | ||||
| 		.tx_stats_read = iwl_ucode_tx_stats_read, | ||||
| 		.general_stats_read = iwl_ucode_general_stats_read, | ||||
| 		.bt_stats_read = iwl_ucode_bt_stats_read, | ||||
| 		.reply_tx_error = iwl_reply_tx_error_read, | ||||
| 	}, | ||||
| 	.txfifo_flush = iwlagn_txfifo_flush, | ||||
| 	.dev_txfifo_flush = iwlagn_dev_txfifo_flush, | ||||
| }; | ||||
|  | @ -468,7 +447,6 @@ static struct iwl_ht_params iwl5000_ht_params = { | |||
| 	.eeprom_ver = EEPROM_5000_EEPROM_VERSION,		\ | ||||
| 	.eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,	\ | ||||
| 	.ops = &iwl5000_ops,					\ | ||||
| 	.mod_params = &iwlagn_mod_params,			\ | ||||
| 	.base_params = &iwl5000_base_params,			\ | ||||
| 	.led_mode = IWL_LED_BLINK | ||||
| 
 | ||||
|  | @ -512,7 +490,6 @@ struct iwl_cfg iwl5350_agn_cfg = { | |||
| 	.eeprom_ver = EEPROM_5050_EEPROM_VERSION, | ||||
| 	.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION, | ||||
| 	.ops = &iwl5000_ops, | ||||
| 	.mod_params = &iwlagn_mod_params, | ||||
| 	.base_params = &iwl5000_base_params, | ||||
| 	.ht_params = &iwl5000_ht_params, | ||||
| 	.led_mode = IWL_LED_BLINK, | ||||
|  | @ -526,7 +503,6 @@ struct iwl_cfg iwl5350_agn_cfg = { | |||
| 	.eeprom_ver = EEPROM_5050_EEPROM_VERSION,		\ | ||||
| 	.eeprom_calib_ver = EEPROM_5050_TX_POWER_VERSION,	\ | ||||
| 	.ops = &iwl5150_ops,					\ | ||||
| 	.mod_params = &iwlagn_mod_params,			\ | ||||
| 	.base_params = &iwl5000_base_params,			\ | ||||
| 	.need_dc_calib = true,					\ | ||||
| 	.led_mode = IWL_LED_BLINK,				\ | ||||
|  |  | |||
|  | @ -46,7 +46,6 @@ | |||
| #include "iwl-helpers.h" | ||||
| #include "iwl-agn-hw.h" | ||||
| #include "iwl-6000-hw.h" | ||||
| #include "iwl-agn-debugfs.h" | ||||
| 
 | ||||
| /* Highest firmware API version supported */ | ||||
| #define IWL6000_UCODE_API_MAX 4 | ||||
|  | @ -80,7 +79,7 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv) | |||
| static void iwl6050_additional_nic_config(struct iwl_priv *priv) | ||||
| { | ||||
| 	/* Indicate calibration version to uCode. */ | ||||
| 	if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6) | ||||
| 	if (iwlagn_eeprom_calib_version(priv) >= 6) | ||||
| 		iwl_set_bit(priv, CSR_GP_DRIVER_REG, | ||||
| 				CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | ||||
| } | ||||
|  | @ -88,7 +87,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv) | |||
| static void iwl6150_additional_nic_config(struct iwl_priv *priv) | ||||
| { | ||||
| 	/* Indicate calibration version to uCode. */ | ||||
| 	if (priv->cfg->ops->lib->eeprom_ops.calib_version(priv) >= 6) | ||||
| 	if (iwlagn_eeprom_calib_version(priv) >= 6) | ||||
| 		iwl_set_bit(priv, CSR_GP_DRIVER_REG, | ||||
| 				CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); | ||||
| 	iwl_set_bit(priv, CSR_GP_DRIVER_REG, | ||||
|  | @ -154,10 +153,10 @@ static struct iwl_sensitivity_ranges iwl6000_sensitivity = { | |||
| 
 | ||||
| static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) | ||||
| { | ||||
| 	if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES && | ||||
| 	    priv->cfg->mod_params->num_of_queues <= IWLAGN_NUM_QUEUES) | ||||
| 	if (iwlagn_mod_params.num_of_queues >= IWL_MIN_NUM_QUEUES && | ||||
| 	    iwlagn_mod_params.num_of_queues <= IWLAGN_NUM_QUEUES) | ||||
| 		priv->cfg->base_params->num_of_queues = | ||||
| 			priv->cfg->mod_params->num_of_queues; | ||||
| 			iwlagn_mod_params.num_of_queues; | ||||
| 
 | ||||
| 	priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues; | ||||
| 	priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM; | ||||
|  | @ -305,22 +304,12 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
| 			EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||||
| 			EEPROM_REG_BAND_52_HT40_CHANNELS | ||||
| 		}, | ||||
| 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||||
| 		.release_semaphore = iwlcore_eeprom_release_semaphore, | ||||
| 		.calib_version	= iwlagn_eeprom_calib_version, | ||||
| 		.query_addr = iwlagn_eeprom_query_addr, | ||||
| 		.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, | ||||
| 	}, | ||||
| 	.temp_ops = { | ||||
| 		.temperature = iwlagn_temperature, | ||||
| 	 }, | ||||
| 	.debugfs_ops = { | ||||
| 		.rx_stats_read = iwl_ucode_rx_stats_read, | ||||
| 		.tx_stats_read = iwl_ucode_tx_stats_read, | ||||
| 		.general_stats_read = iwl_ucode_general_stats_read, | ||||
| 		.bt_stats_read = iwl_ucode_bt_stats_read, | ||||
| 		.reply_tx_error = iwl_reply_tx_error_read, | ||||
| 	}, | ||||
| 	.txfifo_flush = iwlagn_txfifo_flush, | ||||
| 	.dev_txfifo_flush = iwlagn_dev_txfifo_flush, | ||||
| }; | ||||
|  | @ -354,22 +343,12 @@ static struct iwl_lib_ops iwl6030_lib = { | |||
| 			EEPROM_6000_REG_BAND_24_HT40_CHANNELS, | ||||
| 			EEPROM_REG_BAND_52_HT40_CHANNELS | ||||
| 		}, | ||||
| 		.acquire_semaphore = iwlcore_eeprom_acquire_semaphore, | ||||
| 		.release_semaphore = iwlcore_eeprom_release_semaphore, | ||||
| 		.calib_version	= iwlagn_eeprom_calib_version, | ||||
| 		.query_addr = iwlagn_eeprom_query_addr, | ||||
| 		.update_enhanced_txpower = iwlcore_eeprom_enhanced_txpower, | ||||
| 	}, | ||||
| 	.temp_ops = { | ||||
| 		.temperature = iwlagn_temperature, | ||||
| 	 }, | ||||
| 	.debugfs_ops = { | ||||
| 		.rx_stats_read = iwl_ucode_rx_stats_read, | ||||
| 		.tx_stats_read = iwl_ucode_tx_stats_read, | ||||
| 		.general_stats_read = iwl_ucode_general_stats_read, | ||||
| 		.bt_stats_read = iwl_ucode_bt_stats_read, | ||||
| 		.reply_tx_error = iwl_reply_tx_error_read, | ||||
| 	}, | ||||
| 	.txfifo_flush = iwlagn_txfifo_flush, | ||||
| 	.dev_txfifo_flush = iwlagn_dev_txfifo_flush, | ||||
| }; | ||||
|  | @ -482,7 +461,6 @@ static struct iwl_bt_params iwl6000_bt_params = { | |||
| 	.eeprom_ver = EEPROM_6005_EEPROM_VERSION,		\ | ||||
| 	.eeprom_calib_ver = EEPROM_6005_TX_POWER_VERSION,	\ | ||||
| 	.ops = &iwl6000_ops,					\ | ||||
| 	.mod_params = &iwlagn_mod_params,			\ | ||||
| 	.base_params = &iwl6000_g2_base_params,			\ | ||||
| 	.need_dc_calib = true,					\ | ||||
| 	.need_temp_offset_calib = true,				\ | ||||
|  | @ -511,7 +489,6 @@ struct iwl_cfg iwl6005_2bg_cfg = { | |||
| 	.eeprom_ver = EEPROM_6030_EEPROM_VERSION,		\ | ||||
| 	.eeprom_calib_ver = EEPROM_6030_TX_POWER_VERSION,	\ | ||||
| 	.ops = &iwl6030_ops,					\ | ||||
| 	.mod_params = &iwlagn_mod_params,			\ | ||||
| 	.base_params = &iwl6000_g2_base_params,			\ | ||||
| 	.bt_params = &iwl6000_bt_params,			\ | ||||
| 	.need_dc_calib = true,					\ | ||||
|  | @ -593,7 +570,6 @@ struct iwl_cfg iwl130_bg_cfg = { | |||
| 	.eeprom_ver = EEPROM_6000_EEPROM_VERSION,		\ | ||||
| 	.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION,	\ | ||||
| 	.ops = &iwl6000_ops,					\ | ||||
| 	.mod_params = &iwlagn_mod_params,			\ | ||||
| 	.base_params = &iwl6000_base_params,			\ | ||||
| 	.pa_type = IWL_PA_INTERNAL,				\ | ||||
| 	.led_mode = IWL_LED_BLINK | ||||
|  | @ -623,7 +599,6 @@ struct iwl_cfg iwl6000i_2bg_cfg = { | |||
| 	.ops = &iwl6050_ops,					\ | ||||
| 	.eeprom_ver = EEPROM_6050_EEPROM_VERSION,		\ | ||||
| 	.eeprom_calib_ver = EEPROM_6050_TX_POWER_VERSION,	\ | ||||
| 	.mod_params = &iwlagn_mod_params,			\ | ||||
| 	.base_params = &iwl6050_base_params,			\ | ||||
| 	.need_dc_calib = true,					\ | ||||
| 	.led_mode = IWL_LED_BLINK,				\ | ||||
|  | @ -648,7 +623,6 @@ struct iwl_cfg iwl6150_bgn_cfg = { | |||
| 	.eeprom_ver = EEPROM_6150_EEPROM_VERSION, | ||||
| 	.eeprom_calib_ver = EEPROM_6150_TX_POWER_VERSION, | ||||
| 	.ops = &iwl6150_ops, | ||||
| 	.mod_params = &iwlagn_mod_params, | ||||
| 	.base_params = &iwl6050_base_params, | ||||
| 	.ht_params = &iwl6000_ht_params, | ||||
| 	.need_dc_calib = true, | ||||
|  | @ -664,7 +638,6 @@ struct iwl_cfg iwl6000_3agn_cfg = { | |||
| 	.eeprom_ver = EEPROM_6000_EEPROM_VERSION, | ||||
| 	.eeprom_calib_ver = EEPROM_6000_TX_POWER_VERSION, | ||||
| 	.ops = &iwl6000_ops, | ||||
| 	.mod_params = &iwlagn_mod_params, | ||||
| 	.base_params = &iwl6000_base_params, | ||||
| 	.ht_params = &iwl6000_ht_params, | ||||
| 	.need_dc_calib = true, | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -1,70 +0,0 @@ | |||
| /******************************************************************************
 | ||||
|  * | ||||
|  * GPL LICENSE SUMMARY | ||||
|  * | ||||
|  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of version 2 of the GNU General Public License as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but | ||||
|  * WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||||
|  * General Public License for more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License | ||||
|  * along with this program; if not, write to the Free Software | ||||
|  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, | ||||
|  * USA | ||||
|  * | ||||
|  * The full GNU General Public License is included in this distribution | ||||
|  * in the file called LICENSE.GPL. | ||||
|  * | ||||
|  * Contact Information: | ||||
|  *  Intel Linux Wireless <ilw@linux.intel.com> | ||||
|  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
|  *****************************************************************************/ | ||||
| 
 | ||||
| #include "iwl-dev.h" | ||||
| #include "iwl-core.h" | ||||
| #include "iwl-debug.h" | ||||
| 
 | ||||
| #ifdef CONFIG_IWLWIFI_DEBUGFS | ||||
| ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, | ||||
| 				size_t count, loff_t *ppos); | ||||
| ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf, | ||||
| 				size_t count, loff_t *ppos); | ||||
| ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, | ||||
| 				     size_t count, loff_t *ppos); | ||||
| ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, | ||||
| 				size_t count, loff_t *ppos); | ||||
| ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf, | ||||
| 				size_t count, loff_t *ppos); | ||||
| #else | ||||
| static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf, | ||||
| 				       size_t count, loff_t *ppos) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| static ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf, | ||||
| 				       size_t count, loff_t *ppos) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf, | ||||
| 					    size_t count, loff_t *ppos) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf, | ||||
| 				       size_t count, loff_t *ppos) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| static ssize_t iwl_reply_tx_error_read(struct file *file, char __user *user_buf, | ||||
| 				       size_t count, loff_t *ppos) | ||||
| { | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  | @ -81,52 +81,13 @@ | |||
|  * | ||||
| ******************************************************************************/ | ||||
| 
 | ||||
| /*
 | ||||
|  * The device's EEPROM semaphore prevents conflicts between driver and uCode | ||||
|  * when accessing the EEPROM; each access is a series of pulses to/from the | ||||
|  * EEPROM chip, not a single event, so even reads could conflict if they | ||||
|  * weren't arbitrated by the semaphore. | ||||
|  */ | ||||
| int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv) | ||||
| { | ||||
| 	u16 count; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { | ||||
| 		/* Request semaphore */ | ||||
| 		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||||
| 			    CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||||
| 
 | ||||
| 		/* See if we got it */ | ||||
| 		ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, | ||||
| 				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||||
| 				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||||
| 				EEPROM_SEM_TIMEOUT); | ||||
| 		if (ret >= 0) { | ||||
| 			IWL_DEBUG_EEPROM(priv, | ||||
| 				"Acquired semaphore after %d tries.\n", | ||||
| 				count+1); | ||||
| 			return ret; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv) | ||||
| { | ||||
| 	iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, | ||||
| 		CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| int iwl_eeprom_check_version(struct iwl_priv *priv) | ||||
| { | ||||
| 	u16 eeprom_ver; | ||||
| 	u16 calib_ver; | ||||
| 
 | ||||
| 	eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); | ||||
| 	calib_ver = priv->cfg->ops->lib->eeprom_ops.calib_version(priv); | ||||
| 	calib_ver = iwlagn_eeprom_calib_version(priv); | ||||
| 
 | ||||
| 	if (eeprom_ver < priv->cfg->eeprom_ver || | ||||
| 	    calib_ver < priv->cfg->eeprom_calib_ver) | ||||
|  |  | |||
|  | @ -37,54 +37,6 @@ | |||
| #include "iwl-io.h" | ||||
| #include "iwl-agn.h" | ||||
| 
 | ||||
| int iwlagn_send_rxon_assoc(struct iwl_priv *priv, | ||||
| 			   struct iwl_rxon_context *ctx) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	struct iwl5000_rxon_assoc_cmd rxon_assoc; | ||||
| 	const struct iwl_rxon_cmd *rxon1 = &ctx->staging; | ||||
| 	const struct iwl_rxon_cmd *rxon2 = &ctx->active; | ||||
| 
 | ||||
| 	if ((rxon1->flags == rxon2->flags) && | ||||
| 	    (rxon1->filter_flags == rxon2->filter_flags) && | ||||
| 	    (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && | ||||
| 	    (rxon1->ofdm_ht_single_stream_basic_rates == | ||||
| 	     rxon2->ofdm_ht_single_stream_basic_rates) && | ||||
| 	    (rxon1->ofdm_ht_dual_stream_basic_rates == | ||||
| 	     rxon2->ofdm_ht_dual_stream_basic_rates) && | ||||
| 	    (rxon1->ofdm_ht_triple_stream_basic_rates == | ||||
| 	     rxon2->ofdm_ht_triple_stream_basic_rates) && | ||||
| 	    (rxon1->acquisition_data == rxon2->acquisition_data) && | ||||
| 	    (rxon1->rx_chain == rxon2->rx_chain) && | ||||
| 	    (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { | ||||
| 		IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC.  Not resending.\n"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	rxon_assoc.flags = ctx->staging.flags; | ||||
| 	rxon_assoc.filter_flags = ctx->staging.filter_flags; | ||||
| 	rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; | ||||
| 	rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; | ||||
| 	rxon_assoc.reserved1 = 0; | ||||
| 	rxon_assoc.reserved2 = 0; | ||||
| 	rxon_assoc.reserved3 = 0; | ||||
| 	rxon_assoc.ofdm_ht_single_stream_basic_rates = | ||||
| 	    ctx->staging.ofdm_ht_single_stream_basic_rates; | ||||
| 	rxon_assoc.ofdm_ht_dual_stream_basic_rates = | ||||
| 	    ctx->staging.ofdm_ht_dual_stream_basic_rates; | ||||
| 	rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; | ||||
| 	rxon_assoc.ofdm_ht_triple_stream_basic_rates = | ||||
| 		 ctx->staging.ofdm_ht_triple_stream_basic_rates; | ||||
| 	rxon_assoc.acquisition_data = ctx->staging.acquisition_data; | ||||
| 
 | ||||
| 	ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd, | ||||
| 				     sizeof(rxon_assoc), &rxon_assoc, NULL); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant) | ||||
| { | ||||
| 	struct iwl_tx_ant_config_cmd tx_ant_cmd = { | ||||
|  | @ -364,7 +316,6 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv) | |||
| } | ||||
| 
 | ||||
| struct iwl_hcmd_ops iwlagn_hcmd = { | ||||
| 	.rxon_assoc = iwlagn_send_rxon_assoc, | ||||
| 	.commit_rxon = iwlagn_commit_rxon, | ||||
| 	.set_rxon_chain = iwlagn_set_rxon_chain, | ||||
| 	.set_tx_ant = iwlagn_send_tx_ant_config, | ||||
|  | @ -373,7 +324,6 @@ struct iwl_hcmd_ops iwlagn_hcmd = { | |||
| }; | ||||
| 
 | ||||
| struct iwl_hcmd_ops iwlagn_bt_hcmd = { | ||||
| 	.rxon_assoc = iwlagn_send_rxon_assoc, | ||||
| 	.commit_rxon = iwlagn_commit_rxon, | ||||
| 	.set_rxon_chain = iwlagn_set_rxon_chain, | ||||
| 	.set_tx_ant = iwlagn_send_tx_ant_config, | ||||
|  |  | |||
|  | @ -483,8 +483,6 @@ void iwlagn_rx_handler_setup(struct iwl_priv *priv) | |||
| 	/* init calibration handlers */ | ||||
| 	priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] = | ||||
| 					iwlagn_rx_calib_result; | ||||
| 	priv->rx_handlers[CALIBRATION_COMPLETE_NOTIFICATION] = | ||||
| 					iwlagn_rx_calib_complete; | ||||
| 	priv->rx_handlers[REPLY_TX] = iwlagn_rx_reply_tx; | ||||
| 
 | ||||
| 	/* set up notification wait support */ | ||||
|  | @ -667,7 +665,7 @@ int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
| 
 | ||||
| 	rb_timeout = RX_RB_TIMEOUT; | ||||
| 
 | ||||
| 	if (priv->cfg->mod_params->amsdu_size_8K) | ||||
| 	if (iwlagn_mod_params.amsdu_size_8K) | ||||
| 		rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | ||||
| 	else | ||||
| 		rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | ||||
|  | @ -1296,9 +1294,17 @@ int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
| 	 * mean we never reach it, but at the same time work around | ||||
| 	 * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER | ||||
| 	 * here instead of IWL_GOOD_CRC_TH_DISABLED. | ||||
| 	 * | ||||
| 	 * This was fixed in later versions along with some other | ||||
| 	 * scan changes, and the threshold behaves as a flag in those | ||||
| 	 * versions. | ||||
| 	 */ | ||||
| 	scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : | ||||
| 					IWL_GOOD_CRC_TH_NEVER; | ||||
| 	if (priv->new_scan_threshold_behaviour) | ||||
| 		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : | ||||
| 						IWL_GOOD_CRC_TH_DISABLED; | ||||
| 	else | ||||
| 		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : | ||||
| 						IWL_GOOD_CRC_TH_NEVER; | ||||
| 
 | ||||
| 	band = priv->scan_band; | ||||
| 
 | ||||
|  | @ -2256,34 +2262,44 @@ int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display) | |||
| /* notification wait support */ | ||||
| void iwlagn_init_notification_wait(struct iwl_priv *priv, | ||||
| 				   struct iwl_notification_wait *wait_entry, | ||||
| 				   u8 cmd, | ||||
| 				   void (*fn)(struct iwl_priv *priv, | ||||
| 					      struct iwl_rx_packet *pkt), | ||||
| 				   u8 cmd) | ||||
| 					      struct iwl_rx_packet *pkt, | ||||
| 					      void *data), | ||||
| 				   void *fn_data) | ||||
| { | ||||
| 	wait_entry->fn = fn; | ||||
| 	wait_entry->fn_data = fn_data; | ||||
| 	wait_entry->cmd = cmd; | ||||
| 	wait_entry->triggered = false; | ||||
| 	wait_entry->aborted = false; | ||||
| 
 | ||||
| 	spin_lock_bh(&priv->_agn.notif_wait_lock); | ||||
| 	list_add(&wait_entry->list, &priv->_agn.notif_waits); | ||||
| 	spin_unlock_bh(&priv->_agn.notif_wait_lock); | ||||
| } | ||||
| 
 | ||||
| signed long iwlagn_wait_notification(struct iwl_priv *priv, | ||||
| 				     struct iwl_notification_wait *wait_entry, | ||||
| 				     unsigned long timeout) | ||||
| int iwlagn_wait_notification(struct iwl_priv *priv, | ||||
| 			     struct iwl_notification_wait *wait_entry, | ||||
| 			     unsigned long timeout) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	ret = wait_event_timeout(priv->_agn.notif_waitq, | ||||
| 				 wait_entry->triggered, | ||||
| 				 wait_entry->triggered || wait_entry->aborted, | ||||
| 				 timeout); | ||||
| 
 | ||||
| 	spin_lock_bh(&priv->_agn.notif_wait_lock); | ||||
| 	list_del(&wait_entry->list); | ||||
| 	spin_unlock_bh(&priv->_agn.notif_wait_lock); | ||||
| 
 | ||||
| 	return ret; | ||||
| 	if (wait_entry->aborted) | ||||
| 		return -EIO; | ||||
| 
 | ||||
| 	/* return value is always >= 0 */ | ||||
| 	if (ret <= 0) | ||||
| 		return -ETIMEDOUT; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void iwlagn_remove_notification(struct iwl_priv *priv, | ||||
|  | @ -2293,3 +2309,87 @@ void iwlagn_remove_notification(struct iwl_priv *priv, | |||
| 	list_del(&wait_entry->list); | ||||
| 	spin_unlock_bh(&priv->_agn.notif_wait_lock); | ||||
| } | ||||
| 
 | ||||
| int iwlagn_start_device(struct iwl_priv *priv) | ||||
| { | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (iwl_prepare_card_hw(priv)) { | ||||
| 		IWL_WARN(priv, "Exit HW not ready\n"); | ||||
| 		return -EIO; | ||||
| 	} | ||||
| 
 | ||||
| 	/* If platform's RF_KILL switch is NOT set to KILL */ | ||||
| 	if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | ||||
| 		clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||||
| 	else | ||||
| 		set_bit(STATUS_RF_KILL_HW, &priv->status); | ||||
| 
 | ||||
| 	if (iwl_is_rfkill(priv)) { | ||||
| 		wiphy_rfkill_set_hw_state(priv->hw->wiphy, true); | ||||
| 		iwl_enable_interrupts(priv); | ||||
| 		return -ERFKILL; | ||||
| 	} | ||||
| 
 | ||||
| 	iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | ||||
| 
 | ||||
| 	ret = iwlagn_hw_nic_init(priv); | ||||
| 	if (ret) { | ||||
| 		IWL_ERR(priv, "Unable to init nic\n"); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	/* make sure rfkill handshake bits are cleared */ | ||||
| 	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||||
| 	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, | ||||
| 		    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | ||||
| 
 | ||||
| 	/* clear (again), then enable host interrupts */ | ||||
| 	iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | ||||
| 	iwl_enable_interrupts(priv); | ||||
| 
 | ||||
| 	/* really make sure rfkill handshake bits are cleared */ | ||||
| 	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||||
| 	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| void iwlagn_stop_device(struct iwl_priv *priv) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 
 | ||||
| 	/* stop and reset the on-board processor */ | ||||
| 	iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | ||||
| 
 | ||||
| 	/* tell the device to stop sending interrupts */ | ||||
| 	spin_lock_irqsave(&priv->lock, flags); | ||||
| 	iwl_disable_interrupts(priv); | ||||
| 	spin_unlock_irqrestore(&priv->lock, flags); | ||||
| 	iwl_synchronize_irq(priv); | ||||
| 
 | ||||
| 	/* device going down, Stop using ICT table */ | ||||
| 	iwl_disable_ict(priv); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * If a HW restart happens during firmware loading, | ||||
| 	 * then the firmware loading might call this function | ||||
| 	 * and later it might be called again due to the | ||||
| 	 * restart. So don't process again if the device is | ||||
| 	 * already dead. | ||||
| 	 */ | ||||
| 	if (test_bit(STATUS_DEVICE_ENABLED, &priv->status)) { | ||||
|                 iwlagn_txq_ctx_stop(priv); | ||||
|                 iwlagn_rxq_stop(priv); | ||||
| 
 | ||||
|                 /* Power-down device's busmaster DMA clocks */ | ||||
|                 iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); | ||||
|                 udelay(5); | ||||
|         } | ||||
| 
 | ||||
| 	/* Make sure (redundant) we've released our request to stay awake */ | ||||
| 	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||||
| 
 | ||||
| 	/* Stop the device, and put it in low power state */ | ||||
| 	iwl_apm_stop(priv); | ||||
| } | ||||
|  |  | |||
|  | @ -58,8 +58,9 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, | |||
| 	u8 old_dev_type = send->dev_type; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	iwlagn_init_notification_wait(priv, &disable_wait, NULL, | ||||
| 				      REPLY_WIPAN_DEACTIVATION_COMPLETE); | ||||
| 	iwlagn_init_notification_wait(priv, &disable_wait, | ||||
| 				      REPLY_WIPAN_DEACTIVATION_COMPLETE, | ||||
| 				      NULL, NULL); | ||||
| 
 | ||||
| 	send->filter_flags &= ~RXON_FILTER_ASSOC_MSK; | ||||
| 	send->dev_type = RXON_DEV_TYPE_P2P; | ||||
|  | @ -72,13 +73,9 @@ static int iwlagn_disable_pan(struct iwl_priv *priv, | |||
| 		IWL_ERR(priv, "Error disabling PAN (%d)\n", ret); | ||||
| 		iwlagn_remove_notification(priv, &disable_wait); | ||||
| 	} else { | ||||
| 		signed long wait_res; | ||||
| 
 | ||||
| 		wait_res = iwlagn_wait_notification(priv, &disable_wait, HZ); | ||||
| 		if (wait_res == 0) { | ||||
| 		ret = iwlagn_wait_notification(priv, &disable_wait, HZ); | ||||
| 		if (ret) | ||||
| 			IWL_ERR(priv, "Timed out waiting for PAN disable\n"); | ||||
| 			ret = -EIO; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
|  | @ -124,6 +121,151 @@ static int iwlagn_update_beacon(struct iwl_priv *priv, | |||
| 	return iwlagn_send_beacon_cmd(priv); | ||||
| } | ||||
| 
 | ||||
| static int iwlagn_send_rxon_assoc(struct iwl_priv *priv, | ||||
| 			   struct iwl_rxon_context *ctx) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	struct iwl_rxon_assoc_cmd rxon_assoc; | ||||
| 	const struct iwl_rxon_cmd *rxon1 = &ctx->staging; | ||||
| 	const struct iwl_rxon_cmd *rxon2 = &ctx->active; | ||||
| 
 | ||||
| 	if ((rxon1->flags == rxon2->flags) && | ||||
| 	    (rxon1->filter_flags == rxon2->filter_flags) && | ||||
| 	    (rxon1->cck_basic_rates == rxon2->cck_basic_rates) && | ||||
| 	    (rxon1->ofdm_ht_single_stream_basic_rates == | ||||
| 	     rxon2->ofdm_ht_single_stream_basic_rates) && | ||||
| 	    (rxon1->ofdm_ht_dual_stream_basic_rates == | ||||
| 	     rxon2->ofdm_ht_dual_stream_basic_rates) && | ||||
| 	    (rxon1->ofdm_ht_triple_stream_basic_rates == | ||||
| 	     rxon2->ofdm_ht_triple_stream_basic_rates) && | ||||
| 	    (rxon1->acquisition_data == rxon2->acquisition_data) && | ||||
| 	    (rxon1->rx_chain == rxon2->rx_chain) && | ||||
| 	    (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) { | ||||
| 		IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC.  Not resending.\n"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	rxon_assoc.flags = ctx->staging.flags; | ||||
| 	rxon_assoc.filter_flags = ctx->staging.filter_flags; | ||||
| 	rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates; | ||||
| 	rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates; | ||||
| 	rxon_assoc.reserved1 = 0; | ||||
| 	rxon_assoc.reserved2 = 0; | ||||
| 	rxon_assoc.reserved3 = 0; | ||||
| 	rxon_assoc.ofdm_ht_single_stream_basic_rates = | ||||
| 	    ctx->staging.ofdm_ht_single_stream_basic_rates; | ||||
| 	rxon_assoc.ofdm_ht_dual_stream_basic_rates = | ||||
| 	    ctx->staging.ofdm_ht_dual_stream_basic_rates; | ||||
| 	rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain; | ||||
| 	rxon_assoc.ofdm_ht_triple_stream_basic_rates = | ||||
| 		 ctx->staging.ofdm_ht_triple_stream_basic_rates; | ||||
| 	rxon_assoc.acquisition_data = ctx->staging.acquisition_data; | ||||
| 
 | ||||
| 	ret = iwl_send_cmd_pdu_async(priv, ctx->rxon_assoc_cmd, | ||||
| 				     sizeof(rxon_assoc), &rxon_assoc, NULL); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int iwlagn_rxon_disconn(struct iwl_priv *priv, | ||||
| 			       struct iwl_rxon_context *ctx) | ||||
| { | ||||
| 	int ret; | ||||
| 	struct iwl_rxon_cmd *active = (void *)&ctx->active; | ||||
| 
 | ||||
| 	if (ctx->ctxid == IWL_RXON_CTX_BSS) | ||||
| 		ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); | ||||
| 	else | ||||
| 		ret = iwlagn_disable_pan(priv, ctx, &ctx->staging); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Un-assoc RXON clears the station table and WEP | ||||
| 	 * keys, so we have to restore those afterwards. | ||||
| 	 */ | ||||
| 	iwl_clear_ucode_stations(priv, ctx); | ||||
| 	iwl_restore_stations(priv, ctx); | ||||
| 	ret = iwl_restore_default_wep_keys(priv, ctx); | ||||
| 	if (ret) { | ||||
| 		IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	memcpy(active, &ctx->staging, sizeof(*active)); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int iwlagn_rxon_connect(struct iwl_priv *priv, | ||||
| 			       struct iwl_rxon_context *ctx) | ||||
| { | ||||
| 	int ret; | ||||
| 	struct iwl_rxon_cmd *active = (void *)&ctx->active; | ||||
| 
 | ||||
| 	/* RXON timing must be before associated RXON */ | ||||
| 	ret = iwl_send_rxon_timing(priv, ctx); | ||||
| 	if (ret) { | ||||
| 		IWL_ERR(priv, "Failed to send timing (%d)!\n", ret); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	/* QoS info may be cleared by previous un-assoc RXON */ | ||||
| 	iwlagn_update_qos(priv, ctx); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * We'll run into this code path when beaconing is | ||||
| 	 * enabled, but then we also need to send the beacon | ||||
| 	 * to the device. | ||||
| 	 */ | ||||
| 	if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) { | ||||
| 		ret = iwlagn_update_beacon(priv, ctx->vif); | ||||
| 		if (ret) { | ||||
| 			IWL_ERR(priv, | ||||
| 				"Error sending required beacon (%d)!\n", | ||||
| 				ret); | ||||
| 			return ret; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	priv->start_calib = 0; | ||||
| 	/*
 | ||||
| 	 * Apply the new configuration. | ||||
| 	 * | ||||
| 	 * Associated RXON doesn't clear the station table in uCode, | ||||
| 	 * so we don't need to restore stations etc. after this. | ||||
| 	 */ | ||||
| 	ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, | ||||
| 		      sizeof(struct iwl_rxon_cmd), &ctx->staging); | ||||
| 	if (ret) { | ||||
| 		IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	memcpy(active, &ctx->staging, sizeof(*active)); | ||||
| 
 | ||||
| 	iwl_reprogram_ap_sta(priv, ctx); | ||||
| 
 | ||||
| 	/* IBSS beacon needs to be sent after setting assoc */ | ||||
| 	if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) | ||||
| 		if (iwlagn_update_beacon(priv, ctx->vif)) | ||||
| 			IWL_ERR(priv, "Error sending IBSS beacon\n"); | ||||
| 	iwl_init_sensitivity(priv); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * If we issue a new RXON command which required a tune then | ||||
| 	 * we must send a new TXPOWER command or we won't be able to | ||||
| 	 * Tx any frames. | ||||
| 	 * | ||||
| 	 * It's expected we set power here if channel is changing. | ||||
| 	 */ | ||||
| 	ret = iwl_set_tx_power(priv, priv->tx_power_next, true); | ||||
| 	if (ret) { | ||||
| 		IWL_ERR(priv, "Error sending TX power (%d)\n", ret); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * iwlagn_commit_rxon - commit staging_rxon to hardware | ||||
|  * | ||||
|  | @ -131,6 +273,16 @@ static int iwlagn_update_beacon(struct iwl_priv *priv, | |||
|  * the active_rxon structure is updated with the new data.  This | ||||
|  * function correctly transitions out of the RXON_ASSOC_MSK state if | ||||
|  * a HW tune is required based on the RXON structure changes. | ||||
|  * | ||||
|  * The connect/disconnect flow should be as the following: | ||||
|  * | ||||
|  * 1. make sure send RXON command with association bit unset if not connect | ||||
|  *	this should include the channel and the band for the candidate | ||||
|  *	to be connected to | ||||
|  * 2. Add Station before RXON association with the AP | ||||
|  * 3. RXON_timing has to send before RXON for connection | ||||
|  * 4. full RXON command - associated bit set | ||||
|  * 5. use RXON_ASSOC command to update any flags changes | ||||
|  */ | ||||
| int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | ||||
| { | ||||
|  | @ -180,6 +332,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 	else | ||||
| 		ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; | ||||
| 
 | ||||
| 	iwl_print_rx_config_cmd(priv, ctx); | ||||
| 	ret = iwl_check_rxon_cmd(priv, ctx); | ||||
| 	if (ret) { | ||||
| 		IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); | ||||
|  | @ -203,14 +356,13 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 	 * and other flags for the current radio configuration. | ||||
| 	 */ | ||||
| 	if (!iwl_full_rxon_required(priv, ctx)) { | ||||
| 		ret = iwl_send_rxon_assoc(priv, ctx); | ||||
| 		ret = iwlagn_send_rxon_assoc(priv, ctx); | ||||
| 		if (ret) { | ||||
| 			IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); | ||||
| 			return ret; | ||||
| 		} | ||||
| 
 | ||||
| 		memcpy(active, &ctx->staging, sizeof(*active)); | ||||
| 		iwl_print_rx_config_cmd(priv, ctx); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -220,7 +372,7 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 			return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto); | ||||
| 	iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto); | ||||
| 
 | ||||
| 	IWL_DEBUG_INFO(priv, | ||||
| 		       "Going to commit RXON\n" | ||||
|  | @ -238,92 +390,13 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | |||
| 	 * set up filters in the device. | ||||
| 	 */ | ||||
| 	if ((old_assoc && new_assoc) || !new_assoc) { | ||||
| 		if (ctx->ctxid == IWL_RXON_CTX_BSS) | ||||
| 			ret = iwlagn_disable_bss(priv, ctx, &ctx->staging); | ||||
| 		else | ||||
| 			ret = iwlagn_disable_pan(priv, ctx, &ctx->staging); | ||||
| 		ret = iwlagn_rxon_disconn(priv, ctx); | ||||
| 		if (ret) | ||||
| 			return ret; | ||||
| 
 | ||||
| 		memcpy(active, &ctx->staging, sizeof(*active)); | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * Un-assoc RXON clears the station table and WEP | ||||
| 		 * keys, so we have to restore those afterwards. | ||||
| 		 */ | ||||
| 		iwl_clear_ucode_stations(priv, ctx); | ||||
| 		iwl_restore_stations(priv, ctx); | ||||
| 		ret = iwl_restore_default_wep_keys(priv, ctx); | ||||
| 		if (ret) { | ||||
| 			IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret); | ||||
| 			return ret; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/* RXON timing must be before associated RXON */ | ||||
| 	ret = iwl_send_rxon_timing(priv, ctx); | ||||
| 	if (ret) { | ||||
| 		IWL_ERR(priv, "Failed to send timing (%d)!\n", ret); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	if (new_assoc) { | ||||
| 		/* QoS info may be cleared by previous un-assoc RXON */ | ||||
| 		iwlagn_update_qos(priv, ctx); | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * We'll run into this code path when beaconing is | ||||
| 		 * enabled, but then we also need to send the beacon | ||||
| 		 * to the device. | ||||
| 		 */ | ||||
| 		if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) { | ||||
| 			ret = iwlagn_update_beacon(priv, ctx->vif); | ||||
| 			if (ret) { | ||||
| 				IWL_ERR(priv, | ||||
| 					"Error sending required beacon (%d)!\n", | ||||
| 					ret); | ||||
| 				return ret; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		priv->start_calib = 0; | ||||
| 		/*
 | ||||
| 		 * Apply the new configuration. | ||||
| 		 * | ||||
| 		 * Associated RXON doesn't clear the station table in uCode, | ||||
| 		 * so we don't need to restore stations etc. after this. | ||||
| 		 */ | ||||
| 		ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, | ||||
| 			      sizeof(struct iwl_rxon_cmd), &ctx->staging); | ||||
| 		if (ret) { | ||||
| 			IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); | ||||
| 			return ret; | ||||
| 		} | ||||
| 		memcpy(active, &ctx->staging, sizeof(*active)); | ||||
| 
 | ||||
| 		iwl_reprogram_ap_sta(priv, ctx); | ||||
| 
 | ||||
| 		/* IBSS beacon needs to be sent after setting assoc */ | ||||
| 		if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC)) | ||||
| 			if (iwlagn_update_beacon(priv, ctx->vif)) | ||||
| 				IWL_ERR(priv, "Error sending IBSS beacon\n"); | ||||
| 	} | ||||
| 
 | ||||
| 	iwl_print_rx_config_cmd(priv, ctx); | ||||
| 
 | ||||
| 	iwl_init_sensitivity(priv); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * If we issue a new RXON command which required a tune then we must | ||||
| 	 * send a new TXPOWER command or we won't be able to Tx any frames. | ||||
| 	 * | ||||
| 	 * It's expected we set power here if channel is changing. | ||||
| 	 */ | ||||
| 	ret = iwl_set_tx_power(priv, priv->tx_power_next, true); | ||||
| 	if (ret) { | ||||
| 		IWL_ERR(priv, "Error sending TX power (%d)\n", ret); | ||||
| 		return ret; | ||||
| 	} | ||||
| 	if (new_assoc) | ||||
| 		return iwlagn_rxon_connect(priv, ctx); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
|  |  | |||
|  | @ -161,47 +161,19 @@ static int iwlagn_load_section(struct iwl_priv *priv, const char *name, | |||
| } | ||||
| 
 | ||||
| static int iwlagn_load_given_ucode(struct iwl_priv *priv, | ||||
| 		struct fw_desc *inst_image, | ||||
| 		struct fw_desc *data_image) | ||||
| 				   struct fw_img *image) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	ret = iwlagn_load_section(priv, "INST", inst_image, | ||||
| 	ret = iwlagn_load_section(priv, "INST", &image->code, | ||||
| 				   IWLAGN_RTC_INST_LOWER_BOUND); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	return iwlagn_load_section(priv, "DATA", data_image, | ||||
| 	return iwlagn_load_section(priv, "DATA", &image->data, | ||||
| 				    IWLAGN_RTC_DATA_LOWER_BOUND); | ||||
| } | ||||
| 
 | ||||
| int iwlagn_load_ucode(struct iwl_priv *priv) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	/* check whether init ucode should be loaded, or rather runtime ucode */ | ||||
| 	if (priv->ucode_init.len && (priv->ucode_type == UCODE_NONE)) { | ||||
| 		IWL_DEBUG_INFO(priv, "Init ucode found. Loading init ucode...\n"); | ||||
| 		ret = iwlagn_load_given_ucode(priv, | ||||
| 			&priv->ucode_init, &priv->ucode_init_data); | ||||
| 		if (!ret) { | ||||
| 			IWL_DEBUG_INFO(priv, "Init ucode load complete.\n"); | ||||
| 			priv->ucode_type = UCODE_INIT; | ||||
| 		} | ||||
| 	} else { | ||||
| 		IWL_DEBUG_INFO(priv, "Init ucode not found, or already loaded. " | ||||
| 			"Loading runtime ucode...\n"); | ||||
| 		ret = iwlagn_load_given_ucode(priv, | ||||
| 			&priv->ucode_code, &priv->ucode_data); | ||||
| 		if (!ret) { | ||||
| 			IWL_DEBUG_INFO(priv, "Runtime ucode load complete.\n"); | ||||
| 			priv->ucode_type = UCODE_RT; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  *  Calibration | ||||
|  */ | ||||
|  | @ -297,33 +269,9 @@ void iwlagn_rx_calib_result(struct iwl_priv *priv, | |||
| 	iwl_calib_set(&priv->calib_results[index], pkt->u.raw, len); | ||||
| } | ||||
| 
 | ||||
| void iwlagn_rx_calib_complete(struct iwl_priv *priv, | ||||
| 			       struct iwl_rx_mem_buffer *rxb) | ||||
| static int iwlagn_init_alive_start(struct iwl_priv *priv) | ||||
| { | ||||
| 	IWL_DEBUG_INFO(priv, "Init. calibration is completed, restarting fw.\n"); | ||||
| 	queue_work(priv->workqueue, &priv->restart); | ||||
| } | ||||
| 
 | ||||
| void iwlagn_init_alive_start(struct iwl_priv *priv) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	/* initialize uCode was loaded... verify inst image.
 | ||||
| 	 * This is a paranoid check, because we would not have gotten the | ||||
| 	 * "initialize" alive if code weren't properly loaded.  */ | ||||
| 	if (iwl_verify_ucode(priv, &priv->ucode_init)) { | ||||
| 		/* Runtime instruction load was bad;
 | ||||
| 		 * take it all the way back down so we can try again */ | ||||
| 		IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n"); | ||||
| 		goto restart; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = iwlagn_alive_notify(priv); | ||||
| 	if (ret) { | ||||
| 		IWL_WARN(priv, | ||||
| 			"Could not complete ALIVE transition: %d\n", ret); | ||||
| 		goto restart; | ||||
| 	} | ||||
| 	int ret; | ||||
| 
 | ||||
| 	if (priv->cfg->bt_params && | ||||
| 	    priv->cfg->bt_params->advanced_bt_coexist) { | ||||
|  | @ -333,24 +281,25 @@ void iwlagn_init_alive_start(struct iwl_priv *priv) | |||
| 		 * no need to close the envlope since we are going | ||||
| 		 * to load the runtime uCode later. | ||||
| 		 */ | ||||
| 		iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, | ||||
| 		ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, | ||||
| 			BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | ||||
| 		if (ret) | ||||
| 			return ret; | ||||
| 
 | ||||
| 	} | ||||
| 	iwlagn_send_calib_cfg(priv); | ||||
| 
 | ||||
| 	ret = iwlagn_send_calib_cfg(priv); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	/**
 | ||||
| 	 * temperature offset calibration is only needed for runtime ucode, | ||||
| 	 * so prepare the value now. | ||||
| 	 */ | ||||
| 	if (priv->cfg->need_temp_offset_calib) | ||||
| 		iwlagn_set_temperature_offset_calib(priv); | ||||
| 		return iwlagn_set_temperature_offset_calib(priv); | ||||
| 
 | ||||
| 	return; | ||||
| 
 | ||||
| restart: | ||||
| 	/* real restart (first load init_ucode) */ | ||||
| 	queue_work(priv->workqueue, &priv->restart); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int iwlagn_send_wimax_coex(struct iwl_priv *priv) | ||||
|  | @ -413,19 +362,22 @@ void iwlagn_send_prio_tbl(struct iwl_priv *priv) | |||
| 		IWL_ERR(priv, "failed to send BT prio tbl command\n"); | ||||
| } | ||||
| 
 | ||||
| void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) | ||||
| int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type) | ||||
| { | ||||
| 	struct iwl_bt_coex_prot_env_cmd env_cmd; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	env_cmd.action = action; | ||||
| 	env_cmd.type = type; | ||||
| 	if (iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV, | ||||
| 			     sizeof(env_cmd), &env_cmd)) | ||||
| 	ret = iwl_send_cmd_pdu(priv, REPLY_BT_COEX_PROT_ENV, | ||||
| 			       sizeof(env_cmd), &env_cmd); | ||||
| 	if (ret) | ||||
| 		IWL_ERR(priv, "failed to send BT env command\n"); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int iwlagn_alive_notify(struct iwl_priv *priv) | ||||
| static int iwlagn_alive_notify(struct iwl_priv *priv) | ||||
| { | ||||
| 	const struct queue_to_fifo_ac *queue_to_fifo; | ||||
| 	struct iwl_rxon_context *ctx; | ||||
|  | @ -604,15 +556,164 @@ static void iwl_print_mismatch_inst(struct iwl_priv *priv, | |||
|  * iwl_verify_ucode - determine which instruction image is in SRAM, | ||||
|  *    and verify its contents | ||||
|  */ | ||||
| int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc) | ||||
| static int iwl_verify_ucode(struct iwl_priv *priv, struct fw_img *img) | ||||
| { | ||||
| 	if (!iwlcore_verify_inst_sparse(priv, fw_desc)) { | ||||
| 	if (!iwlcore_verify_inst_sparse(priv, &img->code)) { | ||||
| 		IWL_DEBUG_INFO(priv, "uCode is good in inst SRAM\n"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	IWL_ERR(priv, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); | ||||
| 
 | ||||
| 	iwl_print_mismatch_inst(priv, fw_desc); | ||||
| 	iwl_print_mismatch_inst(priv, &img->code); | ||||
| 	return -EIO; | ||||
| } | ||||
| 
 | ||||
| struct iwlagn_alive_data { | ||||
| 	bool valid; | ||||
| 	u8 subtype; | ||||
| }; | ||||
| 
 | ||||
| static void iwlagn_alive_fn(struct iwl_priv *priv, | ||||
| 			    struct iwl_rx_packet *pkt, | ||||
| 			    void *data) | ||||
| { | ||||
| 	struct iwlagn_alive_data *alive_data = data; | ||||
| 	struct iwl_alive_resp *palive; | ||||
| 
 | ||||
| 	palive = &pkt->u.alive_frame; | ||||
| 
 | ||||
| 	IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " | ||||
| 		       "0x%01X 0x%01X\n", | ||||
| 		       palive->is_valid, palive->ver_type, | ||||
| 		       palive->ver_subtype); | ||||
| 
 | ||||
| 	priv->device_pointers.error_event_table = | ||||
| 		le32_to_cpu(palive->error_event_table_ptr); | ||||
| 	priv->device_pointers.log_event_table = | ||||
| 		le32_to_cpu(palive->log_event_table_ptr); | ||||
| 
 | ||||
| 	alive_data->subtype = palive->ver_subtype; | ||||
| 	alive_data->valid = palive->is_valid == UCODE_VALID_OK; | ||||
| } | ||||
| 
 | ||||
| #define UCODE_ALIVE_TIMEOUT	HZ | ||||
| #define UCODE_CALIB_TIMEOUT	(2*HZ) | ||||
| 
 | ||||
| int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | ||||
| 				 struct fw_img *image, | ||||
| 				 int subtype, int alternate_subtype) | ||||
| { | ||||
| 	struct iwl_notification_wait alive_wait; | ||||
| 	struct iwlagn_alive_data alive_data; | ||||
| 	int ret; | ||||
| 	enum iwlagn_ucode_subtype old_type; | ||||
| 
 | ||||
| 	ret = iwlagn_start_device(priv); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	iwlagn_init_notification_wait(priv, &alive_wait, REPLY_ALIVE, | ||||
| 				      iwlagn_alive_fn, &alive_data); | ||||
| 
 | ||||
| 	old_type = priv->ucode_type; | ||||
| 	priv->ucode_type = subtype; | ||||
| 
 | ||||
| 	ret = iwlagn_load_given_ucode(priv, image); | ||||
| 	if (ret) { | ||||
| 		priv->ucode_type = old_type; | ||||
| 		iwlagn_remove_notification(priv, &alive_wait); | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Remove all resets to allow NIC to operate */ | ||||
| 	iwl_write32(priv, CSR_RESET, 0); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Some things may run in the background now, but we | ||||
| 	 * just wait for the ALIVE notification here. | ||||
| 	 */ | ||||
| 	ret = iwlagn_wait_notification(priv, &alive_wait, UCODE_ALIVE_TIMEOUT); | ||||
| 	if (ret) { | ||||
| 		priv->ucode_type = old_type; | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	if (!alive_data.valid) { | ||||
| 		IWL_ERR(priv, "Loaded ucode is not valid!\n"); | ||||
| 		priv->ucode_type = old_type; | ||||
| 		return -EIO; | ||||
| 	} | ||||
| 
 | ||||
| 	if (alive_data.subtype != subtype && | ||||
| 	    alive_data.subtype != alternate_subtype) { | ||||
| 		IWL_ERR(priv, | ||||
| 			"Loaded ucode is not expected type (got %d, expected %d)!\n", | ||||
| 			alive_data.subtype, subtype); | ||||
| 		priv->ucode_type = old_type; | ||||
| 		return -EIO; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = iwl_verify_ucode(priv, image); | ||||
| 	if (ret) { | ||||
| 		priv->ucode_type = old_type; | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	/* delay a bit to give rfkill time to run */ | ||||
| 	msleep(5); | ||||
| 
 | ||||
| 	ret = iwlagn_alive_notify(priv); | ||||
| 	if (ret) { | ||||
| 		IWL_WARN(priv, | ||||
| 			"Could not complete ALIVE transition: %d\n", ret); | ||||
| 		priv->ucode_type = old_type; | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int iwlagn_run_init_ucode(struct iwl_priv *priv) | ||||
| { | ||||
| 	struct iwl_notification_wait calib_wait; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	lockdep_assert_held(&priv->mutex); | ||||
| 
 | ||||
| 	/* No init ucode required? Curious, but maybe ok */ | ||||
| 	if (!priv->ucode_init.code.len) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	if (priv->ucode_type != UCODE_SUBTYPE_NONE_LOADED) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	iwlagn_init_notification_wait(priv, &calib_wait, | ||||
| 				      CALIBRATION_COMPLETE_NOTIFICATION, | ||||
| 				      NULL, NULL); | ||||
| 
 | ||||
| 	/* Will also start the device */ | ||||
| 	ret = iwlagn_load_ucode_wait_alive(priv, &priv->ucode_init, | ||||
| 					   UCODE_SUBTYPE_INIT, -1); | ||||
| 	if (ret) | ||||
| 		goto error; | ||||
| 
 | ||||
| 	ret = iwlagn_init_alive_start(priv); | ||||
| 	if (ret) | ||||
| 		goto error; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Some things may run in the background now, but we | ||||
| 	 * just wait for the calibration complete notification. | ||||
| 	 */ | ||||
| 	ret = iwlagn_wait_notification(priv, &calib_wait, UCODE_CALIB_TIMEOUT); | ||||
| 
 | ||||
| 	goto out; | ||||
| 
 | ||||
|  error: | ||||
| 	iwlagn_remove_notification(priv, &calib_wait); | ||||
|  out: | ||||
| 	/* Whatever happened, stop the device */ | ||||
| 	iwlagn_stop_device(priv); | ||||
| 	return ret; | ||||
| } | ||||
|  |  | |||
|  | @ -769,7 +769,7 @@ static void iwl_rx_handle(struct iwl_priv *priv) | |||
| 				if (w->cmd == pkt->hdr.cmd) { | ||||
| 					w->triggered = true; | ||||
| 					if (w->fn) | ||||
| 						w->fn(priv, pkt); | ||||
| 						w->fn(priv, pkt, w->fn_data); | ||||
| 				} | ||||
| 			} | ||||
| 			spin_unlock(&priv->_agn.notif_wait_lock); | ||||
|  | @ -846,14 +846,6 @@ static void iwl_rx_handle(struct iwl_priv *priv) | |||
| 		iwlagn_rx_queue_restock(priv); | ||||
| } | ||||
| 
 | ||||
| /* call this function to flush any scheduled tasklet */ | ||||
| static inline void iwl_synchronize_irq(struct iwl_priv *priv) | ||||
| { | ||||
| 	/* wait to make sure we flush pending tasklet*/ | ||||
| 	synchronize_irq(priv->pci_dev->irq); | ||||
| 	tasklet_kill(&priv->irq_tasklet); | ||||
| } | ||||
| 
 | ||||
| /* tasklet for iwlagn interrupt */ | ||||
| static void iwl_irq_tasklet(struct iwl_priv *priv) | ||||
| { | ||||
|  | @ -1181,18 +1173,42 @@ static struct attribute_group iwl_attribute_group = { | |||
|  * | ||||
|  ******************************************************************************/ | ||||
| 
 | ||||
| static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) | ||||
| static void iwl_free_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc) | ||||
| { | ||||
| 	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_code); | ||||
| 	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_data); | ||||
| 	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init); | ||||
| 	iwl_free_fw_desc(priv->pci_dev, &priv->ucode_init_data); | ||||
| 	if (desc->v_addr) | ||||
| 		dma_free_coherent(&pci_dev->dev, desc->len, | ||||
| 				  desc->v_addr, desc->p_addr); | ||||
| 	desc->v_addr = NULL; | ||||
| 	desc->len = 0; | ||||
| } | ||||
| 
 | ||||
| static void iwl_nic_start(struct iwl_priv *priv) | ||||
| static void iwl_free_fw_img(struct pci_dev *pci_dev, struct fw_img *img) | ||||
| { | ||||
| 	/* Remove all resets to allow NIC to operate */ | ||||
| 	iwl_write32(priv, CSR_RESET, 0); | ||||
| 	iwl_free_fw_desc(pci_dev, &img->code); | ||||
| 	iwl_free_fw_desc(pci_dev, &img->data); | ||||
| } | ||||
| 
 | ||||
| static int iwl_alloc_fw_desc(struct pci_dev *pci_dev, struct fw_desc *desc, | ||||
| 			     const void *data, size_t len) | ||||
| { | ||||
| 	if (!len) { | ||||
| 		desc->v_addr = NULL; | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	desc->v_addr = dma_alloc_coherent(&pci_dev->dev, len, | ||||
| 					  &desc->p_addr, GFP_KERNEL); | ||||
| 	if (!desc->v_addr) | ||||
| 		return -ENOMEM; | ||||
| 	desc->len = len; | ||||
| 	memcpy(desc->v_addr, data, len); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static void iwl_dealloc_ucode_pci(struct iwl_priv *priv) | ||||
| { | ||||
| 	iwl_free_fw_img(priv->pci_dev, &priv->ucode_rt); | ||||
| 	iwl_free_fw_img(priv->pci_dev, &priv->ucode_init); | ||||
| } | ||||
| 
 | ||||
| struct iwlagn_ucode_capabilities { | ||||
|  | @ -1661,24 +1677,20 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
| 	/* Runtime instructions and 2 copies of data:
 | ||||
| 	 * 1) unmodified from disk | ||||
| 	 * 2) backup cache for save/restore during power-downs */ | ||||
| 	priv->ucode_code.len = pieces.inst_size; | ||||
| 	iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code); | ||||
| 
 | ||||
| 	priv->ucode_data.len = pieces.data_size; | ||||
| 	iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data); | ||||
| 
 | ||||
| 	if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr) | ||||
| 	if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.code, | ||||
| 			      pieces.inst, pieces.inst_size)) | ||||
| 		goto err_pci_alloc; | ||||
| 	if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_rt.data, | ||||
| 			      pieces.data, pieces.data_size)) | ||||
| 		goto err_pci_alloc; | ||||
| 
 | ||||
| 	/* Initialization instructions and data */ | ||||
| 	if (pieces.init_size && pieces.init_data_size) { | ||||
| 		priv->ucode_init.len = pieces.init_size; | ||||
| 		iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init); | ||||
| 
 | ||||
| 		priv->ucode_init_data.len = pieces.init_data_size; | ||||
| 		iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data); | ||||
| 
 | ||||
| 		if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr) | ||||
| 		if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.code, | ||||
| 				      pieces.init, pieces.init_size)) | ||||
| 			goto err_pci_alloc; | ||||
| 		if (iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init.data, | ||||
| 				      pieces.init_data, pieces.init_data_size)) | ||||
| 			goto err_pci_alloc; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -1704,6 +1716,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
| 			priv->cfg->base_params->max_event_log_size; | ||||
| 	priv->_agn.inst_errlog_ptr = pieces.inst_errlog_ptr; | ||||
| 
 | ||||
| 	priv->new_scan_threshold_behaviour = | ||||
| 		!!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); | ||||
| 
 | ||||
| 	if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { | ||||
| 		priv->valid_contexts |= BIT(IWL_RXON_CTX_PAN); | ||||
| 		priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; | ||||
|  | @ -1715,39 +1730,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) | |||
| 	else | ||||
| 		priv->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; | ||||
| 
 | ||||
| 	/* Copy images into buffers for card's bus-master reads ... */ | ||||
| 
 | ||||
| 	/* Runtime instructions (first block of data in file) */ | ||||
| 	IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", | ||||
| 			pieces.inst_size); | ||||
| 	memcpy(priv->ucode_code.v_addr, pieces.inst, pieces.inst_size); | ||||
| 
 | ||||
| 	IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", | ||||
| 		priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Runtime data | ||||
| 	 * NOTE:  Copy into backup buffer will be done in iwl_up() | ||||
| 	 */ | ||||
| 	IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", | ||||
| 			pieces.data_size); | ||||
| 	memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size); | ||||
| 
 | ||||
| 	/* Initialization instructions */ | ||||
| 	if (pieces.init_size) { | ||||
| 		IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n", | ||||
| 				pieces.init_size); | ||||
| 		memcpy(priv->ucode_init.v_addr, pieces.init, pieces.init_size); | ||||
| 	} | ||||
| 
 | ||||
| 	/* Initialization data */ | ||||
| 	if (pieces.init_data_size) { | ||||
| 		IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n", | ||||
| 			       pieces.init_data_size); | ||||
| 		memcpy(priv->ucode_init_data.v_addr, pieces.init_data, | ||||
| 		       pieces.init_data_size); | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * figure out the offset of chain noise reset and gain commands | ||||
| 	 * base on the size of standard phy calibration commands table size | ||||
|  | @ -1878,9 +1860,10 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
| 	u32 desc, time, count, base, data1; | ||||
| 	u32 blink1, blink2, ilink1, ilink2; | ||||
| 	u32 pc, hcmd; | ||||
| 	struct iwl_error_event_table table; | ||||
| 
 | ||||
| 	base = priv->device_pointers.error_event_table; | ||||
| 	if (priv->ucode_type == UCODE_INIT) { | ||||
| 	if (priv->ucode_type == UCODE_SUBTYPE_INIT) { | ||||
| 		if (!base) | ||||
| 			base = priv->_agn.init_errlog_ptr; | ||||
| 	} else { | ||||
|  | @ -1891,11 +1874,15 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
| 	if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | ||||
| 		IWL_ERR(priv, | ||||
| 			"Not valid error log pointer 0x%08X for %s uCode\n", | ||||
| 			base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); | ||||
| 			base, | ||||
| 			(priv->ucode_type == UCODE_SUBTYPE_INIT) | ||||
| 					? "Init" : "RT"); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	count = iwl_read_targ_mem(priv, base); | ||||
| 	iwl_read_targ_mem_words(priv, base, &table, sizeof(table)); | ||||
| 
 | ||||
| 	count = table.valid; | ||||
| 
 | ||||
| 	if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) { | ||||
| 		IWL_ERR(priv, "Start IWL Error Log Dump:\n"); | ||||
|  | @ -1903,18 +1890,18 @@ void iwl_dump_nic_error_log(struct iwl_priv *priv) | |||
| 			priv->status, count); | ||||
| 	} | ||||
| 
 | ||||
| 	desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32)); | ||||
| 	desc = table.error_id; | ||||
| 	priv->isr_stats.err_code = desc; | ||||
| 	pc = iwl_read_targ_mem(priv, base + 2 * sizeof(u32)); | ||||
| 	blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32)); | ||||
| 	blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32)); | ||||
| 	ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32)); | ||||
| 	ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32)); | ||||
| 	data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32)); | ||||
| 	data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32)); | ||||
| 	line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32)); | ||||
| 	time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32)); | ||||
| 	hcmd = iwl_read_targ_mem(priv, base + 22 * sizeof(u32)); | ||||
| 	pc = table.pc; | ||||
| 	blink1 = table.blink1; | ||||
| 	blink2 = table.blink2; | ||||
| 	ilink1 = table.ilink1; | ||||
| 	ilink2 = table.ilink2; | ||||
| 	data1 = table.data1; | ||||
| 	data2 = table.data2; | ||||
| 	line = table.line; | ||||
| 	time = table.tsf_low; | ||||
| 	hcmd = table.hcmd; | ||||
| 
 | ||||
| 	trace_iwlwifi_dev_ucode_error(priv, desc, time, data1, data2, line, | ||||
| 				      blink1, blink2, ilink1, ilink2); | ||||
|  | @ -1949,7 +1936,7 @@ static int iwl_print_event_log(struct iwl_priv *priv, u32 start_idx, | |||
| 		return pos; | ||||
| 
 | ||||
| 	base = priv->device_pointers.log_event_table; | ||||
| 	if (priv->ucode_type == UCODE_INIT) { | ||||
| 	if (priv->ucode_type == UCODE_SUBTYPE_INIT) { | ||||
| 		if (!base) | ||||
| 			base = priv->_agn.init_evtlog_ptr; | ||||
| 	} else { | ||||
|  | @ -2062,7 +2049,7 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | |||
| 	size_t bufsz = 0; | ||||
| 
 | ||||
| 	base = priv->device_pointers.log_event_table; | ||||
| 	if (priv->ucode_type == UCODE_INIT) { | ||||
| 	if (priv->ucode_type == UCODE_SUBTYPE_INIT) { | ||||
| 		logsize = priv->_agn.init_evtlog_size; | ||||
| 		if (!base) | ||||
| 			base = priv->_agn.init_evtlog_ptr; | ||||
|  | @ -2075,7 +2062,9 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, bool full_log, | |||
| 	if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) { | ||||
| 		IWL_ERR(priv, | ||||
| 			"Invalid event log pointer 0x%08X for %s uCode\n", | ||||
| 			base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT"); | ||||
| 			base, | ||||
| 			(priv->ucode_type == UCODE_SUBTYPE_INIT) | ||||
| 					? "Init" : "RT"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -2222,31 +2211,15 @@ static int iwlagn_send_calib_cfg_rt(struct iwl_priv *priv, u32 cfg) | |||
|  *                   from protocol/runtime uCode (initialization uCode's | ||||
|  *                   Alive gets handled by iwl_init_alive_start()). | ||||
|  */ | ||||
| static void iwl_alive_start(struct iwl_priv *priv) | ||||
| static int iwl_alive_start(struct iwl_priv *priv) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||||
| 
 | ||||
| 	iwl_reset_ict(priv); | ||||
| 
 | ||||
| 	IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | ||||
| 
 | ||||
| 	/* Initialize uCode has loaded Runtime uCode ... verify inst image.
 | ||||
| 	 * This is a paranoid check, because we would not have gotten the | ||||
| 	 * "runtime" alive if code weren't properly loaded.  */ | ||||
| 	if (iwl_verify_ucode(priv, &priv->ucode_code)) { | ||||
| 		/* Runtime instruction load was bad;
 | ||||
| 		 * take it all the way back down so we can try again */ | ||||
| 		IWL_DEBUG_INFO(priv, "Bad runtime uCode load.\n"); | ||||
| 		goto restart; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = iwlagn_alive_notify(priv); | ||||
| 	if (ret) { | ||||
| 		IWL_WARN(priv, | ||||
| 			"Could not complete ALIVE transition [ntf]: %d\n", ret); | ||||
| 		goto restart; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	/* After the ALIVE response, we can send host commands to the uCode */ | ||||
| 	set_bit(STATUS_ALIVE, &priv->status); | ||||
| 
 | ||||
|  | @ -2254,7 +2227,7 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
| 	iwl_setup_watchdog(priv); | ||||
| 
 | ||||
| 	if (iwl_is_rfkill(priv)) | ||||
| 		return; | ||||
| 		return -ERFKILL; | ||||
| 
 | ||||
| 	/* download priority table before any calibration request */ | ||||
| 	if (priv->cfg->bt_params && | ||||
|  | @ -2268,10 +2241,14 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
| 		iwlagn_send_prio_tbl(priv); | ||||
| 
 | ||||
| 		/* FIXME: w/a to force change uCode BT state machine */ | ||||
| 		iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, | ||||
| 			BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | ||||
| 		iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, | ||||
| 			BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | ||||
| 		ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_OPEN, | ||||
| 					 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | ||||
| 		if (ret) | ||||
| 			return ret; | ||||
| 		ret = iwlagn_send_bt_env(priv, IWL_BT_COEX_ENV_CLOSE, | ||||
| 					 BT_COEX_PRIO_TBL_EVT_INIT_CALIB2); | ||||
| 		if (ret) | ||||
| 			return ret; | ||||
| 	} | ||||
| 	if (priv->hw_params.calib_rt_cfg) | ||||
| 		iwlagn_send_calib_cfg_rt(priv, priv->hw_params.calib_rt_cfg); | ||||
|  | @ -2313,29 +2290,22 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
| 	set_bit(STATUS_READY, &priv->status); | ||||
| 
 | ||||
| 	/* Configure the adapter for unassociated operation */ | ||||
| 	iwlcore_commit_rxon(priv, ctx); | ||||
| 	ret = iwlcore_commit_rxon(priv, ctx); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	/* At this point, the NIC is initialized and operational */ | ||||
| 	iwl_rf_kill_ct_config(priv); | ||||
| 
 | ||||
| 	IWL_DEBUG_INFO(priv, "ALIVE processing complete.\n"); | ||||
| 	wake_up_interruptible(&priv->wait_command_queue); | ||||
| 
 | ||||
| 	iwl_power_update_mode(priv, true); | ||||
| 	IWL_DEBUG_INFO(priv, "Updated power mode\n"); | ||||
| 
 | ||||
| 
 | ||||
| 	return; | ||||
| 
 | ||||
|  restart: | ||||
| 	queue_work(priv->workqueue, &priv->restart); | ||||
| 	return iwl_power_update_mode(priv, true); | ||||
| } | ||||
| 
 | ||||
| static void iwl_cancel_deferred_work(struct iwl_priv *priv); | ||||
| 
 | ||||
| static void __iwl_down(struct iwl_priv *priv) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 	int exit_pending; | ||||
| 
 | ||||
| 	IWL_DEBUG_INFO(priv, DRV_NAME " is going down\n"); | ||||
|  | @ -2367,32 +2337,10 @@ static void __iwl_down(struct iwl_priv *priv) | |||
| 	if (!exit_pending) | ||||
| 		clear_bit(STATUS_EXIT_PENDING, &priv->status); | ||||
| 
 | ||||
| 	/* stop and reset the on-board processor */ | ||||
| 	iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); | ||||
| 
 | ||||
| 	/* tell the device to stop sending interrupts */ | ||||
| 	spin_lock_irqsave(&priv->lock, flags); | ||||
| 	iwl_disable_interrupts(priv); | ||||
| 	spin_unlock_irqrestore(&priv->lock, flags); | ||||
| 	iwl_synchronize_irq(priv); | ||||
| 
 | ||||
| 	if (priv->mac80211_registered) | ||||
| 		ieee80211_stop_queues(priv->hw); | ||||
| 
 | ||||
| 	/* If we have not previously called iwl_init() then
 | ||||
| 	 * clear all bits but the RF Kill bit and return */ | ||||
| 	if (!iwl_is_init(priv)) { | ||||
| 		priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) << | ||||
| 					STATUS_RF_KILL_HW | | ||||
| 			       test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | ||||
| 					STATUS_GEO_CONFIGURED | | ||||
| 			       test_bit(STATUS_EXIT_PENDING, &priv->status) << | ||||
| 					STATUS_EXIT_PENDING; | ||||
| 		goto exit; | ||||
| 	} | ||||
| 
 | ||||
| 	/* ...otherwise clear out all the status bits but the RF Kill
 | ||||
| 	 * bit and continue taking the NIC down. */ | ||||
| 	/* Clear out all status bits but a few that are stable across reset */ | ||||
| 	priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) << | ||||
| 				STATUS_RF_KILL_HW | | ||||
| 			test_bit(STATUS_GEO_CONFIGURED, &priv->status) << | ||||
|  | @ -2402,23 +2350,8 @@ static void __iwl_down(struct iwl_priv *priv) | |||
| 		       test_bit(STATUS_EXIT_PENDING, &priv->status) << | ||||
| 				STATUS_EXIT_PENDING; | ||||
| 
 | ||||
| 	/* device going down, Stop using ICT table */ | ||||
| 	iwl_disable_ict(priv); | ||||
| 	iwlagn_stop_device(priv); | ||||
| 
 | ||||
| 	iwlagn_txq_ctx_stop(priv); | ||||
| 	iwlagn_rxq_stop(priv); | ||||
| 
 | ||||
| 	/* Power-down device's busmaster DMA clocks */ | ||||
| 	iwl_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); | ||||
| 	udelay(5); | ||||
| 
 | ||||
| 	/* Make sure (redundant) we've released our request to stay awake */ | ||||
| 	iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); | ||||
| 
 | ||||
| 	/* Stop the device, and put it in low power state */ | ||||
| 	iwl_apm_stop(priv); | ||||
| 
 | ||||
|  exit: | ||||
| 	dev_kfree_skb(priv->beacon_skb); | ||||
| 	priv->beacon_skb = NULL; | ||||
| 
 | ||||
|  | @ -2437,9 +2370,10 @@ static void iwl_down(struct iwl_priv *priv) | |||
| 
 | ||||
| #define HW_READY_TIMEOUT (50) | ||||
| 
 | ||||
| /* Note: returns poll_bit return value, which is >= 0 if success */ | ||||
| static int iwl_set_hw_ready(struct iwl_priv *priv) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||||
| 		CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); | ||||
|  | @ -2449,25 +2383,21 @@ static int iwl_set_hw_ready(struct iwl_priv *priv) | |||
| 				CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, | ||||
| 				CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, | ||||
| 				HW_READY_TIMEOUT); | ||||
| 	if (ret != -ETIMEDOUT) | ||||
| 		priv->hw_ready = true; | ||||
| 	else | ||||
| 		priv->hw_ready = false; | ||||
| 
 | ||||
| 	IWL_DEBUG_INFO(priv, "hardware %s\n", | ||||
| 		      (priv->hw_ready == 1) ? "ready" : "not ready"); | ||||
| 	IWL_DEBUG_INFO(priv, "hardware%s ready\n", ret < 0 ? " not" : ""); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static int iwl_prepare_card_hw(struct iwl_priv *priv) | ||||
| /* Note: returns standard 0/-ERROR code */ | ||||
| int iwl_prepare_card_hw(struct iwl_priv *priv) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	IWL_DEBUG_INFO(priv, "iwl_prepare_card_hw enter\n"); | ||||
| 
 | ||||
| 	ret = iwl_set_hw_ready(priv); | ||||
| 	if (priv->hw_ready) | ||||
| 		return ret; | ||||
| 	if (ret >= 0) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/* If HW is not ready, prepare the conditions to check again */ | ||||
| 	iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||||
|  | @ -2477,10 +2407,13 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv) | |||
| 			~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, | ||||
| 			CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); | ||||
| 
 | ||||
| 	/* HW should be ready by now, check again. */ | ||||
| 	if (ret != -ETIMEDOUT) | ||||
| 		iwl_set_hw_ready(priv); | ||||
| 	if (ret < 0) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	/* HW should be ready by now, check again. */ | ||||
| 	ret = iwl_set_hw_ready(priv); | ||||
| 	if (ret >= 0) | ||||
| 		return 0; | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
|  | @ -2489,9 +2422,10 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv) | |||
| static int __iwl_up(struct iwl_priv *priv) | ||||
| { | ||||
| 	struct iwl_rxon_context *ctx; | ||||
| 	int i; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	lockdep_assert_held(&priv->mutex); | ||||
| 
 | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||||
| 		IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); | ||||
| 		return -EIO; | ||||
|  | @ -2505,77 +2439,33 @@ static int __iwl_up(struct iwl_priv *priv) | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	iwl_prepare_card_hw(priv); | ||||
| 
 | ||||
| 	if (!priv->hw_ready) { | ||||
| 		IWL_WARN(priv, "Exit HW not ready\n"); | ||||
| 		return -EIO; | ||||
| 	} | ||||
| 
 | ||||
| 	/* If platform's RF_KILL switch is NOT set to KILL */ | ||||
| 	if (iwl_read32(priv, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) | ||||
| 		clear_bit(STATUS_RF_KILL_HW, &priv->status); | ||||
| 	else | ||||
| 		set_bit(STATUS_RF_KILL_HW, &priv->status); | ||||
| 
 | ||||
| 	if (iwl_is_rfkill(priv)) { | ||||
| 		wiphy_rfkill_set_hw_state(priv->hw->wiphy, true); | ||||
| 
 | ||||
| 		iwl_enable_interrupts(priv); | ||||
| 		IWL_WARN(priv, "Radio disabled by HW RF Kill switch\n"); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | ||||
| 
 | ||||
| 	ret = iwlagn_hw_nic_init(priv); | ||||
| 	ret = iwlagn_run_init_ucode(priv); | ||||
| 	if (ret) { | ||||
| 		IWL_ERR(priv, "Unable to init nic\n"); | ||||
| 		return ret; | ||||
| 		IWL_ERR(priv, "Failed to run INIT ucode: %d\n", ret); | ||||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
| 	/* make sure rfkill handshake bits are cleared */ | ||||
| 	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||||
| 	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, | ||||
| 		    CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); | ||||
| 
 | ||||
| 	/* clear (again), then enable host interrupts */ | ||||
| 	iwl_write32(priv, CSR_INT, 0xFFFFFFFF); | ||||
| 	iwl_enable_interrupts(priv); | ||||
| 
 | ||||
| 	/* really make sure rfkill handshake bits are cleared */ | ||||
| 	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||||
| 	iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); | ||||
| 
 | ||||
| 	for (i = 0; i < MAX_HW_RESTARTS; i++) { | ||||
| 
 | ||||
| 		/* load bootstrap state machine,
 | ||||
| 		 * load bootstrap program into processor's memory, | ||||
| 		 * prepare to load the "initialize" uCode */ | ||||
| 		ret = iwlagn_load_ucode(priv); | ||||
| 
 | ||||
| 		if (ret) { | ||||
| 			IWL_ERR(priv, "Unable to set up bootstrap uCode: %d\n", | ||||
| 				ret); | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		/* start card; "initialize" will load runtime ucode */ | ||||
| 		iwl_nic_start(priv); | ||||
| 
 | ||||
| 		IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n"); | ||||
| 
 | ||||
| 		return 0; | ||||
| 	ret = iwlagn_load_ucode_wait_alive(priv, | ||||
| 					   &priv->ucode_rt, | ||||
| 					   UCODE_SUBTYPE_REGULAR, | ||||
| 					   UCODE_SUBTYPE_REGULAR_NEW); | ||||
| 	if (ret) { | ||||
| 		IWL_ERR(priv, "Failed to start RT ucode: %d\n", ret); | ||||
| 		goto error; | ||||
| 	} | ||||
| 
 | ||||
| 	ret = iwl_alive_start(priv); | ||||
| 	if (ret) | ||||
| 		goto error; | ||||
| 	return 0; | ||||
| 
 | ||||
|  error: | ||||
| 	set_bit(STATUS_EXIT_PENDING, &priv->status); | ||||
| 	__iwl_down(priv); | ||||
| 	clear_bit(STATUS_EXIT_PENDING, &priv->status); | ||||
| 
 | ||||
| 	/* tried to restart and config the device for as long as our
 | ||||
| 	 * patience could withstand */ | ||||
| 	IWL_ERR(priv, "Unable to initialize device after %d attempts.\n", i); | ||||
| 	return -EIO; | ||||
| 	IWL_ERR(priv, "Unable to initialize device.\n"); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -2585,39 +2475,6 @@ static int __iwl_up(struct iwl_priv *priv) | |||
|  * | ||||
|  *****************************************************************************/ | ||||
| 
 | ||||
| static void iwl_bg_init_alive_start(struct work_struct *data) | ||||
| { | ||||
| 	struct iwl_priv *priv = | ||||
| 	    container_of(data, struct iwl_priv, init_alive_start.work); | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 
 | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||||
| 		mutex_unlock(&priv->mutex); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	iwlagn_init_alive_start(priv); | ||||
| 	mutex_unlock(&priv->mutex); | ||||
| } | ||||
| 
 | ||||
| static void iwl_bg_alive_start(struct work_struct *data) | ||||
| { | ||||
| 	struct iwl_priv *priv = | ||||
| 	    container_of(data, struct iwl_priv, alive_start.work); | ||||
| 
 | ||||
| 	mutex_lock(&priv->mutex); | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 		goto unlock; | ||||
| 
 | ||||
| 	/* enable dram interrupt */ | ||||
| 	iwl_reset_ict(priv); | ||||
| 
 | ||||
| 	iwl_alive_start(priv); | ||||
| unlock: | ||||
| 	mutex_unlock(&priv->mutex); | ||||
| } | ||||
| 
 | ||||
| static void iwl_bg_run_time_calib_work(struct work_struct *work) | ||||
| { | ||||
| 	struct iwl_priv *priv = container_of(work, struct iwl_priv, | ||||
|  | @ -2639,6 +2496,42 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work) | |||
| 	mutex_unlock(&priv->mutex); | ||||
| } | ||||
| 
 | ||||
| static void iwlagn_prepare_restart(struct iwl_priv *priv) | ||||
| { | ||||
| 	struct iwl_rxon_context *ctx; | ||||
| 	bool bt_full_concurrent; | ||||
| 	u8 bt_ci_compliance; | ||||
| 	u8 bt_load; | ||||
| 	u8 bt_status; | ||||
| 
 | ||||
| 	lockdep_assert_held(&priv->mutex); | ||||
| 
 | ||||
| 	for_each_context(priv, ctx) | ||||
| 		ctx->vif = NULL; | ||||
| 	priv->is_open = 0; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * __iwl_down() will clear the BT status variables, | ||||
| 	 * which is correct, but when we restart we really | ||||
| 	 * want to keep them so restore them afterwards. | ||||
| 	 * | ||||
| 	 * The restart process will later pick them up and | ||||
| 	 * re-configure the hw when we reconfigure the BT | ||||
| 	 * command. | ||||
| 	 */ | ||||
| 	bt_full_concurrent = priv->bt_full_concurrent; | ||||
| 	bt_ci_compliance = priv->bt_ci_compliance; | ||||
| 	bt_load = priv->bt_traffic_load; | ||||
| 	bt_status = priv->bt_status; | ||||
| 
 | ||||
| 	__iwl_down(priv); | ||||
| 
 | ||||
| 	priv->bt_full_concurrent = bt_full_concurrent; | ||||
| 	priv->bt_ci_compliance = bt_ci_compliance; | ||||
| 	priv->bt_traffic_load = bt_load; | ||||
| 	priv->bt_status = bt_status; | ||||
| } | ||||
| 
 | ||||
| static void iwl_bg_restart(struct work_struct *data) | ||||
| { | ||||
| 	struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); | ||||
|  | @ -2647,50 +2540,13 @@ static void iwl_bg_restart(struct work_struct *data) | |||
| 		return; | ||||
| 
 | ||||
| 	if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { | ||||
| 		struct iwl_rxon_context *ctx; | ||||
| 		bool bt_full_concurrent; | ||||
| 		u8 bt_ci_compliance; | ||||
| 		u8 bt_load; | ||||
| 		u8 bt_status; | ||||
| 
 | ||||
| 		mutex_lock(&priv->mutex); | ||||
| 		for_each_context(priv, ctx) | ||||
| 			ctx->vif = NULL; | ||||
| 		priv->is_open = 0; | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * __iwl_down() will clear the BT status variables, | ||||
| 		 * which is correct, but when we restart we really | ||||
| 		 * want to keep them so restore them afterwards. | ||||
| 		 * | ||||
| 		 * The restart process will later pick them up and | ||||
| 		 * re-configure the hw when we reconfigure the BT | ||||
| 		 * command. | ||||
| 		 */ | ||||
| 		bt_full_concurrent = priv->bt_full_concurrent; | ||||
| 		bt_ci_compliance = priv->bt_ci_compliance; | ||||
| 		bt_load = priv->bt_traffic_load; | ||||
| 		bt_status = priv->bt_status; | ||||
| 
 | ||||
| 		__iwl_down(priv); | ||||
| 
 | ||||
| 		priv->bt_full_concurrent = bt_full_concurrent; | ||||
| 		priv->bt_ci_compliance = bt_ci_compliance; | ||||
| 		priv->bt_traffic_load = bt_load; | ||||
| 		priv->bt_status = bt_status; | ||||
| 
 | ||||
| 		iwlagn_prepare_restart(priv); | ||||
| 		mutex_unlock(&priv->mutex); | ||||
| 		iwl_cancel_deferred_work(priv); | ||||
| 		ieee80211_restart_hw(priv->hw); | ||||
| 	} else { | ||||
| 		iwl_down(priv); | ||||
| 
 | ||||
| 		if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
| 			return; | ||||
| 
 | ||||
| 		mutex_lock(&priv->mutex); | ||||
| 		__iwl_up(priv); | ||||
| 		mutex_unlock(&priv->mutex); | ||||
| 		WARN_ON(1); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -2801,8 +2657,6 @@ unlock: | |||
|  * | ||||
|  *****************************************************************************/ | ||||
| 
 | ||||
| #define UCODE_READY_TIMEOUT	(4 * HZ) | ||||
| 
 | ||||
| /*
 | ||||
|  * Not a mac80211 entry point function, but it fits in with all the | ||||
|  * other mac80211 functions grouped here. | ||||
|  | @ -2895,31 +2749,17 @@ static int iwlagn_mac_start(struct ieee80211_hw *hw) | |||
| 	mutex_lock(&priv->mutex); | ||||
| 	ret = __iwl_up(priv); | ||||
| 	mutex_unlock(&priv->mutex); | ||||
| 
 | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	if (iwl_is_rfkill(priv)) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	IWL_DEBUG_INFO(priv, "Start UP work done.\n"); | ||||
| 
 | ||||
| 	/* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
 | ||||
| 	 * mac80211 will not be run successfully. */ | ||||
| 	ret = wait_event_interruptible_timeout(priv->wait_command_queue, | ||||
| 			test_bit(STATUS_READY, &priv->status), | ||||
| 			UCODE_READY_TIMEOUT); | ||||
| 	if (!ret) { | ||||
| 		if (!test_bit(STATUS_READY, &priv->status)) { | ||||
| 			IWL_ERR(priv, "START_ALIVE timeout after %dms.\n", | ||||
| 				jiffies_to_msecs(UCODE_READY_TIMEOUT)); | ||||
| 			return -ETIMEDOUT; | ||||
| 		} | ||||
| 	} | ||||
| 	/* Now we should be done, and the READY bit should be set. */ | ||||
| 	if (WARN_ON(!test_bit(STATUS_READY, &priv->status))) | ||||
| 		ret = -EIO; | ||||
| 
 | ||||
| 	iwlagn_led_enable(priv); | ||||
| 
 | ||||
| out: | ||||
| 	priv->is_open = 1; | ||||
| 	IWL_DEBUG_MAC80211(priv, "leave\n"); | ||||
| 	return 0; | ||||
|  | @ -2994,7 +2834,7 @@ static int iwlagn_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | |||
| 
 | ||||
| 	IWL_DEBUG_MAC80211(priv, "enter\n"); | ||||
| 
 | ||||
| 	if (priv->cfg->mod_params->sw_crypto) { | ||||
| 	if (iwlagn_mod_params.sw_crypto) { | ||||
| 		IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n"); | ||||
| 		return -EOPNOTSUPP; | ||||
| 	} | ||||
|  | @ -3506,8 +3346,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv) | |||
| 	INIT_WORK(&priv->tx_flush, iwl_bg_tx_flush); | ||||
| 	INIT_WORK(&priv->bt_full_concurrency, iwl_bg_bt_full_concurrency); | ||||
| 	INIT_WORK(&priv->bt_runtime_config, iwl_bg_bt_runtime_config); | ||||
| 	INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); | ||||
| 	INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); | ||||
| 	INIT_DELAYED_WORK(&priv->_agn.hw_roc_work, iwlagn_bg_roc_done); | ||||
| 
 | ||||
| 	iwl_setup_scan_deferred_work(priv); | ||||
|  | @ -3536,8 +3374,6 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv) | |||
| 	if (priv->cfg->ops->lib->cancel_deferred_work) | ||||
| 		priv->cfg->ops->lib->cancel_deferred_work(priv); | ||||
| 
 | ||||
| 	cancel_delayed_work_sync(&priv->init_alive_start); | ||||
| 	cancel_delayed_work(&priv->alive_start); | ||||
| 	cancel_work_sync(&priv->run_time_calib_work); | ||||
| 	cancel_work_sync(&priv->beacon_update); | ||||
| 
 | ||||
|  | @ -3617,12 +3453,6 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
| 		priv->dynamic_frag_thresh = BT_FRAG_THRESHOLD_DEF; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Set the tx_power_user_lmt to the lowest power level
 | ||||
| 	 * this value will get overwritten by channel max power avg | ||||
| 	 * from eeprom */ | ||||
| 	priv->tx_power_user_lmt = IWLAGN_TX_POWER_TARGET_POWER_MIN; | ||||
| 	priv->tx_power_next = IWLAGN_TX_POWER_TARGET_POWER_MIN; | ||||
| 
 | ||||
| 	ret = iwl_init_channel_map(priv); | ||||
| 	if (ret) { | ||||
| 		IWL_ERR(priv, "initializing regulatory failed: %d\n", ret); | ||||
|  | @ -3692,14 +3522,14 @@ static int iwl_set_hw_params(struct iwl_priv *priv) | |||
| { | ||||
| 	priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; | ||||
| 	priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; | ||||
| 	if (priv->cfg->mod_params->amsdu_size_8K) | ||||
| 	if (iwlagn_mod_params.amsdu_size_8K) | ||||
| 		priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_8K); | ||||
| 	else | ||||
| 		priv->hw_params.rx_page_order = get_order(IWL_RX_BUF_SIZE_4K); | ||||
| 
 | ||||
| 	priv->hw_params.max_beacon_itrvl = IWL_MAX_UCODE_BEACON_INTERVAL; | ||||
| 
 | ||||
| 	if (priv->cfg->mod_params->disable_11n) | ||||
| 	if (iwlagn_mod_params.disable_11n) | ||||
| 		priv->cfg->sku &= ~IWL_SKU_N; | ||||
| 
 | ||||
| 	/* Device-specific setup */ | ||||
|  | @ -3772,6 +3602,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 	priv = hw->priv; | ||||
| 	/* At this point both hw and priv are allocated. */ | ||||
| 
 | ||||
| 	priv->ucode_type = UCODE_SUBTYPE_NONE_LOADED; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * The default context is always valid, | ||||
| 	 * more may be discovered when firmware | ||||
|  | @ -3912,8 +3744,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 	 * PCI Tx retries from interfering with C3 CPU state */ | ||||
| 	pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | ||||
| 
 | ||||
| 	iwl_prepare_card_hw(priv); | ||||
| 	if (!priv->hw_ready) { | ||||
| 	if (iwl_prepare_card_hw(priv)) { | ||||
| 		IWL_WARN(priv, "Failed, HW not ready\n"); | ||||
| 		goto out_iounmap; | ||||
| 	} | ||||
|  | @ -4069,17 +3900,9 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
| 	if (priv->mac80211_registered) { | ||||
| 		ieee80211_unregister_hw(priv->hw); | ||||
| 		priv->mac80211_registered = 0; | ||||
| 	} else { | ||||
| 		iwl_down(priv); | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Make sure device is reset to low power before unloading driver. | ||||
| 	 * This may be redundant with iwl_down(), but there are paths to | ||||
| 	 * run iwl_down() without calling apm_ops.stop(), and there are | ||||
| 	 * paths to avoid running iwl_down() at all before leaving driver. | ||||
| 	 * This (inexpensive) call *makes sure* device is reset. | ||||
| 	 */ | ||||
| 	/* Reset to low power before unloading driver. */ | ||||
| 	iwl_apm_stop(priv); | ||||
| 
 | ||||
| 	iwl_tt_exit(priv); | ||||
|  | @ -4306,21 +4129,21 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { | |||
| 	{IWL_PCI_DEVICE(0x088F, 0x4266, iwl6035_2bg_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x088E, 0x4466, iwl6035_2bg_cfg)}, | ||||
| 
 | ||||
| /* 200 Series */ | ||||
| 	{IWL_PCI_DEVICE(0x0894, 0x0022, iwl200_bgn_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0895, 0x0222, iwl200_bgn_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0894, 0x0422, iwl200_bgn_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0894, 0x0026, iwl200_bg_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0895, 0x0226, iwl200_bg_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0894, 0x0426, iwl200_bg_cfg)}, | ||||
| /* 105 Series */ | ||||
| 	{IWL_PCI_DEVICE(0x0894, 0x0022, iwl105_bgn_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0895, 0x0222, iwl105_bgn_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0894, 0x0422, iwl105_bgn_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0894, 0x0026, iwl105_bg_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0895, 0x0226, iwl105_bg_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0894, 0x0426, iwl105_bg_cfg)}, | ||||
| 
 | ||||
| /* 230 Series */ | ||||
| 	{IWL_PCI_DEVICE(0x0892, 0x0062, iwl230_bgn_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0893, 0x0262, iwl230_bgn_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0892, 0x0462, iwl230_bgn_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0892, 0x0066, iwl230_bg_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0893, 0x0266, iwl230_bg_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0892, 0x0466, iwl230_bg_cfg)}, | ||||
| /* 135 Series */ | ||||
| 	{IWL_PCI_DEVICE(0x0892, 0x0062, iwl135_bgn_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0893, 0x0262, iwl135_bgn_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0892, 0x0462, iwl135_bgn_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0892, 0x0066, iwl135_bg_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0893, 0x0266, iwl135_bg_cfg)}, | ||||
| 	{IWL_PCI_DEVICE(0x0892, 0x0466, iwl135_bg_cfg)}, | ||||
| 
 | ||||
| 	{0} | ||||
| }; | ||||
|  |  | |||
|  | @ -102,10 +102,10 @@ extern struct iwl_cfg iwl2030_2bg_cfg; | |||
| extern struct iwl_cfg iwl6035_2agn_cfg; | ||||
| extern struct iwl_cfg iwl6035_2abg_cfg; | ||||
| extern struct iwl_cfg iwl6035_2bg_cfg; | ||||
| extern struct iwl_cfg iwl200_bg_cfg; | ||||
| extern struct iwl_cfg iwl200_bgn_cfg; | ||||
| extern struct iwl_cfg iwl230_bg_cfg; | ||||
| extern struct iwl_cfg iwl230_bgn_cfg; | ||||
| extern struct iwl_cfg iwl105_bg_cfg; | ||||
| extern struct iwl_cfg iwl105_bgn_cfg; | ||||
| extern struct iwl_cfg iwl135_bg_cfg; | ||||
| extern struct iwl_cfg iwl135_bgn_cfg; | ||||
| 
 | ||||
| extern struct iwl_mod_params iwlagn_mod_params; | ||||
| extern struct iwl_hcmd_ops iwlagn_hcmd; | ||||
|  | @ -120,6 +120,19 @@ int iwl_alloc_isr_ict(struct iwl_priv *priv); | |||
| void iwl_free_isr_ict(struct iwl_priv *priv); | ||||
| irqreturn_t iwl_isr_ict(int irq, void *data); | ||||
| 
 | ||||
| /* call this function to flush any scheduled tasklet */ | ||||
| static inline void iwl_synchronize_irq(struct iwl_priv *priv) | ||||
| { | ||||
| 	/* wait to make sure we flush pending tasklet*/ | ||||
| 	synchronize_irq(priv->pci_dev->irq); | ||||
| 	tasklet_kill(&priv->irq_tasklet); | ||||
| } | ||||
| 
 | ||||
| int iwl_prepare_card_hw(struct iwl_priv *priv); | ||||
| 
 | ||||
| int iwlagn_start_device(struct iwl_priv *priv); | ||||
| void iwlagn_stop_device(struct iwl_priv *priv); | ||||
| 
 | ||||
| /* tx queue */ | ||||
| void iwlagn_set_wr_ptrs(struct iwl_priv *priv, | ||||
| 		     int txq_id, u32 index); | ||||
|  | @ -145,16 +158,14 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw, | |||
| 			     u32 changes); | ||||
| 
 | ||||
| /* uCode */ | ||||
| int iwlagn_load_ucode(struct iwl_priv *priv); | ||||
| void iwlagn_rx_calib_result(struct iwl_priv *priv, | ||||
| 			 struct iwl_rx_mem_buffer *rxb); | ||||
| void iwlagn_rx_calib_complete(struct iwl_priv *priv, | ||||
| 			   struct iwl_rx_mem_buffer *rxb); | ||||
| void iwlagn_init_alive_start(struct iwl_priv *priv); | ||||
| int iwlagn_alive_notify(struct iwl_priv *priv); | ||||
| int iwl_verify_ucode(struct iwl_priv *priv, struct fw_desc *fw_desc); | ||||
| void iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); | ||||
| int iwlagn_send_bt_env(struct iwl_priv *priv, u8 action, u8 type); | ||||
| void iwlagn_send_prio_tbl(struct iwl_priv *priv); | ||||
| int iwlagn_run_init_ucode(struct iwl_priv *priv); | ||||
| int iwlagn_load_ucode_wait_alive(struct iwl_priv *priv, | ||||
| 				 struct fw_img *image, | ||||
| 				 int subtype, int alternate_subtype); | ||||
| 
 | ||||
| /* lib */ | ||||
| void iwl_check_abort_status(struct iwl_priv *priv, | ||||
|  | @ -245,8 +256,6 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv, | |||
| 			       struct ieee80211_vif *vif, bool add); | ||||
| 
 | ||||
| /* hcmd */ | ||||
| int iwlagn_send_rxon_assoc(struct iwl_priv *priv, | ||||
| 			   struct iwl_rxon_context *ctx); | ||||
| int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); | ||||
| int iwlagn_send_beacon_cmd(struct iwl_priv *priv); | ||||
| 
 | ||||
|  | @ -318,17 +327,17 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags) | |||
| /* eeprom */ | ||||
| void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv); | ||||
| void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac); | ||||
| int iwlcore_eeprom_acquire_semaphore(struct iwl_priv *priv); | ||||
| void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv); | ||||
| 
 | ||||
| /* notification wait support */ | ||||
| void __acquires(wait_entry) | ||||
| iwlagn_init_notification_wait(struct iwl_priv *priv, | ||||
| 			      struct iwl_notification_wait *wait_entry, | ||||
| 			      u8 cmd, | ||||
| 			      void (*fn)(struct iwl_priv *priv, | ||||
| 					 struct iwl_rx_packet *pkt), | ||||
| 			      u8 cmd); | ||||
| signed long __releases(wait_entry) | ||||
| 					 struct iwl_rx_packet *pkt, | ||||
| 					 void *data), | ||||
| 			      void *fn_data); | ||||
| int __must_check __releases(wait_entry) | ||||
| iwlagn_wait_notification(struct iwl_priv *priv, | ||||
| 			 struct iwl_notification_wait *wait_entry, | ||||
| 			 unsigned long timeout); | ||||
|  |  | |||
|  | @ -386,7 +386,18 @@ struct iwl_tx_ant_config_cmd { | |||
|  *****************************************************************************/ | ||||
| 
 | ||||
| #define UCODE_VALID_OK	cpu_to_le32(0x1) | ||||
| #define INITIALIZE_SUBTYPE    (9) | ||||
| 
 | ||||
| enum iwlagn_ucode_subtype { | ||||
| 	UCODE_SUBTYPE_REGULAR	= 0, | ||||
| 	UCODE_SUBTYPE_REGULAR_NEW = 1, | ||||
| 	UCODE_SUBTYPE_INIT	= 9, | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Not a valid subtype, the ucode has just a u8, so | ||||
| 	 * we can use something > 0xff for this value. | ||||
| 	 */ | ||||
| 	UCODE_SUBTYPE_NONE_LOADED = 0x100, | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * REPLY_ALIVE = 0x1 (response only, not a command) | ||||
|  | @ -422,49 +433,61 @@ struct iwl_tx_ant_config_cmd { | |||
|  * | ||||
|  * 2)  error_event_table_ptr indicates base of the error log.  This contains | ||||
|  *     information about any uCode error that occurs.  For agn, the format | ||||
|  *     of the error log is: | ||||
|  * | ||||
|  *	__le32 valid;        (nonzero) valid, (0) log is empty | ||||
|  *	__le32 error_id;     type of error | ||||
|  *	__le32 pc;           program counter | ||||
|  *	__le32 blink1;       branch link | ||||
|  *	__le32 blink2;       branch link | ||||
|  *	__le32 ilink1;       interrupt link | ||||
|  *	__le32 ilink2;       interrupt link | ||||
|  *	__le32 data1;        error-specific data | ||||
|  *	__le32 data2;        error-specific data | ||||
|  *	__le32 line;         source code line of error | ||||
|  *	__le32 bcon_time;    beacon timer | ||||
|  *	__le32 tsf_low;      network timestamp function timer | ||||
|  *	__le32 tsf_hi;       network timestamp function timer | ||||
|  *	__le32 gp1;          GP1 timer register | ||||
|  *	__le32 gp2;          GP2 timer register | ||||
|  *	__le32 gp3;          GP3 timer register | ||||
|  *	__le32 ucode_ver;    uCode version | ||||
|  *	__le32 hw_ver;       HW Silicon version | ||||
|  *	__le32 brd_ver;      HW board version | ||||
|  *	__le32 log_pc;       log program counter | ||||
|  *	__le32 frame_ptr;    frame pointer | ||||
|  *	__le32 stack_ptr;    stack pointer | ||||
|  *	__le32 hcmd;         last host command | ||||
|  *	__le32 isr0;         isr status register LMPM_NIC_ISR0: rxtx_flag | ||||
|  *	__le32 isr1;         isr status register LMPM_NIC_ISR1: host_flag | ||||
|  *	__le32 isr2;         isr status register LMPM_NIC_ISR2: enc_flag | ||||
|  *	__le32 isr3;         isr status register LMPM_NIC_ISR3: time_flag | ||||
|  *	__le32 isr4;         isr status register LMPM_NIC_ISR4: wico interrupt | ||||
|  *	__le32 isr_pref;     isr status register LMPM_NIC_PREF_STAT | ||||
|  *	__le32 wait_event;   wait event() caller address | ||||
|  *	__le32 l2p_control;  L2pControlField | ||||
|  *	__le32 l2p_duration; L2pDurationField | ||||
|  *	__le32 l2p_mhvalid;  L2pMhValidBits | ||||
|  *	__le32 l2p_addr_match; L2pAddrMatchStat | ||||
|  *	__le32 lmpm_pmg_sel; indicate which clocks are turned on (LMPM_PMG_SEL) | ||||
|  *	__le32 u_timestamp;  indicate when the date and time of the compilation | ||||
|  *	__le32 reserved; | ||||
|  *     of the error log is defined by struct iwl_error_event_table. | ||||
|  * | ||||
|  * The Linux driver can print both logs to the system log when a uCode error | ||||
|  * occurs. | ||||
|  */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Note: This structure is read from the device with IO accesses, | ||||
|  * and the reading already does the endian conversion. As it is | ||||
|  * read with u32-sized accesses, any members with a different size | ||||
|  * need to be ordered correctly though! | ||||
|  */ | ||||
| struct iwl_error_event_table { | ||||
| 	u32 valid;		/* (nonzero) valid, (0) log is empty */ | ||||
| 	u32 error_id;		/* type of error */ | ||||
| 	u32 pc;			/* program counter */ | ||||
| 	u32 blink1;		/* branch link */ | ||||
| 	u32 blink2;		/* branch link */ | ||||
| 	u32 ilink1;		/* interrupt link */ | ||||
| 	u32 ilink2;		/* interrupt link */ | ||||
| 	u32 data1;		/* error-specific data */ | ||||
| 	u32 data2;		/* error-specific data */ | ||||
| 	u32 line;		/* source code line of error */ | ||||
| 	u32 bcon_time;		/* beacon timer */ | ||||
| 	u32 tsf_low;		/* network timestamp function timer */ | ||||
| 	u32 tsf_hi;		/* network timestamp function timer */ | ||||
| 	u32 gp1;		/* GP1 timer register */ | ||||
| 	u32 gp2;		/* GP2 timer register */ | ||||
| 	u32 gp3;		/* GP3 timer register */ | ||||
| 	u32 ucode_ver;		/* uCode version */ | ||||
| 	u32 hw_ver;		/* HW Silicon version */ | ||||
| 	u32 brd_ver;		/* HW board version */ | ||||
| 	u32 log_pc;		/* log program counter */ | ||||
| 	u32 frame_ptr;		/* frame pointer */ | ||||
| 	u32 stack_ptr;		/* stack pointer */ | ||||
| 	u32 hcmd;		/* last host command header */ | ||||
| #if 0 | ||||
| 	/* no need to read the remainder, we don't use the values */ | ||||
| 	u32 isr0;		/* isr status register LMPM_NIC_ISR0: rxtx_flag */ | ||||
| 	u32 isr1;		/* isr status register LMPM_NIC_ISR1: host_flag */ | ||||
| 	u32 isr2;		/* isr status register LMPM_NIC_ISR2: enc_flag */ | ||||
| 	u32 isr3;		/* isr status register LMPM_NIC_ISR3: time_flag */ | ||||
| 	u32 isr4;		/* isr status register LMPM_NIC_ISR4: wico interrupt */ | ||||
| 	u32 isr_pref;		/* isr status register LMPM_NIC_PREF_STAT */ | ||||
| 	u32 wait_event;		/* wait event() caller address */ | ||||
| 	u32 l2p_control;	/* L2pControlField */ | ||||
| 	u32 l2p_duration;	/* L2pDurationField */ | ||||
| 	u32 l2p_mhvalid;	/* L2pMhValidBits */ | ||||
| 	u32 l2p_addr_match;	/* L2pAddrMatchStat */ | ||||
| 	u32 lmpm_pmg_sel;	/* indicate which clocks are turned on (LMPM_PMG_SEL) */ | ||||
| 	u32 u_timestamp;	/* indicate when the date and time of the compilation */ | ||||
| 	u32 flow_handler;	/* FH read/write pointers, RX credit */ | ||||
| #endif | ||||
| } __packed; | ||||
| 
 | ||||
| struct iwl_alive_resp { | ||||
| 	u8 ucode_minor; | ||||
| 	u8 ucode_major; | ||||
|  | @ -638,7 +661,7 @@ struct iwl_rxon_cmd { | |||
| /*
 | ||||
|  * REPLY_RXON_ASSOC = 0x11 (command, has simple generic response) | ||||
|  */ | ||||
| struct iwl5000_rxon_assoc_cmd { | ||||
| struct iwl_rxon_assoc_cmd { | ||||
| 	__le32 flags; | ||||
| 	__le32 filter_flags; | ||||
| 	u8 ofdm_basic_rates; | ||||
|  |  | |||
|  | @ -41,6 +41,7 @@ | |||
| #include "iwl-power.h" | ||||
| #include "iwl-sta.h" | ||||
| #include "iwl-helpers.h" | ||||
| #include "iwl-agn.h" | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -94,7 +95,7 @@ static void iwlcore_init_ht_hw_capab(const struct iwl_priv *priv, | |||
| 		max_bit_rate = MAX_BIT_RATE_40_MHZ; | ||||
| 	} | ||||
| 
 | ||||
| 	if (priv->cfg->mod_params->amsdu_size_8K) | ||||
| 	if (iwlagn_mod_params.amsdu_size_8K) | ||||
| 		ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; | ||||
| 
 | ||||
| 	ht_info->ampdu_factor = CFG_HT_RX_AMPDU_FACTOR_DEF; | ||||
|  | @ -135,6 +136,7 @@ int iwlcore_init_geos(struct iwl_priv *priv) | |||
| 	struct ieee80211_channel *geo_ch; | ||||
| 	struct ieee80211_rate *rates; | ||||
| 	int i = 0; | ||||
| 	s8 max_tx_power = IWLAGN_TX_POWER_TARGET_POWER_MIN; | ||||
| 
 | ||||
| 	if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates || | ||||
| 	    priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) { | ||||
|  | @ -208,8 +210,8 @@ int iwlcore_init_geos(struct iwl_priv *priv) | |||
| 
 | ||||
| 			geo_ch->flags |= ch->ht40_extension_channel; | ||||
| 
 | ||||
| 			if (ch->max_power_avg > priv->tx_power_device_lmt) | ||||
| 				priv->tx_power_device_lmt = ch->max_power_avg; | ||||
| 			if (ch->max_power_avg > max_tx_power) | ||||
| 				max_tx_power = ch->max_power_avg; | ||||
| 		} else { | ||||
| 			geo_ch->flags |= IEEE80211_CHAN_DISABLED; | ||||
| 		} | ||||
|  | @ -222,6 +224,10 @@ int iwlcore_init_geos(struct iwl_priv *priv) | |||
| 				 geo_ch->flags); | ||||
| 	} | ||||
| 
 | ||||
| 	priv->tx_power_device_lmt = max_tx_power; | ||||
| 	priv->tx_power_user_lmt = max_tx_power; | ||||
| 	priv->tx_power_next = max_tx_power; | ||||
| 
 | ||||
| 	if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && | ||||
| 	     priv->cfg->sku & IWL_SKU_A) { | ||||
| 		IWL_INFO(priv, "Incorrectly detected BG card as ABG. " | ||||
|  | @ -410,72 +416,72 @@ void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, | |||
| int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx) | ||||
| { | ||||
| 	struct iwl_rxon_cmd *rxon = &ctx->staging; | ||||
| 	bool error = false; | ||||
| 	u32 errors = 0; | ||||
| 
 | ||||
| 	if (rxon->flags & RXON_FLG_BAND_24G_MSK) { | ||||
| 		if (rxon->flags & RXON_FLG_TGJ_NARROW_BAND_MSK) { | ||||
| 			IWL_WARN(priv, "check 2.4G: wrong narrow\n"); | ||||
| 			error = true; | ||||
| 			errors |= BIT(0); | ||||
| 		} | ||||
| 		if (rxon->flags & RXON_FLG_RADAR_DETECT_MSK) { | ||||
| 			IWL_WARN(priv, "check 2.4G: wrong radar\n"); | ||||
| 			error = true; | ||||
| 			errors |= BIT(1); | ||||
| 		} | ||||
| 	} else { | ||||
| 		if (!(rxon->flags & RXON_FLG_SHORT_SLOT_MSK)) { | ||||
| 			IWL_WARN(priv, "check 5.2G: not short slot!\n"); | ||||
| 			error = true; | ||||
| 			errors |= BIT(2); | ||||
| 		} | ||||
| 		if (rxon->flags & RXON_FLG_CCK_MSK) { | ||||
| 			IWL_WARN(priv, "check 5.2G: CCK!\n"); | ||||
| 			error = true; | ||||
| 			errors |= BIT(3); | ||||
| 		} | ||||
| 	} | ||||
| 	if ((rxon->node_addr[0] | rxon->bssid_addr[0]) & 0x1) { | ||||
| 		IWL_WARN(priv, "mac/bssid mcast!\n"); | ||||
| 		error = true; | ||||
| 		errors |= BIT(4); | ||||
| 	} | ||||
| 
 | ||||
| 	/* make sure basic rates 6Mbps and 1Mbps are supported */ | ||||
| 	if ((rxon->ofdm_basic_rates & IWL_RATE_6M_MASK) == 0 && | ||||
| 	    (rxon->cck_basic_rates & IWL_RATE_1M_MASK) == 0) { | ||||
| 		IWL_WARN(priv, "neither 1 nor 6 are basic\n"); | ||||
| 		error = true; | ||||
| 		errors |= BIT(5); | ||||
| 	} | ||||
| 
 | ||||
| 	if (le16_to_cpu(rxon->assoc_id) > 2007) { | ||||
| 		IWL_WARN(priv, "aid > 2007\n"); | ||||
| 		error = true; | ||||
| 		errors |= BIT(6); | ||||
| 	} | ||||
| 
 | ||||
| 	if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) | ||||
| 			== (RXON_FLG_CCK_MSK | RXON_FLG_SHORT_SLOT_MSK)) { | ||||
| 		IWL_WARN(priv, "CCK and short slot\n"); | ||||
| 		error = true; | ||||
| 		errors |= BIT(7); | ||||
| 	} | ||||
| 
 | ||||
| 	if ((rxon->flags & (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) | ||||
| 			== (RXON_FLG_CCK_MSK | RXON_FLG_AUTO_DETECT_MSK)) { | ||||
| 		IWL_WARN(priv, "CCK and auto detect"); | ||||
| 		error = true; | ||||
| 		errors |= BIT(8); | ||||
| 	} | ||||
| 
 | ||||
| 	if ((rxon->flags & (RXON_FLG_AUTO_DETECT_MSK | | ||||
| 			    RXON_FLG_TGG_PROTECT_MSK)) == | ||||
| 			    RXON_FLG_TGG_PROTECT_MSK) { | ||||
| 		IWL_WARN(priv, "TGg but no auto-detect\n"); | ||||
| 		error = true; | ||||
| 		errors |= BIT(9); | ||||
| 	} | ||||
| 
 | ||||
| 	if (error) | ||||
| 		IWL_WARN(priv, "Tuning to channel %d\n", | ||||
| 			    le16_to_cpu(rxon->channel)); | ||||
| 
 | ||||
| 	if (error) { | ||||
| 		IWL_ERR(priv, "Invalid RXON\n"); | ||||
| 		return -EINVAL; | ||||
| 	if (rxon->channel == 0) { | ||||
| 		IWL_WARN(priv, "zero channel is invalid\n"); | ||||
| 		errors |= BIT(10); | ||||
| 	} | ||||
| 	return 0; | ||||
| 
 | ||||
| 	WARN(errors, "Invalid RXON (%#x), channel %d", | ||||
| 	     errors, le16_to_cpu(rxon->channel)); | ||||
| 
 | ||||
| 	return errors ? -EINVAL : 0; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -867,6 +873,19 @@ void iwl_print_rx_config_cmd(struct iwl_priv *priv, | |||
| } | ||||
| #endif | ||||
| 
 | ||||
| static void iwlagn_abort_notification_waits(struct iwl_priv *priv) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 	struct iwl_notification_wait *wait_entry; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->_agn.notif_wait_lock, flags); | ||||
| 	list_for_each_entry(wait_entry, &priv->_agn.notif_waits, list) | ||||
| 		wait_entry->aborted = true; | ||||
| 	spin_unlock_irqrestore(&priv->_agn.notif_wait_lock, flags); | ||||
| 
 | ||||
| 	wake_up_all(&priv->_agn.notif_waitq); | ||||
| } | ||||
| 
 | ||||
| void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | ||||
| { | ||||
| 	unsigned int reload_msec; | ||||
|  | @ -878,6 +897,8 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
| 	/* Cancel currently queued command. */ | ||||
| 	clear_bit(STATUS_HCMD_ACTIVE, &priv->status); | ||||
| 
 | ||||
| 	iwlagn_abort_notification_waits(priv); | ||||
| 
 | ||||
| 	/* Keep the restart process from trying to send host
 | ||||
| 	 * commands by clearing the ready bit */ | ||||
| 	clear_bit(STATUS_READY, &priv->status); | ||||
|  | @ -906,7 +927,7 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) | |||
| 	} | ||||
| 
 | ||||
| 	if (!test_bit(STATUS_EXIT_PENDING, &priv->status)) { | ||||
| 		if (priv->cfg->mod_params->restart_fw) { | ||||
| 		if (iwlagn_mod_params.restart_fw) { | ||||
| 			IWL_DEBUG(priv, IWL_DL_FW_ERRORS, | ||||
| 				  "Restarting adapter due to uCode error.\n"); | ||||
| 			queue_work(priv->workqueue, &priv->restart); | ||||
|  | @ -975,6 +996,8 @@ void iwl_apm_stop(struct iwl_priv *priv) | |||
| { | ||||
| 	IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n"); | ||||
| 
 | ||||
| 	clear_bit(STATUS_DEVICE_ENABLED, &priv->status); | ||||
| 
 | ||||
| 	/* Stop device's DMA activity */ | ||||
| 	iwl_apm_stop_master(priv); | ||||
| 
 | ||||
|  | @ -1089,6 +1112,8 @@ int iwl_apm_init(struct iwl_priv *priv) | |||
| 	iwl_set_bits_prph(priv, APMG_PCIDEV_STT_REG, | ||||
| 			  APMG_PCIDEV_STT_VAL_L1_ACT_DIS); | ||||
| 
 | ||||
| 	set_bit(STATUS_DEVICE_ENABLED, &priv->status); | ||||
| 
 | ||||
| out: | ||||
| 	return ret; | ||||
| } | ||||
|  | @ -1723,7 +1748,7 @@ int iwl_force_reset(struct iwl_priv *priv, int mode, bool external) | |||
| 		 * detect failure), then fw_restart module parameter | ||||
| 		 * need to be check before performing firmware reload | ||||
| 		 */ | ||||
| 		if (!external && !priv->cfg->mod_params->restart_fw) { | ||||
| 		if (!external && !iwlagn_mod_params.restart_fw) { | ||||
| 			IWL_DEBUG_INFO(priv, "Cancel firmware reload based on " | ||||
| 				       "module parameter setting\n"); | ||||
| 			break; | ||||
|  | @ -1740,6 +1765,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| { | ||||
| 	struct iwl_priv *priv = hw->priv; | ||||
| 	struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | ||||
| 	struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||||
| 	struct iwl_rxon_context *tmp; | ||||
| 	u32 interface_modes; | ||||
| 	int err; | ||||
|  | @ -1764,6 +1790,19 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Refuse a change that should be done by moving from the PAN | ||||
| 	 * context to the BSS context instead, if the BSS context is | ||||
| 	 * available and can support the new interface type. | ||||
| 	 */ | ||||
| 	if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif && | ||||
| 	    (bss_ctx->interface_modes & BIT(newtype) || | ||||
| 	     bss_ctx->exclusive_interface_modes & BIT(newtype))) { | ||||
| 		BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); | ||||
| 		err = -EBUSY; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	if (ctx->exclusive_interface_modes & BIT(newtype)) { | ||||
| 		for_each_context(priv, tmp) { | ||||
| 			if (ctx == tmp) | ||||
|  |  | |||
|  | @ -90,7 +90,6 @@ struct iwl_cmd; | |||
| #define IWL_CMD(x) case x: return #x | ||||
| 
 | ||||
| struct iwl_hcmd_ops { | ||||
| 	int (*rxon_assoc)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||||
| 	int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||||
| 	void (*set_rxon_chain)(struct iwl_priv *priv, | ||||
| 			       struct iwl_rxon_context *ctx); | ||||
|  | @ -122,19 +121,6 @@ struct iwl_apm_ops { | |||
| 	void (*config)(struct iwl_priv *priv); | ||||
| }; | ||||
| 
 | ||||
| struct iwl_debugfs_ops { | ||||
| 	ssize_t (*rx_stats_read)(struct file *file, char __user *user_buf, | ||||
| 				 size_t count, loff_t *ppos); | ||||
| 	ssize_t (*tx_stats_read)(struct file *file, char __user *user_buf, | ||||
| 				 size_t count, loff_t *ppos); | ||||
| 	ssize_t (*general_stats_read)(struct file *file, char __user *user_buf, | ||||
| 				      size_t count, loff_t *ppos); | ||||
| 	ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf, | ||||
| 				 size_t count, loff_t *ppos); | ||||
| 	ssize_t (*reply_tx_error)(struct file *file, char __user *user_buf, | ||||
| 				 size_t count, loff_t *ppos); | ||||
| }; | ||||
| 
 | ||||
| struct iwl_temp_ops { | ||||
| 	void (*temperature)(struct iwl_priv *priv); | ||||
| }; | ||||
|  | @ -183,7 +169,6 @@ struct iwl_lib_ops { | |||
| 	int (*txfifo_flush)(struct iwl_priv *priv, u16 flush_control); | ||||
| 	void (*dev_txfifo_flush)(struct iwl_priv *priv, u16 flush_control); | ||||
| 
 | ||||
| 	struct iwl_debugfs_ops debugfs_ops; | ||||
| }; | ||||
| 
 | ||||
| /* NIC specific ops */ | ||||
|  | @ -326,8 +311,6 @@ struct iwl_cfg { | |||
| 	u16  eeprom_ver; | ||||
| 	u16  eeprom_calib_ver; | ||||
| 	const struct iwl_ops *ops; | ||||
| 	/* module based parameters which can be set from modprobe cmd */ | ||||
| 	const struct iwl_mod_params *mod_params; | ||||
| 	/* params not likely to change within a device family */ | ||||
| 	struct iwl_base_params *base_params; | ||||
| 	/* params likely to change within a device family */ | ||||
|  | @ -592,6 +575,7 @@ void iwlcore_free_geos(struct iwl_priv *priv); | |||
| #define STATUS_SCAN_HW		15 | ||||
| #define STATUS_POWER_PMI	16 | ||||
| #define STATUS_FW_ERROR		17 | ||||
| #define STATUS_DEVICE_ENABLED	18 | ||||
| 
 | ||||
| 
 | ||||
| static inline int iwl_is_ready(struct iwl_priv *priv) | ||||
|  | @ -644,11 +628,6 @@ void iwl_apm_stop(struct iwl_priv *priv); | |||
| int iwl_apm_init(struct iwl_priv *priv); | ||||
| 
 | ||||
| int iwl_send_rxon_timing(struct iwl_priv *priv, struct iwl_rxon_context *ctx); | ||||
| static inline int iwl_send_rxon_assoc(struct iwl_priv *priv, | ||||
| 				      struct iwl_rxon_context *ctx) | ||||
| { | ||||
| 	return priv->cfg->ops->hcmd->rxon_assoc(priv, ctx); | ||||
| } | ||||
| static inline int iwlcore_commit_rxon(struct iwl_priv *priv, | ||||
| 				      struct iwl_rxon_context *ctx) | ||||
| { | ||||
|  |  | |||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							|  | @ -479,6 +479,10 @@ struct fw_desc { | |||
| 	u32 len;		/* bytes */ | ||||
| }; | ||||
| 
 | ||||
| struct fw_img { | ||||
| 	struct fw_desc code, data; | ||||
| }; | ||||
| 
 | ||||
| /* v1/v2 uCode file layout */ | ||||
| struct iwl_ucode_header { | ||||
| 	__le32 ver;	/* major/minor/API/serial */ | ||||
|  | @ -543,12 +547,13 @@ enum iwl_ucode_tlv_type { | |||
|  * enum iwl_ucode_tlv_flag - ucode API flags | ||||
|  * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously | ||||
|  *	was a separate TLV but moved here to save space. | ||||
|  * @IWL_UCODE_TLV_FLAGS_RESERVED_1: reserved | ||||
|  * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, | ||||
|  *	treats good CRC threshold as a boolean | ||||
|  * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). | ||||
|  */ | ||||
| enum iwl_ucode_tlv_flag { | ||||
| 	IWL_UCODE_TLV_FLAGS_PAN		= BIT(0), | ||||
| 	IWL_UCODE_TLV_FLAGS_RESERVED_1	= BIT(1), | ||||
| 	IWL_UCODE_TLV_FLAGS_NEWSCAN	= BIT(1), | ||||
| 	IWL_UCODE_TLV_FLAGS_MFP		= BIT(2), | ||||
| }; | ||||
| 
 | ||||
|  | @ -794,12 +799,6 @@ struct iwl_calib_result { | |||
| 	size_t buf_len; | ||||
| }; | ||||
| 
 | ||||
| enum ucode_type { | ||||
| 	UCODE_NONE = 0, | ||||
| 	UCODE_INIT, | ||||
| 	UCODE_RT | ||||
| }; | ||||
| 
 | ||||
| /* Sensitivity calib data */ | ||||
| struct iwl_sensitivity_data { | ||||
| 	u32 auto_corr_ofdm; | ||||
|  | @ -1105,10 +1104,12 @@ struct iwl_force_reset { | |||
| struct iwl_notification_wait { | ||||
| 	struct list_head list; | ||||
| 
 | ||||
| 	void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt); | ||||
| 	void (*fn)(struct iwl_priv *priv, struct iwl_rx_packet *pkt, | ||||
| 		   void *data); | ||||
| 	void *fn_data; | ||||
| 
 | ||||
| 	u8 cmd; | ||||
| 	bool triggered; | ||||
| 	bool triggered, aborted; | ||||
| }; | ||||
| 
 | ||||
| enum iwl_rxon_context_id { | ||||
|  | @ -1263,6 +1264,8 @@ struct iwl_priv { | |||
| 	/* max number of station keys */ | ||||
| 	u8 sta_key_max_num; | ||||
| 
 | ||||
| 	bool new_scan_threshold_behaviour; | ||||
| 
 | ||||
| 	/* EEPROM MAC addresses */ | ||||
| 	struct mac_address addresses[2]; | ||||
| 
 | ||||
|  | @ -1270,11 +1273,10 @@ struct iwl_priv { | |||
| 	int fw_index;			/* firmware we're trying to load */ | ||||
| 	u32 ucode_ver;			/* version of ucode, copy of
 | ||||
| 					   iwl_ucode.ver */ | ||||
| 	struct fw_desc ucode_code;	/* runtime inst */ | ||||
| 	struct fw_desc ucode_data;	/* runtime data original */ | ||||
| 	struct fw_desc ucode_init;	/* initialization inst */ | ||||
| 	struct fw_desc ucode_init_data;	/* initialization data */ | ||||
| 	enum ucode_type ucode_type; | ||||
| 	struct fw_img ucode_rt; | ||||
| 	struct fw_img ucode_init; | ||||
| 
 | ||||
| 	enum iwlagn_ucode_subtype ucode_type; | ||||
| 	u8 ucode_write_complete;	/* the image write is complete */ | ||||
| 	char firmware_name[25]; | ||||
| 
 | ||||
|  | @ -1472,8 +1474,6 @@ struct iwl_priv { | |||
| 
 | ||||
| 	struct tasklet_struct irq_tasklet; | ||||
| 
 | ||||
| 	struct delayed_work init_alive_start; | ||||
| 	struct delayed_work alive_start; | ||||
| 	struct delayed_work scan_check; | ||||
| 
 | ||||
| 	/* TX Power */ | ||||
|  | @ -1506,7 +1506,6 @@ struct iwl_priv { | |||
| 	struct timer_list statistics_periodic; | ||||
| 	struct timer_list ucode_trace; | ||||
| 	struct timer_list watchdog; | ||||
| 	bool hw_ready; | ||||
| 
 | ||||
| 	struct iwl_event_log event_log; | ||||
| 
 | ||||
|  |  | |||
|  | @ -142,6 +142,45 @@ static const u8 iwl_eeprom_band_7[] = {       /* 5.2 ht40 channel */ | |||
|  * | ||||
| ******************************************************************************/ | ||||
| 
 | ||||
| /*
 | ||||
|  * The device's EEPROM semaphore prevents conflicts between driver and uCode | ||||
|  * when accessing the EEPROM; each access is a series of pulses to/from the | ||||
|  * EEPROM chip, not a single event, so even reads could conflict if they | ||||
|  * weren't arbitrated by the semaphore. | ||||
|  */ | ||||
| static int iwl_eeprom_acquire_semaphore(struct iwl_priv *priv) | ||||
| { | ||||
| 	u16 count; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { | ||||
| 		/* Request semaphore */ | ||||
| 		iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG, | ||||
| 			    CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||||
| 
 | ||||
| 		/* See if we got it */ | ||||
| 		ret = iwl_poll_bit(priv, CSR_HW_IF_CONFIG_REG, | ||||
| 				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||||
| 				CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, | ||||
| 				EEPROM_SEM_TIMEOUT); | ||||
| 		if (ret >= 0) { | ||||
| 			IWL_DEBUG_EEPROM(priv, | ||||
| 				"Acquired semaphore after %d tries.\n", | ||||
| 				count+1); | ||||
| 			return ret; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void iwl_eeprom_release_semaphore(struct iwl_priv *priv) | ||||
| { | ||||
| 	iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG, | ||||
| 		CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| static int iwl_eeprom_verify_signature(struct iwl_priv *priv) | ||||
| { | ||||
| 	u32 gp = iwl_read32(priv, CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; | ||||
|  | @ -421,7 +460,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
| 	} | ||||
| 
 | ||||
| 	/* Make sure driver (instead of uCode) is allowed to read EEPROM */ | ||||
| 	ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv); | ||||
| 	ret = iwl_eeprom_acquire_semaphore(priv); | ||||
| 	if (ret < 0) { | ||||
| 		IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n"); | ||||
| 		ret = -ENOENT; | ||||
|  | @ -488,7 +527,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) | |||
| 
 | ||||
| 	ret = 0; | ||||
| done: | ||||
| 	priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv); | ||||
| 	iwl_eeprom_release_semaphore(priv); | ||||
| 
 | ||||
| err: | ||||
| 	if (ret) | ||||
|  | @ -711,13 +750,6 @@ int iwl_init_channel_map(struct iwl_priv *priv) | |||
| 					     flags & EEPROM_CHANNEL_RADAR)) | ||||
| 				       ? "" : "not "); | ||||
| 
 | ||||
| 			/* Set the tx_power_user_lmt to the highest power
 | ||||
| 			 * supported by any channel */ | ||||
| 			if (eeprom_ch_info[ch].max_power_avg > | ||||
| 						priv->tx_power_user_lmt) | ||||
| 				priv->tx_power_user_lmt = | ||||
| 				    eeprom_ch_info[ch].max_power_avg; | ||||
| 
 | ||||
| 			ch_info++; | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -294,9 +294,6 @@ extern const u8 iwl_eeprom_band_1[14]; | |||
| 
 | ||||
| struct iwl_eeprom_ops { | ||||
| 	const u32 regulatory_bands[7]; | ||||
| 	int (*acquire_semaphore) (struct iwl_priv *priv); | ||||
| 	void (*release_semaphore) (struct iwl_priv *priv); | ||||
| 	u16 (*calib_version) (struct iwl_priv *priv); | ||||
| 	const u8* (*query_addr) (const struct iwl_priv *priv, size_t offset); | ||||
| 	void (*update_enhanced_txpower) (struct iwl_priv *priv); | ||||
| }; | ||||
|  |  | |||
|  | @ -64,30 +64,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd) | |||
| 	return --index & (n_bd - 1); | ||||
| } | ||||
| 
 | ||||
| /* TODO: Move fw_desc functions to iwl-pci.ko */ | ||||
| static inline void iwl_free_fw_desc(struct pci_dev *pci_dev, | ||||
| 				    struct fw_desc *desc) | ||||
| { | ||||
| 	if (desc->v_addr) | ||||
| 		dma_free_coherent(&pci_dev->dev, desc->len, | ||||
| 				  desc->v_addr, desc->p_addr); | ||||
| 	desc->v_addr = NULL; | ||||
| 	desc->len = 0; | ||||
| } | ||||
| 
 | ||||
| static inline int iwl_alloc_fw_desc(struct pci_dev *pci_dev, | ||||
| 				    struct fw_desc *desc) | ||||
| { | ||||
| 	if (!desc->len) { | ||||
| 		desc->v_addr = NULL; | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	desc->v_addr = dma_alloc_coherent(&pci_dev->dev, desc->len, | ||||
| 					  &desc->p_addr, GFP_KERNEL); | ||||
| 	return (desc->v_addr != NULL) ? 0 : -ENOMEM; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * we have 8 bits used like this: | ||||
|  * | ||||
|  |  | |||
|  | @ -73,10 +73,9 @@ int iwl_poll_bit(struct iwl_priv *priv, u32 addr, | |||
| 	return -ETIMEDOUT; | ||||
| } | ||||
| 
 | ||||
| int iwl_grab_nic_access(struct iwl_priv *priv) | ||||
| int iwl_grab_nic_access_silent(struct iwl_priv *priv) | ||||
| { | ||||
| 	int ret; | ||||
| 	u32 val; | ||||
| 
 | ||||
| 	lockdep_assert_held(&priv->reg_lock); | ||||
| 
 | ||||
|  | @ -107,9 +106,6 @@ int iwl_grab_nic_access(struct iwl_priv *priv) | |||
| 			   (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | | ||||
| 			    CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); | ||||
| 	if (ret < 0) { | ||||
| 		val = iwl_read32(priv, CSR_GP_CNTRL); | ||||
| 		IWL_ERR(priv, | ||||
| 			"MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); | ||||
| 		iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); | ||||
| 		return -EIO; | ||||
| 	} | ||||
|  | @ -117,6 +113,18 @@ int iwl_grab_nic_access(struct iwl_priv *priv) | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int iwl_grab_nic_access(struct iwl_priv *priv) | ||||
| { | ||||
| 	int ret = iwl_grab_nic_access_silent(priv); | ||||
| 	if (ret) { | ||||
| 		u32 val = iwl_read32(priv, CSR_GP_CNTRL); | ||||
| 		IWL_ERR(priv, | ||||
| 			"MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); | ||||
| 	} | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| void iwl_release_nic_access(struct iwl_priv *priv) | ||||
| { | ||||
| 	lockdep_assert_held(&priv->reg_lock); | ||||
|  | @ -242,20 +250,32 @@ void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask) | |||
| 	spin_unlock_irqrestore(&priv->reg_lock, flags); | ||||
| } | ||||
| 
 | ||||
| u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr) | ||||
| void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr, | ||||
| 			      void *buf, int words) | ||||
| { | ||||
| 	unsigned long flags; | ||||
| 	u32 value; | ||||
| 	int offs; | ||||
| 	u32 *vals = buf; | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->reg_lock, flags); | ||||
| 	iwl_grab_nic_access(priv); | ||||
| 
 | ||||
| 	iwl_write32(priv, HBUS_TARG_MEM_RADDR, addr); | ||||
| 	rmb(); | ||||
| 	value = iwl_read32(priv, HBUS_TARG_MEM_RDAT); | ||||
| 
 | ||||
| 	for (offs = 0; offs < words; offs++) | ||||
| 		vals[offs] = iwl_read32(priv, HBUS_TARG_MEM_RDAT); | ||||
| 
 | ||||
| 	iwl_release_nic_access(priv); | ||||
| 	spin_unlock_irqrestore(&priv->reg_lock, flags); | ||||
| } | ||||
| 
 | ||||
| u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr) | ||||
| { | ||||
| 	u32 value; | ||||
| 
 | ||||
| 	_iwl_read_targ_mem_words(priv, addr, &value, 1); | ||||
| 
 | ||||
| 	return value; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -62,6 +62,7 @@ int iwl_poll_bit(struct iwl_priv *priv, u32 addr, | |||
| int iwl_poll_direct_bit(struct iwl_priv *priv, u32 addr, u32 mask, | ||||
| 			int timeout); | ||||
| 
 | ||||
| int iwl_grab_nic_access_silent(struct iwl_priv *priv); | ||||
| int iwl_grab_nic_access(struct iwl_priv *priv); | ||||
| void iwl_release_nic_access(struct iwl_priv *priv); | ||||
| 
 | ||||
|  | @ -76,6 +77,16 @@ void iwl_set_bits_mask_prph(struct iwl_priv *priv, u32 reg, | |||
| 			    u32 bits, u32 mask); | ||||
| void iwl_clear_bits_prph(struct iwl_priv *priv, u32 reg, u32 mask); | ||||
| 
 | ||||
| void _iwl_read_targ_mem_words(struct iwl_priv *priv, u32 addr, | ||||
| 			      void *buf, int words); | ||||
| 
 | ||||
| #define iwl_read_targ_mem_words(priv, addr, buf, bufsize)	\ | ||||
| 	do {							\ | ||||
| 		BUILD_BUG_ON((bufsize) % sizeof(u32));		\ | ||||
| 		_iwl_read_targ_mem_words(priv, addr, buf,	\ | ||||
| 					 (bufsize) / sizeof(u32));\ | ||||
| 	} while (0) | ||||
| 
 | ||||
| u32 iwl_read_targ_mem(struct iwl_priv *priv, u32 addr); | ||||
| void iwl_write_targ_mem(struct iwl_priv *priv, u32 addr, u32 val); | ||||
| #endif | ||||
|  |  | |||
|  | @ -225,55 +225,6 @@ err_bd: | |||
|  * | ||||
|  ******************************************************************************/ | ||||
| 
 | ||||
| static void iwl_rx_reply_alive(struct iwl_priv *priv, | ||||
| 			       struct iwl_rx_mem_buffer *rxb) | ||||
| { | ||||
| 	struct iwl_rx_packet *pkt = rxb_addr(rxb); | ||||
| 	struct iwl_alive_resp *palive; | ||||
| 	struct delayed_work *pwork; | ||||
| 
 | ||||
| 	palive = &pkt->u.alive_frame; | ||||
| 
 | ||||
| 	IWL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision " | ||||
| 		       "0x%01X 0x%01X\n", | ||||
| 		       palive->is_valid, palive->ver_type, | ||||
| 		       palive->ver_subtype); | ||||
| 
 | ||||
| 	priv->device_pointers.log_event_table = | ||||
| 		le32_to_cpu(palive->log_event_table_ptr); | ||||
| 	priv->device_pointers.error_event_table = | ||||
| 		le32_to_cpu(palive->error_event_table_ptr); | ||||
| 
 | ||||
| 	if (palive->ver_subtype == INITIALIZE_SUBTYPE) { | ||||
| 		IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); | ||||
| 		pwork = &priv->init_alive_start; | ||||
| 	} else { | ||||
| 		IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); | ||||
| 		pwork = &priv->alive_start; | ||||
| 	} | ||||
| 
 | ||||
| 	/* We delay the ALIVE response by 5ms to
 | ||||
| 	 * give the HW RF Kill time to activate... */ | ||||
| 	if (palive->is_valid == UCODE_VALID_OK) | ||||
| 		queue_delayed_work(priv->workqueue, pwork, | ||||
| 				   msecs_to_jiffies(5)); | ||||
| 	else { | ||||
| 		IWL_WARN(priv, "%s uCode did not respond OK.\n", | ||||
| 			(palive->ver_subtype == INITIALIZE_SUBTYPE) ? | ||||
| 			"init" : "runtime"); | ||||
| 		/*
 | ||||
| 		 * If fail to load init uCode, | ||||
| 		 * let's try to load the init uCode again. | ||||
| 		 * We should not get into this situation, but if it | ||||
| 		 * does happen, we should not move on and loading "runtime" | ||||
| 		 * without proper calibrate the device. | ||||
| 		 */ | ||||
| 		if (palive->ver_subtype == INITIALIZE_SUBTYPE) | ||||
| 			priv->ucode_type = UCODE_NONE; | ||||
| 		queue_work(priv->workqueue, &priv->restart); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| static void iwl_rx_reply_error(struct iwl_priv *priv, | ||||
| 			       struct iwl_rx_mem_buffer *rxb) | ||||
| { | ||||
|  | @ -482,7 +433,6 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv, | |||
| 					struct statistics_tx *tx, | ||||
| 					unsigned long stamp) | ||||
| { | ||||
| 	const struct iwl_mod_params *mod_params = priv->cfg->mod_params; | ||||
| 	unsigned int msecs; | ||||
| 
 | ||||
| 	if (test_bit(STATUS_EXIT_PENDING, &priv->status)) | ||||
|  | @ -498,13 +448,13 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv, | |||
| 	if (msecs < 99) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (mod_params->ack_check && !iwl_good_ack_health(priv, tx)) { | ||||
| 	if (iwlagn_mod_params.ack_check && !iwl_good_ack_health(priv, tx)) { | ||||
| 		IWL_ERR(priv, "low ack count detected, restart firmware\n"); | ||||
| 		if (!iwl_force_reset(priv, IWL_FW_RESET, false)) | ||||
| 			return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (mod_params->plcp_check && | ||||
| 	if (iwlagn_mod_params.plcp_check && | ||||
| 	    !iwl_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs)) | ||||
| 		iwl_force_reset(priv, IWL_RF_RESET, false); | ||||
| } | ||||
|  | @ -895,7 +845,7 @@ static void iwl_pass_packet_to_mac80211(struct iwl_priv *priv, | |||
| 	} | ||||
| 
 | ||||
| 	/* In case of HW accelerated crypto and bad decryption, drop */ | ||||
| 	if (!priv->cfg->mod_params->sw_crypto && | ||||
| 	if (!iwlagn_mod_params.sw_crypto && | ||||
| 	    iwl_set_decrypted_flag(priv, hdr, ampdu_status, stats)) | ||||
| 		return; | ||||
| 
 | ||||
|  | @ -1125,7 +1075,6 @@ void iwl_setup_rx_handlers(struct iwl_priv *priv) | |||
| 
 | ||||
| 	handlers = priv->rx_handlers; | ||||
| 
 | ||||
| 	handlers[REPLY_ALIVE]			= iwl_rx_reply_alive; | ||||
| 	handlers[REPLY_ERROR]			= iwl_rx_reply_error; | ||||
| 	handlers[CHANNEL_SWITCH_NOTIFICATION]	= iwl_rx_csa; | ||||
| 	handlers[SPECTRUM_MEASURE_NOTIFICATION]	= iwl_rx_spectrum_measure_notif; | ||||
|  |  | |||
|  | @ -1,92 +0,0 @@ | |||
| /******************************************************************************
 | ||||
|  * | ||||
|  * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. | ||||
|  * | ||||
|  * Portions of this file are derived from the ieee80211 subsystem header files. | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify it | ||||
|  * under the terms of version 2 of the GNU General Public License as | ||||
|  * published by the Free Software Foundation. | ||||
|  * | ||||
|  * This program is distributed in the hope that it will be useful, but WITHOUT | ||||
|  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||||
|  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for | ||||
|  * more details. | ||||
|  * | ||||
|  * You should have received a copy of the GNU General Public License along with | ||||
|  * this program; if not, write to the Free Software Foundation, Inc., | ||||
|  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||||
|  * | ||||
|  * The full GNU General Public License is included in this distribution in the | ||||
|  * file called LICENSE. | ||||
|  * | ||||
|  * Contact Information: | ||||
|  *  Intel Linux Wireless <ilw@linux.intel.com> | ||||
|  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||||
|  * | ||||
|  *****************************************************************************/ | ||||
| 
 | ||||
| #ifndef __iwl_spectrum_h__ | ||||
| #define __iwl_spectrum_h__ | ||||
| enum {				/* ieee80211_basic_report.map */ | ||||
| 	IEEE80211_BASIC_MAP_BSS = (1 << 0), | ||||
| 	IEEE80211_BASIC_MAP_OFDM = (1 << 1), | ||||
| 	IEEE80211_BASIC_MAP_UNIDENTIFIED = (1 << 2), | ||||
| 	IEEE80211_BASIC_MAP_RADAR = (1 << 3), | ||||
| 	IEEE80211_BASIC_MAP_UNMEASURED = (1 << 4), | ||||
| 	/* Bits 5-7 are reserved */ | ||||
| 
 | ||||
| }; | ||||
| struct ieee80211_basic_report { | ||||
| 	u8 channel; | ||||
| 	__le64 start_time; | ||||
| 	__le16 duration; | ||||
| 	u8 map; | ||||
| } __packed; | ||||
| 
 | ||||
| enum {				/* ieee80211_measurement_request.mode */ | ||||
| 	/* Bit 0 is reserved */ | ||||
| 	IEEE80211_MEASUREMENT_ENABLE = (1 << 1), | ||||
| 	IEEE80211_MEASUREMENT_REQUEST = (1 << 2), | ||||
| 	IEEE80211_MEASUREMENT_REPORT = (1 << 3), | ||||
| 	/* Bits 4-7 are reserved */ | ||||
| }; | ||||
| 
 | ||||
| enum { | ||||
| 	IEEE80211_REPORT_BASIC = 0,	/* required */ | ||||
| 	IEEE80211_REPORT_CCA = 1,	/* optional */ | ||||
| 	IEEE80211_REPORT_RPI = 2,	/* optional */ | ||||
| 	/* 3-255 reserved */ | ||||
| }; | ||||
| 
 | ||||
| struct ieee80211_measurement_params { | ||||
| 	u8 channel; | ||||
| 	__le64 start_time; | ||||
| 	__le16 duration; | ||||
| } __packed; | ||||
| 
 | ||||
| struct ieee80211_info_element { | ||||
| 	u8 id; | ||||
| 	u8 len; | ||||
| 	u8 data[0]; | ||||
| } __packed; | ||||
| 
 | ||||
| struct ieee80211_measurement_request { | ||||
| 	struct ieee80211_info_element ie; | ||||
| 	u8 token; | ||||
| 	u8 mode; | ||||
| 	u8 type; | ||||
| 	struct ieee80211_measurement_params params[0]; | ||||
| } __packed; | ||||
| 
 | ||||
| struct ieee80211_measurement_report { | ||||
| 	struct ieee80211_info_element ie; | ||||
| 	u8 token; | ||||
| 	u8 mode; | ||||
| 	u8 type; | ||||
| 	union { | ||||
| 		struct ieee80211_basic_report basic[0]; | ||||
| 	} u; | ||||
| } __packed; | ||||
| 
 | ||||
| #endif | ||||
|  | @ -621,9 +621,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
| 	struct iwl_cmd_meta *meta; | ||||
| 	struct iwl_tx_queue *txq = &priv->txq[priv->cmd_queue]; | ||||
| 	unsigned long flags; | ||||
| 	void (*callback) (struct iwl_priv *priv, struct iwl_device_cmd *cmd, | ||||
| 			  struct iwl_rx_packet *pkt); | ||||
| 
 | ||||
| 
 | ||||
| 	/* If a Tx command is being handled and it isn't in the actual
 | ||||
| 	 * command queue then there a command routing bug has been introduced | ||||
|  | @ -637,8 +634,6 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->hcmd_lock, flags); | ||||
| 
 | ||||
| 	cmd_index = get_cmd_index(&txq->q, index, huge); | ||||
| 	cmd = txq->cmd[cmd_index]; | ||||
| 	meta = &txq->meta[cmd_index]; | ||||
|  | @ -648,13 +643,14 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
| 			 dma_unmap_len(meta, len), | ||||
| 			 PCI_DMA_BIDIRECTIONAL); | ||||
| 
 | ||||
| 	callback = NULL; | ||||
| 	/* Input error checking is done when commands are added to queue. */ | ||||
| 	if (meta->flags & CMD_WANT_SKB) { | ||||
| 		meta->source->reply_page = (unsigned long)rxb_addr(rxb); | ||||
| 		rxb->page = NULL; | ||||
| 	} else | ||||
| 		callback = meta->callback; | ||||
| 	} else if (meta->callback) | ||||
| 		meta->callback(priv, cmd, pkt); | ||||
| 
 | ||||
| 	spin_lock_irqsave(&priv->hcmd_lock, flags); | ||||
| 
 | ||||
| 	iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); | ||||
| 
 | ||||
|  | @ -669,7 +665,4 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
| 	meta->flags = 0; | ||||
| 
 | ||||
| 	spin_unlock_irqrestore(&priv->hcmd_lock, flags); | ||||
| 
 | ||||
| 	if (callback) | ||||
| 		callback(priv, cmd, pkt); | ||||
| } | ||||
|  |  | |||
|  | @ -122,8 +122,10 @@ static u8 lbs_auth_to_authtype(enum nl80211_auth_type auth_type) | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Various firmware commands need the list of supported rates, but with
 | ||||
|    the hight-bit set for basic rates */ | ||||
| /*
 | ||||
|  * Various firmware commands need the list of supported rates, but with | ||||
|  * the hight-bit set for basic rates | ||||
|  */ | ||||
| static int lbs_add_rates(u8 *rates) | ||||
| { | ||||
| 	size_t i; | ||||
|  | @ -425,7 +427,7 @@ static int lbs_add_wpa_tlv(u8 *tlv, const u8 *ie, u8 ie_len) | |||
| 	return ie_len + 2; | ||||
| } | ||||
| 
 | ||||
| /***************************************************************************
 | ||||
| /*
 | ||||
|  * Set Channel | ||||
|  */ | ||||
| 
 | ||||
|  | @ -452,7 +454,7 @@ static int lbs_cfg_set_channel(struct wiphy *wiphy, | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /***************************************************************************
 | ||||
| /*
 | ||||
|  * Scanning | ||||
|  */ | ||||
| 
 | ||||
|  | @ -538,8 +540,10 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
| 		goto done; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Validity check: the TLV holds TSF values with 8 bytes each, so
 | ||||
| 	 * the size in the TLV must match the nr_sets value */ | ||||
| 	/*
 | ||||
| 	 * Validity check: the TLV holds TSF values with 8 bytes each, so | ||||
| 	 * the size in the TLV must match the nr_sets value | ||||
| 	 */ | ||||
| 	i = get_unaligned_le16(tsfdesc); | ||||
| 	tsfdesc += 2; | ||||
| 	if (i / 8 != scanresp->nr_sets) { | ||||
|  | @ -581,8 +585,10 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
| 
 | ||||
| 		/* To find out the channel, we must parse the IEs */ | ||||
| 		ie = pos; | ||||
| 		/* 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon
 | ||||
| 		   interval, capabilities */ | ||||
| 		/*
 | ||||
| 		 * 6+1+8+2+2: size of BSSID, RSSI, time stamp, beacon | ||||
| 		 * interval, capabilities | ||||
| 		 */ | ||||
| 		ielen = left = len - (6 + 1 + 8 + 2 + 2); | ||||
| 		while (left >= 2) { | ||||
| 			u8 id, elen; | ||||
|  | @ -790,7 +796,7 @@ static int lbs_cfg_scan(struct wiphy *wiphy, | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /***************************************************************************
 | ||||
| /*
 | ||||
|  * Events | ||||
|  */ | ||||
| 
 | ||||
|  | @ -825,7 +831,7 @@ void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event) | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /***************************************************************************
 | ||||
| /*
 | ||||
|  * Connect/disconnect | ||||
|  */ | ||||
| 
 | ||||
|  | @ -950,8 +956,10 @@ static int lbs_enable_rsn(struct lbs_private *priv, int enable) | |||
|  * Set WPA/WPA key material | ||||
|  */ | ||||
| 
 | ||||
| /* like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we
 | ||||
|  * get rid of WEXT, this should go into host.h */ | ||||
| /*
 | ||||
|  * like "struct cmd_ds_802_11_key_material", but with cmd_header. Once we | ||||
|  * get rid of WEXT, this should go into host.h | ||||
|  */ | ||||
| 
 | ||||
| struct cmd_key_material { | ||||
| 	struct cmd_header hdr; | ||||
|  | @ -1536,7 +1544,7 @@ static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev, | |||
| } | ||||
| 
 | ||||
| 
 | ||||
| /***************************************************************************
 | ||||
| /*
 | ||||
|  * Get station | ||||
|  */ | ||||
| 
 | ||||
|  | @ -1581,7 +1589,7 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /***************************************************************************
 | ||||
| /*
 | ||||
|  * "Site survey", here just current channel and noise level | ||||
|  */ | ||||
| 
 | ||||
|  | @ -1614,7 +1622,7 @@ static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev, | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /***************************************************************************
 | ||||
| /*
 | ||||
|  * Change interface | ||||
|  */ | ||||
| 
 | ||||
|  | @ -1656,11 +1664,12 @@ static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev, | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /***************************************************************************
 | ||||
| /*
 | ||||
|  * IBSS (Ad-Hoc) | ||||
|  */ | ||||
| 
 | ||||
| /* The firmware needs the following bits masked out of the beacon-derived
 | ||||
| /*
 | ||||
|  * The firmware needs the following bits masked out of the beacon-derived | ||||
|  * capability field when associating/joining to a BSS: | ||||
|  *  9 (QoS), 11 (APSD), 12 (unused), 14 (unused), 15 (unused) | ||||
|  */ | ||||
|  | @ -1999,7 +2008,7 @@ static int lbs_leave_ibss(struct wiphy *wiphy, struct net_device *dev) | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /***************************************************************************
 | ||||
| /*
 | ||||
|  * Initialization | ||||
|  */ | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| /**
 | ||||
|   * This file contains the handling of command. | ||||
|   * It prepares command and sends it to firmware when it is ready. | ||||
|   */ | ||||
| /*
 | ||||
|  * This file contains the handling of command. | ||||
|  * It prepares command and sends it to firmware when it is ready. | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/kfifo.h> | ||||
| #include <linux/sched.h> | ||||
|  | @ -16,14 +16,14 @@ | |||
| #define CAL_RSSI(snr, nf)	((s32)((s32)(snr) + CAL_NF(nf))) | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Simple callback that copies response back into command | ||||
|  * lbs_cmd_copyback - Simple callback that copies response back into command | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param extra  	A pointer to the original command structure for which | ||||
|  *                      'resp' is a response | ||||
|  *  @param resp         A pointer to the command response | ||||
|  * @priv:	A pointer to &struct lbs_private structure | ||||
|  * @extra:	A pointer to the original command structure for which | ||||
|  *		'resp' is a response | ||||
|  * @resp:	A pointer to the command response | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  * returns:	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra, | ||||
| 		     struct cmd_header *resp) | ||||
|  | @ -38,15 +38,15 @@ int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra, | |||
| EXPORT_SYMBOL_GPL(lbs_cmd_copyback); | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Simple callback that ignores the result. Use this if | ||||
|  *  you just want to send a command to the hardware, but don't | ||||
|  *  lbs_cmd_async_callback - Simple callback that ignores the result. | ||||
|  *  Use this if you just want to send a command to the hardware, but don't | ||||
|  *  care for the result. | ||||
|  * | ||||
|  *  @param priv         ignored | ||||
|  *  @param extra        ignored | ||||
|  *  @param resp         ignored | ||||
|  *  @priv:	ignored | ||||
|  *  @extra:	ignored | ||||
|  *  @resp:	ignored | ||||
|  * | ||||
|  *  @return 	   	0 for success | ||||
|  *  returns:	0 for success | ||||
|  */ | ||||
| static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra, | ||||
| 		     struct cmd_header *resp) | ||||
|  | @ -56,10 +56,11 @@ static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra, | |||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Checks whether a command is allowed in Power Save mode | ||||
|  *  is_command_allowed_in_ps - tests if a command is allowed in Power Save mode | ||||
|  * | ||||
|  *  @param command the command ID | ||||
|  *  @return 	   1 if allowed, 0 if not allowed | ||||
|  *  @cmd:	the command ID | ||||
|  * | ||||
|  *  returns:	1 if allowed, 0 if not allowed | ||||
|  */ | ||||
| static u8 is_command_allowed_in_ps(u16 cmd) | ||||
| { | ||||
|  | @ -75,11 +76,12 @@ static u8 is_command_allowed_in_ps(u16 cmd) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Updates the hardware details like MAC address and regulatory region | ||||
|  *  lbs_update_hw_spec - Updates the hardware details like MAC address | ||||
|  *  and regulatory region | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  *  returns:	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_update_hw_spec(struct lbs_private *priv) | ||||
| { | ||||
|  | @ -217,14 +219,14 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria, | |||
| EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg); | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Sets the Power Save mode | ||||
|  *  lbs_set_ps_mode - Sets the Power Save mode | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param cmd_action	The Power Save operation (PS_MODE_ACTION_ENTER_PS or | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  *  @cmd_action: The Power Save operation (PS_MODE_ACTION_ENTER_PS or | ||||
|  *                         PS_MODE_ACTION_EXIT_PS) | ||||
|  *  @param block	Whether to block on a response or not | ||||
|  *  @block:	Whether to block on a response or not | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  *  returns:	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block) | ||||
| { | ||||
|  | @ -417,13 +419,13 @@ int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Set an SNMP MIB value | ||||
|  *  lbs_set_snmp_mib - Set an SNMP MIB value | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param oid  	The OID to set in the firmware | ||||
|  *  @param val  	Value to set the OID to | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  *  @oid:	The OID to set in the firmware | ||||
|  *  @val:	Value to set the OID to | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  *  returns: 	   	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val) | ||||
| { | ||||
|  | @ -467,13 +469,13 @@ out: | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Get an SNMP MIB value | ||||
|  *  lbs_get_snmp_mib - Get an SNMP MIB value | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param oid  	The OID to retrieve from the firmware | ||||
|  *  @param out_val  	Location for the returned value | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  *  @oid:	The OID to retrieve from the firmware | ||||
|  *  @out_val:	Location for the returned value | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  *  returns:	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val) | ||||
| { | ||||
|  | @ -510,14 +512,14 @@ out: | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Get the min, max, and current TX power | ||||
|  *  lbs_get_tx_power - Get the min, max, and current TX power | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param curlevel  	Current power level in dBm | ||||
|  *  @param minlevel  	Minimum supported power level in dBm (optional) | ||||
|  *  @param maxlevel  	Maximum supported power level in dBm (optional) | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  *  @curlevel:	Current power level in dBm | ||||
|  *  @minlevel:	Minimum supported power level in dBm (optional) | ||||
|  *  @maxlevel:	Maximum supported power level in dBm (optional) | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  *  returns:	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel, | ||||
| 		     s16 *maxlevel) | ||||
|  | @ -545,12 +547,12 @@ int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Set the TX power | ||||
|  *  lbs_set_tx_power - Set the TX power | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param dbm  	The desired power level in dBm | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  *  @dbm:	The desired power level in dBm | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  *  returns: 	   	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_set_tx_power(struct lbs_private *priv, s16 dbm) | ||||
| { | ||||
|  | @ -573,12 +575,13 @@ int lbs_set_tx_power(struct lbs_private *priv, s16 dbm) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Enable or disable monitor mode (only implemented on OLPC usb8388 FW) | ||||
|  *  lbs_set_monitor_mode - Enable or disable monitor mode | ||||
|  *  (only implemented on OLPC usb8388 FW) | ||||
|  * | ||||
|  *  @param priv        A pointer to struct lbs_private structure | ||||
|  *  @param enable      1 to enable monitor mode, 0 to disable | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  *  @enable:	1 to enable monitor mode, 0 to disable | ||||
|  * | ||||
|  *  @return            0 on success, error on failure | ||||
|  *  returns:	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_set_monitor_mode(struct lbs_private *priv, int enable) | ||||
| { | ||||
|  | @ -604,11 +607,11 @@ int lbs_set_monitor_mode(struct lbs_private *priv, int enable) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Get the radio channel | ||||
|  *  lbs_get_channel - Get the radio channel | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  * | ||||
|  *  @return 	   	The channel on success, error on failure | ||||
|  *  returns:	The channel on success, error on failure | ||||
|  */ | ||||
| static int lbs_get_channel(struct lbs_private *priv) | ||||
| { | ||||
|  | @ -650,12 +653,12 @@ int lbs_update_channel(struct lbs_private *priv) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Set the radio channel | ||||
|  *  lbs_set_channel - Set the radio channel | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param channel  	The desired channel, or 0 to clear a locked channel | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  *  @channel:	The desired channel, or 0 to clear a locked channel | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  *  returns:	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_set_channel(struct lbs_private *priv, u8 channel) | ||||
| { | ||||
|  | @ -686,12 +689,13 @@ out: | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Get current RSSI and noise floor | ||||
|  * lbs_get_rssi - Get current RSSI and noise floor | ||||
|  * | ||||
|  *  @param priv		A pointer to struct lbs_private structure | ||||
|  *  @param rssi		On successful return, signal level in mBm | ||||
|  * @priv:	A pointer to &struct lbs_private structure | ||||
|  * @rssi:	On successful return, signal level in mBm | ||||
|  * @nf:		On successful return, Noise floor | ||||
|  * | ||||
|  *  @return 	   	The channel on success, error on failure | ||||
|  * returns:	The channel on success, error on failure | ||||
|  */ | ||||
| int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf) | ||||
| { | ||||
|  | @ -719,13 +723,14 @@ int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Send regulatory and 802.11d domain information to the firmware | ||||
|  *  lbs_set_11d_domain_info - Send regulatory and 802.11d domain information | ||||
|  *  to the firmware | ||||
|  * | ||||
|  *  @param priv		pointer to struct lbs_private | ||||
|  *  @param request	cfg80211 regulatory request structure | ||||
|  *  @param bands	the device's supported bands and channels | ||||
|  *  @priv:	pointer to &struct lbs_private | ||||
|  *  @request:	cfg80211 regulatory request structure | ||||
|  *  @bands:	the device's supported bands and channels | ||||
|  * | ||||
|  *  @return		0 on success, error code on failure | ||||
|  *  returns:	0 on success, error code on failure | ||||
| */ | ||||
| int lbs_set_11d_domain_info(struct lbs_private *priv, | ||||
| 			    struct regulatory_request *request, | ||||
|  | @ -842,15 +847,15 @@ int lbs_set_11d_domain_info(struct lbs_private *priv, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Read a MAC, Baseband, or RF register | ||||
|  *  lbs_get_reg - Read a MAC, Baseband, or RF register | ||||
|  * | ||||
|  *  @param priv		pointer to struct lbs_private | ||||
|  *  @param cmd		register command, one of CMD_MAC_REG_ACCESS, | ||||
|  *                        CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS | ||||
|  *  @param offset       byte offset of the register to get | ||||
|  *  @param value        on success, the value of the register at 'offset' | ||||
|  *  @priv:	pointer to &struct lbs_private | ||||
|  *  @reg:	register command, one of CMD_MAC_REG_ACCESS, | ||||
|  *		CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS | ||||
|  *  @offset:	byte offset of the register to get | ||||
|  *  @value:	on success, the value of the register at 'offset' | ||||
|  * | ||||
|  *  @return		0 on success, error code on failure | ||||
|  *  returns:	0 on success, error code on failure | ||||
| */ | ||||
| int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value) | ||||
| { | ||||
|  | @ -886,15 +891,15 @@ out: | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Write a MAC, Baseband, or RF register | ||||
|  *  lbs_set_reg - Write a MAC, Baseband, or RF register | ||||
|  * | ||||
|  *  @param priv		pointer to struct lbs_private | ||||
|  *  @param cmd		register command, one of CMD_MAC_REG_ACCESS, | ||||
|  *                        CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS | ||||
|  *  @param offset       byte offset of the register to set | ||||
|  *  @param value        the value to write to the register at 'offset' | ||||
|  *  @priv:	pointer to &struct lbs_private | ||||
|  *  @reg:	register command, one of CMD_MAC_REG_ACCESS, | ||||
|  *		CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS | ||||
|  *  @offset:	byte offset of the register to set | ||||
|  *  @value:	the value to write to the register at 'offset' | ||||
|  * | ||||
|  *  @return		0 on success, error code on failure | ||||
|  *  returns:	0 on success, error code on failure | ||||
| */ | ||||
| int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value) | ||||
| { | ||||
|  | @ -1023,7 +1028,7 @@ static void lbs_submit_command(struct lbs_private *priv, | |||
| 	lbs_deb_leave(LBS_DEB_HOST); | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| /*
 | ||||
|  *  This function inserts command node to cmdfreeq | ||||
|  *  after cleans it. Requires priv->driver_lock held. | ||||
|  */ | ||||
|  | @ -1125,11 +1130,12 @@ void lbs_set_mac_control(struct lbs_private *priv) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function allocates the command buffer and link | ||||
|  *  it to command free queue. | ||||
|  *  lbs_allocate_cmd_buffer - allocates the command buffer and links | ||||
|  *  it to command free queue | ||||
|  * | ||||
|  *  @param priv		A pointer to struct lbs_private structure | ||||
|  *  @return 		0 or -1 | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  * | ||||
|  *  returns:	0 for success or -1 on error | ||||
|  */ | ||||
| int lbs_allocate_cmd_buffer(struct lbs_private *priv) | ||||
| { | ||||
|  | @ -1171,10 +1177,11 @@ done: | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function frees the command buffer. | ||||
|  *  lbs_free_cmd_buffer - free the command buffer | ||||
|  * | ||||
|  *  @param priv		A pointer to struct lbs_private structure | ||||
|  *  @return 		0 or -1 | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  * | ||||
|  *  returns:	0 for success | ||||
|  */ | ||||
| int lbs_free_cmd_buffer(struct lbs_private *priv) | ||||
| { | ||||
|  | @ -1211,11 +1218,13 @@ done: | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function gets a free command node if available in | ||||
|  *  command free queue. | ||||
|  *  lbs_get_free_cmd_node - gets a free command node if available in | ||||
|  *  command free queue | ||||
|  * | ||||
|  *  @param priv		A pointer to struct lbs_private structure | ||||
|  *  @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  * | ||||
|  *  returns:	A pointer to &cmd_ctrl_node structure on success | ||||
|  *		or %NULL on error | ||||
|  */ | ||||
| static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv) | ||||
| { | ||||
|  | @ -1245,12 +1254,12 @@ static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function executes next command in command | ||||
|  *  pending queue. It will put firmware back to PS mode | ||||
|  *  if applicable. | ||||
|  *  lbs_execute_next_command - execute next command in command | ||||
|  *  pending queue. Will put firmware back to PS mode if applicable. | ||||
|  * | ||||
|  *  @param priv     A pointer to struct lbs_private structure | ||||
|  *  @return 	   0 or -1 | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  * | ||||
|  *  returns:	0 on success or -1 on error | ||||
|  */ | ||||
| int lbs_execute_next_command(struct lbs_private *priv) | ||||
| { | ||||
|  | @ -1454,12 +1463,12 @@ out: | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function checks condition and prepares to | ||||
|  *  send sleep confirm command to firmware if ok. | ||||
|  * lbs_ps_confirm_sleep - checks condition and prepares to | ||||
|  * send sleep confirm command to firmware if ok | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param psmode  	Power Saving mode | ||||
|  *  @return 	   	n/a | ||||
|  * @priv:	A pointer to &struct lbs_private structure | ||||
|  * | ||||
|  * returns:	n/a | ||||
|  */ | ||||
| void lbs_ps_confirm_sleep(struct lbs_private *priv) | ||||
| { | ||||
|  | @ -1499,16 +1508,16 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv) | |||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Configures the transmission power control functionality. | ||||
|  * lbs_set_tpc_cfg - Configures the transmission power control functionality | ||||
|  * | ||||
|  * @param priv		A pointer to struct lbs_private structure | ||||
|  * @param enable	Transmission power control enable | ||||
|  * @param p0		Power level when link quality is good (dBm). | ||||
|  * @param p1		Power level when link quality is fair (dBm). | ||||
|  * @param p2		Power level when link quality is poor (dBm). | ||||
|  * @param usesnr	Use Signal to Noise Ratio in TPC | ||||
|  * @priv:	A pointer to &struct lbs_private structure | ||||
|  * @enable:	Transmission power control enable | ||||
|  * @p0:		Power level when link quality is good (dBm). | ||||
|  * @p1:		Power level when link quality is fair (dBm). | ||||
|  * @p2:		Power level when link quality is poor (dBm). | ||||
|  * @usesnr:	Use Signal to Noise Ratio in TPC | ||||
|  * | ||||
|  * @return 0 on success | ||||
|  * returns:	0 on success | ||||
|  */ | ||||
| int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1, | ||||
| 		int8_t p2, int usesnr) | ||||
|  | @ -1531,15 +1540,15 @@ int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Configures the power adaptation settings. | ||||
|  * lbs_set_power_adapt_cfg - Configures the power adaptation settings | ||||
|  * | ||||
|  * @param priv		A pointer to struct lbs_private structure | ||||
|  * @param enable	Power adaptation enable | ||||
|  * @param p0		Power level for 1, 2, 5.5 and 11 Mbps (dBm). | ||||
|  * @param p1		Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm). | ||||
|  * @param p2		Power level for 48 and 54 Mbps (dBm). | ||||
|  * @priv:	A pointer to &struct lbs_private structure | ||||
|  * @enable:	Power adaptation enable | ||||
|  * @p0:		Power level for 1, 2, 5.5 and 11 Mbps (dBm). | ||||
|  * @p1:		Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm). | ||||
|  * @p2:		Power level for 48 and 54 Mbps (dBm). | ||||
|  * | ||||
|  * @return 0 on Success | ||||
|  * returns:	0 on Success | ||||
|  */ | ||||
| 
 | ||||
| int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0, | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| /**
 | ||||
|   * This file contains the handling of command | ||||
|   * responses as well as events generated by firmware. | ||||
|   */ | ||||
| /*
 | ||||
|  * This file contains the handling of command | ||||
|  * responses as well as events generated by firmware. | ||||
|  */ | ||||
| #include <linux/slab.h> | ||||
| #include <linux/delay.h> | ||||
| #include <linux/sched.h> | ||||
|  | @ -12,12 +12,13 @@ | |||
| #include "cmd.h" | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function handles disconnect event. it | ||||
|  *  reports disconnect to upper layer, clean tx/rx packets, | ||||
|  *  reset link state etc. | ||||
|  * lbs_mac_event_disconnected - handles disconnect event. It | ||||
|  * reports disconnect to upper layer, clean tx/rx packets, | ||||
|  * reset link state etc. | ||||
|  * | ||||
|  *  @param priv    A pointer to struct lbs_private structure | ||||
|  *  @return 	   n/a | ||||
|  * @priv:	A pointer to struct lbs_private structure | ||||
|  * | ||||
|  * returns:	n/a | ||||
|  */ | ||||
| void lbs_mac_event_disconnected(struct lbs_private *priv) | ||||
| { | ||||
|  |  | |||
|  | @ -849,15 +849,14 @@ static struct debug_data items[] = { | |||
| static int num_of_items = ARRAY_SIZE(items); | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief proc read function | ||||
|  * lbs_debugfs_read - proc read function | ||||
|  * | ||||
|  *  @param page	   pointer to buffer | ||||
|  *  @param s       read data starting position | ||||
|  *  @param off     offset | ||||
|  *  @param cnt     counter | ||||
|  *  @param eof     end of file flag | ||||
|  *  @param data    data to output | ||||
|  *  @return 	   number of output data | ||||
|  * @file:	file to read | ||||
|  * @userbuf:	pointer to buffer | ||||
|  * @count:	number of bytes to read | ||||
|  * @ppos:	read data starting position | ||||
|  * | ||||
|  * returns:	amount of data read or negative error code | ||||
|  */ | ||||
| static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf, | ||||
| 			size_t count, loff_t *ppos) | ||||
|  | @ -897,13 +896,14 @@ static ssize_t lbs_debugfs_read(struct file *file, char __user *userbuf, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief proc write function | ||||
|  * lbs_debugfs_write - proc write function | ||||
|  * | ||||
|  *  @param f	   file pointer | ||||
|  *  @param buf     pointer to data buffer | ||||
|  *  @param cnt     data number to write | ||||
|  *  @param data    data to write | ||||
|  *  @return 	   number of data | ||||
|  * @f:		file pointer | ||||
|  * @buf:	pointer to data buffer | ||||
|  * @cnt:	data number to write | ||||
|  * @ppos:	file position | ||||
|  * | ||||
|  * returns:	amount of data written | ||||
|  */ | ||||
| static ssize_t lbs_debugfs_write(struct file *f, const char __user *buf, | ||||
| 			    size_t cnt, loff_t *ppos) | ||||
|  | @ -966,11 +966,11 @@ static const struct file_operations lbs_debug_fops = { | |||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief create debug proc file | ||||
|  * lbs_debug_init - create debug proc file | ||||
|  * | ||||
|  *  @param priv	   pointer struct lbs_private | ||||
|  *  @param dev     pointer net_device | ||||
|  *  @return 	   N/A | ||||
|  * @priv:	pointer to &struct lbs_private | ||||
|  * | ||||
|  * returns:	N/A | ||||
|  */ | ||||
| static void lbs_debug_init(struct lbs_private *priv) | ||||
| { | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| 
 | ||||
| /**
 | ||||
|   *  This file contains declaration referring to | ||||
|   *  functions defined in other source files | ||||
|   */ | ||||
| /*
 | ||||
|  *  This file contains declaration referring to | ||||
|  *  functions defined in other source files | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _LBS_DECL_H_ | ||||
| #define _LBS_DECL_H_ | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| /**
 | ||||
|   * This header file contains global constant/enum definitions, | ||||
|   * global variable declaration. | ||||
|   */ | ||||
| /*
 | ||||
|  * This header file contains global constant/enum definitions, | ||||
|  * global variable declaration. | ||||
|  */ | ||||
| #ifndef _LBS_DEFS_H_ | ||||
| #define _LBS_DEFS_H_ | ||||
| 
 | ||||
|  | @ -123,19 +123,19 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /** Buffer Constants */ | ||||
| /* Buffer Constants */ | ||||
| 
 | ||||
| /*	The size of SQ memory PPA, DPA are 8 DWORDs, that keep the physical
 | ||||
| *	addresses of TxPD buffers. Station has only 8 TxPD available, Whereas | ||||
| *	driver has more local TxPDs. Each TxPD on the host memory is associated | ||||
| *	with a Tx control node. The driver maintains 8 RxPD descriptors for | ||||
| *	station firmware to store Rx packet information. | ||||
| * | ||||
| *	Current version of MAC has a 32x6 multicast address buffer. | ||||
| * | ||||
| *	802.11b can have up to  14 channels, the driver keeps the | ||||
| *	BSSID(MAC address) of each APs or Ad hoc stations it has sensed. | ||||
| */ | ||||
|  *	addresses of TxPD buffers. Station has only 8 TxPD available, Whereas | ||||
|  *	driver has more local TxPDs. Each TxPD on the host memory is associated | ||||
|  *	with a Tx control node. The driver maintains 8 RxPD descriptors for | ||||
|  *	station firmware to store Rx packet information. | ||||
|  * | ||||
|  *	Current version of MAC has a 32x6 multicast address buffer. | ||||
|  * | ||||
|  *	802.11b can have up to  14 channels, the driver keeps the | ||||
|  *	BSSID(MAC address) of each APs or Ad hoc stations it has sensed. | ||||
|  */ | ||||
| 
 | ||||
| #define MRVDRV_MAX_MULTICAST_LIST_SIZE	32 | ||||
| #define LBS_NUM_CMD_BUFFERS             10 | ||||
|  | @ -166,7 +166,7 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
| #define WOL_RESULT_NOSPC_ERR		1 | ||||
| #define WOL_RESULT_EEXIST_ERR		2 | ||||
| 
 | ||||
| /** Misc constants */ | ||||
| /* Misc constants */ | ||||
| /* This section defines 802.11 specific contants */ | ||||
| 
 | ||||
| #define MRVDRV_MAX_BSS_DESCRIPTS		16 | ||||
|  | @ -183,7 +183,8 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
| 
 | ||||
| #define MARVELL_MESH_IE_LENGTH		9 | ||||
| 
 | ||||
| /* Values used to populate the struct mrvl_mesh_ie.  The only time you need this
 | ||||
| /*
 | ||||
|  * Values used to populate the struct mrvl_mesh_ie.  The only time you need this | ||||
|  * is when enabling the mesh using CMD_MESH_CONFIG. | ||||
|  */ | ||||
| #define MARVELL_MESH_IE_TYPE		4 | ||||
|  | @ -193,7 +194,7 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
| #define MARVELL_MESH_METRIC_ID		0 | ||||
| #define MARVELL_MESH_CAPABILITY		0 | ||||
| 
 | ||||
| /** INT status Bit Definition*/ | ||||
| /* INT status Bit Definition */ | ||||
| #define MRVDRV_TX_DNLD_RDY		0x0001 | ||||
| #define MRVDRV_RX_UPLD_RDY		0x0002 | ||||
| #define MRVDRV_CMD_DNLD_RDY		0x0004 | ||||
|  | @ -208,59 +209,63 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
| #define TPC_DEFAULT_P1 10 | ||||
| #define TPC_DEFAULT_P2 13 | ||||
| 
 | ||||
| /** TxPD status */ | ||||
| /* TxPD status */ | ||||
| 
 | ||||
| /*	Station firmware use TxPD status field to report final Tx transmit
 | ||||
| *	result, Bit masks are used to present combined situations. | ||||
| */ | ||||
| /*
 | ||||
|  *	Station firmware use TxPD status field to report final Tx transmit | ||||
|  *	result, Bit masks are used to present combined situations. | ||||
|  */ | ||||
| 
 | ||||
| #define MRVDRV_TxPD_POWER_MGMT_NULL_PACKET 0x01 | ||||
| #define MRVDRV_TxPD_POWER_MGMT_LAST_PACKET 0x08 | ||||
| 
 | ||||
| /** Tx mesh flag */ | ||||
| /* Currently we are using normal WDS flag as mesh flag.
 | ||||
| /* Tx mesh flag */ | ||||
| /*
 | ||||
|  * Currently we are using normal WDS flag as mesh flag. | ||||
|  * TODO: change to proper mesh flag when MAC understands it. | ||||
|  */ | ||||
| #define TxPD_CONTROL_WDS_FRAME (1<<17) | ||||
| #define TxPD_MESH_FRAME TxPD_CONTROL_WDS_FRAME | ||||
| 
 | ||||
| /** Mesh interface ID */ | ||||
| /* Mesh interface ID */ | ||||
| #define MESH_IFACE_ID					0x0001 | ||||
| /** Mesh id should be in bits 14-13-12 */ | ||||
| /* Mesh id should be in bits 14-13-12 */ | ||||
| #define MESH_IFACE_BIT_OFFSET				0x000c | ||||
| /** Mesh enable bit in FW capability */ | ||||
| /* Mesh enable bit in FW capability */ | ||||
| #define MESH_CAPINFO_ENABLE_MASK			(1<<16) | ||||
| 
 | ||||
| /** FW definition from Marvell v4 */ | ||||
| /* FW definition from Marvell v4 */ | ||||
| #define MRVL_FW_V4					(0x04) | ||||
| /** FW definition from Marvell v5 */ | ||||
| /* FW definition from Marvell v5 */ | ||||
| #define MRVL_FW_V5					(0x05) | ||||
| /** FW definition from Marvell v10 */ | ||||
| /* FW definition from Marvell v10 */ | ||||
| #define MRVL_FW_V10					(0x0a) | ||||
| /** FW major revision definition */ | ||||
| /* FW major revision definition */ | ||||
| #define MRVL_FW_MAJOR_REV(x)				((x)>>24) | ||||
| 
 | ||||
| /** RxPD status */ | ||||
| /* RxPD status */ | ||||
| 
 | ||||
| #define MRVDRV_RXPD_STATUS_OK                0x0001 | ||||
| 
 | ||||
| /** RxPD status - Received packet types */ | ||||
| /** Rx mesh flag */ | ||||
| /* Currently we are using normal WDS flag as mesh flag.
 | ||||
| /* RxPD status - Received packet types */ | ||||
| /* Rx mesh flag */ | ||||
| /*
 | ||||
|  * Currently we are using normal WDS flag as mesh flag. | ||||
|  * TODO: change to proper mesh flag when MAC understands it. | ||||
|  */ | ||||
| #define RxPD_CONTROL_WDS_FRAME (0x40) | ||||
| #define RxPD_MESH_FRAME RxPD_CONTROL_WDS_FRAME | ||||
| 
 | ||||
| /** RSSI-related defines */ | ||||
| /*	RSSI constants are used to implement 802.11 RSSI threshold
 | ||||
| *	indication. if the Rx packet signal got too weak for 5 consecutive | ||||
| *	times, miniport driver (driver) will report this event to wrapper | ||||
| */ | ||||
| /* RSSI-related defines */ | ||||
| /*
 | ||||
|  *	RSSI constants are used to implement 802.11 RSSI threshold | ||||
|  *	indication. if the Rx packet signal got too weak for 5 consecutive | ||||
|  *	times, miniport driver (driver) will report this event to wrapper | ||||
|  */ | ||||
| 
 | ||||
| #define MRVDRV_NF_DEFAULT_SCAN_VALUE		(-96) | ||||
| 
 | ||||
| /** RTS/FRAG related defines */ | ||||
| /* RTS/FRAG related defines */ | ||||
| #define MRVDRV_RTS_MIN_VALUE		0 | ||||
| #define MRVDRV_RTS_MAX_VALUE		2347 | ||||
| #define MRVDRV_FRAG_MIN_VALUE		256 | ||||
|  | @ -300,36 +305,36 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in | |||
| 
 | ||||
| #define	MAX_LEDS			8 | ||||
| 
 | ||||
| /** Global Variable Declaration */ | ||||
| /* Global Variable Declaration */ | ||||
| extern const char lbs_driver_version[]; | ||||
| extern u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE]; | ||||
| 
 | ||||
| 
 | ||||
| /** ENUM definition*/ | ||||
| /** SNRNF_TYPE */ | ||||
| /* ENUM definition */ | ||||
| /* SNRNF_TYPE */ | ||||
| enum SNRNF_TYPE { | ||||
| 	TYPE_BEACON = 0, | ||||
| 	TYPE_RXPD, | ||||
| 	MAX_TYPE_B | ||||
| }; | ||||
| 
 | ||||
| /** SNRNF_DATA*/ | ||||
| /* SNRNF_DATA */ | ||||
| enum SNRNF_DATA { | ||||
| 	TYPE_NOAVG = 0, | ||||
| 	TYPE_AVG, | ||||
| 	MAX_TYPE_AVG | ||||
| }; | ||||
| 
 | ||||
| /** LBS_802_11_POWER_MODE */ | ||||
| /* LBS_802_11_POWER_MODE */ | ||||
| enum LBS_802_11_POWER_MODE { | ||||
| 	LBS802_11POWERMODECAM, | ||||
| 	LBS802_11POWERMODEMAX_PSP, | ||||
| 	LBS802_11POWERMODEFAST_PSP, | ||||
| 	/*not a real mode, defined as an upper bound */ | ||||
| 	/* not a real mode, defined as an upper bound */ | ||||
| 	LBS802_11POWEMODEMAX | ||||
| }; | ||||
| 
 | ||||
| /** PS_STATE */ | ||||
| /* PS_STATE */ | ||||
| enum PS_STATE { | ||||
| 	PS_STATE_FULL_POWER, | ||||
| 	PS_STATE_AWAKE, | ||||
|  | @ -337,7 +342,7 @@ enum PS_STATE { | |||
| 	PS_STATE_SLEEP | ||||
| }; | ||||
| 
 | ||||
| /** DNLD_STATE */ | ||||
| /* DNLD_STATE */ | ||||
| enum DNLD_STATE { | ||||
| 	DNLD_RES_RECEIVED, | ||||
| 	DNLD_DATA_SENT, | ||||
|  | @ -345,19 +350,19 @@ enum DNLD_STATE { | |||
| 	DNLD_BOOTCMD_SENT, | ||||
| }; | ||||
| 
 | ||||
| /** LBS_MEDIA_STATE */ | ||||
| /* LBS_MEDIA_STATE */ | ||||
| enum LBS_MEDIA_STATE { | ||||
| 	LBS_CONNECTED, | ||||
| 	LBS_DISCONNECTED | ||||
| }; | ||||
| 
 | ||||
| /** LBS_802_11_PRIVACY_FILTER */ | ||||
| /* LBS_802_11_PRIVACY_FILTER */ | ||||
| enum LBS_802_11_PRIVACY_FILTER { | ||||
| 	LBS802_11PRIVFILTERACCEPTALL, | ||||
| 	LBS802_11PRIVFILTER8021XWEP | ||||
| }; | ||||
| 
 | ||||
| /** mv_ms_type */ | ||||
| /* mv_ms_type */ | ||||
| enum mv_ms_type { | ||||
| 	MVMS_DAT = 0, | ||||
| 	MVMS_CMD = 1, | ||||
|  | @ -365,14 +370,14 @@ enum mv_ms_type { | |||
| 	MVMS_EVENT | ||||
| }; | ||||
| 
 | ||||
| /** KEY_TYPE_ID */ | ||||
| /* KEY_TYPE_ID */ | ||||
| enum KEY_TYPE_ID { | ||||
| 	KEY_TYPE_ID_WEP = 0, | ||||
| 	KEY_TYPE_ID_TKIP, | ||||
| 	KEY_TYPE_ID_AES | ||||
| }; | ||||
| 
 | ||||
| /** KEY_INFO_WPA (applies to both TKIP and AES/CCMP) */ | ||||
| /* KEY_INFO_WPA (applies to both TKIP and AES/CCMP) */ | ||||
| enum KEY_INFO_WPA { | ||||
| 	KEY_INFO_WPA_MCAST = 0x01, | ||||
| 	KEY_INFO_WPA_UNICAST = 0x02, | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| /**
 | ||||
|   * This file contains definitions and data structures specific | ||||
|   * to Marvell 802.11 NIC. It contains the Device Information | ||||
|   * structure struct lbs_private.. | ||||
|   */ | ||||
| /*
 | ||||
|  * This file contains definitions and data structures specific | ||||
|  * to Marvell 802.11 NIC. It contains the Device Information | ||||
|  * structure struct lbs_private.. | ||||
|  */ | ||||
| #ifndef _LBS_DEV_H_ | ||||
| #define _LBS_DEV_H_ | ||||
| 
 | ||||
|  | @ -12,7 +12,7 @@ | |||
| 
 | ||||
| #include <linux/kfifo.h> | ||||
| 
 | ||||
| /** sleep_params */ | ||||
| /* sleep_params */ | ||||
| struct sleep_params { | ||||
| 	uint16_t sp_error; | ||||
| 	uint16_t sp_offset; | ||||
|  | @ -23,7 +23,7 @@ struct sleep_params { | |||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /** Private structure for the MV device */ | ||||
| /* Private structure for the MV device */ | ||||
| struct lbs_private { | ||||
| 
 | ||||
| 	/* Basic networking */ | ||||
|  | @ -125,12 +125,12 @@ struct lbs_private { | |||
| 	/* Events sent from hardware to driver */ | ||||
| 	struct kfifo event_fifo; | ||||
| 
 | ||||
| 	/** thread to service interrupts */ | ||||
| 	/* thread to service interrupts */ | ||||
| 	struct task_struct *main_thread; | ||||
| 	wait_queue_head_t waitq; | ||||
| 	struct workqueue_struct *work_thread; | ||||
| 
 | ||||
| 	/** Encryption stuff */ | ||||
| 	/* Encryption stuff */ | ||||
| 	u8 authtype_auto; | ||||
| 	u8 wep_tx_key; | ||||
| 	u8 wep_key[4][WLAN_KEY_LEN_WEP104]; | ||||
|  | @ -162,7 +162,7 @@ struct lbs_private { | |||
| 	s16 txpower_min; | ||||
| 	s16 txpower_max; | ||||
| 
 | ||||
| 	/** Scanning */ | ||||
| 	/* Scanning */ | ||||
| 	struct delayed_work scan_work; | ||||
| 	int scan_channel; | ||||
| 	/* Queue of things waiting for scan completion */ | ||||
|  |  | |||
|  | @ -20,7 +20,8 @@ static void lbs_ethtool_get_drvinfo(struct net_device *dev, | |||
| 	strcpy(info->version, lbs_driver_version); | ||||
| } | ||||
| 
 | ||||
| /* All 8388 parts have 16KiB EEPROM size at the time of writing.
 | ||||
| /*
 | ||||
|  * All 8388 parts have 16KiB EEPROM size at the time of writing. | ||||
|  * In case that changes this needs fixing. | ||||
|  */ | ||||
| #define LBS_EEPROM_LEN 16384 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| /**
 | ||||
|   * This file function prototypes, data structure | ||||
|   * and  definitions for all the host/station commands | ||||
|   */ | ||||
| /*
 | ||||
|  * This file function prototypes, data structure | ||||
|  * and  definitions for all the host/station commands | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _LBS_HOST_H_ | ||||
| #define _LBS_HOST_H_ | ||||
|  | @ -13,9 +13,10 @@ | |||
| 
 | ||||
| #define CMD_OPTION_WAITFORRSP                   0x0002 | ||||
| 
 | ||||
| /** Host command IDs */ | ||||
| /* Host command IDs */ | ||||
| 
 | ||||
| /* Return command are almost always the same as the host command, but with
 | ||||
| /*
 | ||||
|  * Return command are almost always the same as the host command, but with | ||||
|  * bit 15 set high.  There are a few exceptions, though... | ||||
|  */ | ||||
| #define CMD_RET(cmd)                            (0x8000 | cmd) | ||||
|  | @ -251,7 +252,7 @@ enum cmd_mesh_config_types { | |||
| 	CMD_TYPE_MESH_GET_MESH_IE, /* GET_DEFAULTS is superset of GET_MESHIE */ | ||||
| }; | ||||
| 
 | ||||
| /** Card Event definition */ | ||||
| /* Card Event definition */ | ||||
| #define MACREG_INT_CODE_TX_PPA_FREE		0 | ||||
| #define MACREG_INT_CODE_TX_DMA_DONE		1 | ||||
| #define MACREG_INT_CODE_LINK_LOST_W_SCAN	2 | ||||
|  | @ -624,12 +625,14 @@ struct cmd_ds_802_11_rf_channel { | |||
| struct cmd_ds_802_11_rssi { | ||||
| 	struct cmd_header hdr; | ||||
| 
 | ||||
| 	/* request:  number of beacons (N) to average the SNR and NF over
 | ||||
| 	/*
 | ||||
| 	 * request:  number of beacons (N) to average the SNR and NF over | ||||
| 	 * response: SNR of most recent beacon | ||||
| 	 */ | ||||
| 	__le16 n_or_snr; | ||||
| 
 | ||||
| 	/* The following fields are only set in the response.
 | ||||
| 	/*
 | ||||
| 	 * The following fields are only set in the response. | ||||
| 	 * In the request these are reserved and should be set to 0. | ||||
| 	 */ | ||||
| 	__le16 nf;       /* most recent beacon noise floor */ | ||||
|  | @ -680,14 +683,16 @@ struct cmd_ds_802_11_ps_mode { | |||
| 
 | ||||
| 	__le16 action; | ||||
| 
 | ||||
| 	/* Interval for keepalive in PS mode:
 | ||||
| 	/*
 | ||||
| 	 * Interval for keepalive in PS mode: | ||||
| 	 * 0x0000 = don't change | ||||
| 	 * 0x001E = firmware default | ||||
| 	 * 0xFFFF = disable | ||||
| 	 */ | ||||
| 	__le16 nullpktinterval; | ||||
| 
 | ||||
| 	/* Number of DTIM intervals to wake up for:
 | ||||
| 	/*
 | ||||
| 	 * Number of DTIM intervals to wake up for: | ||||
| 	 * 0 = don't change | ||||
| 	 * 1 = firmware default | ||||
| 	 * 5 = max | ||||
|  | @ -697,7 +702,8 @@ struct cmd_ds_802_11_ps_mode { | |||
| 	__le16 reserved; | ||||
| 	__le16 locallisteninterval; | ||||
| 
 | ||||
| 	/* AdHoc awake period (FW v9+ only):
 | ||||
| 	/*
 | ||||
| 	 * AdHoc awake period (FW v9+ only): | ||||
| 	 * 0 = don't change | ||||
| 	 * 1 = always awake (IEEE standard behavior) | ||||
| 	 * 2 - 31 = sleep for (n - 1) periods and awake for 1 period | ||||
|  | @ -771,7 +777,8 @@ struct adhoc_bssdesc { | |||
| 	__le16 capability; | ||||
| 	u8 rates[MAX_RATES]; | ||||
| 
 | ||||
| 	/* DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the
 | ||||
| 	/*
 | ||||
| 	 * DO NOT ADD ANY FIELDS TO THIS STRUCTURE. It is used below in the | ||||
| 	 * Adhoc join command and will cause a binary layout mismatch with | ||||
| 	 * the firmware | ||||
| 	 */ | ||||
|  |  | |||
|  | @ -312,7 +312,8 @@ static int if_cs_poll_while_fw_download(struct if_cs_card *card, uint addr, u8 r | |||
| #define CF8385_MANFID		0x02df | ||||
| #define CF8385_CARDID		0x8103 | ||||
| 
 | ||||
| /* FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when
 | ||||
| /*
 | ||||
|  * FIXME: just use the 'driver_info' field of 'struct pcmcia_device_id' when | ||||
|  * that gets fixed.  Currently there's no way to access it from the probe hook. | ||||
|  */ | ||||
| static inline u32 get_model(u16 manf_id, u16 card_id) | ||||
|  | @ -621,8 +622,10 @@ static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw) | |||
| 		if (remain < count) | ||||
| 			count = remain; | ||||
| 
 | ||||
| 		/* "write the number of bytes to be sent to the I/O Command
 | ||||
| 		 * write length register" */ | ||||
| 		/*
 | ||||
| 		 * "write the number of bytes to be sent to the I/O Command | ||||
| 		 * write length register" | ||||
| 		 */ | ||||
| 		if_cs_write16(card, IF_CS_CMD_LEN, count); | ||||
| 
 | ||||
| 		/* "write this to I/O Command port register as 16 bit writes */ | ||||
|  | @ -631,16 +634,22 @@ static int if_cs_prog_helper(struct if_cs_card *card, const struct firmware *fw) | |||
| 				&fw->data[sent], | ||||
| 				count >> 1); | ||||
| 
 | ||||
| 		/* "Assert the download over interrupt command in the Host
 | ||||
| 		 * status register" */ | ||||
| 		/*
 | ||||
| 		 * "Assert the download over interrupt command in the Host | ||||
| 		 * status register" | ||||
| 		 */ | ||||
| 		if_cs_write8(card, IF_CS_HOST_STATUS, IF_CS_BIT_COMMAND); | ||||
| 
 | ||||
| 		/* "Assert the download over interrupt command in the Card
 | ||||
| 		 * interrupt case register" */ | ||||
| 		/*
 | ||||
| 		 * "Assert the download over interrupt command in the Card | ||||
| 		 * interrupt case register" | ||||
| 		 */ | ||||
| 		if_cs_write16(card, IF_CS_HOST_INT_CAUSE, IF_CS_BIT_COMMAND); | ||||
| 
 | ||||
| 		/* "The host polls the Card Status register ... for 50 ms before
 | ||||
| 		   declaring a failure */ | ||||
| 		/*
 | ||||
| 		 * "The host polls the Card Status register ... for 50 ms before | ||||
| 		 * declaring a failure" | ||||
| 		 */ | ||||
| 		ret = if_cs_poll_while_fw_download(card, IF_CS_CARD_STATUS, | ||||
| 			IF_CS_BIT_COMMAND); | ||||
| 		if (ret < 0) { | ||||
|  | @ -841,7 +850,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
| 
 | ||||
| 	/*
 | ||||
| 	 * Most of the libertas cards can do unaligned register access, but some | ||||
| 	 * weird ones can not. That's especially true for the CF8305 card. | ||||
| 	 * weird ones cannot. That's especially true for the CF8305 card. | ||||
| 	 */ | ||||
| 	card->align_regs = 0; | ||||
| 
 | ||||
|  | @ -913,8 +922,10 @@ static int if_cs_probe(struct pcmcia_device *p_dev) | |||
| 		goto out3; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Clear any interrupt cause that happened while sending
 | ||||
| 	 * firmware/initializing card */ | ||||
| 	/*
 | ||||
| 	 * Clear any interrupt cause that happened while sending | ||||
| 	 * firmware/initializing card | ||||
| 	 */ | ||||
| 	if_cs_write16(card, IF_CS_CARD_INT_CAUSE, IF_CS_BIT_MASK); | ||||
| 	if_cs_enable_ints(card); | ||||
| 
 | ||||
|  |  | |||
|  | @ -143,8 +143,10 @@ static void spu_transaction_finish(struct if_spi_card *card) | |||
| 	card->prev_xfer_time = jiffies; | ||||
| } | ||||
| 
 | ||||
| /* Write out a byte buffer to an SPI register,
 | ||||
|  * using a series of 16-bit transfers. */ | ||||
| /*
 | ||||
|  * Write out a byte buffer to an SPI register, | ||||
|  * using a series of 16-bit transfers. | ||||
|  */ | ||||
| static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) | ||||
| { | ||||
| 	int err = 0; | ||||
|  | @ -208,8 +210,10 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) | |||
| 	struct spi_transfer dummy_trans; | ||||
| 	struct spi_transfer data_trans; | ||||
| 
 | ||||
| 	/* You must take an even number of bytes from the SPU, even if you
 | ||||
| 	 * don't care about the last one.  */ | ||||
| 	/*
 | ||||
| 	 * You must take an even number of bytes from the SPU, even if you | ||||
| 	 * don't care about the last one. | ||||
| 	 */ | ||||
| 	BUG_ON(len & 0x1); | ||||
| 
 | ||||
| 	spu_transaction_init(card); | ||||
|  | @ -258,8 +262,10 @@ static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val) | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /* Read 32 bits from an SPI register.
 | ||||
|  * The low 16 bits are read first. */ | ||||
| /*
 | ||||
|  * Read 32 bits from an SPI register. | ||||
|  * The low 16 bits are read first. | ||||
|  */ | ||||
| static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) | ||||
| { | ||||
| 	__le32 buf; | ||||
|  | @ -271,13 +277,15 @@ static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) | |||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| /* Keep reading 16 bits from an SPI register until you get the correct result.
 | ||||
| /*
 | ||||
|  * Keep reading 16 bits from an SPI register until you get the correct result. | ||||
|  * | ||||
|  * If mask = 0, the correct result is any non-zero number. | ||||
|  * If mask != 0, the correct result is any number where | ||||
|  * number & target_mask == target | ||||
|  * | ||||
|  * Returns -ETIMEDOUT if a second passes without the correct result. */ | ||||
|  * Returns -ETIMEDOUT if a second passes without the correct result. | ||||
|  */ | ||||
| static int spu_wait_for_u16(struct if_spi_card *card, u16 reg, | ||||
| 			u16 target_mask, u16 target) | ||||
| { | ||||
|  | @ -305,8 +313,10 @@ static int spu_wait_for_u16(struct if_spi_card *card, u16 reg, | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| /* Read 16 bits from an SPI register until you receive a specific value.
 | ||||
|  * Returns -ETIMEDOUT if a 4 tries pass without success. */ | ||||
| /*
 | ||||
|  * Read 16 bits from an SPI register until you receive a specific value. | ||||
|  * Returns -ETIMEDOUT if a 4 tries pass without success. | ||||
|  */ | ||||
| static int spu_wait_for_u32(struct if_spi_card *card, u32 reg, u32 target) | ||||
| { | ||||
| 	int err, try; | ||||
|  | @ -328,8 +338,10 @@ static int spu_set_interrupt_mode(struct if_spi_card *card, | |||
| { | ||||
| 	int err = 0; | ||||
| 
 | ||||
| 	/* We can suppress a host interrupt by clearing the appropriate
 | ||||
| 	 * bit in the "host interrupt status mask" register */ | ||||
| 	/*
 | ||||
| 	 * We can suppress a host interrupt by clearing the appropriate | ||||
| 	 * bit in the "host interrupt status mask" register | ||||
| 	 */ | ||||
| 	if (suppress_host_int) { | ||||
| 		err = spu_write_u16(card, IF_SPI_HOST_INT_STATUS_MASK_REG, 0); | ||||
| 		if (err) | ||||
|  | @ -345,10 +357,12 @@ static int spu_set_interrupt_mode(struct if_spi_card *card, | |||
| 			return err; | ||||
| 	} | ||||
| 
 | ||||
| 	/* If auto-interrupts are on, the completion of certain transactions
 | ||||
| 	/*
 | ||||
| 	 * If auto-interrupts are on, the completion of certain transactions | ||||
| 	 * will trigger an interrupt automatically. If auto-interrupts | ||||
| 	 * are off, we need to set the "Card Interrupt Cause" register to | ||||
| 	 * trigger a card interrupt. */ | ||||
| 	 * trigger a card interrupt. | ||||
| 	 */ | ||||
| 	if (auto_int) { | ||||
| 		err = spu_write_u16(card, IF_SPI_HOST_INT_CTRL_REG, | ||||
| 				IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO | | ||||
|  | @ -402,8 +416,10 @@ static int spu_init(struct if_spi_card *card, int use_dummy_writes) | |||
| 	int err = 0; | ||||
| 	u32 delay; | ||||
| 
 | ||||
| 	/* We have to start up in timed delay mode so that we can safely
 | ||||
| 	 * read the Delay Read Register. */ | ||||
| 	/*
 | ||||
| 	 * We have to start up in timed delay mode so that we can safely | ||||
| 	 * read the Delay Read Register. | ||||
| 	 */ | ||||
| 	card->use_dummy_writes = 0; | ||||
| 	err = spu_set_bus_mode(card, | ||||
| 				IF_SPI_BUS_MODE_SPI_CLOCK_PHASE_RISING | | ||||
|  | @ -459,8 +475,10 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card, | |||
| 
 | ||||
| 	/* Load helper firmware image */ | ||||
| 	while (bytes_remaining > 0) { | ||||
| 		/* Scratch pad 1 should contain the number of bytes we
 | ||||
| 		 * want to download to the firmware */ | ||||
| 		/*
 | ||||
| 		 * Scratch pad 1 should contain the number of bytes we | ||||
| 		 * want to download to the firmware | ||||
| 		 */ | ||||
| 		err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, | ||||
| 					HELPER_FW_LOAD_CHUNK_SZ); | ||||
| 		if (err) | ||||
|  | @ -472,8 +490,10 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card, | |||
| 		if (err) | ||||
| 			goto out; | ||||
| 
 | ||||
| 		/* Feed the data into the command read/write port reg
 | ||||
| 		 * in chunks of 64 bytes */ | ||||
| 		/*
 | ||||
| 		 * Feed the data into the command read/write port reg | ||||
| 		 * in chunks of 64 bytes | ||||
| 		 */ | ||||
| 		memset(temp, 0, sizeof(temp)); | ||||
| 		memcpy(temp, fw, | ||||
| 		       min(bytes_remaining, HELPER_FW_LOAD_CHUNK_SZ)); | ||||
|  | @ -495,9 +515,11 @@ static int if_spi_prog_helper_firmware(struct if_spi_card *card, | |||
| 		fw += HELPER_FW_LOAD_CHUNK_SZ; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Once the helper / single stage firmware download is complete,
 | ||||
| 	/*
 | ||||
| 	 * Once the helper / single stage firmware download is complete, | ||||
| 	 * write 0 to scratch pad 1 and interrupt the | ||||
| 	 * bootloader. This completes the helper download. */ | ||||
| 	 * bootloader. This completes the helper download. | ||||
| 	 */ | ||||
| 	err = spu_write_u16(card, IF_SPI_SCRATCH_1_REG, FIRMWARE_DNLD_OK); | ||||
| 	if (err) | ||||
| 		goto out; | ||||
|  | @ -517,16 +539,20 @@ out: | |||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| /* Returns the length of the next packet the firmware expects us to send
 | ||||
|  * Sets crc_err if the previous transfer had a CRC error. */ | ||||
| /*
 | ||||
|  * Returns the length of the next packet the firmware expects us to send. | ||||
|  * Sets crc_err if the previous transfer had a CRC error. | ||||
|  */ | ||||
| static int if_spi_prog_main_firmware_check_len(struct if_spi_card *card, | ||||
| 						int *crc_err) | ||||
| { | ||||
| 	u16 len; | ||||
| 	int err = 0; | ||||
| 
 | ||||
| 	/* wait until the host interrupt status register indicates
 | ||||
| 	 * that we are ready to download */ | ||||
| 	/*
 | ||||
| 	 * wait until the host interrupt status register indicates | ||||
| 	 * that we are ready to download | ||||
| 	 */ | ||||
| 	err = spu_wait_for_u16(card, IF_SPI_HOST_INT_STATUS_REG, | ||||
| 				IF_SPI_HIST_CMD_DOWNLOAD_RDY, | ||||
| 				IF_SPI_HIST_CMD_DOWNLOAD_RDY); | ||||
|  | @ -587,8 +613,10 @@ static int if_spi_prog_main_firmware(struct if_spi_card *card, | |||
| 			goto out; | ||||
| 		} | ||||
| 		if (bytes < 0) { | ||||
| 			/* If there are no more bytes left, we would normally
 | ||||
| 			 * expect to have terminated with len = 0 */ | ||||
| 			/*
 | ||||
| 			 * If there are no more bytes left, we would normally | ||||
| 			 * expect to have terminated with len = 0 | ||||
| 			 */ | ||||
| 			lbs_pr_err("Firmware load wants more bytes " | ||||
| 				   "than we have to offer.\n"); | ||||
| 			break; | ||||
|  | @ -660,14 +688,18 @@ static int if_spi_c2h_cmd(struct if_spi_card *card) | |||
| 	u16 len; | ||||
| 	u8 i; | ||||
| 
 | ||||
| 	/* We need a buffer big enough to handle whatever people send to
 | ||||
| 	 * hw_host_to_card */ | ||||
| 	/*
 | ||||
| 	 * We need a buffer big enough to handle whatever people send to | ||||
| 	 * hw_host_to_card | ||||
| 	 */ | ||||
| 	BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_CMD_BUFFER_SIZE); | ||||
| 	BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE < LBS_UPLD_SIZE); | ||||
| 
 | ||||
| 	/* It's just annoying if the buffer size isn't a multiple of 4, because
 | ||||
| 	 * then we might have len <  IF_SPI_CMD_BUF_SIZE but | ||||
| 	 * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE */ | ||||
| 	/*
 | ||||
| 	 * It's just annoying if the buffer size isn't a multiple of 4, because | ||||
| 	 * then we might have len < IF_SPI_CMD_BUF_SIZE but | ||||
| 	 * ALIGN(len, 4) > IF_SPI_CMD_BUF_SIZE | ||||
| 	 */ | ||||
| 	BUILD_BUG_ON(IF_SPI_CMD_BUF_SIZE % 4 != 0); | ||||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_SPI); | ||||
|  | @ -838,8 +870,10 @@ static void if_spi_host_to_card_worker(struct work_struct *work) | |||
| 
 | ||||
| 	lbs_deb_enter(LBS_DEB_SPI); | ||||
| 
 | ||||
| 	/* Read the host interrupt status register to see what we
 | ||||
| 	 * can do. */ | ||||
| 	/*
 | ||||
| 	 * Read the host interrupt status register to see what we | ||||
| 	 * can do. | ||||
| 	 */ | ||||
| 	err = spu_read_u16(card, IF_SPI_HOST_INT_STATUS_REG, | ||||
| 				&hiStatus); | ||||
| 	if (err) { | ||||
|  | @ -858,12 +892,15 @@ static void if_spi_host_to_card_worker(struct work_struct *work) | |||
| 			goto err; | ||||
| 	} | ||||
| 
 | ||||
| 	/* workaround: in PS mode, the card does not set the Command
 | ||||
| 	 * Download Ready bit, but it sets TX Download Ready. */ | ||||
| 	/*
 | ||||
| 	 * workaround: in PS mode, the card does not set the Command | ||||
| 	 * Download Ready bit, but it sets TX Download Ready. | ||||
| 	 */ | ||||
| 	if (hiStatus & IF_SPI_HIST_CMD_DOWNLOAD_RDY || | ||||
| 	   (card->priv->psstate != PS_STATE_FULL_POWER && | ||||
| 	    (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY))) { | ||||
| 		/* This means two things. First of all,
 | ||||
| 		/*
 | ||||
| 		 * This means two things. First of all, | ||||
| 		 * if there was a previous command sent, the card has | ||||
| 		 * successfully received it. | ||||
| 		 * Secondly, it is now ready to download another | ||||
|  | @ -871,8 +908,7 @@ static void if_spi_host_to_card_worker(struct work_struct *work) | |||
| 		 */ | ||||
| 		lbs_host_to_card_done(card->priv); | ||||
| 
 | ||||
| 		/* Do we have any command packets from the host to
 | ||||
| 		 * send? */ | ||||
| 		/* Do we have any command packets from the host to send? */ | ||||
| 		packet = NULL; | ||||
| 		spin_lock_irqsave(&card->buffer_lock, flags); | ||||
| 		if (!list_empty(&card->cmd_packet_list)) { | ||||
|  | @ -886,8 +922,7 @@ static void if_spi_host_to_card_worker(struct work_struct *work) | |||
| 			if_spi_h2c(card, packet, MVMS_CMD); | ||||
| 	} | ||||
| 	if (hiStatus & IF_SPI_HIST_TX_DOWNLOAD_RDY) { | ||||
| 		/* Do we have any data packets from the host to
 | ||||
| 		 * send? */ | ||||
| 		/* Do we have any data packets from the host to send? */ | ||||
| 		packet = NULL; | ||||
| 		spin_lock_irqsave(&card->buffer_lock, flags); | ||||
| 		if (!list_empty(&card->data_packet_list)) { | ||||
|  | @ -914,7 +949,8 @@ err: | |||
|  * Host to Card | ||||
|  * | ||||
|  * Called from Libertas to transfer some data to the WLAN device | ||||
|  * We can't sleep here. */ | ||||
|  * We can't sleep here. | ||||
|  */ | ||||
| static int if_spi_host_to_card(struct lbs_private *priv, | ||||
| 				u8 type, u8 *buf, u16 nb) | ||||
| { | ||||
|  | @ -1125,8 +1161,10 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
| 	if (err) | ||||
| 		goto free_card; | ||||
| 
 | ||||
| 	/* Register our card with libertas.
 | ||||
| 	 * This will call alloc_etherdev */ | ||||
| 	/*
 | ||||
| 	 * Register our card with libertas. | ||||
| 	 * This will call alloc_etherdev. | ||||
| 	 */ | ||||
| 	priv = lbs_add_card(card, &spi->dev); | ||||
| 	if (!priv) { | ||||
| 		err = -ENOMEM; | ||||
|  | @ -1153,9 +1191,11 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
| 		goto terminate_workqueue; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Start the card.
 | ||||
| 	/*
 | ||||
| 	 * Start the card. | ||||
| 	 * This will call register_netdev, and we'll start | ||||
| 	 * getting interrupts... */ | ||||
| 	 * getting interrupts... | ||||
| 	 */ | ||||
| 	err = lbs_start_card(priv); | ||||
| 	if (err) | ||||
| 		goto release_irq; | ||||
|  |  | |||
|  | @ -86,34 +86,34 @@ | |||
| #define IF_SPI_DEVICEID_CTRL_REG_TO_CARD_REV(dc) (dc & 0x000000ff) | ||||
| 
 | ||||
| /***************** IF_SPI_HOST_INT_CTRL_REG *****************/ | ||||
| /** Host Interrupt Control bit : Wake up */ | ||||
| /* Host Interrupt Control bit : Wake up */ | ||||
| #define IF_SPI_HICT_WAKE_UP				(1<<0) | ||||
| /** Host Interrupt Control bit : WLAN ready */ | ||||
| /* Host Interrupt Control bit : WLAN ready */ | ||||
| #define IF_SPI_HICT_WLAN_READY				(1<<1) | ||||
| /*#define IF_SPI_HICT_FIFO_FIRST_HALF_EMPTY		(1<<2) */ | ||||
| /*#define IF_SPI_HICT_FIFO_SECOND_HALF_EMPTY		(1<<3) */ | ||||
| /*#define IF_SPI_HICT_IRQSRC_WLAN			(1<<4) */ | ||||
| /** Host Interrupt Control bit : Tx auto download */ | ||||
| /* Host Interrupt Control bit : Tx auto download */ | ||||
| #define IF_SPI_HICT_TX_DOWNLOAD_OVER_AUTO		(1<<5) | ||||
| /** Host Interrupt Control bit : Rx auto upload */ | ||||
| /* Host Interrupt Control bit : Rx auto upload */ | ||||
| #define IF_SPI_HICT_RX_UPLOAD_OVER_AUTO			(1<<6) | ||||
| /** Host Interrupt Control bit : Command auto download */ | ||||
| /* Host Interrupt Control bit : Command auto download */ | ||||
| #define IF_SPI_HICT_CMD_DOWNLOAD_OVER_AUTO		(1<<7) | ||||
| /** Host Interrupt Control bit : Command auto upload */ | ||||
| /* Host Interrupt Control bit : Command auto upload */ | ||||
| #define IF_SPI_HICT_CMD_UPLOAD_OVER_AUTO		(1<<8) | ||||
| 
 | ||||
| /***************** IF_SPI_CARD_INT_CAUSE_REG *****************/ | ||||
| /** Card Interrupt Case bit : Tx download over */ | ||||
| /* Card Interrupt Case bit : Tx download over */ | ||||
| #define IF_SPI_CIC_TX_DOWNLOAD_OVER			(1<<0) | ||||
| /** Card Interrupt Case bit : Rx upload over */ | ||||
| /* Card Interrupt Case bit : Rx upload over */ | ||||
| #define IF_SPI_CIC_RX_UPLOAD_OVER			(1<<1) | ||||
| /** Card Interrupt Case bit : Command download over */ | ||||
| /* Card Interrupt Case bit : Command download over */ | ||||
| #define IF_SPI_CIC_CMD_DOWNLOAD_OVER			(1<<2) | ||||
| /** Card Interrupt Case bit : Host event */ | ||||
| /* Card Interrupt Case bit : Host event */ | ||||
| #define IF_SPI_CIC_HOST_EVENT				(1<<3) | ||||
| /** Card Interrupt Case bit : Command upload over */ | ||||
| /* Card Interrupt Case bit : Command upload over */ | ||||
| #define IF_SPI_CIC_CMD_UPLOAD_OVER			(1<<4) | ||||
| /** Card Interrupt Case bit : Power down */ | ||||
| /* Card Interrupt Case bit : Power down */ | ||||
| #define IF_SPI_CIC_POWER_DOWN				(1<<5) | ||||
| 
 | ||||
| /***************** IF_SPI_CARD_INT_STATUS_REG *****************/ | ||||
|  | @ -138,51 +138,51 @@ | |||
| #define IF_SPI_HICU_CMD_RD_FIFO_UNDERFLOW		(1<<10) | ||||
| 
 | ||||
| /***************** IF_SPI_HOST_INT_STATUS_REG *****************/ | ||||
| /** Host Interrupt Status bit : Tx download ready */ | ||||
| /* Host Interrupt Status bit : Tx download ready */ | ||||
| #define IF_SPI_HIST_TX_DOWNLOAD_RDY			(1<<0) | ||||
| /** Host Interrupt Status bit : Rx upload ready */ | ||||
| /* Host Interrupt Status bit : Rx upload ready */ | ||||
| #define IF_SPI_HIST_RX_UPLOAD_RDY			(1<<1) | ||||
| /** Host Interrupt Status bit : Command download ready */ | ||||
| /* Host Interrupt Status bit : Command download ready */ | ||||
| #define IF_SPI_HIST_CMD_DOWNLOAD_RDY			(1<<2) | ||||
| /** Host Interrupt Status bit : Card event */ | ||||
| /* Host Interrupt Status bit : Card event */ | ||||
| #define IF_SPI_HIST_CARD_EVENT				(1<<3) | ||||
| /** Host Interrupt Status bit : Command upload ready */ | ||||
| /* Host Interrupt Status bit : Command upload ready */ | ||||
| #define IF_SPI_HIST_CMD_UPLOAD_RDY			(1<<4) | ||||
| /** Host Interrupt Status bit : I/O write FIFO overflow */ | ||||
| /* Host Interrupt Status bit : I/O write FIFO overflow */ | ||||
| #define IF_SPI_HIST_IO_WR_FIFO_OVERFLOW			(1<<5) | ||||
| /** Host Interrupt Status bit : I/O read FIFO underflow */ | ||||
| /* Host Interrupt Status bit : I/O read FIFO underflow */ | ||||
| #define IF_SPI_HIST_IO_RD_FIFO_UNDRFLOW			(1<<6) | ||||
| /** Host Interrupt Status bit : Data write FIFO overflow */ | ||||
| /* Host Interrupt Status bit : Data write FIFO overflow */ | ||||
| #define IF_SPI_HIST_DATA_WR_FIFO_OVERFLOW		(1<<7) | ||||
| /** Host Interrupt Status bit : Data read FIFO underflow */ | ||||
| /* Host Interrupt Status bit : Data read FIFO underflow */ | ||||
| #define IF_SPI_HIST_DATA_RD_FIFO_UNDERFLOW		(1<<8) | ||||
| /** Host Interrupt Status bit : Command write FIFO overflow */ | ||||
| /* Host Interrupt Status bit : Command write FIFO overflow */ | ||||
| #define IF_SPI_HIST_CMD_WR_FIFO_OVERFLOW		(1<<9) | ||||
| /** Host Interrupt Status bit : Command read FIFO underflow */ | ||||
| /* Host Interrupt Status bit : Command read FIFO underflow */ | ||||
| #define IF_SPI_HIST_CMD_RD_FIFO_UNDERFLOW		(1<<10) | ||||
| 
 | ||||
| /***************** IF_SPI_HOST_INT_STATUS_MASK_REG *****************/ | ||||
| /** Host Interrupt Status Mask bit : Tx download ready */ | ||||
| /* Host Interrupt Status Mask bit : Tx download ready */ | ||||
| #define IF_SPI_HISM_TX_DOWNLOAD_RDY			(1<<0) | ||||
| /** Host Interrupt Status Mask bit : Rx upload ready */ | ||||
| /* Host Interrupt Status Mask bit : Rx upload ready */ | ||||
| #define IF_SPI_HISM_RX_UPLOAD_RDY			(1<<1) | ||||
| /** Host Interrupt Status Mask bit : Command download ready */ | ||||
| /* Host Interrupt Status Mask bit : Command download ready */ | ||||
| #define IF_SPI_HISM_CMD_DOWNLOAD_RDY			(1<<2) | ||||
| /** Host Interrupt Status Mask bit : Card event */ | ||||
| /* Host Interrupt Status Mask bit : Card event */ | ||||
| #define IF_SPI_HISM_CARDEVENT				(1<<3) | ||||
| /** Host Interrupt Status Mask bit : Command upload ready */ | ||||
| /* Host Interrupt Status Mask bit : Command upload ready */ | ||||
| #define IF_SPI_HISM_CMD_UPLOAD_RDY			(1<<4) | ||||
| /** Host Interrupt Status Mask bit : I/O write FIFO overflow */ | ||||
| /* Host Interrupt Status Mask bit : I/O write FIFO overflow */ | ||||
| #define IF_SPI_HISM_IO_WR_FIFO_OVERFLOW			(1<<5) | ||||
| /** Host Interrupt Status Mask bit : I/O read FIFO underflow */ | ||||
| /* Host Interrupt Status Mask bit : I/O read FIFO underflow */ | ||||
| #define IF_SPI_HISM_IO_RD_FIFO_UNDERFLOW		(1<<6) | ||||
| /** Host Interrupt Status Mask bit : Data write FIFO overflow */ | ||||
| /* Host Interrupt Status Mask bit : Data write FIFO overflow */ | ||||
| #define IF_SPI_HISM_DATA_WR_FIFO_OVERFLOW		(1<<7) | ||||
| /** Host Interrupt Status Mask bit : Data write FIFO underflow */ | ||||
| /* Host Interrupt Status Mask bit : Data write FIFO underflow */ | ||||
| #define IF_SPI_HISM_DATA_RD_FIFO_UNDERFLOW		(1<<8) | ||||
| /** Host Interrupt Status Mask bit : Command write FIFO overflow */ | ||||
| /* Host Interrupt Status Mask bit : Command write FIFO overflow */ | ||||
| #define IF_SPI_HISM_CMD_WR_FIFO_OVERFLOW		(1<<9) | ||||
| /** Host Interrupt Status Mask bit : Command write FIFO underflow */ | ||||
| /* Host Interrupt Status Mask bit : Command write FIFO underflow */ | ||||
| #define IF_SPI_HISM_CMD_RD_FIFO_UNDERFLOW		(1<<10) | ||||
| 
 | ||||
| /***************** IF_SPI_SPU_BUS_MODE_REG *****************/ | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /**
 | ||||
|   * This file contains functions used in USB interface module. | ||||
|   */ | ||||
| /*
 | ||||
|  * This file contains functions used in USB interface module. | ||||
|  */ | ||||
| #include <linux/delay.h> | ||||
| #include <linux/moduleparam.h> | ||||
| #include <linux/firmware.h> | ||||
|  | @ -66,7 +66,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp); | |||
| 
 | ||||
| /* sysfs hooks */ | ||||
| 
 | ||||
| /**
 | ||||
| /*
 | ||||
|  *  Set function to write firmware to device's persistent memory | ||||
|  */ | ||||
| static ssize_t if_usb_firmware_set(struct device *dev, | ||||
|  | @ -85,7 +85,7 @@ static ssize_t if_usb_firmware_set(struct device *dev, | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| /*
 | ||||
|  * lbs_flash_fw attribute to be exported per ethX interface through sysfs | ||||
|  * (/sys/class/net/ethX/lbs_flash_fw).  Use this like so to write firmware to | ||||
|  * the device's persistent memory: | ||||
|  | @ -94,7 +94,14 @@ static ssize_t if_usb_firmware_set(struct device *dev, | |||
| static DEVICE_ATTR(lbs_flash_fw, 0200, NULL, if_usb_firmware_set); | ||||
| 
 | ||||
| /**
 | ||||
|  *  Set function to write firmware to device's persistent memory | ||||
|  * if_usb_boot2_set - write firmware to device's persistent memory | ||||
|  * | ||||
|  * @dev: target device | ||||
|  * @attr: device attributes | ||||
|  * @buf: firmware buffer to write | ||||
|  * @count: number of bytes to write | ||||
|  * | ||||
|  * returns: number of bytes written or negative error code | ||||
|  */ | ||||
| static ssize_t if_usb_boot2_set(struct device *dev, | ||||
| 		struct device_attribute *attr, const char *buf, size_t count) | ||||
|  | @ -112,7 +119,7 @@ static ssize_t if_usb_boot2_set(struct device *dev, | |||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| /*
 | ||||
|  * lbs_flash_boot2 attribute to be exported per ethX interface through sysfs | ||||
|  * (/sys/class/net/ethX/lbs_flash_boot2).  Use this like so to write firmware | ||||
|  * to the device's persistent memory: | ||||
|  | @ -121,9 +128,10 @@ static ssize_t if_usb_boot2_set(struct device *dev, | |||
| static DEVICE_ATTR(lbs_flash_boot2, 0200, NULL, if_usb_boot2_set); | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief  call back function to handle the status of the URB | ||||
|  *  @param urb 		pointer to urb structure | ||||
|  *  @return 	   	N/A | ||||
|  * if_usb_write_bulk_callback - callback function to handle the status | ||||
|  * of the URB | ||||
|  * @urb:	pointer to &urb structure | ||||
|  * returns:	N/A | ||||
|  */ | ||||
| static void if_usb_write_bulk_callback(struct urb *urb) | ||||
| { | ||||
|  | @ -150,9 +158,9 @@ static void if_usb_write_bulk_callback(struct urb *urb) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief  free tx/rx urb, skb and rx buffer | ||||
|  *  @param cardp	pointer if_usb_card | ||||
|  *  @return 	   	N/A | ||||
|  * if_usb_free - free tx/rx urb, skb and rx buffer | ||||
|  * @cardp:	pointer to &if_usb_card | ||||
|  * returns:	N/A | ||||
|  */ | ||||
| static void if_usb_free(struct if_usb_card *cardp) | ||||
| { | ||||
|  | @ -231,10 +239,10 @@ static void if_usb_reset_olpc_card(struct lbs_private *priv) | |||
| #endif | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief sets the configuration values | ||||
|  *  @param ifnum	interface number | ||||
|  *  @param id		pointer to usb_device_id | ||||
|  *  @return 	   	0 on success, error code on failure | ||||
|  * if_usb_probe - sets the configuration values | ||||
|  * @intf:	&usb_interface pointer | ||||
|  * @id:	pointer to usb_device_id | ||||
|  * returns:	0 on success, error code on failure | ||||
|  */ | ||||
| static int if_usb_probe(struct usb_interface *intf, | ||||
| 			const struct usb_device_id *id) | ||||
|  | @ -366,9 +374,9 @@ error: | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief free resource and cleanup | ||||
|  *  @param intf		USB interface structure | ||||
|  *  @return 	   	N/A | ||||
|  * if_usb_disconnect - free resource and cleanup | ||||
|  * @intf:	USB interface structure | ||||
|  * returns:	N/A | ||||
|  */ | ||||
| static void if_usb_disconnect(struct usb_interface *intf) | ||||
| { | ||||
|  | @ -398,9 +406,9 @@ static void if_usb_disconnect(struct usb_interface *intf) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief  This function download FW | ||||
|  *  @param priv		pointer to struct lbs_private | ||||
|  *  @return 	   	0 | ||||
|  * if_usb_send_fw_pkt - download FW | ||||
|  * @cardp:	pointer to &struct if_usb_card | ||||
|  * returns:	0 | ||||
|  */ | ||||
| static int if_usb_send_fw_pkt(struct if_usb_card *cardp) | ||||
| { | ||||
|  | @ -486,11 +494,11 @@ static int if_usb_reset_device(struct if_usb_card *cardp) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function transfer the data to the device. | ||||
|  *  @param priv 	pointer to struct lbs_private | ||||
|  *  @param payload	pointer to payload data | ||||
|  *  @param nb		data length | ||||
|  *  @return 	   	0 or -1 | ||||
|  *  usb_tx_block - transfer the data to the device | ||||
|  *  @cardp: 	pointer to &struct if_usb_card | ||||
|  *  @payload:	pointer to payload data | ||||
|  *  @nb:	data length | ||||
|  *  returns:	0 for success or negative error code | ||||
|  */ | ||||
| static int usb_tx_block(struct if_usb_card *cardp, uint8_t *payload, uint16_t nb) | ||||
| { | ||||
|  | @ -727,11 +735,11 @@ static inline void process_cmdrequest(int recvlength, uint8_t *recvbuff, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function reads of the packet into the upload buff, | ||||
|  *  wake up the main thread and initialise the Rx callack. | ||||
|  *  if_usb_receive - read the packet into the upload buffer, | ||||
|  *  wake up the main thread and initialise the Rx callack | ||||
|  * | ||||
|  *  @param urb		pointer to struct urb | ||||
|  *  @return 	   	N/A | ||||
|  *  @urb:	pointer to &struct urb | ||||
|  *  returns:	N/A | ||||
|  */ | ||||
| static void if_usb_receive(struct urb *urb) | ||||
| { | ||||
|  | @ -802,12 +810,12 @@ rx_exit: | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function downloads data to FW | ||||
|  *  @param priv		pointer to struct lbs_private structure | ||||
|  *  @param type		type of data | ||||
|  *  @param buf		pointer to data buffer | ||||
|  *  @param len		number of bytes | ||||
|  *  @return 	   	0 or -1 | ||||
|  *  if_usb_host_to_card - downloads data to FW | ||||
|  *  @priv:	pointer to &struct lbs_private structure | ||||
|  *  @type:	type of data | ||||
|  *  @payload:	pointer to data buffer | ||||
|  *  @nb:	number of bytes | ||||
|  *  returns:	0 for success or negative error code | ||||
|  */ | ||||
| static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type, | ||||
| 			       uint8_t *payload, uint16_t nb) | ||||
|  | @ -831,10 +839,11 @@ static int if_usb_host_to_card(struct lbs_private *priv, uint8_t type, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function issues Boot command to the Boot2 code | ||||
|  *  @param ivalue   1:Boot from FW by USB-Download | ||||
|  *                  2:Boot from FW in EEPROM | ||||
|  *  @return 	   	0 | ||||
|  *  if_usb_issue_boot_command - issues Boot command to the Boot2 code | ||||
|  *  @cardp:	pointer to &if_usb_card | ||||
|  *  @ivalue:	1:Boot from FW by USB-Download | ||||
|  *		2:Boot from FW in EEPROM | ||||
|  *  returns:	0 for success or negative error code | ||||
|  */ | ||||
| static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue) | ||||
| { | ||||
|  | @ -853,11 +862,11 @@ static int if_usb_issue_boot_command(struct if_usb_card *cardp, int ivalue) | |||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function checks the validity of Boot2/FW image. | ||||
|  *  check_fwfile_format - check the validity of Boot2/FW image | ||||
|  * | ||||
|  *  @param data              pointer to image | ||||
|  *         len               image length | ||||
|  *  @return     0 or -1 | ||||
|  *  @data:	pointer to image | ||||
|  *  @totlen:	image length | ||||
|  *  returns:     0 (good) or 1 (failure) | ||||
|  */ | ||||
| static int check_fwfile_format(const uint8_t *data, uint32_t totlen) | ||||
| { | ||||
|  | @ -901,13 +910,13 @@ static int check_fwfile_format(const uint8_t *data, uint32_t totlen) | |||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
| *  @brief This function programs the firmware subject to cmd | ||||
| *  if_usb_prog_firmware - programs the firmware subject to cmd | ||||
| * | ||||
| *  @param cardp             the if_usb_card descriptor | ||||
| *         fwname            firmware or boot2 image file name | ||||
| *         cmd               either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW, | ||||
| *                           or BOOT_CMD_UPDATE_BOOT2. | ||||
| *  @return     0 or error code | ||||
| *  @cardp:	the if_usb_card descriptor | ||||
| *  @fwname:	firmware or boot2 image file name | ||||
| *  @cmd:	either BOOT_CMD_FW_BY_USB, BOOT_CMD_UPDATE_FW, | ||||
| *		or BOOT_CMD_UPDATE_BOOT2. | ||||
| *  returns:	0 or error code | ||||
| */ | ||||
| static int if_usb_prog_firmware(struct if_usb_card *cardp, | ||||
| 				const char *fwname, int cmd) | ||||
|  |  | |||
|  | @ -6,9 +6,9 @@ | |||
| 
 | ||||
| struct lbs_private; | ||||
| 
 | ||||
| /**
 | ||||
|   * This file contains definition for USB interface. | ||||
|   */ | ||||
| /*
 | ||||
|  * This file contains definition for USB interface. | ||||
|  */ | ||||
| #define CMD_TYPE_REQUEST		0xF00DFACE | ||||
| #define CMD_TYPE_DATA			0xBEADC0DE | ||||
| #define CMD_TYPE_INDICATION		0xBEEFFACE | ||||
|  | @ -40,7 +40,7 @@ struct bootcmdresp | |||
| 	uint8_t	pad[2]; | ||||
| }; | ||||
| 
 | ||||
| /** USB card description structure*/ | ||||
| /* USB card description structure*/ | ||||
| struct if_usb_card { | ||||
| 	struct usb_device *udev; | ||||
| 	uint32_t model;  /* MODEL_* */ | ||||
|  | @ -77,7 +77,7 @@ struct if_usb_card { | |||
| 	__le16 boot2_version; | ||||
| }; | ||||
| 
 | ||||
| /** fwheader */ | ||||
| /* fwheader */ | ||||
| struct fwheader { | ||||
| 	__le32 dnldcmd; | ||||
| 	__le32 baseaddr; | ||||
|  | @ -86,14 +86,14 @@ struct fwheader { | |||
| }; | ||||
| 
 | ||||
| #define FW_MAX_DATA_BLK_SIZE	600 | ||||
| /** FWData */ | ||||
| /* FWData */ | ||||
| struct fwdata { | ||||
| 	struct fwheader hdr; | ||||
| 	__le32 seqnum; | ||||
| 	uint8_t data[0]; | ||||
| }; | ||||
| 
 | ||||
| /** fwsyncheader */ | ||||
| /* fwsyncheader */ | ||||
| struct fwsyncheader { | ||||
| 	__le32 cmd; | ||||
| 	__le32 seqnum; | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| /**
 | ||||
|   * This file contains the major functions in WLAN | ||||
|   * driver. It includes init, exit, open, close and main | ||||
|   * thread etc.. | ||||
|   */ | ||||
| /*
 | ||||
|  * This file contains the major functions in WLAN | ||||
|  * driver. It includes init, exit, open, close and main | ||||
|  * thread etc.. | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/moduleparam.h> | ||||
| #include <linux/delay.h> | ||||
|  | @ -35,18 +35,20 @@ EXPORT_SYMBOL_GPL(lbs_debug); | |||
| module_param_named(libertas_debug, lbs_debug, int, 0644); | ||||
| 
 | ||||
| 
 | ||||
| /* This global structure is used to send the confirm_sleep command as
 | ||||
|  * fast as possible down to the firmware. */ | ||||
| /*
 | ||||
|  * This global structure is used to send the confirm_sleep command as | ||||
|  * fast as possible down to the firmware. | ||||
|  */ | ||||
| struct cmd_confirm_sleep confirm_sleep; | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
| /*
 | ||||
|  * the table to keep region code | ||||
|  */ | ||||
| u16 lbs_region_code_to_index[MRVDRV_MAX_REGION_CODE] = | ||||
|     { 0x10, 0x20, 0x30, 0x31, 0x32, 0x40 }; | ||||
| 
 | ||||
| /**
 | ||||
| /*
 | ||||
|  * FW rate table.  FW refers to rates by their index in this table, not by the | ||||
|  * rate value itself.  Values of 0x00 are | ||||
|  * reserved positions. | ||||
|  | @ -57,10 +59,10 @@ static u8 fw_data_rates[MAX_RATES] = | |||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief use index to get the data rate | ||||
|  *  lbs_fw_index_to_data_rate - use index to get the data rate | ||||
|  * | ||||
|  *  @param idx                The index of data rate | ||||
|  *  @return 	   		data rate or 0 | ||||
|  *  @idx:	The index of data rate | ||||
|  *  returns:	data rate or 0 | ||||
|  */ | ||||
| u32 lbs_fw_index_to_data_rate(u8 idx) | ||||
| { | ||||
|  | @ -70,10 +72,10 @@ u32 lbs_fw_index_to_data_rate(u8 idx) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief use rate to get the index | ||||
|  *  lbs_data_rate_to_fw_index - use rate to get the index | ||||
|  * | ||||
|  *  @param rate                 data rate | ||||
|  *  @return 	   		index or 0 | ||||
|  *  @rate:	data rate | ||||
|  *  returns:	index or 0 | ||||
|  */ | ||||
| u8 lbs_data_rate_to_fw_index(u32 rate) | ||||
| { | ||||
|  | @ -91,10 +93,10 @@ u8 lbs_data_rate_to_fw_index(u32 rate) | |||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function opens the ethX interface | ||||
|  *  lbs_dev_open - open the ethX interface | ||||
|  * | ||||
|  *  @param dev     A pointer to net_device structure | ||||
|  *  @return 	   0 or -EBUSY if monitor mode active | ||||
|  *  @dev:	A pointer to &net_device structure | ||||
|  *  returns:	0 or -EBUSY if monitor mode active | ||||
|  */ | ||||
| static int lbs_dev_open(struct net_device *dev) | ||||
| { | ||||
|  | @ -120,10 +122,10 @@ static int lbs_dev_open(struct net_device *dev) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function closes the ethX interface | ||||
|  *  lbs_eth_stop - close the ethX interface | ||||
|  * | ||||
|  *  @param dev     A pointer to net_device structure | ||||
|  *  @return 	   0 | ||||
|  *  @dev:	A pointer to &net_device structure | ||||
|  *  returns:	0 | ||||
|  */ | ||||
| static int lbs_eth_stop(struct net_device *dev) | ||||
| { | ||||
|  | @ -336,12 +338,12 @@ void lbs_set_multicast_list(struct net_device *dev) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function handles the major jobs in the LBS driver. | ||||
|  *  lbs_thread - handles the major jobs in the LBS driver. | ||||
|  *  It handles all events generated by firmware, RX data received | ||||
|  *  from firmware and TX data sent from kernel. | ||||
|  * | ||||
|  *  @param data    A pointer to lbs_thread structure | ||||
|  *  @return 	   0 | ||||
|  *  @data:	A pointer to &lbs_thread structure | ||||
|  *  returns:	0 | ||||
|  */ | ||||
| static int lbs_thread(void *data) | ||||
| { | ||||
|  | @ -540,11 +542,11 @@ static int lbs_thread(void *data) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief This function gets the HW spec from the firmware and sets | ||||
|  *        some basic parameters. | ||||
|  * lbs_setup_firmware - gets the HW spec from the firmware and sets | ||||
|  *        some basic parameters | ||||
|  * | ||||
|  *  @param priv    A pointer to struct lbs_private structure | ||||
|  *  @return        0 or -1 | ||||
|  *  @priv:	A pointer to &struct lbs_private structure | ||||
|  *  returns:	0 or -1 | ||||
|  */ | ||||
| static int lbs_setup_firmware(struct lbs_private *priv) | ||||
| { | ||||
|  | @ -630,8 +632,10 @@ int lbs_resume(struct lbs_private *priv) | |||
| EXPORT_SYMBOL_GPL(lbs_resume); | ||||
| 
 | ||||
| /**
 | ||||
|  *  This function handles the timeout of command sending. | ||||
|  *  It will re-send the same command again. | ||||
|  * lbs_cmd_timeout_handler - handles the timeout of command sending. | ||||
|  * It will re-send the same command again. | ||||
|  * | ||||
|  * @data: &struct lbs_private pointer | ||||
|  */ | ||||
| static void lbs_cmd_timeout_handler(unsigned long data) | ||||
| { | ||||
|  | @ -655,8 +659,10 @@ out: | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  This function put the device back to deep sleep mode when timer expires | ||||
|  *  and no activity (command, event, data etc.) is detected. | ||||
|  * auto_deepsleep_timer_fn - put the device back to deep sleep mode when | ||||
|  * timer expires and no activity (command, event, data etc.) is detected. | ||||
|  * @data:	&struct lbs_private pointer | ||||
|  * returns:	N/A | ||||
|  */ | ||||
| static void auto_deepsleep_timer_fn(unsigned long data) | ||||
| { | ||||
|  | @ -792,11 +798,12 @@ static const struct net_device_ops lbs_netdev_ops = { | |||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief This function adds the card. it will probe the | ||||
|  * lbs_add_card - adds the card. It will probe the | ||||
|  * card, allocate the lbs_priv and initialize the device. | ||||
|  * | ||||
|  *  @param card    A pointer to card | ||||
|  *  @return 	   A pointer to struct lbs_private structure | ||||
|  * @card:	A pointer to card | ||||
|  * @dmdev:	A pointer to &struct device | ||||
|  * returns:	A pointer to &struct lbs_private structure | ||||
|  */ | ||||
| struct lbs_private *lbs_add_card(void *card, struct device *dmdev) | ||||
| { | ||||
|  | @ -1057,19 +1064,19 @@ void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx) | |||
| EXPORT_SYMBOL_GPL(lbs_notify_command_response); | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Retrieves two-stage firmware | ||||
|  *  lbs_get_firmware - Retrieves two-stage firmware | ||||
|  * | ||||
|  *  @param dev     	A pointer to device structure | ||||
|  *  @param user_helper	User-defined helper firmware file | ||||
|  *  @param user_mainfw	User-defined main firmware file | ||||
|  *  @param card_model	Bus-specific card model ID used to filter firmware table | ||||
|  *                         elements | ||||
|  *  @param fw_table	Table of firmware file names and device model numbers | ||||
|  *                         terminated by an entry with a NULL helper name | ||||
|  *  @param helper	On success, the helper firmware; caller must free | ||||
|  *  @param mainfw	On success, the main firmware; caller must free | ||||
|  *  @dev:     	A pointer to &device structure | ||||
|  *  @user_helper: User-defined helper firmware file | ||||
|  *  @user_mainfw: User-defined main firmware file | ||||
|  *  @card_model: Bus-specific card model ID used to filter firmware table | ||||
|  *		elements | ||||
|  *  @fw_table:	Table of firmware file names and device model numbers | ||||
|  *		terminated by an entry with a NULL helper name | ||||
|  *  @helper:	On success, the helper firmware; caller must free | ||||
|  *  @mainfw:	On success, the main firmware; caller must free | ||||
|  * | ||||
|  *  @return		0 on success, non-zero on failure | ||||
|  *  returns:		0 on success, non-zero on failure | ||||
|  */ | ||||
| int lbs_get_firmware(struct device *dev, const char *user_helper, | ||||
| 			const char *user_mainfw, u32 card_model, | ||||
|  |  | |||
|  | @ -16,12 +16,15 @@ | |||
|  * Mesh sysfs support | ||||
|  */ | ||||
| 
 | ||||
| /**
 | ||||
| /*
 | ||||
|  * Attributes exported through sysfs | ||||
|  */ | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Get function for sysfs attribute anycast_mask | ||||
|  * lbs_anycast_get - Get function for sysfs attribute anycast_mask | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer where data will be returned | ||||
|  */ | ||||
| static ssize_t lbs_anycast_get(struct device *dev, | ||||
| 		struct device_attribute *attr, char * buf) | ||||
|  | @ -40,7 +43,11 @@ static ssize_t lbs_anycast_get(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Set function for sysfs attribute anycast_mask | ||||
|  * lbs_anycast_set - Set function for sysfs attribute anycast_mask | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer that contains new attribute value | ||||
|  * @count: size of buffer | ||||
|  */ | ||||
| static ssize_t lbs_anycast_set(struct device *dev, | ||||
| 		struct device_attribute *attr, const char * buf, size_t count) | ||||
|  | @ -62,7 +69,10 @@ static ssize_t lbs_anycast_set(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Get function for sysfs attribute prb_rsp_limit | ||||
|  * lbs_prb_rsp_limit_get - Get function for sysfs attribute prb_rsp_limit | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer where data will be returned | ||||
|  */ | ||||
| static ssize_t lbs_prb_rsp_limit_get(struct device *dev, | ||||
| 		struct device_attribute *attr, char *buf) | ||||
|  | @ -85,7 +95,11 @@ static ssize_t lbs_prb_rsp_limit_get(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Set function for sysfs attribute prb_rsp_limit | ||||
|  * lbs_prb_rsp_limit_set - Set function for sysfs attribute prb_rsp_limit | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer that contains new attribute value | ||||
|  * @count: size of buffer | ||||
|  */ | ||||
| static ssize_t lbs_prb_rsp_limit_set(struct device *dev, | ||||
| 		struct device_attribute *attr, const char *buf, size_t count) | ||||
|  | @ -114,7 +128,10 @@ static ssize_t lbs_prb_rsp_limit_set(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Get function for sysfs attribute mesh | ||||
|  * lbs_mesh_get - Get function for sysfs attribute mesh | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer where data will be returned | ||||
|  */ | ||||
| static ssize_t lbs_mesh_get(struct device *dev, | ||||
| 		struct device_attribute *attr, char * buf) | ||||
|  | @ -124,7 +141,11 @@ static ssize_t lbs_mesh_get(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  Set function for sysfs attribute mesh | ||||
|  * lbs_mesh_set - Set function for sysfs attribute mesh | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer that contains new attribute value | ||||
|  * @count: size of buffer | ||||
|  */ | ||||
| static ssize_t lbs_mesh_set(struct device *dev, | ||||
| 		struct device_attribute *attr, const char * buf, size_t count) | ||||
|  | @ -151,19 +172,19 @@ static ssize_t lbs_mesh_set(struct device *dev, | |||
| 	return count; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
| /*
 | ||||
|  * lbs_mesh attribute to be exported per ethX interface | ||||
|  * through sysfs (/sys/class/net/ethX/lbs_mesh) | ||||
|  */ | ||||
| static DEVICE_ATTR(lbs_mesh, 0644, lbs_mesh_get, lbs_mesh_set); | ||||
| 
 | ||||
| /**
 | ||||
| /*
 | ||||
|  * anycast_mask attribute to be exported per mshX interface | ||||
|  * through sysfs (/sys/class/net/mshX/anycast_mask) | ||||
|  */ | ||||
| static DEVICE_ATTR(anycast_mask, 0644, lbs_anycast_get, lbs_anycast_set); | ||||
| 
 | ||||
| /**
 | ||||
| /*
 | ||||
|  * prb_rsp_limit attribute to be exported per mshX interface | ||||
|  * through sysfs (/sys/class/net/mshX/prb_rsp_limit) | ||||
|  */ | ||||
|  | @ -274,10 +295,10 @@ int lbs_deinit_mesh(struct lbs_private *priv) | |||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function closes the mshX interface | ||||
|  * lbs_mesh_stop - close the mshX interface | ||||
|  * | ||||
|  *  @param dev     A pointer to net_device structure | ||||
|  *  @return 	   0 | ||||
|  * @dev:	A pointer to &net_device structure | ||||
|  * returns:	0 | ||||
|  */ | ||||
| static int lbs_mesh_stop(struct net_device *dev) | ||||
| { | ||||
|  | @ -301,10 +322,10 @@ static int lbs_mesh_stop(struct net_device *dev) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function opens the mshX interface | ||||
|  * lbs_mesh_dev_open - open the mshX interface | ||||
|  * | ||||
|  *  @param dev     A pointer to net_device structure | ||||
|  *  @return 	   0 or -EBUSY if monitor mode active | ||||
|  * @dev:	A pointer to &net_device structure | ||||
|  * returns:	0 or -EBUSY if monitor mode active | ||||
|  */ | ||||
| static int lbs_mesh_dev_open(struct net_device *dev) | ||||
| { | ||||
|  | @ -342,10 +363,10 @@ static const struct net_device_ops mesh_netdev_ops = { | |||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief This function adds mshX interface | ||||
|  * lbs_add_mesh - add mshX interface | ||||
|  * | ||||
|  *  @param priv    A pointer to the struct lbs_private structure | ||||
|  *  @return 	   0 if successful, -X otherwise | ||||
|  * @priv:	A pointer to the &struct lbs_private structure | ||||
|  * returns:	0 if successful, -X otherwise | ||||
|  */ | ||||
| int lbs_add_mesh(struct lbs_private *priv) | ||||
| { | ||||
|  | @ -456,13 +477,13 @@ void lbs_mesh_set_txpd(struct lbs_private *priv, | |||
|  */ | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Add or delete Mesh Blinding Table entries | ||||
|  * lbs_mesh_bt_add_del - Add or delete Mesh Blinding Table entries | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param add  	TRUE to add the entry, FALSE to delete it | ||||
|  *  @param addr1        Destination address to blind or unblind | ||||
|  * @priv:	A pointer to &struct lbs_private structure | ||||
|  * @add:	TRUE to add the entry, FALSE to delete it | ||||
|  * @addr1:	Destination address to blind or unblind | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  * returns:	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1) | ||||
| { | ||||
|  | @ -493,11 +514,11 @@ int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Reset/clear the mesh blinding table | ||||
|  * lbs_mesh_bt_reset - Reset/clear the mesh blinding table | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  * @priv:	A pointer to &struct lbs_private structure | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  * returns:	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_mesh_bt_reset(struct lbs_private *priv) | ||||
| { | ||||
|  | @ -517,17 +538,18 @@ int lbs_mesh_bt_reset(struct lbs_private *priv) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Gets the inverted status of the mesh blinding table | ||||
|  * lbs_mesh_bt_get_inverted - Gets the inverted status of the mesh | ||||
|  * blinding table | ||||
|  * | ||||
|  *  Normally the firmware "blinds" or ignores traffic from mesh nodes in the | ||||
|  *  table, but an inverted table allows *only* traffic from nodes listed in | ||||
|  *  the table. | ||||
|  * Normally the firmware "blinds" or ignores traffic from mesh nodes in the | ||||
|  * table, but an inverted table allows *only* traffic from nodes listed in | ||||
|  * the table. | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param invert  	On success, TRUE if the blinding table is inverted, | ||||
|  *                        FALSE if it is not inverted | ||||
|  * @priv:	A pointer to &struct lbs_private structure | ||||
|  * @inverted:  	On success, TRUE if the blinding table is inverted, | ||||
|  *		FALSE if it is not inverted | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  * returns:	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted) | ||||
| { | ||||
|  | @ -551,18 +573,19 @@ int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Sets the inverted status of the mesh blinding table | ||||
|  * lbs_mesh_bt_set_inverted - Sets the inverted status of the mesh | ||||
|  * blinding table | ||||
|  * | ||||
|  *  Normally the firmware "blinds" or ignores traffic from mesh nodes in the | ||||
|  *  table, but an inverted table allows *only* traffic from nodes listed in | ||||
|  *  the table. | ||||
|  * Normally the firmware "blinds" or ignores traffic from mesh nodes in the | ||||
|  * table, but an inverted table allows *only* traffic from nodes listed in | ||||
|  * the table. | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param invert  	TRUE to invert the blinding table (only traffic from | ||||
|  *                         listed nodes allowed), FALSE to return it | ||||
|  *                         to normal state (listed nodes ignored) | ||||
|  * @priv:	A pointer to &struct lbs_private structure | ||||
|  * @inverted:	TRUE to invert the blinding table (only traffic from | ||||
|  *		listed nodes allowed), FALSE to return it | ||||
|  *		to normal state (listed nodes ignored) | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  * returns:	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted) | ||||
| { | ||||
|  | @ -583,13 +606,13 @@ int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief List an entry in the mesh blinding table | ||||
|  * lbs_mesh_bt_get_entry - List an entry in the mesh blinding table | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param id		The ID of the entry to list | ||||
|  *  @param addr1	MAC address associated with the table entry | ||||
|  * @priv:	A pointer to &struct lbs_private structure | ||||
|  * @id:		The ID of the entry to list | ||||
|  * @addr1:	MAC address associated with the table entry | ||||
|  * | ||||
|  *  @return 	   	0 on success, error on failure | ||||
|  * returns: 	   	0 on success, error on failure | ||||
|  */ | ||||
| int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1) | ||||
| { | ||||
|  | @ -614,14 +637,14 @@ int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief Access the mesh forwarding table | ||||
|  * lbs_cmd_fwt_access - Access the mesh forwarding table | ||||
|  * | ||||
|  *  @param priv    	A pointer to struct lbs_private structure | ||||
|  *  @param cmd_action	The forwarding table action to perform | ||||
|  *  @param cmd		The pre-filled FWT_ACCESS command | ||||
|  * @priv:	A pointer to &struct lbs_private structure | ||||
|  * @cmd_action:	The forwarding table action to perform | ||||
|  * @cmd:	The pre-filled FWT_ACCESS command | ||||
|  * | ||||
|  *  @return 	   	0 on success and 'cmd' will be filled with the | ||||
|  *                        firmware's response | ||||
|  * returns:	0 on success and 'cmd' will be filled with the | ||||
|  *		firmware's response | ||||
|  */ | ||||
| int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action, | ||||
| 			struct cmd_ds_fwt_access *cmd) | ||||
|  | @ -774,7 +797,10 @@ static int mesh_get_default_parameters(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Get function for sysfs attribute bootflag | ||||
|  * bootflag_get - Get function for sysfs attribute bootflag | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer where data will be returned | ||||
|  */ | ||||
| static ssize_t bootflag_get(struct device *dev, | ||||
| 			    struct device_attribute *attr, char *buf) | ||||
|  | @ -791,7 +817,11 @@ static ssize_t bootflag_get(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Set function for sysfs attribute bootflag | ||||
|  * bootflag_set - Set function for sysfs attribute bootflag | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer that contains new attribute value | ||||
|  * @count: size of buffer | ||||
|  */ | ||||
| static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr, | ||||
| 			    const char *buf, size_t count) | ||||
|  | @ -817,7 +847,10 @@ static ssize_t bootflag_set(struct device *dev, struct device_attribute *attr, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Get function for sysfs attribute boottime | ||||
|  * boottime_get - Get function for sysfs attribute boottime | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer where data will be returned | ||||
|  */ | ||||
| static ssize_t boottime_get(struct device *dev, | ||||
| 			    struct device_attribute *attr, char *buf) | ||||
|  | @ -834,7 +867,11 @@ static ssize_t boottime_get(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Set function for sysfs attribute boottime | ||||
|  * boottime_set - Set function for sysfs attribute boottime | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer that contains new attribute value | ||||
|  * @count: size of buffer | ||||
|  */ | ||||
| static ssize_t boottime_set(struct device *dev, | ||||
| 		struct device_attribute *attr, const char *buf, size_t count) | ||||
|  | @ -869,7 +906,10 @@ static ssize_t boottime_set(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Get function for sysfs attribute channel | ||||
|  * channel_get - Get function for sysfs attribute channel | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer where data will be returned | ||||
|  */ | ||||
| static ssize_t channel_get(struct device *dev, | ||||
| 			   struct device_attribute *attr, char *buf) | ||||
|  | @ -886,7 +926,11 @@ static ssize_t channel_get(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Set function for sysfs attribute channel | ||||
|  * channel_set - Set function for sysfs attribute channel | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer that contains new attribute value | ||||
|  * @count: size of buffer | ||||
|  */ | ||||
| static ssize_t channel_set(struct device *dev, struct device_attribute *attr, | ||||
| 			   const char *buf, size_t count) | ||||
|  | @ -912,7 +956,10 @@ static ssize_t channel_set(struct device *dev, struct device_attribute *attr, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Get function for sysfs attribute mesh_id | ||||
|  * mesh_id_get - Get function for sysfs attribute mesh_id | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer where data will be returned | ||||
|  */ | ||||
| static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr, | ||||
| 			   char *buf) | ||||
|  | @ -938,7 +985,11 @@ static ssize_t mesh_id_get(struct device *dev, struct device_attribute *attr, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Set function for sysfs attribute mesh_id | ||||
|  * mesh_id_set - Set function for sysfs attribute mesh_id | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer that contains new attribute value | ||||
|  * @count: size of buffer | ||||
|  */ | ||||
| static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr, | ||||
| 			   const char *buf, size_t count) | ||||
|  | @ -980,7 +1031,10 @@ static ssize_t mesh_id_set(struct device *dev, struct device_attribute *attr, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Get function for sysfs attribute protocol_id | ||||
|  * protocol_id_get - Get function for sysfs attribute protocol_id | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer where data will be returned | ||||
|  */ | ||||
| static ssize_t protocol_id_get(struct device *dev, | ||||
| 			       struct device_attribute *attr, char *buf) | ||||
|  | @ -997,7 +1051,11 @@ static ssize_t protocol_id_get(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Set function for sysfs attribute protocol_id | ||||
|  * protocol_id_set - Set function for sysfs attribute protocol_id | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer that contains new attribute value | ||||
|  * @count: size of buffer | ||||
|  */ | ||||
| static ssize_t protocol_id_set(struct device *dev, | ||||
| 		struct device_attribute *attr, const char *buf, size_t count) | ||||
|  | @ -1034,7 +1092,10 @@ static ssize_t protocol_id_set(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Get function for sysfs attribute metric_id | ||||
|  * metric_id_get - Get function for sysfs attribute metric_id | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer where data will be returned | ||||
|  */ | ||||
| static ssize_t metric_id_get(struct device *dev, | ||||
| 		struct device_attribute *attr, char *buf) | ||||
|  | @ -1051,7 +1112,11 @@ static ssize_t metric_id_get(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Set function for sysfs attribute metric_id | ||||
|  * metric_id_set - Set function for sysfs attribute metric_id | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer that contains new attribute value | ||||
|  * @count: size of buffer | ||||
|  */ | ||||
| static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr, | ||||
| 			     const char *buf, size_t count) | ||||
|  | @ -1088,7 +1153,10 @@ static ssize_t metric_id_set(struct device *dev, struct device_attribute *attr, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Get function for sysfs attribute capability | ||||
|  * capability_get - Get function for sysfs attribute capability | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer where data will be returned | ||||
|  */ | ||||
| static ssize_t capability_get(struct device *dev, | ||||
| 		struct device_attribute *attr, char *buf) | ||||
|  | @ -1105,7 +1173,11 @@ static ssize_t capability_get(struct device *dev, | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * @brief Set function for sysfs attribute capability | ||||
|  * capability_set - Set function for sysfs attribute capability | ||||
|  * @dev: the &struct device | ||||
|  * @attr: device attributes | ||||
|  * @buf: buffer that contains new attribute value | ||||
|  * @count: size of buffer | ||||
|  */ | ||||
| static ssize_t capability_set(struct device *dev, struct device_attribute *attr, | ||||
| 			      const char *buf, size_t count) | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /**
 | ||||
|   * Contains all definitions needed for the Libertas' MESH implementation. | ||||
|   */ | ||||
| /*
 | ||||
|  * Contains all definitions needed for the Libertas' MESH implementation. | ||||
|  */ | ||||
| #ifndef _LBS_MESH_H_ | ||||
| #define _LBS_MESH_H_ | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /**
 | ||||
|   * This file contains the handling of RX in wlan driver. | ||||
|   */ | ||||
| /*
 | ||||
|  * This file contains the handling of RX in wlan driver. | ||||
|  */ | ||||
| #include <linux/etherdevice.h> | ||||
| #include <linux/slab.h> | ||||
| #include <linux/types.h> | ||||
|  | @ -40,12 +40,12 @@ static int process_rxed_802_11_packet(struct lbs_private *priv, | |||
| 	struct sk_buff *skb); | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function processes received packet and forwards it | ||||
|  *  to kernel/upper layer | ||||
|  * lbs_process_rxed_packet - processes received packet and forwards it | ||||
|  * to kernel/upper layer | ||||
|  * | ||||
|  *  @param	priv	A pointer to struct lbs_private | ||||
|  *  @param	skb		A pointer to skb which includes the received packet | ||||
|  *  @return	0 or -1 | ||||
|  * @priv:	A pointer to &struct lbs_private | ||||
|  * @skb:	A pointer to skb which includes the received packet | ||||
|  * returns:	0 or -1 | ||||
|  */ | ||||
| int lbs_process_rxed_packet(struct lbs_private *priv, struct sk_buff *skb) | ||||
| { | ||||
|  | @ -156,11 +156,11 @@ done: | |||
| EXPORT_SYMBOL_GPL(lbs_process_rxed_packet); | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function converts Tx/Rx rates from the Marvell WLAN format | ||||
|  *  (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s) | ||||
|  * convert_mv_rate_to_radiotap - converts Tx/Rx rates from Marvell WLAN format | ||||
|  * (see Table 2 in Section 3.1) to IEEE80211_RADIOTAP_RATE units (500 Kb/s) | ||||
|  * | ||||
|  *  @param	rate	Input rate | ||||
|  *  @return	Output Rate (0 if invalid) | ||||
|  * @rate:	Input rate | ||||
|  * returns:	Output Rate (0 if invalid) | ||||
|  */ | ||||
| static u8 convert_mv_rate_to_radiotap(u8 rate) | ||||
| { | ||||
|  | @ -196,12 +196,12 @@ static u8 convert_mv_rate_to_radiotap(u8 rate) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function processes a received 802.11 packet and forwards it | ||||
|  *  to kernel/upper layer | ||||
|  * process_rxed_802_11_packet - processes a received 802.11 packet and forwards | ||||
|  * it to kernel/upper layer | ||||
|  * | ||||
|  *  @param	priv	A pointer to struct lbs_private | ||||
|  *  @param	skb		A pointer to skb which includes the received packet | ||||
|  *  @return	0 or -1 | ||||
|  * @priv:	A pointer to &struct lbs_private | ||||
|  * @skb:	A pointer to skb which includes the received packet | ||||
|  * returns:	0 or -1 | ||||
|  */ | ||||
| static int process_rxed_802_11_packet(struct lbs_private *priv, | ||||
| 	struct sk_buff *skb) | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| /**
 | ||||
|   * This file contains the handling of TX in wlan driver. | ||||
|   */ | ||||
| /*
 | ||||
|  * This file contains the handling of TX in wlan driver. | ||||
|  */ | ||||
| #include <linux/netdevice.h> | ||||
| #include <linux/etherdevice.h> | ||||
| #include <linux/sched.h> | ||||
|  | @ -13,11 +13,11 @@ | |||
| #include "dev.h" | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE | ||||
|  *  units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1) | ||||
|  * convert_radiotap_rate_to_mv - converts Tx/Rx rates from IEEE80211_RADIOTAP_RATE | ||||
|  * units (500 Kb/s) into Marvell WLAN format (see Table 8 in Section 3.2.1) | ||||
|  * | ||||
|  *  @param rate    Input rate | ||||
|  *  @return      Output Rate (0 if invalid) | ||||
|  * @rate:	Input rate | ||||
|  * returns:	Output Rate (0 if invalid) | ||||
|  */ | ||||
| static u32 convert_radiotap_rate_to_mv(u8 rate) | ||||
| { | ||||
|  | @ -51,12 +51,12 @@ static u32 convert_radiotap_rate_to_mv(u8 rate) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function checks the conditions and sends packet to IF | ||||
|  *  layer if everything is ok. | ||||
|  * lbs_hard_start_xmit - checks the conditions and sends packet to IF | ||||
|  * layer if everything is ok | ||||
|  * | ||||
|  *  @param priv    A pointer to struct lbs_private structure | ||||
|  *  @param skb     A pointer to skb which includes TX packet | ||||
|  *  @return 	   0 or -1 | ||||
|  * @skb:	A pointer to skb which includes TX packet | ||||
|  * @dev:	A pointer to the &struct net_device | ||||
|  * returns:	0 or -1 | ||||
|  */ | ||||
| netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | ||||
| { | ||||
|  | @ -168,13 +168,13 @@ netdev_tx_t lbs_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  *  @brief This function sends to the host the last transmitted packet, | ||||
|  *  filling the radiotap headers with transmission information. | ||||
|  * lbs_send_tx_feedback - sends to the host the last transmitted packet, | ||||
|  * filling the radiotap headers with transmission information. | ||||
|  * | ||||
|  *  @param priv     A pointer to struct lbs_private structure | ||||
|  *  @param status   A 32 bit value containing transmission status. | ||||
|  * @priv:	A pointer to &struct lbs_private structure | ||||
|  * @try_count:	A 32-bit value containing transmission retry status. | ||||
|  * | ||||
|  *  @returns void | ||||
|  * returns:	void | ||||
|  */ | ||||
| void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count) | ||||
| { | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 John W. Linville
						John W. Linville