Root/package/madwifi/patches/454-cca.patch

1--- a/ath/if_ath.c
2+++ b/ath/if_ath.c
3@@ -383,6 +383,8 @@ static void ath_poll_disable(struct net_
4 static void ath_poll_enable(struct net_device *dev);
5 static void ath_fetch_idle_time(struct ath_softc *sc);
6 static void ath_set_timing(struct ath_softc *sc);
7+static void ath_update_cca_thresh(struct ath_softc *sc);
8+static int ath_hw_read_nf(struct ath_softc *sc);
9 
10 /* calibrate every 30 secs in steady state but check every second at first. */
11 static int ath_calinterval = ATH_SHORT_CALINTERVAL;
12@@ -2623,6 +2625,10 @@ ath_init(struct net_device *dev)
13         goto done;
14     }
15 
16+ ath_hal_process_noisefloor(ah);
17+ ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
18+ ath_update_cca_thresh(sc);
19+
20     if (sc->sc_softled)
21         ath_hal_gpioCfgOutput(ah, sc->sc_ledpin);
22 
23@@ -3024,6 +3030,10 @@ ath_reset(struct net_device *dev)
24         EPRINTF(sc, "Unable to reset hardware: '%s' (HAL status %u)\n",
25             ath_get_hal_status_desc(status), status);
26 
27+ ath_hal_process_noisefloor(ah);
28+ ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
29+ ath_update_cca_thresh(sc);
30+
31     ath_setintmit(sc);
32     ath_update_txpow(sc); /* update tx power state */
33     ath_radar_update(sc);
34@@ -9374,9 +9384,11 @@ ath_calibrate(unsigned long arg)
35             sc->sc_curchan.channel);
36         sc->sc_stats.ast_per_calfail++;
37     }
38- ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
39 
40     ath_hal_process_noisefloor(ah);
41+ ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
42+ ath_update_cca_thresh(sc);
43+
44     if (isIQdone == AH_TRUE) {
45         /* Unless user has overridden calibration interval,
46          * upgrade to less frequent calibration */
47@@ -9711,8 +9723,6 @@ ath_newstate(struct ieee80211vap *vap, e
48             break;
49         }
50 
51- ath_hal_process_noisefloor(ah);
52- ic->ic_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan));
53         /*
54          * Reset rssi stats; maybe not the best place...
55          */
56@@ -10968,6 +10978,7 @@ enum {
57     ATH_INTMIT,
58     ATH_NOISE_IMMUNITY,
59     ATH_OFDM_WEAK_DET,
60+ ATH_CCA_THRESH,
61     ATH_CHANBW,
62     ATH_OUTDOOR,
63     ATH_DISTANCE,
64@@ -11110,6 +11121,66 @@ ath_sysctl_get_intmit(struct ath_softc *
65     return 0;
66 }
67 
68+#define AR_PHY_CCA 0x9864
69+#define AR_PHY_MINCCA_PWR 0x0FF80000
70+#define AR_PHY_MINCCA_PWR_S 19
71+#define AR_PHY_CCA_THRESH62 0x0007F000
72+#define AR_PHY_CCA_THRESH62_S 12
73+
74+static int
75+ath_nf_from_cca(u32 phy_cca)
76+{
77+ int nf = (phy_cca >> 19) & 0x1ff;
78+ nf = -((nf ^ 0x1ff) + 1);
79+ return nf;
80+}
81+
82+static int
83+ath_hw_read_nf(struct ath_softc *sc)
84+{
85+ return ath_nf_from_cca(OS_REG_READ(sc->sc_ah, AR_PHY_CCA));
86+}
87+
88+static void
89+ath_update_cca_thresh(struct ath_softc *sc)
90+{
91+ struct ath_hal *ah = sc->sc_ah;
92+ int newthr = 0;
93+ u32 phy_cca;
94+ int nf;
95+
96+ phy_cca = OS_REG_READ(ah, AR_PHY_CCA);
97+ if (sc->sc_cca_thresh < 0) {
98+ newthr = sc->sc_cca_thresh - ath_nf_from_cca(phy_cca);
99+
100+ /* 0xf is a typical eeprom value for thresh62,
101+ * use it as minimum for signal based thresholds
102+ * to prevent complete connection drops */
103+ if (newthr < 0xf)
104+ newthr = 0xf;
105+ } else {
106+ newthr = sc->sc_cca_thresh;
107+ }
108+
109+ if ((newthr < 4) || (newthr >= 127))
110+ return;
111+
112+ phy_cca &= ~AR_PHY_CCA_THRESH62;
113+ phy_cca |= newthr << AR_PHY_CCA_THRESH62_S;
114+ OS_REG_WRITE(ah, AR_PHY_CCA, phy_cca);
115+}
116+
117+static int
118+ath_get_cca_thresh(struct ath_softc *sc)
119+{
120+ struct ath_hal *ah = sc->sc_ah;
121+ u32 phy_cca;
122+
123+ phy_cca = OS_REG_READ(ah, AR_PHY_CCA);
124+ return ath_nf_from_cca(phy_cca) +
125+ ((phy_cca & AR_PHY_CCA_THRESH62) >> AR_PHY_CCA_THRESH62_S);
126+}
127+
128 static int
129 ATH_SYSCTL_DECL(ath_sysctl_hwinfo, ctl, write, filp, buffer, lenp, ppos)
130 {
131@@ -11356,6 +11427,10 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
132             case ATH_OFDM_WEAK_DET:
133                 ret = ath_sysctl_set_intmit(sc, (long)ctl->extra2, val);
134                 break;
135+ case ATH_CCA_THRESH:
136+ sc->sc_cca_thresh = val;
137+ ath_update_cca_thresh(sc);
138+ break;
139             default:
140                 ret = -EINVAL;
141                 break;
142@@ -11436,6 +11511,9 @@ ATH_SYSCTL_DECL(ath_sysctl_halparam, ctl
143         case ATH_OFDM_WEAK_DET:
144             ret = ath_sysctl_get_intmit(sc, (long)ctl->extra2, &val);
145             break;
146+ case ATH_CCA_THRESH:
147+ val = ath_get_cca_thresh(sc);
148+ break;
149         default:
150             ret = -EINVAL;
151             break;
152@@ -11667,6 +11745,12 @@ static const ctl_table ath_sysctl_templa
153       .proc_handler = ath_sysctl_halparam,
154       .extra2 = (void *)ATH_OFDM_WEAK_DET,
155     },
156+ { .ctl_name = CTL_AUTO,
157+ .procname = "cca_thresh",
158+ .mode = 0644,
159+ .proc_handler = ath_sysctl_halparam,
160+ .extra2 = (void *)ATH_CCA_THRESH,
161+ },
162     { 0 }
163 };
164 
165--- a/ath/if_athvar.h
166+++ b/ath/if_athvar.h
167@@ -844,6 +844,7 @@ struct ath_softc {
168     int sc_cal_interval; /* current calibration interval */
169     struct timer_list sc_cal_ch; /* calibration timer */
170     HAL_NODE_STATS sc_halstats; /* station-mode rssi stats */
171+ int sc_cca_thresh; /* configured CCA threshold */
172 
173     struct ctl_table_header *sc_sysctl_header;
174     struct ctl_table *sc_sysctls;
175--- a/ath/ath_wprobe.c
176+++ b/ath/ath_wprobe.c
177@@ -133,8 +133,7 @@ ath_wprobe_sync(struct wprobe_iface *dev
178     rx = READ_CLR(ah, AR5K_RXFC);
179     tx = READ_CLR(ah, AR5K_TXFC);
180     OS_REG_WRITE(ah, AR5K_MIBC, 0);
181- noise = ath_hal_get_channel_noise(sc->sc_ah, &(sc->sc_curchan));
182- ic->ic_channoise = noise;
183+ noise = ath_hw_read_nf(sc);
184 
185     WPROBE_FILL_BEGIN(val, ath_wprobe_globals);
186     if (cc & 0xf0000000) {
187

Archive Download this file



interactive