00001
00013 #ifndef _TXL_BUFFER_H_
00014 #define _TXL_BUFFER_H_
00015
00025
00026
00027
00028
00029 #include "co_int.h"
00030 #include "co_bool.h"
00031 #include "rwnx_config.h"
00032 #include "co_list.h"
00033 #include "txl_cntrl.h"
00034 #include "tx_swdesc.h"
00035 #include "txl_agg.h"
00036 #include "txl_he.h"
00037 #include "co_utils.h"
00038 #if NX_UMAC_PRESENT
00039 #include "me_mic.h"
00040 #include "txu_cntrl.h"
00041 #include "rc.h"
00042 #endif
00043
00044
00045
00046
00047
00048
00050 #define TX_BUFFER_MTU 1536
00051
00053 #define TX_ADD_BUFFER 64
00054
00056 #define TX_MPDU_LEN_MAX (TX_BUFFER_MTU + TX_ADD_BUFFER)
00057
00059 #define TX_BUFFER_MAX (sizeof_b(struct txl_buffer_tag) + TX_MPDU_LEN_MAX)
00060
00062 #define TX_BUFFER_POOL_MAX (AC_MAX * RW_USER_MAX + NX_BEACONING)
00063
00065 #if NX_AMPDU_TX
00066 #if defined(CFG_VIRTEX7) && !defined(CFG_FHOST)
00068 #define TX_MIN_DOWNLOAD_CNT 8
00069 #else
00070 #if NX_AMSDU_TX
00072 #define TX_MIN_DOWNLOAD_CNT 4
00073 #else
00075 #define TX_MIN_DOWNLOAD_CNT 3
00076 #endif // NX_AMSDU_TX
00077 #endif // defined(CFG_VIRTEX7)
00079 #define TX_BUFFER_POOL_SIZE ((TX_MIN_DOWNLOAD_CNT * TX_BUFFER_MAX) / 4)
00080 #else
00082 #define TX_MIN_DOWNLOAD_CNT 2
00084 #define TX_BUFFER_POOL_SIZE ((TX_MIN_DOWNLOAD_CNT * TX_BUFFER_MAX) / 4)
00085 #endif // NX_AMPDU_TX
00086
00088 #define TX_BUFFER_NULL 0xFFFFFFFF
00089
00090 #if NX_UMAC_PRESENT
00092 #define TX_BUFFER_PADDING_MAX 0
00093 #else
00095 #define TX_BUFFER_PADDING_MAX 3
00096 #endif
00097
00099 #define TX_BUFFER_PADDING_MASK 0x00000003
00100
00102 #define TX_BUFFER_PADDING_OFT 0
00103
00105 #define TX_BUFFER_MIN_SIZE 256
00106
00108 #define TX_BUFFER_MIN_AMPDU_DWNLD 500
00109
00111 #if NX_UMAC_PRESENT && NX_AMSDU_TX
00112 #define TX_DMA_DESC_MAX NX_TX_PAYLOAD_MAX
00113 #elif NX_MFP
00114 #define TX_DMA_DESC_MAX 2
00115 #else
00116 #define TX_DMA_DESC_MAX 1
00117 #endif
00118
00119 #if NX_FULLY_HOSTED
00120
00122 #define TX_PBD_CNT 3
00123 #endif
00124
00126 enum
00127 {
00129 BUF_FRONTIER = CO_BIT(0),
00131 BUF_SPLIT = CO_BIT(1),
00133 BUF_ALLOC_OK = CO_BIT(2),
00135 BUF_INT_MSDU = CO_BIT(3),
00136 #if NX_MAC_HE
00138 BUF_SINGLETON_READY = CO_BIT(4),
00139 #endif
00140 };
00141
00142
00143
00144
00145
00147 struct txl_buffer_hw_desc_tag
00148 {
00150 struct dma_desc dma_desc;
00152 struct tx_pbd pbd;
00153 };
00154
00156 struct txl_buffer_list_tag
00157 {
00159 struct txl_buffer_tag *first;
00161 struct txl_buffer_tag *last;
00162 };
00163
00165 struct txl_buffer_idx_tag
00166 {
00168 uint32_t used_area;
00170 uint32_t free;
00172 uint32_t free_size;
00174 uint32_t last;
00177 uint32_t next_needed;
00179 uint32_t buf_size;
00181 uint32_t *pool;
00183 struct txl_buffer_hw_desc_tag *desc;
00185 uint8_t count;
00186 };
00187
00188
00190 struct txl_buffer_env_tag
00191 {
00193 struct txl_buffer_idx_tag buf_idx[NX_TXQ_CNT][RW_USER_MAX];
00195 struct txl_buffer_list_tag list[NX_TXQ_CNT];
00196 };
00197
00199 struct txl_buffer_tag
00200 {
00201 #if !NX_FULLY_HOSTED
00203 uint32_t length;
00205 struct txl_buffer_tag *next;
00207 struct txdesc *txdesc;
00209 struct dma_desc dma_desc[TX_DMA_DESC_MAX];
00211 struct dma_desc dma_desc_pat;
00212 #if (RW_BFMER_EN)
00214 struct dma_desc dma_desc_bfr;
00215 #endif //(RW_BFMER_EN)
00217 struct tx_pbd tbd;
00219 uint8_t user_idx;
00220 #endif
00221
00222 uint32_t flags;
00224 struct txl_buffer_control buffer_control;
00225 #if NX_FULLY_HOSTED
00227 struct tx_pbd pbd[TX_PBD_CNT];
00229 struct tx_pbd pbd_tail;
00231 uint8_t sec_tail[MIC_LEN];
00233 uint8_t headers[MAC_LONG_QOS_MAC_HDR_LEN + LLC_802_2_HDR_LEN + WPI_IV_LEN - LLC_ETHER_HDR_LEN];
00234 #endif
00236 uint32_t payload[];
00237 };
00238
00239
00240
00241
00242
00243
00245 extern uint32_t txl_buffer_pool[TX_BUFFER_POOL_MAX][TX_BUFFER_POOL_SIZE];
00246
00248 extern struct txl_buffer_hw_desc_tag txl_buffer_hw_desc[TX_BUFFER_POOL_MAX];
00249
00251 extern struct txl_buffer_env_tag txl_buffer_env;
00252
00253 #if NX_UMAC_PRESENT
00255 extern struct txl_buffer_control txl_buffer_control_desc[NX_REMOTE_STA_MAX];
00257 extern struct txl_buffer_control txl_buffer_control_desc_bcmc[NX_VIRT_DEV_MAX];
00258 #endif
00259
00260
00261
00262
00263
00264
00267
00268 #if !NX_FULLY_HOSTED
00269
00279 __INLINE void txl_buffer_push(uint8_t access_category, struct txl_buffer_tag *buf)
00280 {
00281 struct txl_buffer_list_tag *list = &txl_buffer_env.list[access_category];
00282
00283
00284 if (list->first == NULL)
00285 {
00286
00287 list->first = buf;
00288 }
00289 else
00290 {
00291
00292 list->last->next = buf;
00293 }
00294
00295
00296 list->last = buf;
00297 buf->next = NULL;
00298 }
00299
00311 __INLINE struct txl_buffer_tag *txl_buffer_pop(uint8_t access_category)
00312 {
00313 struct txl_buffer_list_tag *list = &txl_buffer_env.list[access_category];
00314 struct txl_buffer_tag *buf;
00315
00316
00317 buf = list->first;
00318 if (buf != NULL)
00319 {
00320
00321 list->first = list->first->next;
00322 }
00323
00324 return buf;
00325 }
00326
00337 __INLINE struct txl_buffer_tag *txl_buffer_pick(uint8_t access_category)
00338 {
00339 struct txl_buffer_list_tag *list = &txl_buffer_env.list[access_category];
00340
00341 return list->first;
00342 }
00343
00353 __INLINE bool txl_buffer_list_empty(uint8_t access_category)
00354 {
00355 struct txl_buffer_list_tag *list = &txl_buffer_env.list[access_category];
00356
00357 return (list->first == NULL);
00358 }
00359 #endif
00360
00361
00372 __INLINE struct txl_buffer_tag *txl_buffer_get(struct txdesc *txdesc)
00373 {
00374 #if NX_AMSDU_TX
00375 struct txl_buffer_tag *buffer = txdesc->lmac.buffer[0];
00376 #else
00377 struct txl_buffer_tag *buffer = txdesc->lmac.buffer;
00378 #endif
00379 return (buffer);
00380 }
00381
00382
00393 __INLINE struct txl_buffer_control *txl_buffer_control_get(struct txdesc *txdesc)
00394 {
00395 struct txl_buffer_tag *buffer = txl_buffer_get(txdesc);
00396 return (&buffer->buffer_control);
00397 }
00398
00409 __INLINE void *txl_buffer_payload_get(struct txdesc *txdesc)
00410 {
00411 struct txl_buffer_tag *buffer = txl_buffer_get(txdesc);
00412 return ((void *)buffer->payload);
00413 }
00414
00426 __INLINE uint32_t txl_buffer_machdr_get(struct txdesc *txdesc)
00427 {
00428 struct tx_hd *thd = &txdesc->lmac.hw_desc->thd;
00429 struct tx_pbd *pbd;
00430
00431
00432 ASSERT_ERR(txl_buffer_get(txdesc) != NULL);
00433
00434
00435 if (thd->datastartptr)
00436 return (thd->datastartptr);
00437
00438
00439 ASSERT_ERR(thd->first_pbd_ptr);
00440 pbd = HW2CPU(thd->first_pbd_ptr);
00441
00442 return (pbd->datastartptr);
00443 }
00444
00445 #if NX_UMAC_PRESENT
00446
00456 __INLINE void txl_buffer_control_trial(struct txdesc *txdesc, struct txl_buffer_tag *buf)
00457 {
00458
00459 if (txdesc->host.flags & TXU_CNTRL_RC_TRIAL)
00460 {
00461 struct txl_buffer_control *buf_ctrl_src = txdesc->umac.buf_control;
00462 struct txl_buffer_control *buf_ctrl_dest = &buf->buffer_control;
00463
00464 struct rc_sta_stats *rc_ss = rc_get_sta_stats(txdesc->host.staid);
00465
00466 PROF_RC_SET_TRIAL_BUFFER_SET();
00467
00468
00469 buf_ctrl_dest->policy_tbl.ratecntrlinfo[1] = buf_ctrl_src->policy_tbl.ratecntrlinfo[0];
00470 #if NX_MAC_HE
00471 buf_ctrl_dest->policy_tbl.powercntrlinfo[1] = buf_ctrl_src->policy_tbl.powercntrlinfo[0];
00472 #endif
00473
00474
00475 buf_ctrl_dest->policy_tbl.ratecntrlinfo[0] = rc_ss->trial_rate;
00476 #if NX_MAC_HE
00477 if (txl_he_is_he_su(rc_ss->trial_rate))
00478 {
00479 txl_he_ltf_type_set(rc_ss->trial_rate,
00480 &buf_ctrl_dest->policy_tbl.powercntrlinfo[0]);
00481 }
00482 #endif
00483
00484
00485 if ((buf_ctrl_src->tx_flags & TX_SWDESC_UMAC_TRIAL_STBC_BIT) == 0)
00486 {
00487 buf_ctrl_dest->policy_tbl.phycntrlinfo1 &= ~STBC_PT_MASK;
00488 }
00489
00490 PROF_RC_SET_TRIAL_BUFFER_CLR();
00491 }
00492 }
00493
00503 __INLINE void txl_buffer_control_copy(struct txdesc *txdesc,
00504 struct txl_buffer_tag *buf)
00505 {
00506 uint32_t *dst = (uint32_t *)&buf->buffer_control;
00507 uint32_t *src = (uint32_t *)txdesc->umac.buf_control;
00508 unsigned int i;
00509
00510
00511 for (i = 0; i < (sizeof_b(struct txl_buffer_control)/sizeof_b(uint32_t)); i++)
00512 {
00513 *dst++ = *src++;
00514 }
00515
00516
00517 txl_buffer_control_trial(txdesc, buf);
00518
00519 }
00520 #endif
00521
00522
00534 __INLINE int txl_buffer_padding(struct txdesc *txdesc)
00535 {
00536 #if NX_UMAC_PRESENT
00537 return (0);
00538 #else
00539 return (txdesc->host.padding);
00540 #endif
00541 }
00542
00543 #if NX_AMSDU_TX
00544
00554 __INLINE bool txl_buffer_is_amsdu_multi_buf(struct txdesc *txdesc)
00555 {
00556 return (is_mpdu_split(txdesc) && (txdesc->lmac.hw_desc->thd.frmlen > TX_MPDU_LEN_MAX));
00557 }
00568 __INLINE bool txl_buffer_is_amsdu_single_buf(struct txdesc *txdesc)
00569 {
00570 return (is_mpdu_split(txdesc) && (txdesc->lmac.hw_desc->thd.frmlen <= TX_MPDU_LEN_MAX));
00571 }
00572 #endif
00573
00574 #if NX_MAC_HE
00575
00590 __INLINE void txl_buffer_remove_htc(struct tx_hd *thd)
00591 {
00592 #if NX_UMAC_PRESENT
00593 uint32_t mac_hdr_addr = thd->datastartptr;
00594 uint16_t framectl = co_read16p(mac_hdr_addr);
00595
00596
00597
00598 if ((framectl & MAC_FCTRL_ORDER) == 0)
00599 return;
00600
00601 framectl &= ~MAC_FCTRL_ORDER;
00602 co_write16p(mac_hdr_addr, framectl);
00603
00604 thd->frmlen -= MAC_HTC_LEN;
00605 thd->dataendptr -= MAC_HTC_LEN;
00606 #endif
00607 }
00608
00626 __INLINE void txl_buffer_add_htc(struct tx_hd *thd)
00627 {
00628 #if NX_UMAC_PRESENT
00629 uint32_t mac_hdr_addr = thd->datastartptr;
00630 uint16_t framectl;
00631
00632 if (!mac_hdr_addr || ((framectl = co_read16p(mac_hdr_addr)) & MAC_FCTRL_ORDER))
00633 return;
00634
00635 framectl |= MAC_FCTRL_ORDER;
00636 co_write16p(mac_hdr_addr, framectl);
00637
00638 thd->frmlen += MAC_HTC_LEN;
00639 thd->dataendptr += MAC_HTC_LEN;
00640 #endif
00641 }
00642
00657 __INLINE bool txl_buffer_update_htc(struct tx_hd *thd, uint32_t htc)
00658 {
00659 #if NX_UMAC_PRESENT
00660
00661 if (!thd->datastartptr)
00662 return false;
00663
00664 co_write32p(thd->dataendptr - MAC_HTC_LEN + 1, htc);
00665 return true;
00666 #else
00667 return false;
00668 #endif
00669 }
00670
00671
00672 #endif
00673
00674 #if !NX_FULLY_HOSTED
00675
00688 __INLINE void txl_buffer_update_thd(struct txdesc *txdesc,
00689 uint8_t access_category)
00690 {
00691 struct tx_hd *thd = &txdesc->lmac.hw_desc->thd;
00692 #if NX_AMSDU_TX
00693 struct txl_list *txlist = &txl_cntrl_env.txlist[access_category];
00694 #endif
00695 struct txl_buffer_tag *buffer = txl_buffer_get(txdesc);
00696 struct txl_buffer_idx_tag *idx = &txl_buffer_env.buf_idx[access_category][buffer->user_idx];
00697 uint32_t pool_size = TX_BUFFER_POOL_SIZE * sizeof_b(uint32_t);
00698 uint32_t pool_start = CPU2HW(idx->pool);
00699 uint32_t pool_end = pool_start + pool_size - 1;
00700 uint32_t start = CPU2HW(buffer->payload) + txl_buffer_padding(txdesc);
00701 #if NX_UMAC_PRESENT
00702 uint16_t add_len;
00703 uint32_t payl = start + txdesc->umac.machead_len;
00704 #else
00705 uint32_t payl = start;
00706 #endif
00707 #if NX_AMSDU_TX
00708 uint32_t pkt_len = txdesc->host.packet_len[0];
00709 #else
00710 uint32_t pkt_len = txdesc->host.packet_len;
00711 #endif
00712 uint32_t end;
00713 struct tx_pbd *pbd = &buffer->tbd;
00714 struct tx_pbd *add_pbd = NULL;
00715 struct tx_pbd *last_pbd = pbd;
00716
00717 #if NX_UMAC_PRESENT
00718 #if NX_AMSDU_TX
00719 if (txl_buffer_is_amsdu_single_buf(txdesc))
00720 pkt_len = txdesc->lmac.hw_desc->thd.frmlen - MAC_FCS_LEN;
00721 else
00722 #endif
00723 {
00724 add_len = txdesc->umac.head_len;
00725 #if NX_AMSDU_TX
00726 if (!is_mpdu_split(txdesc))
00727 #endif
00728 add_len += txdesc->umac.tail_len;
00729 pkt_len += add_len;
00730 }
00731 #endif
00732 end = start + pkt_len - 1;
00733
00734
00735 buffer->flags &= ~BUF_SPLIT;
00736
00737
00738 ASSERT_ERR(start < pool_end);
00739
00740
00741 if (end > pool_end)
00742 {
00743
00744 end = pool_end;
00745
00746
00747 add_pbd = &idx->desc->pbd;
00748 add_pbd->datastartptr = pool_start;
00749 add_pbd->dataendptr = pool_start + pkt_len - (end - start) - 2;
00750
00751 last_pbd = add_pbd;
00752
00753
00754 buffer->flags |= BUF_SPLIT;
00755 }
00756
00757
00758 #if NX_UMAC_PRESENT
00759 if (txdesc->umac.machead_len)
00760 {
00761 thd->datastartptr = start;
00762 thd->dataendptr = start + txdesc->umac.machead_len - 1;
00763 }
00764 #endif
00765 pbd->datastartptr = payl;
00766 pbd->dataendptr = end;
00767 pbd->next = CPU2HW(add_pbd);
00768 pbd->bufctrlinfo = 0;
00769
00770 thd->first_pbd_ptr = CPU2HW(pbd);
00771 last_pbd->bufctrlinfo = 0;
00772 #if NX_AMPDU_TX
00773 if ((buffer->flags & BUF_FRONTIER) || is_mpdu_last(txdesc) || !is_mpdu_agg(txdesc))
00774 {
00775 if (!(buffer->flags & BUF_FRONTIER))
00776 {
00777 #if NX_AMSDU_TX
00778 if (!is_mpdu_split(txdesc))
00779 {
00780 #endif
00781 buffer->flags |= BUF_FRONTIER;
00782 idx->count++;
00783 #if NX_AMSDU_TX
00784 }
00785 #endif
00786
00787 thd->macctrlinfo2 |= INTERRUPT_EN_TX;
00788 }
00789 else
00790 {
00791 #if NX_AMSDU_TX
00792 if (txl_buffer_is_amsdu_multi_buf(txdesc))
00793 {
00794
00795 last_pbd->bufctrlinfo = TBD_INTERRUPT_EN;
00796
00797
00798 if (!is_mpdu_agg(txdesc))
00799 thd->macctrlinfo2 |= INTERRUPT_EN_TX;
00800 }
00801 else
00802 #endif
00803 {
00804
00805 thd->macctrlinfo2 |= INTERRUPT_EN_TX;
00806 }
00807 }
00808 }
00809 #else
00810
00811 thd->macctrlinfo2 = WHICHDESC_UNFRAGMENTED_MSDU | INTERRUPT_EN_TX;
00812 #endif
00813 last_pbd->next = 0;
00814
00815 #if NX_AMSDU_TX
00816
00817 txlist->last_pbd[buffer->user_idx] = last_pbd;
00818 #endif
00819 }
00820
00821 #if NX_AMSDU_TX
00822
00836 __INLINE void txl_buffer_update_tbd(struct txdesc *txdesc,
00837 uint8_t access_category,
00838 uint8_t pkt_idx)
00839 {
00840 struct txl_list *txlist = &txl_cntrl_env.txlist[access_category];
00841 struct txl_buffer_tag *buffer = txdesc->lmac.buffer[pkt_idx];
00842 struct tx_pbd *tbd = &buffer->tbd;
00843 uint32_t pkt_len = txdesc->host.packet_len[pkt_idx];
00844 struct txl_buffer_idx_tag *idx = &txl_buffer_env.buf_idx[access_category][buffer->user_idx];
00845 uint32_t pool_size = TX_BUFFER_POOL_SIZE * sizeof_b(uint32_t);
00846 uint32_t pool_start = CPU2HW(idx->pool);
00847 uint32_t pool_end = pool_start + pool_size - 1;
00848 uint32_t start = CPU2HW(buffer->payload);
00849 uint32_t end = start + pkt_len - 1;
00850 struct tx_pbd *pbd = NULL;
00851 struct tx_pbd *last = tbd;
00852
00853 #if NX_UMAC_PRESENT
00854 if ((pkt_idx + 1) == txdesc->host.packet_cnt) {
00855 pkt_len += txdesc->umac.tail_len;
00856 end += txdesc->umac.tail_len;
00857 }
00858 #endif
00859
00860
00861 buffer->flags &= ~BUF_SPLIT;
00862
00863
00864 if (start > pool_end)
00865 {
00866 start -= pool_size;
00867 end -= pool_size;
00868 }
00869 else
00870 {
00871
00872 if (end > pool_end)
00873 {
00874
00875 end = pool_end;
00876
00877
00878 pbd = &idx->desc->pbd;
00879 pbd->datastartptr = pool_start;
00880 pbd->dataendptr = pool_start + pkt_len - (end - start) - 2;
00881
00882 last = pbd;
00883
00884
00885 buffer->flags |= BUF_SPLIT;
00886 }
00887 }
00888
00889
00890 tbd->datastartptr = start;
00891 tbd->dataendptr = end;
00892 tbd->next = CPU2HW(pbd);
00893 tbd->bufctrlinfo = 0;
00894
00895 if ((buffer->flags & BUF_FRONTIER) ||
00896 (is_mpdu_last(txdesc) && ((pkt_idx + 1) == txdesc->host.packet_cnt)))
00897
00898 last->bufctrlinfo = TBD_INTERRUPT_EN;
00899 else
00900 last->bufctrlinfo = 0;
00901
00902
00903 ASSERT_ERR(txlist->last_pbd[buffer->user_idx] != NULL);
00904 txlist->last_pbd[buffer->user_idx]->next = CPU2HW(tbd);
00905
00906
00907 last->next = 0;
00908 txlist->last_pbd[buffer->user_idx] = last;
00909 }
00910 #endif
00911
00912
00913 #if NX_UMAC_PRESENT
00914
00927 __INLINE void txl_buffer_mic_compute(struct txdesc *txdesc,
00928 uint32_t *mic_key,
00929 uint32_t start,
00930 uint32_t len,
00931 uint8_t access_category)
00932 {
00933 struct hostdesc *host = &txdesc->host;
00934 struct mic_calc mic;
00935 struct txl_buffer_tag *buffer = txl_buffer_get(txdesc);
00936 struct txl_buffer_idx_tag *idx = &txl_buffer_env.buf_idx[access_category][buffer->user_idx];
00937 uint32_t pool_size = TX_BUFFER_POOL_SIZE * sizeof_b(uint32_t);
00938 uint32_t pool_start = CPU2HW(idx->pool);
00939 uint32_t pool_end = pool_start + pool_size - 1;
00940 uint32_t end = start + len - 1;
00941 uint32_t clen = len;
00942 uint32_t mic_start = end + 1, mic_end;
00943 uint32_t mic_addr = CPU2HW(&mic.mic_key_least);
00944
00945
00946 me_mic_init(&mic, mic_key, &host->eth_dest_addr, &host->eth_src_addr, host->tid);
00947
00948
00949 if (end > pool_end)
00950 {
00951 clen = pool_end - start + 1;
00952
00953
00954 me_mic_calc(&mic, start, clen);
00955
00956
00957 clen = len - clen;
00958 start = pool_start;
00959 }
00960
00961 me_mic_calc(&mic, start, clen);
00962
00963
00964 me_mic_end(&mic);
00965
00966
00967 if (mic_start > pool_end)
00968 mic_start -= pool_size;
00969 mic_end = mic_start + 7;
00970 clen = 8;
00971 if (mic_end > pool_end)
00972 {
00973 clen = pool_end - mic_start + 1;
00974
00975
00976 co_copy8p(mic_start, mic_addr, clen);
00977
00978
00979 mic_addr += clen;
00980 clen = 8 - clen;
00981 mic_start = pool_start;
00982 }
00983
00984
00985 co_copy8p(mic_start, mic_addr, clen);
00986 }
00987 #endif //NX_UMAC_PRESENT
00988
00995 void txl_buffer_reinit(void);
00996
01007 void txl_buffer_reset(uint8_t access_category);
01008
01029 #if NX_AMSDU_TX
01030 struct txl_buffer_tag *txl_buffer_alloc(struct txdesc *txdesc, uint8_t access_category,
01031 uint8_t user_idx, uint8_t pkt_idx);
01032 #else
01033 struct txl_buffer_tag *txl_buffer_alloc(struct txdesc *txdesc, uint8_t access_category,
01034 uint8_t user_idx);
01035 #endif
01036
01048 bool txl_buffer_free(struct txl_buffer_tag *buf, uint8_t access_category);
01049
01058 void txl_buffer_free_all(struct txdesc *txdesc, uint8_t access_category);
01059
01071 __INLINE uint32_t txl_buffer_used(uint8_t access_category, uint8_t user_idx)
01072 {
01073 return txl_buffer_env.buf_idx[access_category][user_idx].used_area;
01074 }
01075
01087 __INLINE uint8_t txl_buffer_count(uint8_t access_category, uint8_t user_idx)
01088 {
01089 struct txl_buffer_idx_tag *idx = &txl_buffer_env.buf_idx[access_category][user_idx];
01090
01091 return(idx->count);
01092 }
01093 #endif
01094
01095
01101 void txl_buffer_init(void);
01102
01103
01104
01107
01108 #endif