ar9300_xmit_ds.c revision 250003
1/*
2 * Copyright (c) 2013 Qualcomm Atheros, Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "opt_ah.h"
18
19#ifdef AH_SUPPORT_AR9300
20
21#include "ah.h"
22#include "ah_desc.h"
23#include "ah_internal.h"
24
25#include "ar9300/ar9300desc.h"
26#include "ar9300/ar9300.h"
27#include "ar9300/ar9300reg.h"
28#include "ar9300/ar9300phy.h"
29#include "ah_devid.h"
30
31#if AH_BYTE_ORDER == AH_BIG_ENDIAN
32static void ar9300_swap_tx_desc(void *ds);
33#endif
34
35void
36ar9300_tx_req_intr_desc(struct ath_hal *ah, void *ds)
37{
38    HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
39        "%s:Desc Interrupt not supported\n", __func__);
40}
41
42static inline u_int16_t
43ar9300_calc_ptr_chk_sum(struct ar9300_txc *ads)
44{
45    u_int checksum;
46    u_int16_t ptrchecksum;
47
48    /* checksum = __bswap32(ads->ds_info) + ads->ds_link */
49    checksum =    ads->ds_info + ads->ds_link
50                + ads->ds_data0 + ads->ds_ctl3
51                + ads->ds_data1 + ads->ds_ctl5
52                + ads->ds_data2 + ads->ds_ctl7
53                + ads->ds_data3 + ads->ds_ctl9;
54
55    ptrchecksum = ((checksum & 0xffff) + (checksum >> 16)) & AR_tx_ptr_chk_sum;
56    return ptrchecksum;
57}
58
59
60HAL_BOOL
61ar9300_fill_tx_desc(
62    struct ath_hal *ah,
63    void *ds,
64    dma_addr_t *buf_addr,
65    u_int32_t *seg_len,
66    u_int desc_id,
67    u_int qcu,
68    HAL_KEY_TYPE key_type,
69    HAL_BOOL first_seg,
70    HAL_BOOL last_seg,
71    const void *ds0)
72{
73    struct ar9300_txc *ads = AR9300TXC(ds);
74
75    /* Fill TXC info field */
76    ads->ds_info = TXC_INFO(qcu);
77
78    /* Set the buffer addresses */
79    ads->ds_data0 = buf_addr[0];
80    ads->ds_data1 = buf_addr[1];
81    ads->ds_data2 = buf_addr[2];
82    ads->ds_data3 = buf_addr[3];
83
84    /* Set the buffer lengths */
85    ads->ds_ctl3 = (seg_len[0] << AR_buf_len_S) & AR_buf_len;
86    ads->ds_ctl5 = (seg_len[1] << AR_buf_len_S) & AR_buf_len;
87    ads->ds_ctl7 = (seg_len[2] << AR_buf_len_S) & AR_buf_len;
88    ads->ds_ctl9 = (seg_len[3] << AR_buf_len_S) & AR_buf_len;
89
90    /* Fill in pointer checksum and descriptor id */
91    ads->ds_ctl10 = (desc_id << AR_tx_desc_id_S) | ar9300_calc_ptr_chk_sum(ads);
92
93    if (first_seg) {
94        /*
95         * First descriptor, don't clobber xmit control data
96         * setup by ar9300_set_11n_tx_desc.
97         *
98         * Note: AR_encr_type is already setup in the first descriptor by
99         *       set_11n_tx_desc().
100         */
101        ads->ds_ctl12 |= (last_seg ? 0 : AR_tx_more);
102    } else if (last_seg) { /* !first_seg && last_seg */
103        /*
104         * Last descriptor in a multi-descriptor frame,
105         * copy the multi-rate transmit parameters from
106         * the first frame for processing on completion.
107         */
108        ads->ds_ctl11 = 0;
109        ads->ds_ctl12 = 0;
110#ifdef AH_NEED_DESC_SWAP
111        ads->ds_ctl13 = __bswap32(AR9300TXC_CONST(ds0)->ds_ctl13);
112        ads->ds_ctl14 = __bswap32(AR9300TXC_CONST(ds0)->ds_ctl14);
113        ads->ds_ctl17 = __bswap32(SM(key_type, AR_encr_type));
114#else
115        ads->ds_ctl13 = AR9300TXC_CONST(ds0)->ds_ctl13;
116        ads->ds_ctl14 = AR9300TXC_CONST(ds0)->ds_ctl14;
117        ads->ds_ctl17 = SM(key_type, AR_encr_type);
118#endif
119    } else { /* !first_seg && !last_seg */
120        /*
121         * XXX Intermediate descriptor in a multi-descriptor frame.
122         */
123        ads->ds_ctl11 = 0;
124        ads->ds_ctl12 = AR_tx_more;
125        ads->ds_ctl13 = 0;
126        ads->ds_ctl14 = 0;
127        ads->ds_ctl17 = SM(key_type, AR_encr_type);
128    }
129
130    return AH_TRUE;
131}
132
133void
134ar9300_set_desc_link(struct ath_hal *ah, void *ds, u_int32_t link)
135{
136    struct ar9300_txc *ads = AR9300TXC(ds);
137
138    ads->ds_link = link;
139
140    /* TODO - checksum is calculated twice for subframes
141     * Once in filldesc and again when linked. Need to fix.
142     */
143    /* Fill in pointer checksum.  Preserve descriptor id */
144    ads->ds_ctl10 &= ~AR_tx_ptr_chk_sum;
145    ads->ds_ctl10 |= ar9300_calc_ptr_chk_sum(ads);
146}
147
148void
149ar9300_get_desc_link_ptr(struct ath_hal *ah, void *ds, u_int32_t **link)
150{
151    struct ar9300_txc *ads = AR9300TXC(ds);
152
153    *link = &ads->ds_link;
154}
155
156void
157ar9300_clear_tx_desc_status(struct ath_hal *ah, void *ds)
158{
159    struct ar9300_txs *ads = AR9300TXS(ds);
160    ads->status1 = ads->status2 = 0;
161    ads->status3 = ads->status4 = 0;
162    ads->status5 = ads->status6 = 0;
163    ads->status7 = ads->status8 = 0;
164}
165
166#ifdef ATH_SWRETRY
167void
168ar9300_clear_dest_mask(struct ath_hal *ah, void *ds)
169{
170    struct ar9300_txc *ads = AR9300TXC(ds);
171    ads->ds_ctl11 |= AR_clr_dest_mask;
172}
173#endif
174
175#if AH_BYTE_ORDER == AH_BIG_ENDIAN
176/* XXX what words need swapping */
177/* Swap transmit descriptor */
178static __inline void
179ar9300_swap_tx_desc(void *dsp)
180{
181    struct ar9300_txs *ds = (struct ar9300_txs *)dsp;
182
183    ds->ds_info = __bswap32(ds->ds_info);
184    ds->status1 = __bswap32(ds->status1);
185    ds->status2 = __bswap32(ds->status2);
186    ds->status3 = __bswap32(ds->status3);
187    ds->status4 = __bswap32(ds->status4);
188    ds->status5 = __bswap32(ds->status5);
189    ds->status6 = __bswap32(ds->status6);
190    ds->status7 = __bswap32(ds->status7);
191    ds->status8 = __bswap32(ds->status8);
192}
193#endif
194
195
196/*
197 * Extract the transmit rate code.
198 */
199void
200ar9300_get_tx_rate_code(struct ath_hal *ah, void *ds, struct ath_tx_status *ts)
201{
202    struct ar9300_txc *ads = AR9300TXC(ds);
203
204    switch (ts->ts_rateindex) {
205    case 0:
206        ts->ts_ratecode = MS(ads->ds_ctl14, AR_xmit_rate0);
207        break;
208    case 1:
209        ts->ts_ratecode = MS(ads->ds_ctl14, AR_xmit_rate1);
210        break;
211    case 2:
212        ts->ts_ratecode = MS(ads->ds_ctl14, AR_xmit_rate2);
213        break;
214    case 3:
215        ts->ts_ratecode = MS(ads->ds_ctl14, AR_xmit_rate3);
216        break;
217    }
218
219    ar9300_set_selfgenrate_limit(ah, ts->ts_ratecode);
220}
221
222/*
223 * Get TX Status descriptor contents.
224 */
225void
226ar9300_get_raw_tx_desc(struct ath_hal *ah, u_int32_t *txstatus)
227{
228    struct ath_hal_9300 *ahp = AH9300(ah);
229    struct ar9300_txs *ads;
230
231    ads = &ahp->ts_ring[ahp->ts_tail];
232
233    OS_MEMCPY(txstatus, ads, sizeof(struct ar9300_txs));
234}
235
236/*
237 * Processing of HW TX descriptor.
238 */
239HAL_STATUS
240ar9300_proc_tx_desc(struct ath_hal *ah, void *txstatus)
241{
242    struct ath_hal_9300 *ahp = AH9300(ah);
243    struct ar9300_txs *ads;
244    struct ath_tx_status *ts = (struct ath_tx_status *)txstatus;
245    u_int32_t dsinfo;
246
247    ads = &ahp->ts_ring[ahp->ts_tail];
248
249    if ((ads->status8 & AR_tx_done) == 0) {
250        return HAL_EINPROGRESS;
251    }
252    /* Increment the tail to point to the next status element. */
253    ahp->ts_tail = (ahp->ts_tail + 1) & (ahp->ts_size-1);
254
255    /*
256    ** For big endian systems, ds_info is not swapped as the other
257    ** registers are.  Ensure we use the bswap32 version (which is
258    ** defined to "nothing" in little endian systems
259    */
260
261    /*
262     * Sanity check
263     */
264
265#if 0
266    ath_hal_printf(ah,
267        "CHH: ds_info 0x%x  status1: 0x%x  status8: 0x%x\n",
268        ads->ds_info, ads->status1, ads->status8);
269#endif
270
271    dsinfo = ads->ds_info;
272
273    if ((MS(dsinfo, AR_desc_id) != ATHEROS_VENDOR_ID) ||
274        (MS(dsinfo, AR_tx_rx_desc) != 1))
275    {
276        HALDEBUG(AH_NULL, HAL_DEBUG_UNMASKABLE, "%s: Tx Descriptor error %x\n",
277                 __func__, dsinfo);
278        HALASSERT(0);
279        /* Zero out the status for reuse */
280        OS_MEMZERO(ads, sizeof(struct ar9300_txs));
281        return HAL_EIO;
282    }
283
284    /* Update software copies of the HW status */
285    ts->queue_id = MS(dsinfo, AR_tx_qcu_num);
286    ts->desc_id = MS(ads->status1, AR_tx_desc_id);
287    ts->ts_seqnum = MS(ads->status8, AR_seq_num);
288    ts->ts_tstamp = ads->status4;
289    ts->ts_status = 0;
290    ts->ts_flags  = 0;
291
292    if (ads->status3 & AR_excessive_retries) {
293        ts->ts_status |= HAL_TXERR_XRETRY;
294    }
295    if (ads->status3 & AR_filtered) {
296        ts->ts_status |= HAL_TXERR_FILT;
297    }
298    if (ads->status3 & AR_fifounderrun) {
299        ts->ts_status |= HAL_TXERR_FIFO;
300        ar9300_update_tx_trig_level(ah, AH_TRUE);
301    }
302    if (ads->status8 & AR_tx_op_exceeded) {
303        ts->ts_status |= HAL_TXERR_XTXOP;
304    }
305    if (ads->status3 & AR_tx_timer_expired) {
306        ts->ts_status |= HAL_TXERR_TIMER_EXPIRED;
307    }
308    if (ads->status3 & AR_desc_cfg_err) {
309        ts->ts_flags |= HAL_TX_DESC_CFG_ERR;
310    }
311    if (ads->status3 & AR_tx_data_underrun) {
312        ts->ts_flags |= HAL_TX_DATA_UNDERRUN;
313        ar9300_update_tx_trig_level(ah, AH_TRUE);
314    }
315    if (ads->status3 & AR_tx_delim_underrun) {
316        ts->ts_flags |= HAL_TX_DELIM_UNDERRUN;
317        ar9300_update_tx_trig_level(ah, AH_TRUE);
318    }
319    if (ads->status2 & AR_tx_ba_status) {
320        ts->ts_flags |= HAL_TX_BA;
321        ts->ba_low = ads->status5;
322        ts->ba_high = ads->status6;
323    }
324
325    /*
326     * Extract the transmit rate.
327     */
328    ts->ts_rateindex = MS(ads->status8, AR_final_tx_idx);
329
330    ts->ts_rssi = MS(ads->status7, AR_tx_rssi_combined);
331    ts->ts_rssi_ctl0 = MS(ads->status2, AR_tx_rssi_ant00);
332    ts->ts_rssi_ctl1 = MS(ads->status2, AR_tx_rssi_ant01);
333    ts->ts_rssi_ctl2 = MS(ads->status2, AR_tx_rssi_ant02);
334    ts->ts_rssi_ext0 = MS(ads->status7, AR_tx_rssi_ant10);
335    ts->ts_rssi_ext1 = MS(ads->status7, AR_tx_rssi_ant11);
336    ts->ts_rssi_ext2 = MS(ads->status7, AR_tx_rssi_ant12);
337    ts->ts_shortretry = MS(ads->status3, AR_rts_fail_cnt);
338    ts->ts_longretry = MS(ads->status3, AR_data_fail_cnt);
339    ts->ts_virtcol = MS(ads->status3, AR_virt_retry_cnt);
340    ts->ts_antenna = 0;
341
342    /* extract TID from block ack */
343    ts->tid = MS(ads->status8, AR_tx_tid);
344
345    /* Zero out the status for reuse */
346    OS_MEMZERO(ads, sizeof(struct ar9300_txs));
347
348    return HAL_OK;
349}
350
351/*
352 * Calculate air time of a transmit packet
353 * if comp_wastedt is 1, calculate air time only for failed subframes
354 * this is required for VOW_DCS ( dynamic channel selection )
355 */
356u_int32_t
357ar9300_calc_tx_airtime(struct ath_hal *ah, void *ds, struct ath_tx_status *ts,
358        HAL_BOOL comp_wastedt, u_int8_t nbad, u_int8_t nframes )
359{
360    struct ar9300_txc *ads = AR9300TXC(ds);
361    int finalindex_tries;
362    u_int32_t airtime, lastrate_dur;
363
364
365    /*
366     * Number of attempts made on the final index
367     * Note: If no BA was recv, then the data_fail_cnt is the number of tries
368     * made on the final index.  If BA was recv, then add 1 to account for the
369     * successful attempt.
370     */
371    if ( !comp_wastedt ){
372        finalindex_tries = ts->ts_longretry + (ts->ts_flags & HAL_TX_BA)? 1 : 0;
373    } else {
374        finalindex_tries = ts->ts_longretry ;
375    }
376
377    /*
378     * Calculate time of transmit on air for packet including retries
379     * at different rates.
380     */
381    switch (ts->ts_rateindex) {
382    case 0:
383        lastrate_dur = MS(ads->ds_ctl15, AR_packet_dur0);
384        airtime = (lastrate_dur * finalindex_tries);
385        break;
386    case 1:
387        lastrate_dur = MS(ads->ds_ctl15, AR_packet_dur1);
388        airtime = (lastrate_dur * finalindex_tries) +
389            (MS(ads->ds_ctl13, AR_xmit_data_tries0) *
390             MS(ads->ds_ctl15, AR_packet_dur0));
391        break;
392    case 2:
393        lastrate_dur = MS(ads->ds_ctl16, AR_packet_dur2);
394        airtime = (lastrate_dur * finalindex_tries) +
395            (MS(ads->ds_ctl13, AR_xmit_data_tries1) *
396             MS(ads->ds_ctl15, AR_packet_dur1)) +
397            (MS(ads->ds_ctl13, AR_xmit_data_tries0) *
398             MS(ads->ds_ctl15, AR_packet_dur0));
399        break;
400    case 3:
401        lastrate_dur = MS(ads->ds_ctl16, AR_packet_dur3);
402        airtime = (lastrate_dur * finalindex_tries) +
403            (MS(ads->ds_ctl13, AR_xmit_data_tries2) *
404             MS(ads->ds_ctl16, AR_packet_dur2)) +
405            (MS(ads->ds_ctl13, AR_xmit_data_tries1) *
406             MS(ads->ds_ctl15, AR_packet_dur1)) +
407            (MS(ads->ds_ctl13, AR_xmit_data_tries0) *
408             MS(ads->ds_ctl15, AR_packet_dur0));
409        break;
410    default:
411        HALASSERT(0);
412        return 0;
413    }
414
415    if ( comp_wastedt && (ts->ts_flags & HAL_TX_BA)){
416        airtime += nbad?((lastrate_dur*nbad) / nframes):0;
417    }
418    return airtime;
419
420}
421
422#ifdef AH_PRIVATE_DIAG
423void
424ar9300__cont_tx_mode(struct ath_hal *ah, void *ds, int mode)
425{
426#if 0
427    static int qnum = 0;
428    int i;
429    unsigned int qbits, val, val1, val2;
430    int prefetch;
431    struct ar9300_txs *ads = AR9300TXS(ds);
432
433    if (mode == 10) {
434        return;
435    }
436
437    if (mode == 7) { /* print status from the cont tx desc */
438        if (ads) {
439            val1 = ads->ds_txstatus1;
440            val2 = ads->ds_txstatus2;
441            HALDEBUG(ah, HAL_DEBUG_TXDESC, "s0(%x) s1(%x)\n",
442                                       (unsigned)val1, (unsigned)val2);
443        }
444        HALDEBUG(ah, HAL_DEBUG_TXDESC, "txe(%x) txd(%x)\n",
445                                   OS_REG_READ(ah, AR_Q_TXE),
446                                   OS_REG_READ(ah, AR_Q_TXD)
447                );
448        for (i = 0; i < HAL_NUM_TX_QUEUES; i++) {
449            val = OS_REG_READ(ah, AR_QTXDP(i));
450            val2 = OS_REG_READ(ah, AR_QSTS(i)) & AR_Q_STS_PEND_FR_CNT;
451            HALDEBUG(ah, HAL_DEBUG_TXDESC, "[%d] %x %d\n", i, val, val2);
452        }
453        return;
454    }
455    if (mode == 8) {                      /* set TXE for qnum */
456        OS_REG_WRITE(ah, AR_Q_TXE, 1 << qnum);
457        return;
458    }
459    if (mode == 9) {
460        prefetch = (int)ds;
461        return;
462    }
463
464    if (mode >= 1) {                    /* initiate cont tx operation */
465        /* Disable AGC to A2 */
466        qnum = (int) ds;
467
468        OS_REG_WRITE(ah, AR_PHY_TEST,
469            (OS_REG_READ(ah, AR_PHY_TEST) | PHY_AGC_CLR) );
470
471        OS_REG_WRITE(ah, 0x9864, OS_REG_READ(ah, 0x9864) | 0x7f000);
472        OS_REG_WRITE(ah, 0x9924, OS_REG_READ(ah, 0x9924) | 0x7f00fe);
473        OS_REG_WRITE(ah, AR_DIAG_SW,
474            (OS_REG_READ(ah, AR_DIAG_SW) |
475             (AR_DIAG_FORCE_RX_CLEAR + AR_DIAG_IGNORE_VIRT_CS)) );
476
477
478        OS_REG_WRITE(ah, AR_CR, AR_CR_RXD);     /* set receive disable */
479
480        if (mode == 3 || mode == 4) {
481            int txcfg;
482
483            if (mode == 3) {
484                OS_REG_WRITE(ah, AR_DLCL_IFS(qnum), 0);
485                OS_REG_WRITE(ah, AR_DRETRY_LIMIT(qnum), 0xffffffff);
486                OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 100);
487                OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, 100);
488                OS_REG_WRITE(ah, AR_TIME_OUT, 2);
489                OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, 100);
490            }
491
492            OS_REG_WRITE(ah, AR_DRETRY_LIMIT(qnum), 0xffffffff);
493            /* enable prefetch on qnum */
494            OS_REG_WRITE(ah, AR_D_FPCTL, 0x10 | qnum);
495            txcfg = 5 | (6 << AR_FTRIG_S);
496            OS_REG_WRITE(ah, AR_TXCFG, txcfg);
497
498            OS_REG_WRITE(ah, AR_QMISC(qnum),        /* set QCU modes */
499                         AR_Q_MISC_DCU_EARLY_TERM_REQ
500                         + AR_Q_MISC_FSP_ASAP
501                         + AR_Q_MISC_CBR_INCR_DIS1
502                         + AR_Q_MISC_CBR_INCR_DIS0
503                        );
504
505            /* stop tx dma all all except qnum */
506            qbits = 0x3ff;
507            qbits &= ~(1 << qnum);
508            for (i = 0; i < 10; i++) {
509                if (i == qnum) {
510                    continue;
511                }
512                OS_REG_WRITE(ah, AR_Q_TXD, 1 << i);
513            }
514
515            OS_REG_WRITE(ah, AR_Q_TXD, qbits);
516
517            /* clear and freeze MIB counters */
518            OS_REG_WRITE(ah, AR_MIBC, AR_MIBC_CMC);
519            OS_REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC);
520
521            OS_REG_WRITE(ah, AR_DMISC(qnum),
522                         (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
523                          AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
524                         + (AR_D_MISC_ARB_LOCKOUT_IGNORE)
525                         + (AR_D_MISC_POST_FR_BKOFF_DIS)
526                         + (AR_D_MISC_VIR_COL_HANDLING_IGNORE <<
527                            AR_D_MISC_VIR_COL_HANDLING_S));
528
529            for (i = 0; i < HAL_NUM_TX_QUEUES + 2; i++) { /* disconnect QCUs */
530                if (i == qnum) {
531                    continue;
532                }
533                OS_REG_WRITE(ah, AR_DQCUMASK(i), 0);
534            }
535        }
536    }
537    if (mode == 0) {
538        OS_REG_WRITE(ah, AR_PHY_TEST,
539            (OS_REG_READ(ah, AR_PHY_TEST) & ~PHY_AGC_CLR));
540        OS_REG_WRITE(ah, AR_DIAG_SW,
541            (OS_REG_READ(ah, AR_DIAG_SW) &
542             ~(AR_DIAG_FORCE_RX_CLEAR + AR_DIAG_IGNORE_VIRT_CS)));
543    }
544#endif
545}
546#endif
547
548void
549ar9300_set_paprd_tx_desc(struct ath_hal *ah, void *ds, int chain_num)
550{
551    struct ar9300_txc *ads = AR9300TXC(ds);
552
553    ads->ds_ctl12 |= SM((1 << chain_num), AR_paprd_chain_mask);
554}
555HAL_STATUS
556ar9300_is_tx_done(struct ath_hal *ah)
557{
558    struct ath_hal_9300 *ahp = AH9300(ah);
559    struct ar9300_txs *ads;
560
561    ads = &ahp->ts_ring[ahp->ts_tail];
562
563    if (ads->status8 & AR_tx_done) {
564        return HAL_OK;
565    }
566    return HAL_EINPROGRESS;
567}
568
569void
570ar9300_set_11n_tx_desc(
571    struct ath_hal *ah,
572    void *ds,
573    u_int pkt_len,
574    HAL_PKT_TYPE type,
575    u_int tx_power,
576    u_int key_ix,
577    HAL_KEY_TYPE key_type,
578    u_int flags)
579{
580    struct ar9300_txc *ads = AR9300TXC(ds);
581    struct ath_hal_9300 *ahp = AH9300(ah);
582
583    HALASSERT(is_valid_pkt_type(type));
584    HALASSERT(is_valid_key_type(key_type));
585
586    tx_power += ahp->ah_tx_power_index_offset;
587    if (tx_power > 63) {
588        tx_power = 63;
589    }
590    ads->ds_ctl11 =
591        (pkt_len & AR_frame_len)
592      | (flags & HAL_TXDESC_VMF ? AR_virt_more_frag : 0)
593      | SM(tx_power, AR_xmit_power0)
594      | (flags & HAL_TXDESC_VEOL ? AR_veol : 0)
595      | (flags & HAL_TXDESC_CLRDMASK ? AR_clr_dest_mask : 0)
596      | (key_ix != HAL_TXKEYIX_INVALID ? AR_dest_idx_valid : 0)
597      | (flags & HAL_TXDESC_LOWRXCHAIN ? AR_low_rx_chain : 0);
598
599    ads->ds_ctl12 =
600        (key_ix != HAL_TXKEYIX_INVALID ? SM(key_ix, AR_dest_idx) : 0)
601      | SM(type, AR_frame_type)
602      | (flags & HAL_TXDESC_NOACK ? AR_no_ack : 0)
603      | (flags & HAL_TXDESC_EXT_ONLY ? AR_ext_only : 0)
604      | (flags & HAL_TXDESC_EXT_AND_CTL ? AR_ext_and_ctl : 0);
605
606    ads->ds_ctl17 =
607        SM(key_type, AR_encr_type) | (flags & HAL_TXDESC_LDPC ? AR_ldpc : 0);
608
609    ads->ds_ctl18 = 0;
610    ads->ds_ctl19 = AR_not_sounding; /* set not sounding for normal frame */
611
612
613    /*
614     * Clear Ness1/2/3 (Number of Extension Spatial Streams) fields.
615     * Ness0 is cleared in ctl19.  See EV66059 (BB panic).
616     */
617    ads->ds_ctl20 = 0;
618    ads->ds_ctl21 = 0;
619    ads->ds_ctl22 = 0;
620}
621
622void ar9300_set_rx_chainmask(struct ath_hal *ah, int rxchainmask)
623{
624    OS_REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rxchainmask);
625}
626
627void ar9300_update_loc_ctl_reg(struct ath_hal *ah, int pos_bit)
628{
629    u_int32_t reg_val;
630    reg_val = OS_REG_READ(ah, AR_LOC_CTL_REG);
631    if (pos_bit) {
632        if (!(reg_val & AR_LOC_CTL_REG_FS)) {
633            /* set fast timestamp bit in the regiter */
634            OS_REG_WRITE(ah, AR_LOC_CTL_REG, (reg_val | AR_LOC_CTL_REG_FS));
635            OS_REG_WRITE(ah, AR_LOC_TIMER_REG, 0);
636        }
637    }
638    else {
639        OS_REG_WRITE(ah, AR_LOC_CTL_REG, (reg_val & ~AR_LOC_CTL_REG_FS));
640    }
641}
642
643#if 0
644#define HT_RC_2_MCS(_rc)        ((_rc) & 0x0f)
645static const u_int8_t ba_duration_delta[] = {
646    24,     /*  0: BPSK       */
647    12,     /*  1: QPSK 1/2   */
648    12,     /*  2: QPSK 3/4   */
649     4,     /*  3: 16-QAM 1/2 */
650     4,     /*  4: 16-QAM 3/4 */
651     4,     /*  5: 64-QAM 2/3 */
652     4,     /*  6: 64-QAM 3/4 */
653     4,     /*  7: 64-QAM 5/6 */
654    24,     /*  8: BPSK       */
655    12,     /*  9: QPSK 1/2   */
656    12,     /* 10: QPSK 3/4   */
657     4,     /* 11: 16-QAM 1/2 */
658     4,     /* 12: 16-QAM 3/4 */
659     4,     /* 13: 64-QAM 2/3 */
660     4,     /* 14: 64-QAM 3/4 */
661     4,     /* 15: 64-QAM 5/6 */
662};
663#endif
664
665
666static u_int8_t
667ar9300_get_tx_mode(u_int rate_flags)
668{
669
670    /* Check whether STBC is enabled if TxBF is not enabled */
671    if (rate_flags & HAL_RATESERIES_STBC){
672        return AR9300_STBC_MODE;
673    }
674    return AR9300_DEF_MODE;
675}
676void
677ar9300_set_11n_rate_scenario(
678    struct ath_hal *ah,
679    void *ds,
680    void *lastds,
681    u_int dur_update_en,
682    u_int rts_cts_rate,
683    u_int rts_cts_duration,
684    HAL_11N_RATE_SERIES series[],
685    u_int nseries,
686    u_int flags,
687    u_int32_t smart_antenna)
688{
689    struct ath_hal_private *ap = AH_PRIVATE(ah);
690    struct ar9300_txc *ads = AR9300TXC(ds);
691    struct ar9300_txc *last_ads = AR9300TXC(lastds);
692    u_int32_t ds_ctl11;
693    u_int8_t ant, cal_pkt = 0;
694    u_int mode, tx_mode = AR9300_DEF_MODE;
695
696    HALASSERT(nseries == 4);
697    (void)nseries;
698    (void)rts_cts_duration;   /* use H/W to calculate RTSCTSDuration */
699
700    ds_ctl11 = ads->ds_ctl11;
701    /*
702     * Rate control settings override
703     */
704    if (flags & (HAL_TXDESC_RTSENA | HAL_TXDESC_CTSENA)) {
705        if (flags & HAL_TXDESC_RTSENA) {
706            ds_ctl11 &= ~AR_cts_enable;
707            ds_ctl11 |= AR_rts_enable;
708        } else {
709            ds_ctl11 &= ~AR_rts_enable;
710            ds_ctl11 |= AR_cts_enable;
711        }
712    } else {
713        ds_ctl11 = (ds_ctl11 & ~(AR_rts_enable | AR_cts_enable));
714    }
715
716    mode = ath_hal_get_curmode(ah, ap->ah_curchan);
717    cal_pkt = (ads->ds_ctl12 & AR_paprd_chain_mask)?1:0;
718
719    if (ap->ah_config.ath_hal_desc_tpc ) {
720        int16_t txpower;
721
722        if (!cal_pkt) {
723            /* Series 0 TxPower */
724            tx_mode = ar9300_get_tx_mode(series[0].RateFlags);
725            txpower = ar9300_get_rate_txpower(ah, mode, series[0].rate_index,
726                                       series[0].ch_sel, tx_mode);
727        } else {
728            txpower = AH9300(ah)->paprd_training_power;
729        }
730        ds_ctl11 &= ~AR_xmit_power0;
731        ds_ctl11 |=
732            set_11n_tx_power(0, AH_MIN(txpower, series[0].tx_power_cap));
733    }
734
735    ads->ds_ctl11 = ds_ctl11;
736
737
738    ads->ds_ctl13 = set_11n_tries(series, 0)
739                             |  set_11n_tries(series, 1)
740                             |  set_11n_tries(series, 2)
741                             |  set_11n_tries(series, 3)
742                             |  (dur_update_en ? AR_dur_update_ena : 0)
743                             |  SM(0, AR_burst_dur);
744
745    ads->ds_ctl14 = set_11n_rate(series, 0)
746                             |  set_11n_rate(series, 1)
747                             |  set_11n_rate(series, 2)
748                             |  set_11n_rate(series, 3);
749
750    ads->ds_ctl15 = set_11n_pkt_dur_rts_cts(series, 0)
751                             |  set_11n_pkt_dur_rts_cts(series, 1);
752
753    ads->ds_ctl16 = set_11n_pkt_dur_rts_cts(series, 2)
754                             |  set_11n_pkt_dur_rts_cts(series, 3);
755
756    ads->ds_ctl18 = set_11n_rate_flags(series, 0)
757                             |  set_11n_rate_flags(series, 1)
758                             |  set_11n_rate_flags(series, 2)
759                             |  set_11n_rate_flags(series, 3)
760                             | SM(rts_cts_rate, AR_rts_cts_rate);
761    /* set not sounding for normal frame */
762    ads->ds_ctl19 = AR_not_sounding;
763
764    if (ap->ah_config.ath_hal_desc_tpc) {
765        int16_t txpower;
766
767        if (!cal_pkt) {
768            /* Series 1 TxPower */
769            tx_mode = ar9300_get_tx_mode(series[1].RateFlags);
770            txpower = ar9300_get_rate_txpower(
771                ah, mode, series[1].rate_index, series[1].ch_sel, tx_mode);
772        } else {
773            txpower = AH9300(ah)->paprd_training_power;
774        }
775        ads->ds_ctl20 |=
776            set_11n_tx_power(1, AH_MIN(txpower, series[1].tx_power_cap));
777
778
779        /* Series 2 TxPower */
780        if (!cal_pkt) {
781            tx_mode = ar9300_get_tx_mode(series[2].RateFlags);
782            txpower = ar9300_get_rate_txpower(
783                ah, mode, series[2].rate_index, series[2].ch_sel, tx_mode);
784        } else {
785            txpower = AH9300(ah)->paprd_training_power;
786        }
787        ads->ds_ctl21 |=
788            set_11n_tx_power(2, AH_MIN(txpower, series[2].tx_power_cap));
789
790        /* Series 3 TxPower */
791        if (!cal_pkt) {
792            tx_mode = ar9300_get_tx_mode(series[3].RateFlags);
793            txpower = ar9300_get_rate_txpower(
794                ah, mode, series[3].rate_index, series[3].ch_sel, tx_mode);
795        } else {
796            txpower = AH9300(ah)->paprd_training_power;
797        }
798        ads->ds_ctl22 |=
799            set_11n_tx_power(3, AH_MIN(txpower, series[3].tx_power_cap));
800    }
801
802    if (smart_antenna != 0xffffffff)
803    {
804        /* TX DESC dword 19 to 23 are used for smart antenna configuaration
805         * ctl19 for rate series 0 ... ctrl22 for series 3
806         * bits[2:0] used to configure smart anntenna
807         */
808        ant = (smart_antenna&0x000000ff);
809        ads->ds_ctl19 |= ant; /* rateseries 0 */
810
811        ant = (smart_antenna&0x0000ff00) >> 8;
812        ads->ds_ctl20 |= ant;  /* rateseries 1 */
813
814        ant = (smart_antenna&0x00ff0000) >> 16;
815        ads->ds_ctl21 |= ant;  /* rateseries 2 */
816
817        ant = (smart_antenna&0xff000000) >> 24;
818        ads->ds_ctl22 |= ant;  /* rateseries 3 */
819    }
820
821#ifdef AH_NEED_DESC_SWAP
822    last_ads->ds_ctl13 = __bswap32(ads->ds_ctl13);
823    last_ads->ds_ctl14 = __bswap32(ads->ds_ctl14);
824#else
825    last_ads->ds_ctl13 = ads->ds_ctl13;
826    last_ads->ds_ctl14 = ads->ds_ctl14;
827#endif
828}
829
830void
831ar9300_set_11n_aggr_first(struct ath_hal *ah, void *ds, u_int aggr_len)
832{
833    struct ar9300_txc *ads = AR9300TXC(ds);
834
835    ads->ds_ctl12 |= (AR_is_aggr | AR_more_aggr);
836
837    ads->ds_ctl17 &= ~AR_aggr_len;
838    ads->ds_ctl17 |= SM(aggr_len, AR_aggr_len);
839}
840
841void
842ar9300_set_11n_aggr_middle(struct ath_hal *ah, void *ds, u_int num_delims)
843{
844    struct ar9300_txc *ads = AR9300TXC(ds);
845    unsigned int ctl17;
846
847    ads->ds_ctl12 |= (AR_is_aggr | AR_more_aggr);
848
849    /*
850     * We use a stack variable to manipulate ctl6 to reduce uncached
851     * read modify, modfiy, write.
852     */
853    ctl17 = ads->ds_ctl17;
854    ctl17 &= ~AR_pad_delim;
855    ctl17 |= SM(num_delims, AR_pad_delim);
856    ads->ds_ctl17 = ctl17;
857}
858
859void
860ar9300_set_11n_aggr_last(struct ath_hal *ah, void *ds)
861{
862    struct ar9300_txc *ads = AR9300TXC(ds);
863
864    ads->ds_ctl12 |= AR_is_aggr;
865    ads->ds_ctl12 &= ~AR_more_aggr;
866    ads->ds_ctl17 &= ~AR_pad_delim;
867}
868
869void
870ar9300_clr_11n_aggr(struct ath_hal *ah, void *ds)
871{
872    struct ar9300_txc *ads = AR9300TXC(ds);
873
874    ads->ds_ctl12 &= (~AR_is_aggr & ~AR_more_aggr);
875}
876
877void
878ar9300_set_11n_burst_duration(struct ath_hal *ah, void *ds,
879    u_int burst_duration)
880{
881    struct ar9300_txc *ads = AR9300TXC(ds);
882
883    ads->ds_ctl13 &= ~AR_burst_dur;
884    ads->ds_ctl13 |= SM(burst_duration, AR_burst_dur);
885}
886
887void
888ar9300_set_11n_rifs_burst_middle(struct ath_hal *ah, void *ds)
889{
890    struct ar9300_txc *ads = AR9300TXC(ds);
891
892    ads->ds_ctl12 |= AR_more_rifs | AR_no_ack;
893}
894
895void
896ar9300_set_11n_rifs_burst_last(struct ath_hal *ah, void *ds)
897{
898    struct ar9300_txc *ads = AR9300TXC(ds);
899
900    ads->ds_ctl12 &= (~AR_more_aggr & ~AR_more_rifs);
901}
902
903void
904ar9300_clr_11n_rifs_burst(struct ath_hal *ah, void *ds)
905{
906    struct ar9300_txc *ads = AR9300TXC(ds);
907
908    ads->ds_ctl12 &= (~AR_more_rifs & ~AR_no_ack);
909}
910
911void
912ar9300_set_11n_aggr_rifs_burst(struct ath_hal *ah, void *ds)
913{
914    struct ar9300_txc *ads = AR9300TXC(ds);
915
916    ads->ds_ctl12 |= AR_no_ack;
917    ads->ds_ctl12 &= ~AR_more_rifs;
918}
919
920void
921ar9300_set_11n_virtual_more_frag(struct ath_hal *ah, void *ds,
922                                                  u_int vmf)
923{
924    struct ar9300_txc *ads = AR9300TXC(ds);
925
926    if (vmf) {
927        ads->ds_ctl11 |=  AR_virt_more_frag;
928    } else {
929        ads->ds_ctl11 &= ~AR_virt_more_frag;
930    }
931}
932
933void
934ar9300_get_desc_info(struct ath_hal *ah, HAL_DESC_INFO *desc_info)
935{
936    desc_info->txctl_numwords = TXCTL_NUMWORDS(ah);
937    desc_info->txctl_offset = TXCTL_OFFSET(ah);
938    desc_info->txstatus_numwords = TXSTATUS_NUMWORDS(ah);
939    desc_info->txstatus_offset = TXSTATUS_OFFSET(ah);
940
941    desc_info->rxctl_numwords = RXCTL_NUMWORDS(ah);
942    desc_info->rxctl_offset = RXCTL_OFFSET(ah);
943    desc_info->rxstatus_numwords = RXSTATUS_NUMWORDS(ah);
944    desc_info->rxstatus_offset = RXSTATUS_OFFSET(ah);
945}
946
947#endif /* AH_SUPPORT_AR9300 */
948