12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
22 #include <sys/param.h>
23 #include <sys/strsun.h>
24 #include <inet/common.h>
25 #include <inet/nd.h>
26 #include <inet/mi.h>
27 #include <inet/wifi_ioctl.h>
28
29 #include "arn_core.h"
30
31 /*
32 * This function will modify certain transmit queue properties depending on
33 * the operating mode of the station (AP or AdHoc). Parameters are AIFS
34 * settings and channel width min/max
35 */
36
37 static int
38 /* LINTED E_STATIC_UNUSED */
39 arn_beaconq_config(struct arn_softc *sc)
40 {
41 struct ath_hal *ah = sc->sc_ah;
42 struct ath9k_tx_queue_info qi;
43
44 (void) ath9k_hw_get_txq_props(ah, sc->sc_beaconq, &qi);
45 if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) {
46 /* Always burst out beacon and CAB traffic. */
47 qi.tqi_aifs = 1;
48 qi.tqi_cwmin = 0;
49 qi.tqi_cwmax = 0;
50 } else {
51 /* Adhoc mode; important thing is to use 2x cwmin. */
52 qi.tqi_aifs = sc->sc_beacon_qi.tqi_aifs;
53 qi.tqi_cwmin = 2*sc->sc_beacon_qi.tqi_cwmin;
54 qi.tqi_cwmax = sc->sc_beacon_qi.tqi_cwmax;
55 }
56
57 if (!ath9k_hw_set_txq_props(ah, sc->sc_beaconq, &qi)) {
58 arn_problem("unable to update h/w beacon queue parameters\n");
59 return (0);
60 } else {
61 /* push to h/w */
62 (void) ath9k_hw_resettxqueue(ah, sc->sc_beaconq);
63 return (1);
64 }
65 }
66
67 /*
68 * Associates the beacon frame buffer with a transmit descriptor. Will set
69 * up all required antenna switch parameters, rate codes, and channel flags.
70 * Beacons are always sent out at the lowest rate, and are not retried.
71 */
72 #ifdef ARN_IBSS
73 static void
74 arn_beacon_setup(struct arn_softc *sc, struct ath_buf *bf)
75 {
76 #define USE_SHPREAMBLE(_ic) \
77 (((_ic)->ic_flags & (IEEE80211_F_SHPREAMBLE | IEEE80211_F_USEBARKER))\
78 == IEEE80211_F_SHPREAMBLE)
79 mblk_t *mp = bf->bf_m;
80 struct ath_hal *ah = sc->sc_ah;
81 struct ath_desc *ds;
82 /* LINTED E_FUNC_SET_NOT_USED */
83 int flags, antenna = 0;
84 struct ath_rate_table *rt;
85 uint8_t rix, rate;
86 struct ath9k_11n_rate_series series[4];
87 int ctsrate = 0;
135 ds); /* first descriptor */
136
137 (void) memset(series, 0, sizeof (struct ath9k_11n_rate_series) * 4);
138 series[0].Tries = 1;
139 series[0].Rate = rate;
140 series[0].ChSel = sc->sc_tx_chainmask;
141 series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
142 ath9k_hw_set11n_ratescenario(ah, ds, ds, 0,
143 ctsrate, ctsduration, series, 4, 0);
144 #undef USE_SHPREAMBLE
145 }
146 #endif
147
148 /*
149 * Startup beacon transmission for adhoc mode when they are sent entirely
150 * by the hardware using the self-linked descriptor + veol trick.
151 */
152 #ifdef ARN_IBSS
153 static void
154 arn_beacon_start_adhoc(struct arn_softc *sc)
155
156 {
157 struct ath_buf *bf = list_head(&sc->sc_bcbuf_list);
158 struct ieee80211_node *in = bf->bf_in;
159 struct ieee80211com *ic = in->in_ic;
160 struct ath_hal *ah = sc->sc_ah;
161 mblk_t *mp;
162
163 mp = bf->bf_m;
164 if (ieee80211_beacon_update(ic, bf->bf_in, &sc->asc_boff, mp, 0))
165 bcopy(mp->b_rptr, bf->bf_dma.mem_va, MBLKL(mp));
166
167 /* Construct tx descriptor. */
168 arn_beacon_setup(sc, bf);
169
170 /*
171 * Stop any current dma and put the new frame on the queue.
172 * This should never fail since we check above that no frames
173 * are still pending on the queue.
174 */
175 if (!ath9k_hw_stoptxdma(ah, sc->sc_beaconq)) {
240 struct ath_buf *bf;
241
242 mutex_enter(&sc->sc_bcbuflock);
243 bf = list_head(&sc->sc_bcbuf_list);
244 while (bf != NULL) {
245 if (bf->bf_m != NULL) {
246 freemsg(bf->bf_m);
247 bf->bf_m = NULL;
248 }
249 if (bf->bf_in != NULL) {
250 ieee80211_free_node(bf->bf_in);
251 bf->bf_in = NULL;
252 }
253 bf = list_next(&sc->sc_bcbuf_list, bf);
254 }
255 mutex_exit(&sc->sc_bcbuflock);
256 }
257
258 void
259 arn_beacon_config(struct arn_softc *sc)
260
261 {
262 struct ath_beacon_config conf;
263 ieee80211com_t *ic = (ieee80211com_t *)sc;
264 struct ieee80211_node *in = ic->ic_bss;
265
266 /* New added */
267 struct ath9k_beacon_state bs;
268 int dtimperiod, dtimcount, sleepduration;
269 int cfpperiod, cfpcount;
270 uint32_t nexttbtt = 0, intval, tsftu;
271 uint64_t tsf;
272
273 (void) memset(&conf, 0, sizeof (struct ath_beacon_config));
274
275 /* XXX fix me */
276 conf.beacon_interval = in->in_intval ?
277 in->in_intval : ATH_DEFAULT_BINTVAL;
278 ARN_DBG((ARN_DBG_BEACON, "arn: arn_beacon_config():"
279 "conf.beacon_interval = %d\n", conf.beacon_interval));
280 conf.listen_interval = 1;
|
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */
21
22 #include <sys/param.h>
23 #include <sys/strsun.h>
24 #include <inet/common.h>
25 #include <inet/nd.h>
26 #include <inet/mi.h>
27 #include <inet/wifi_ioctl.h>
28
29 #include "arn_core.h"
30
31 /*
32 * Associates the beacon frame buffer with a transmit descriptor. Will set
33 * up all required antenna switch parameters, rate codes, and channel flags.
34 * Beacons are always sent out at the lowest rate, and are not retried.
35 */
36 #ifdef ARN_IBSS
37 static void
38 arn_beacon_setup(struct arn_softc *sc, struct ath_buf *bf)
39 {
40 #define USE_SHPREAMBLE(_ic) \
41 (((_ic)->ic_flags & (IEEE80211_F_SHPREAMBLE | IEEE80211_F_USEBARKER))\
42 == IEEE80211_F_SHPREAMBLE)
43 mblk_t *mp = bf->bf_m;
44 struct ath_hal *ah = sc->sc_ah;
45 struct ath_desc *ds;
46 /* LINTED E_FUNC_SET_NOT_USED */
47 int flags, antenna = 0;
48 struct ath_rate_table *rt;
49 uint8_t rix, rate;
50 struct ath9k_11n_rate_series series[4];
51 int ctsrate = 0;
99 ds); /* first descriptor */
100
101 (void) memset(series, 0, sizeof (struct ath9k_11n_rate_series) * 4);
102 series[0].Tries = 1;
103 series[0].Rate = rate;
104 series[0].ChSel = sc->sc_tx_chainmask;
105 series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
106 ath9k_hw_set11n_ratescenario(ah, ds, ds, 0,
107 ctsrate, ctsduration, series, 4, 0);
108 #undef USE_SHPREAMBLE
109 }
110 #endif
111
112 /*
113 * Startup beacon transmission for adhoc mode when they are sent entirely
114 * by the hardware using the self-linked descriptor + veol trick.
115 */
116 #ifdef ARN_IBSS
117 static void
118 arn_beacon_start_adhoc(struct arn_softc *sc)
119 {
120 struct ath_buf *bf = list_head(&sc->sc_bcbuf_list);
121 struct ieee80211_node *in = bf->bf_in;
122 struct ieee80211com *ic = in->in_ic;
123 struct ath_hal *ah = sc->sc_ah;
124 mblk_t *mp;
125
126 mp = bf->bf_m;
127 if (ieee80211_beacon_update(ic, bf->bf_in, &sc->asc_boff, mp, 0))
128 bcopy(mp->b_rptr, bf->bf_dma.mem_va, MBLKL(mp));
129
130 /* Construct tx descriptor. */
131 arn_beacon_setup(sc, bf);
132
133 /*
134 * Stop any current dma and put the new frame on the queue.
135 * This should never fail since we check above that no frames
136 * are still pending on the queue.
137 */
138 if (!ath9k_hw_stoptxdma(ah, sc->sc_beaconq)) {
203 struct ath_buf *bf;
204
205 mutex_enter(&sc->sc_bcbuflock);
206 bf = list_head(&sc->sc_bcbuf_list);
207 while (bf != NULL) {
208 if (bf->bf_m != NULL) {
209 freemsg(bf->bf_m);
210 bf->bf_m = NULL;
211 }
212 if (bf->bf_in != NULL) {
213 ieee80211_free_node(bf->bf_in);
214 bf->bf_in = NULL;
215 }
216 bf = list_next(&sc->sc_bcbuf_list, bf);
217 }
218 mutex_exit(&sc->sc_bcbuflock);
219 }
220
221 void
222 arn_beacon_config(struct arn_softc *sc)
223 {
224 struct ath_beacon_config conf;
225 ieee80211com_t *ic = (ieee80211com_t *)sc;
226 struct ieee80211_node *in = ic->ic_bss;
227
228 /* New added */
229 struct ath9k_beacon_state bs;
230 int dtimperiod, dtimcount, sleepduration;
231 int cfpperiod, cfpcount;
232 uint32_t nexttbtt = 0, intval, tsftu;
233 uint64_t tsf;
234
235 (void) memset(&conf, 0, sizeof (struct ath_beacon_config));
236
237 /* XXX fix me */
238 conf.beacon_interval = in->in_intval ?
239 in->in_intval : ATH_DEFAULT_BINTVAL;
240 ARN_DBG((ARN_DBG_BEACON, "arn: arn_beacon_config():"
241 "conf.beacon_interval = %d\n", conf.beacon_interval));
242 conf.listen_interval = 1;
|