mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-30 13:34:27 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			187 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| --- a/ath/if_ath.c
 | |
| +++ b/ath/if_ath.c
 | |
| @@ -383,6 +383,8 @@ static void ath_poll_disable(struct net_
 | |
|  static void ath_poll_enable(struct net_device *dev);
 | |
|  static void ath_fetch_idle_time(struct ath_softc *sc);
 | |
|  static void ath_set_timing(struct ath_softc *sc);
 | |
| +static void ath_update_cca_thresh(struct ath_softc *sc);
 | |
| +static int ath_hw_read_nf(struct ath_softc *sc);
 | |
|  
 | |
|  /* calibrate every 30 secs in steady state but check every second at first. */
 | |
|  static int ath_calinterval = ATH_SHORT_CALINTERVAL;
 | |
| @@ -2623,6 +2625,10 @@ ath_init(struct net_device *dev)
 | |
|  		goto done;
 | |
|  	}
 | |
|  
 | |
| +	ath_hal_process_noisefloor(ah);
 | |
| +	ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
 | |
| +	ath_update_cca_thresh(sc);
 | |
| +
 | |
|  	if (sc->sc_softled)
 | |
|  		ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
 | |
|  
 | |
| @@ -3024,6 +3030,10 @@ ath_reset(struct net_device *dev)
 | |
|  		EPRINTF(sc, "Unable to reset hardware: '%s' (HAL status %u)\n",
 | |
|  			ath_get_hal_status_desc(status), status);
 | |
|  
 | |
| +	ath_hal_process_noisefloor(ah);
 | |
| +	ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
 | |
| +	ath_update_cca_thresh(sc);
 | |
| +
 | |
|  	ath_setintmit(sc);
 | |
|  	ath_update_txpow(sc);		/* update tx power state */
 | |
|  	ath_radar_update(sc);
 | |
| @@ -9374,9 +9384,11 @@ ath_calibrate(unsigned long arg)
 | |
|  			sc->sc_curchan.channel);
 | |
|  		sc->sc_stats.ast_per_calfail++;
 | |
|  	}
 | |
| -	ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
 | |
|  
 | |
|  	ath_hal_process_noisefloor(ah);
 | |
| +	ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
 | |
| +	ath_update_cca_thresh(sc);
 | |
| +
 | |
|  	if (isIQdone == AH_TRUE) {
 | |
|  		/* Unless user has overridden calibration interval,
 | |
|  		 * upgrade to less frequent calibration */
 | |
| @@ -9711,8 +9723,6 @@ ath_newstate(struct ieee80211vap *vap, e
 | |
|  			break;
 | |
|  		}
 | |
|  
 | |
| -		ath_hal_process_noisefloor(ah);
 | |
| -		ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
 | |
|  		/*
 | |
|  		 * Reset rssi stats; maybe not the best place...
 | |
|  		 */
 | |
| @@ -10968,6 +10978,7 @@ enum {
 | |
|  	ATH_INTMIT,
 | |
|  	ATH_NOISE_IMMUNITY,
 | |
|  	ATH_OFDM_WEAK_DET,
 | |
| +	ATH_CCA_THRESH,
 | |
|  	ATH_CHANBW,
 | |
|  	ATH_OUTDOOR,
 | |
|  	ATH_DISTANCE,
 | |
| @@ -11110,6 +11121,66 @@ ath_sysctl_get_intmit(struct ath_softc *
 | |
|  	return 0;
 | |
|  }
 | |
|  
 | |
| +#define AR_PHY_CCA              0x9864
 | |
| +#define AR_PHY_MINCCA_PWR       0x0FF80000
 | |
| +#define AR_PHY_MINCCA_PWR_S     19
 | |
| +#define AR_PHY_CCA_THRESH62     0x0007F000
 | |
| +#define AR_PHY_CCA_THRESH62_S   12
 | |
| +
 | |
| +static int
 | |
| +ath_nf_from_cca(u32 phy_cca)
 | |
| +{
 | |
| +	int nf = (phy_cca >> 19) & 0x1ff;
 | |
| +	nf = -((nf ^ 0x1ff) + 1);
 | |
| +	return nf;
 | |
| +}
 | |
| +
 | |
| +static int
 | |
| +ath_hw_read_nf(struct ath_softc *sc)
 | |
| +{
 | |
| +	return ath_nf_from_cca(OS_REG_READ(sc->sc_ah, AR_PHY_CCA));
 | |
| +}
 | |
| +
 | |
| +static void
 | |
| +ath_update_cca_thresh(struct ath_softc *sc)
 | |
| +{
 | |
| +	struct ath_hal *ah = sc->sc_ah;
 | |
| +	int newthr = 0;
 | |
| +	u32 phy_cca;
 | |
| +	int nf;
 | |
| +
 | |
| +	phy_cca = OS_REG_READ(ah, AR_PHY_CCA);
 | |
| +	if (sc->sc_cca_thresh < 0) {
 | |
| +		newthr = sc->sc_cca_thresh - ath_nf_from_cca(phy_cca);
 | |
| +
 | |
| +		/* 0xf is a typical eeprom value for thresh62,
 | |
| +		 * use it as minimum for signal based thresholds
 | |
| +		 * to prevent complete connection drops */
 | |
| +		if (newthr < 0xf)
 | |
| +			newthr = 0xf;
 | |
| +	} else {
 | |
| +		newthr = sc->sc_cca_thresh;
 | |
| +	}
 | |
| +
 | |
| +	if ((newthr < 4) || (newthr >= 127))
 | |
| +		return;
 | |
| +
 | |
| +	phy_cca &= ~AR_PHY_CCA_THRESH62;
 | |
| +	phy_cca |= newthr << AR_PHY_CCA_THRESH62_S;
 | |
| +	OS_REG_WRITE(ah, AR_PHY_CCA, phy_cca);
 | |
| +}
 | |
| +
 | |
| +static int
 | |
| +ath_get_cca_thresh(struct ath_softc *sc)
 | |
| +{
 | |
| +	struct ath_hal *ah = sc->sc_ah;
 | |
| +	u32 phy_cca;
 | |
| +
 | |
| +	phy_cca = OS_REG_READ(ah, AR_PHY_CCA);
 | |
| +	return ath_nf_from_cca(phy_cca) +
 | |
| +		((phy_cca & AR_PHY_CCA_THRESH62) >> AR_PHY_CCA_THRESH62_S);
 | |
| +}
 | |
| +
 | |
|  static int
 | |
|  ATH_SYSCTL_DECL(ath_sysctl_hwinfo, ctl, write, filp, buffer, lenp, ppos)
 | |
|  {
 | |
| @@ -11356,6 +11427,10 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
 | |
|  			case ATH_OFDM_WEAK_DET:
 | |
|  				ret = ath_sysctl_set_intmit(sc, (long)ctl->extra2, val);
 | |
|  				break;
 | |
| +			case ATH_CCA_THRESH:
 | |
| +				sc->sc_cca_thresh = val;
 | |
| +				ath_update_cca_thresh(sc);
 | |
| +				break;
 | |
|  			default:
 | |
|  				ret = -EINVAL;
 | |
|  				break;
 | |
| @@ -11436,6 +11511,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
 | |
|  		case ATH_OFDM_WEAK_DET:
 | |
|  			ret = ath_sysctl_get_intmit(sc, (long)ctl->extra2, &val);
 | |
|  			break;
 | |
| +		case ATH_CCA_THRESH:
 | |
| +			val = ath_get_cca_thresh(sc);
 | |
| +			break;
 | |
|  		default:
 | |
|  			ret = -EINVAL;
 | |
|  			break;
 | |
| @@ -11667,6 +11745,12 @@ static const ctl_table ath_sysctl_templa
 | |
|  	  .proc_handler = ath_sysctl_halparam,
 | |
|  	  .extra2	= (void *)ATH_OFDM_WEAK_DET,
 | |
|  	},
 | |
| +	{ .ctl_name	= CTL_AUTO,
 | |
| +	  .procname     = "cca_thresh",
 | |
| +	  .mode         = 0644,
 | |
| +	  .proc_handler = ath_sysctl_halparam,
 | |
| +	  .extra2	= (void *)ATH_CCA_THRESH,
 | |
| +	},
 | |
|  	{ 0 }
 | |
|  };
 | |
|  
 | |
| --- a/ath/if_athvar.h
 | |
| +++ b/ath/if_athvar.h
 | |
| @@ -844,6 +844,7 @@ struct ath_softc {
 | |
|  	int sc_cal_interval;			/* current calibration interval */
 | |
|  	struct timer_list sc_cal_ch;		/* calibration timer */
 | |
|  	HAL_NODE_STATS sc_halstats;		/* station-mode rssi stats */
 | |
| +	int sc_cca_thresh;				/* configured CCA threshold */
 | |
|  
 | |
|  	struct ctl_table_header *sc_sysctl_header;
 | |
|  	struct ctl_table *sc_sysctls;
 | |
| --- a/ath/ath_wprobe.c
 | |
| +++ b/ath/ath_wprobe.c
 | |
| @@ -133,8 +133,7 @@ ath_wprobe_sync(struct wprobe_iface *dev
 | |
|  	rx = READ_CLR(ah, AR5K_RXFC);
 | |
|  	tx = READ_CLR(ah, AR5K_TXFC);
 | |
|  	OS_REG_WRITE(ah, AR5K_MIBC, 0);
 | |
| -	noise = ath_hal_get_channel_noise(sc->sc_ah, &(sc->sc_curchan));
 | |
| -	ic->ic_channoise = noise;
 | |
| +	noise = ath_hw_read_nf(sc);
 | |
|  
 | |
|  	WPROBE_FILL_BEGIN(val, ath_wprobe_globals);
 | |
|  	if (cc & 0xf0000000) {
 |