The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/ath/ath_hal/ar9300/ar9300_xmit_ds.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 654901f1e1ba82137dc2a5932f7b7d0d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.