00001
00018
00019
00020
00021
00022 #include "rxl_hwdesc.h"
00023
00024 #include "ke_event.h"
00025 #include "rxl_cntrl.h"
00026 #if NX_UMAC_PRESENT
00027 #include "rxu_cntrl.h"
00028 #endif
00029 #include "co_utils.h"
00030 #include "macif.h"
00031 #if NX_AMPDU_TX
00032 #include "txl_cfm.h"
00033 #endif
00034 #if NX_MAC_HE
00035 #include "txl_he.h"
00036 #endif
00037 #include "co_endian.h"
00038 #include "reg_mac_pl.h"
00039 #include "reg_mac_core.h"
00040
00041
00042
00043
00044
00045
00047 struct rxl_hwdesc_env_tag
00048 {
00050 struct co_list ready;
00052 struct rx_dmadesc *first_dmadesc;
00054 struct rx_dmadesc *last_dmadesc;
00056 struct rx_dmadesc *free_dmadesc;
00058 struct rx_pbd *first;
00060 struct rx_pbd *last;
00062 struct rx_pbd *free;
00064 bool monitor_en;
00065 };
00066
00067
00068
00069
00070
00072 static struct rxdesc rx_swdesc_tab[NX_RXDESC_CNT];
00073
00075 static struct rxl_hwdesc_env_tag rx_hwdesc_env;
00076
00078 struct rx_dmadesc rx_dma_hdrdesc[NX_RXDESC_CNT] __SHAREDRAM;
00080 struct rx_payloaddesc rx_payload_desc[NX_RX_PAYLOAD_DESC_CNT] __SHAREDRAM;
00081
00082
00083
00084
00085
00096 static void rxl_hd_append(struct rx_dmadesc *desc)
00097 {
00098 struct rx_dmadesc *free_desc;
00099
00100
00101 ASSERT_ERR(desc != NULL);
00102
00103
00104 if (HW2CPU(nxmac_debug_rx_hdr_c_ptr_get()) == rx_hwdesc_env.free_dmadesc)
00105 {
00106
00107
00108 free_desc = desc;
00109 }
00110 else
00111 {
00112
00113 free_desc = rx_hwdesc_env.free_dmadesc;
00114
00115
00116 rx_hwdesc_env.free_dmadesc = desc;
00117 }
00118
00119
00120 free_desc->hd.statinfo = 0;
00121
00122
00123 free_desc->hd.next = 0;
00124
00125
00126 free_desc->hd.first_pbd_ptr = 0;
00127
00128
00129 free_desc->hd.frmlen = 0;
00130
00131
00132 rx_hwdesc_env.last_dmadesc->hd.next = CPU2HW(&(free_desc->hd));
00133 nxmac_dma_cntrl_set(NXMAC_RX_HEADER_NEW_TAIL_BIT);
00134
00135
00136 rx_hwdesc_env.last_dmadesc = free_desc;
00137
00138
00139 if (rx_hwdesc_env.first_dmadesc == NULL)
00140 {
00141 rx_hwdesc_env.first_dmadesc = free_desc;
00142 }
00143 }
00144
00157 static void rxl_pd_append(struct rx_pbd *first, struct rx_pbd* last, struct rx_pbd* spare)
00158 {
00159
00160 ASSERT_ERR(spare != NULL);
00161
00162
00163 if (HW2CPU(nxmac_debug_rx_pay_c_ptr_get()) == rx_hwdesc_env.free)
00164 {
00165
00166
00167
00168 if (last == NULL)
00169 {
00170
00171 first = spare;
00172 }
00173 last = spare;
00174
00175
00176 last->bufstatinfo = 0;
00177 }
00178 else
00179 {
00180
00181 struct rx_pbd *free = rx_hwdesc_env.free;
00182
00183
00184 rx_hwdesc_env.free = spare;
00185
00186
00187 if (last == NULL)
00188 {
00189
00190 first = last = free;
00191 }
00192 else
00193 {
00194 free->next = CPU2HW(first);
00195 first = free;
00196 }
00197
00198
00199 first->bufstatinfo = 0;
00200 }
00201
00202
00203 last->next = 0;
00204
00205
00206 rx_hwdesc_env.last->next = CPU2HW(first);
00207 nxmac_dma_cntrl_set(NXMAC_RX_PAYLOAD_NEW_TAIL_BIT);
00208
00209
00210 rx_hwdesc_env.last = last;
00211
00212
00213 if (rx_hwdesc_env.first == NULL)
00214 {
00215 rx_hwdesc_env.first = first;
00216 }
00217 }
00218
00219 #if NX_AMSDU_DEAGG
00220
00236 static uint16_t rxl_amsdu_subframe_len_get(struct rx_payloaddesc *pd,
00237 uint16_t payl_offset,
00238 uint16_t mpdu_len)
00239 {
00240 uint16_t subfrm_len;
00241 uint32_t subfrm_len_addr;
00242
00243
00244 if (sizeof_b(struct amsdu_hdr) > mpdu_len)
00245 return 0;
00246
00247
00248
00249
00250
00251 if (payl_offset + sizeof_b(struct amsdu_hdr) <= NX_RX_PAYLOAD_LEN)
00252 {
00253 subfrm_len_addr = pd->pbd.datastartptr + payl_offset + 2 * MAC_ADDR_LEN;
00254 }
00255 else
00256 {
00257 uint16_t offset = payl_offset + 2 * MAC_ADDR_LEN - NX_RX_PAYLOAD_LEN;
00258 struct rx_payloaddesc *pd_tmp = (struct rx_payloaddesc *)HW2CPU(pd->pbd.next);
00259
00260 subfrm_len_addr = pd_tmp->pbd.datastartptr + offset;
00261 }
00262
00263
00264 subfrm_len = co_ntohs(co_read16(HW2CPU(subfrm_len_addr))) + sizeof_b(struct amsdu_hdr);
00265
00266
00267 if ((subfrm_len > mpdu_len) || (subfrm_len > RX_MAX_AMSDU_SUBFRAME_LEN))
00268 return 0;
00269
00270
00271 if ((mpdu_len - subfrm_len) < 3)
00272
00273
00274 subfrm_len = mpdu_len;
00275 else
00276
00277 subfrm_len = CO_ALIGN4_HI(subfrm_len);
00278
00279 return subfrm_len;
00280 }
00281 #endif
00282
00292 static bool rxl_rxcntrl_frame(struct rxdesc* rxdesc)
00293 {
00294 bool handled = true;
00295 struct rx_dmadesc *dma_hdrdesc = rxl_dmadesc_get(rxdesc);
00296
00297
00298 if (dma_hdrdesc->hd.frmlen != 0)
00299 {
00300 uint16_t framectrl;
00301 #if NX_AMPDU_TX
00302 uint32_t statinfo;
00303 #endif
00304 struct rx_pbd *pd = HW2CPU(dma_hdrdesc->hd.first_pbd_ptr);
00305
00306
00307
00308 if (rx_hwdesc_env.monitor_en)
00309 return false;
00310
00311
00312 ASSERT_REC_VAL(pd != NULL, true);
00313
00314
00315 framectrl = co_read16(HW2CPU(pd->datastartptr));
00316
00317 #if NX_AMPDU_TX
00318
00319 statinfo = dma_hdrdesc->hd.statinfo;
00320 #endif
00321
00322
00323 switch(framectrl & MAC_FCTRL_TYPESUBTYPE_MASK)
00324 {
00325 #if NX_AMPDU_TX
00326 case MAC_FCTRL_BA :
00327
00328 if ((statinfo & (RX_HD_RSP_FRM | RX_HD_SUCCESS)) ==
00329 (RX_HD_RSP_FRM | RX_HD_SUCCESS))
00330 {
00331
00332 txl_ba_push(rxdesc);
00333 }
00334 break;
00335 #endif
00336 #if NX_MAC_HE
00337 case MAC_FCTRL_HE_TRIGGER :
00338
00339 if (statinfo & RX_HD_SUCCESS)
00340 {
00341 txl_he_trigger_push(rxdesc);
00342 }
00343 break;
00344 #endif
00345 default:
00346
00347 handled = false;
00348 break;
00349 }
00350 }
00351 else
00352 {
00353
00354 ASSERT_REC_VAL(dma_hdrdesc->hd.first_pbd_ptr == 0, true);
00355 }
00356
00357
00358 if (handled)
00359 {
00360
00361 if (rxdesc->dma_hdrdesc->hd.first_pbd_ptr != 0)
00362 {
00363 rxdesc->spare_pbd = HW2CPU(rxdesc->dma_hdrdesc->hd.first_pbd_ptr);
00364
00365
00366 rx_hwdesc_env.first = HW2CPU(rxdesc->spare_pbd->next);
00367 }
00368 else
00369 {
00370 rxdesc->spare_pbd = NULL;
00371 }
00372 rxdesc->last_pbd = NULL;
00373
00374
00375 if (rxdesc->spare_pbd != NULL)
00376 {
00377
00378 rxl_pd_append(NULL, NULL, rxdesc->spare_pbd);
00379 }
00380
00381
00382 rxl_hd_append(rxdesc->dma_hdrdesc);
00383 }
00384 return (handled);
00385 }
00386
00412 static struct rx_payloaddesc *rxl_payload_transfer(struct rx_payloaddesc **curr_pd,
00413 uint16_t upload_len, uint32_t hostbuf,
00414 uint16_t *payl_offset, int dma_idx,
00415 int irq_en)
00416 {
00417 uint16_t dma_len;
00418 struct dma_desc *dma_desc;
00419 struct dma_desc *first_dma_desc;
00420 struct rx_payloaddesc *pd = *curr_pd;
00421 struct rx_payloaddesc *prev_pd = NULL;
00422 uint16_t payl_off = *payl_offset;
00423
00424
00425 dma_desc = &pd->dma_desc[dma_idx];
00426
00427 first_dma_desc = dma_desc;
00428
00429
00430 while (1)
00431 {
00432 struct dma_desc *dma_desc_next;
00433
00434
00435 dma_desc->dest = hostbuf;
00436 dma_desc->src = pd->pbd.datastartptr + payl_off;
00437
00438
00439 if ((upload_len + payl_off) < NX_RX_PAYLOAD_LEN)
00440 {
00441
00442 dma_len = upload_len;
00443
00444 #if NX_AMSDU_DEAGG
00445
00446 payl_off += upload_len;
00447 #endif
00448 }
00449 else
00450 {
00451
00452 dma_len = NX_RX_PAYLOAD_LEN - payl_off;
00453
00454
00455 payl_off = 0;
00456 }
00457
00458
00459 dma_desc->length = dma_len;
00460
00461
00462 dma_desc->ctrl = RX_LLICTRL(0);
00463
00464
00465 hostbuf += dma_len;
00466
00467
00468 upload_len -= dma_len;
00469
00470
00471 if (upload_len == 0)
00472 {
00473 break;
00474 }
00475
00476
00477 prev_pd = pd;
00478 pd = (struct rx_payloaddesc *)HW2CPU(pd->pbd.next);
00479 dma_desc_next = &pd->dma_desc[0];
00480
00481
00482 ASSERT_ERR(pd != NULL);
00483
00484
00485 dma_desc->next = CPU2HW(dma_desc_next);
00486
00487
00488 dma_desc = dma_desc_next;
00489 }
00490
00491
00492 dma_desc->ctrl = RX_LLICTRL(irq_en);
00493
00494
00495 dma_push(first_dma_desc, dma_desc, RX_DATA_UPLOAD_CHAN);
00496
00497 *curr_pd = pd;
00498 *payl_offset = payl_off;
00499
00500 return prev_pd;
00501 }
00502
00503 #if NX_AMSDU_DEAGG
00504
00523 static struct rx_payloaddesc *rxl_amsdu_deagg(struct rx_dmadesc *dma_hdrdesc,
00524 struct rx_payloaddesc **curr_pd,
00525 uint16_t mpdu_len, uint32_t hostbuf,
00526 uint16_t payl_offset)
00527 {
00528 int dma_idx = 0;
00529 int msdu_idx = 0;
00530 uint16_t upload_len;
00531 struct rx_payloaddesc *pd = *curr_pd;
00532 struct rx_payloaddesc *prev_pd = NULL;
00533
00534
00535 memset(dma_hdrdesc->amsdu_hostids, 0, sizeof(dma_hdrdesc->amsdu_hostids));
00536
00537
00538
00539 upload_len = rxl_amsdu_subframe_len_get(pd, payl_offset, mpdu_len);
00540
00541 while (1)
00542 {
00543 prev_pd = rxl_payload_transfer(&pd, upload_len, hostbuf, &payl_offset, dma_idx, 0);
00544 mpdu_len -= upload_len;
00545
00546
00547 if ((mpdu_len != 0) && macif_rx_buf_check())
00548 {
00549
00550
00551 if (payl_offset)
00552 {
00553
00554 dma_idx++;
00555
00556 if (dma_idx >= NX_DMADESC_PER_RX_PDB_CNT)
00557 break;
00558 }
00559 else
00560 {
00561
00562 prev_pd = pd;
00563 pd = (struct rx_payloaddesc *)HW2CPU(pd->pbd.next);
00564
00565
00566 ASSERT_ERR(pd != NULL);
00567
00568 dma_idx = 0;
00569 }
00570
00571 upload_len = rxl_amsdu_subframe_len_get(pd, payl_offset, mpdu_len);
00572
00573
00574 if (upload_len == 0)
00575 break;
00576
00577
00578 hostbuf = macif_rx_buf_get(&dma_hdrdesc->amsdu_hostids[msdu_idx++]) +
00579 RXL_PAYLOAD_OFFSET;
00580 }
00581 else
00582 break;
00583 }
00584
00585 *curr_pd = pd;
00586
00587 return prev_pd;
00588 }
00589 #endif // NX_AMSDU_DEAGG
00590
00603 static void rxl_go_to_last_rbd(struct rxdesc *rxdesc, struct rx_payloaddesc *pd,
00604 struct rx_payloaddesc *prev_pd)
00605 {
00606
00607 while (1)
00608 {
00609 uint32_t statinfo = pd->pbd.bufstatinfo;
00610
00611
00612 if (statinfo & RX_PD_LASTBUF)
00613 break;
00614
00615
00616 prev_pd = pd;
00617 pd = (struct rx_payloaddesc *)HW2CPU(pd->pbd.next);
00618
00619
00620 ASSERT_REC(pd != NULL);
00621 };
00622
00623
00624 rxdesc->last_pbd = &prev_pd->pbd;
00625 rxdesc->spare_pbd = &pd->pbd;
00626
00627
00628 rx_hwdesc_env.first = HW2CPU(rxdesc->spare_pbd->next);
00629 }
00630
00631 void rxl_hwdesc_init(void)
00632 {
00633 uint32_t i;
00634
00635
00636 memset(&rx_hwdesc_env, 0, sizeof(rx_hwdesc_env));
00637
00638
00639 for (i = 0; i < NX_RXDESC_CNT; i++)
00640 {
00641
00642 rx_dma_hdrdesc[i].hd.datastartptr = 0;
00643 rx_dma_hdrdesc[i].hd.dataendptr = 0;
00644
00645
00646 rx_dma_hdrdesc[i].hd.upatternrx = RX_HEADER_DESC_PATTERN;
00647
00648
00649 rx_dma_hdrdesc[i].hd.statinfo = 0;
00650
00651
00652 rx_dma_hdrdesc[i].hd.headerctrlinfo = 0;
00653
00654
00655 rx_dma_hdrdesc[i].hd.next = CPU2HW(&rx_dma_hdrdesc[i + 1].hd);
00656
00657
00658 rx_dma_hdrdesc[i].hd.first_pbd_ptr = 0;
00659
00660
00661 rx_dma_hdrdesc[i].hd.rxdesc = &rx_swdesc_tab[i];
00662
00663
00664 rx_dma_hdrdesc[i].hd.frmlen = 0;
00665
00666
00667 rx_dma_hdrdesc[i].dma_desc.src = CPU2HW(&rx_dma_hdrdesc[i].hd.frmlen);
00668 rx_dma_hdrdesc[i].dma_desc.length = RXL_HEADER_INFO_LEN;
00669
00670
00671 rx_swdesc_tab[i].dma_hdrdesc = &rx_dma_hdrdesc[i];
00672 rx_swdesc_tab[i].upload_cntrl.rxdesc = &rx_swdesc_tab[i];
00673 }
00674
00675
00676 rx_dma_hdrdesc[NX_RXDESC_CNT - 1].hd.next = 0;
00677
00678
00679 nxmac_rx_header_head_ptr_set(CPU2HW(&rx_dma_hdrdesc[1].hd));
00680
00681
00682 nxmac_dma_cntrl_set(NXMAC_RX_HEADER_NEW_HEAD_BIT);
00683
00684
00685
00686 ASSERT_ERR((CPU2HW(&rx_payload_desc[0].buffer) & WORD_ALIGN) == 0);
00687
00688 for (i = 0 ; i < NX_RX_PAYLOAD_DESC_CNT ; i++)
00689 {
00690 struct rx_payloaddesc *desc = &rx_payload_desc[i];
00691 struct rx_pbd *pbd = &desc->pbd;
00692
00693 pbd->next = CPU2HW(&rx_payload_desc[i+1].pbd);
00694
00695
00696 pbd->upattern = RX_PAYLOAD_DESC_PATTERN;
00697
00698
00699 pbd->bufstatinfo = 0;
00700
00701
00702 pbd->datastartptr = CPU2HW(&(desc->buffer[0]));
00703 pbd->dataendptr = pbd->datastartptr + NX_RX_PAYLOAD_LEN - 1;
00704 }
00705
00706
00707 rx_payload_desc[NX_RX_PAYLOAD_DESC_CNT - 1].pbd.next = 0;
00708
00709
00710 nxmac_rx_payload_head_ptr_set(CPU2HW(&rx_payload_desc[1].pbd));
00711
00712
00713 nxmac_dma_cntrl_set(NXMAC_RX_PAYLOAD_NEW_HEAD_BIT);
00714
00715
00716 nxmac_rx_trigger_timer_pack(NX_RX_PAYLOAD_DESC_CNT/4, 1, 10);
00717
00718
00719 rx_hwdesc_env.free_dmadesc = &rx_dma_hdrdesc[0];
00720 rx_hwdesc_env.first_dmadesc = &rx_dma_hdrdesc[1];
00721 rx_hwdesc_env.last_dmadesc = &rx_dma_hdrdesc[NX_RXDESC_CNT - 1];
00722
00723
00724 rx_hwdesc_env.free = &rx_payload_desc[0].pbd;
00725 rx_hwdesc_env.first = &rx_payload_desc[1].pbd;
00726 rx_hwdesc_env.last = &rx_payload_desc[NX_RX_PAYLOAD_DESC_CNT - 1].pbd;
00727
00728 co_list_init(&rx_hwdesc_env.ready);
00729 }
00730
00731 void rxl_hwdesc_monitor(bool enable)
00732 {
00733
00734
00735 rx_hwdesc_env.monitor_en = enable;
00736 }
00737
00738 void rxl_frame_release(struct rxdesc* rxdesc)
00739 {
00740
00741 GLOBAL_INT_DISABLE();
00742
00743
00744 rxl_pd_append(HW2CPU(rxdesc->dma_hdrdesc->hd.first_pbd_ptr), rxdesc->last_pbd, rxdesc->spare_pbd);
00745
00746
00747 rxl_hd_append(rxdesc->dma_hdrdesc);
00748
00749
00750 GLOBAL_INT_RESTORE();
00751 }
00752
00753 void rxl_mpdu_copy(struct rx_pbd *pbd, uint16_t length, uint16_t offset, uint32_t *dst)
00754 {
00755 uint16_t dst_offset = 0;
00756 uint32_t *src;
00757 while (length)
00758 {
00759 uint16_t copy_len;
00760 if (length < (NX_RX_PAYLOAD_LEN - offset))
00761 copy_len = length;
00762 else
00763 copy_len = NX_RX_PAYLOAD_LEN - offset;
00764
00765 src = HW2CPU(pbd->datastartptr + offset);
00766 co_copy32(dst + dst_offset/4, src, copy_len);
00767
00768 length -= copy_len;
00769 offset = 0;
00770 dst_offset += copy_len;
00771 pbd = HW2CPU(pbd->next);
00772 ASSERT_ERR(pbd != NULL);
00773 }
00774 }
00775
00776 void rxl_mpdu_partial_transfer(struct rxdesc *rxdesc, uint16_t upload_len,
00777 uint32_t hostbuf, uint16_t payl_offset,
00778 cb_rx_dma_func_ptr cb, void *env)
00779 {
00780 struct rx_dmadesc *dma_hdrdesc = rxl_dmadesc_get(rxdesc);
00781 struct rx_payloaddesc *pd = HW2CPU(dma_hdrdesc->hd.first_pbd_ptr);
00782 struct rx_payloaddesc *prev_pd = NULL;
00783
00784
00785 RX_MPDU_XFER_SET();
00786
00787
00788 prev_pd = rxl_payload_transfer(&pd, upload_len, hostbuf, &payl_offset, 0, 1);
00789
00790
00791 rxl_go_to_last_rbd(rxdesc, pd, prev_pd);
00792
00793
00794 RX_MPDU_XFER_CLR();
00795
00796
00797 rxdesc->upload_cntrl.cb = cb;
00798 rxdesc->upload_cntrl.env = env;
00799
00800
00801 rxl_upload_cntrl_push_pending(&rxdesc->upload_cntrl);
00802 }
00803
00804 void rxl_mpdu_transfer(struct rxdesc *rxdesc)
00805 {
00806 #if (NX_UMAC_PRESENT)
00807 struct rx_cntrl_rx_status *rx_status = &rxu_cntrl_env.rx_status;
00808 uint16_t payl_offset = rx_status->payl_offset;
00809 #else
00810 uint16_t payl_offset = 0;
00811 #endif
00812 uint32_t hostbuf, hostbuf_start;
00813 struct dma_desc *dma_desc;
00814 struct rx_dmadesc *dma_hdrdesc = rxl_dmadesc_get(rxdesc);
00815 uint16_t mpdu_len;
00816 struct rx_payloaddesc *pd;
00817 struct rx_payloaddesc *prev_pd = NULL;
00818
00819
00820 RX_MPDU_XFER_SET();
00821
00822
00823 pd = (struct rx_payloaddesc *)HW2CPU(dma_hdrdesc->hd.first_pbd_ptr);
00824
00825
00826 #if (NX_UMAC_PRESENT)
00827 hostbuf_start = macif_rx_buf_get(&rxu_cntrl_env.hostid_current);
00828 #else
00829 hostbuf_start = macif_rx_buf_get();
00830 #endif //(NX_UMAC_PRESENT)
00831
00832
00833 hostbuf = hostbuf_start + RXL_PAYLOAD_OFFSET;
00834
00835
00836 mpdu_len = dma_hdrdesc->hd.frmlen;
00837
00838
00839 ASSERT_REC(mpdu_len != 0);
00840
00841 ASSERT_REC(mpdu_len <= RWNX_MAX_AMSDU_RX);
00842
00843 #if NX_AMSDU_DEAGG
00844
00845 if (dma_hdrdesc->flags & RX_FLAGS_IS_AMSDU_BIT)
00846 {
00847
00848
00849 prev_pd = rxl_amsdu_deagg(dma_hdrdesc, &pd, mpdu_len, hostbuf, payl_offset);
00850 }
00851 else
00852 #endif
00853 {
00854
00855
00856 prev_pd = rxl_payload_transfer(&pd, mpdu_len, hostbuf, &payl_offset, 0, 0);
00857
00858 #if (NX_UMAC_PRESENT)
00859
00860 rx_status->host_buf_addr = hostbuf + mpdu_len;
00861 #endif
00862 }
00863
00864
00865 phy_get_channel(&dma_hdrdesc->phy_info, PHY_PRIM);
00866
00867
00868
00869 dma_hdrdesc->pattern = DMA_HD_RXPATTERN;
00870
00871 dma_desc = &dma_hdrdesc->dma_desc;
00872
00873 dma_desc->next = CPU2HW(&dma_hdrdesc->dma_desc);
00874
00875
00876 dma_desc->dest = hostbuf_start;
00877
00878 #if NX_UMAC_PRESENT && !NX_FULLY_HOSTED
00879
00880 dma_desc->ctrl = RX_LLICTRL(0);
00881 #else
00882
00883 dma_desc->ctrl = RX_LLICTRL(1);
00884 #endif //NX_UMAC_PRESENT && !NX_FULLY_HOSTED
00885
00886
00887 dma_push(dma_desc, dma_desc, RX_DATA_UPLOAD_CHAN);
00888
00889
00890 rxl_go_to_last_rbd(rxdesc, pd, prev_pd);
00891
00892
00893 RX_MPDU_XFER_CLR();
00894
00895 #if NX_FULLY_HOSTED || !NX_UMAC_PRESENT
00896
00897 rxl_upload_cntrl_push_pending(&rxdesc->upload_cntrl);
00898 #endif
00899 }
00900
00901 void rxl_mpdu_free(struct rxdesc *rxdesc)
00902 {
00903 struct rx_payloaddesc *pd;
00904 struct rx_payloaddesc *prev_pd = NULL;
00905 struct rx_dmadesc *dma_hdrdesc = rxl_dmadesc_get(rxdesc);
00906
00907 RX_MPDU_FREE_SET();
00908
00909
00910 pd = (struct rx_payloaddesc *)HW2CPU(dma_hdrdesc->hd.first_pbd_ptr);
00911
00912
00913 rxl_go_to_last_rbd(rxdesc, pd, prev_pd);
00914
00915
00916 rxl_frame_release(rxdesc);
00917
00918 RX_MPDU_FREE_CLR();
00919 }
00920
00921 struct rxdesc *rxl_rxdesc_get(void)
00922 {
00923
00924 return ((struct rxdesc *)co_list_pick(&rx_hwdesc_env.ready));
00925 }
00926
00927 void rxl_rxdesc_ready_for_processing(struct rxdesc *rxdesc)
00928 {
00929
00930 GLOBAL_INT_DISABLE();
00931 co_list_pop_front(&rx_hwdesc_env.ready);
00932 GLOBAL_INT_RESTORE();
00933 }
00934
00935 void rxl_mpdu_isr(void)
00936 {
00937 struct rx_dmadesc *dma_hdrdesc;
00938 struct rxdesc *rxdesc;
00939
00940
00941 PROF_RX_MAC_IRQ_SET();
00942
00943
00944 nxmac_tx_rx_int_ack_clear(NXMAC_TIMER_RX_TRIGGER_BIT | NXMAC_COUNTER_RX_TRIGGER_BIT);
00945
00946 while (1)
00947 {
00948
00949 if ((rx_hwdesc_env.first_dmadesc == NULL) ||
00950 (!RX_HD_DONE_GET(rx_hwdesc_env.first_dmadesc->hd.statinfo)))
00951 break;
00952
00953
00954 dma_hdrdesc = rx_hwdesc_env.first_dmadesc;
00955
00956
00957 rxdesc = dma_hdrdesc->hd.rxdesc;
00958
00959
00960
00961 rx_hwdesc_env.first_dmadesc = (struct rx_dmadesc*)HW2CPU(dma_hdrdesc->hd.next);
00962
00963
00964 if (!rxl_rxcntrl_frame(rxdesc))
00965 {
00966
00967 #if NX_FULLY_HOSTED
00968 rxdesc->upload_cntrl.cb = NULL;
00969 #else
00970 rxdesc->upload_cntrl.cb = rxl_host_irq_mitigation_update;
00971 #endif
00972 rxdesc->upload_cntrl.env = NULL;
00973
00974 co_list_push_back(&rx_hwdesc_env.ready, &rxdesc->upload_cntrl.list_hdr);
00975 }
00976 }
00977
00978
00979 if (!co_list_is_empty(&rx_hwdesc_env.ready))
00980 {
00981 if (macif_rx_buf_check())
00982 {
00983 ke_evt_set(KE_EVT_RXREADY_BIT);
00984 }
00985 }
00986
00987
00988 PROF_RX_MAC_IRQ_CLR();
00989 }
00990
00991 void rxl_immediate_frame_get(void)
00992 {
00993 rxl_mpdu_isr();
00994 }
00995
00996 void rxl_current_desc_get(struct rx_hd **rhd, struct rx_pbd **rbd)
00997 {
00998
00999 *rhd = &(rx_hwdesc_env.free_dmadesc->hd);
01000
01001
01002 *rbd = rx_hwdesc_env.free;
01003 }
01004