00001
00019
00020
00021
00022
00023 #include "co_int.h"
00024
00025 #include "co_bool.h"
00026
00027 #include <string.h>
00028
00029 #include "compiler.h"
00030
00031 #include "rxl_cntrl.h"
00032
00033 #include "ke_event.h"
00034
00035 #include "mac_frame.h"
00036
00037 #include "ps.h"
00038 #include "sta_mgmt.h"
00039 #include "vif_mgmt.h"
00040
00041 #include "macif.h"
00042
00043 #include "dma.h"
00044
00045 #include "hal_machw.h"
00046
00047 #include "mm.h"
00048
00049 #include "rxl_hwdesc.h"
00050
00051 #include "dbg.h"
00052
00053 #include "mac_ie.h"
00054
00055 #if (NX_P2P)
00056
00057 #include "p2p.h"
00058 #endif //(NX_P2P)
00059
00060 #if (NX_TD)
00062 #include "td.h"
00063 #endif //(NX_TD)
00064
00065 #if (RW_BFMER_EN)
00067 #include "bfr.h"
00068 #endif //(RW_BFMER_EN)
00069
00070 #if (NX_REORD)
00071 #include "mac_frame.h"
00072 #endif //(NX_REORD)
00073
00074 #if (NX_UMAC_PRESENT)
00075 #include "rxu_cntrl.h"
00076 #include "apm.h"
00077 #endif
00078
00080 #include "tdls.h"
00081
00082
00083
00084
00085
00087 #define RX_TIMEOUT 200
00088
00090 #define RX_FRAME_PREP_THD 4
00091
00092
00093
00094
00095
00096 struct rxl_cntrl_env_tag rxl_cntrl_env;
00097
00098
00099
00100
00101
00109 __INLINE struct rx_upload_cntrl_tag *rxl_upload_cntrl_pick_pending(void)
00110 {
00111 return ((struct rx_upload_cntrl_tag *)co_list_pick(&rxl_cntrl_env.upload_pending));
00112 }
00113
00121 __INLINE struct rx_upload_cntrl_tag *rxl_upload_cntrl_pop_pending(void)
00122 {
00123 return ((struct rx_upload_cntrl_tag *)co_list_pop_front(&rxl_cntrl_env.upload_pending));
00124 }
00125
00137 static bool rxl_lli_done(uint16_t next_lli_cnt)
00138 {
00139 return (((uint16_t)(dma_lli_counter_get(IPC_DMA_LLI_DATA_RX0) - (next_lli_cnt)))
00140 < (((uint16_t)-1) / 2));
00141 }
00142
00143 #if (NX_RX_FRAME_HANDLING)
00144 #if (NX_UMAC_PRESENT || NX_P2P_GO)
00145
00157 static void rxl_pm_check(uint8_t *frame, uint8_t sta_idx, uint8_t vif_idx)
00158 {
00159 struct vif_info_tag *vif = &vif_info_tab[vif_idx];
00160 struct sta_info_tag *sta = &sta_info_tab[sta_idx];
00161 uint16_t frame_ctrl;
00162
00163
00164 if (vif->type != VIF_AP)
00165 return;
00166
00167 #if (!NX_UMAC_PRESENT)
00168 if (!vif->p2p)
00169 return;
00170 #endif //(!NX_UMAC_PRESENT)
00171
00172
00173 frame_ctrl = co_read16(frame);
00174
00175
00176 if (sta->ps_state == PS_MODE_ON)
00177 {
00178
00179
00180 uint16_t test_val = frame_ctrl & (MAC_FCTRL_TYPE_MASK |
00181 MAC_FCTRL_PWRMGT | MAC_FCTRL_MOREFRAG);
00182 if ((test_val == MAC_FCTRL_DATA_T) || (test_val == MAC_FCTRL_MGT_T))
00183 {
00184 #if (NX_UMAC_PRESENT)
00185 PROF_PS_PEER_STATE_SET();
00186 PROF_PS_STATE_VAL_SET(PS_MODE_OFF);
00187
00188 TRACE_AP(PS, "{VIF-%d} {STA-%d} exit PS mode", vif_idx, sta_idx);
00189 mm_ps_change_ind(sta_idx, PS_MODE_OFF);
00190 #if NX_BEACONING
00191 apm_tx_int_ps_clear(vif, sta_idx);
00192 #endif // NX_BEACONING
00193 PROF_PS_PEER_STATE_CLR();
00194 #else
00195 sta->ps_state = PS_MODE_OFF;
00196 #endif //(NX_UMAC_PRESENT)
00197
00198
00199 vif->u.ap.ps_sta_cnt--;
00200
00201 #if (NX_UMAC_PRESENT)
00202 if (!vif->u.ap.ps_sta_cnt)
00203 {
00204 PROF_PS_BCMC_STATE_SET();
00205 PROF_PS_STATE_VAL_SET(PS_MODE_OFF);
00206 TRACE_AP(PS, "{VIF-%d} disable PS on broadcast/multicast STA", vif_idx);
00207 mm_ps_change_ind(VIF_TO_BCMC_IDX(vif_idx), PS_MODE_OFF);
00208 #if NX_BEACONING
00209 apm_tx_int_ps_clear(vif, VIF_TO_BCMC_IDX(vif_idx));
00210 #endif // NX_BEACONING
00211 PROF_PS_BCMC_STATE_CLR();
00212 }
00213 #endif //(NX_UMAC_PRESENT)
00214
00215 #if (NX_P2P_GO)
00216 p2p_go_ps_state_update(vif);
00217 #endif //(NX_P2P_GO)
00218 return;
00219 }
00220
00221 #if (NX_UMAC_PRESENT)
00222
00223 if ((frame_ctrl & MAC_FCTRL_TYPESUBTYPE_MASK) == MAC_FCTRL_PSPOLL)
00224 {
00225 PROF_PS_PSPOLL_RX_SET();
00226 TRACE_AP(PS, "{VIF-%d} received PS-Poll from STA-%d", vif->index, sta_idx);
00227
00228 #if (NX_BEACONING)
00229 if (sta->traffic_avail & PS_TRAFFIC_INT)
00230 {
00231
00232 sta->ps_service_period |= PS_SERVICE_PERIOD;
00233 sta_mgmt_send_postponed_frame(vif, sta, 1);
00234 sta->ps_service_period &= ~PS_SERVICE_PERIOD;
00235 }
00236 else
00237 #endif // NX_BEACONING
00238 mm_traffic_req_ind(sta_idx, 1, false);
00239
00240 PROF_PS_PSPOLL_RX_CLR();
00241 }
00242
00243
00244 if ((frame_ctrl & (MAC_FCTRL_TYPE_MASK | MAC_QOS_ST_BIT)) ==
00245 (MAC_FCTRL_DATA_T | MAC_QOS_ST_BIT))
00246 {
00247 uint8_t tid;
00248
00249
00250 if ((frame_ctrl & (MAC_FCTRL_TODS | MAC_FCTRL_FROMDS)) ==
00251 (MAC_FCTRL_TODS | MAC_FCTRL_FROMDS))
00252 {
00253 struct mac_hdr_long_qos *hdr = (struct mac_hdr_long_qos *)frame;
00254
00255 tid = (hdr->qos & MAC_QOSCTRL_UP_MSK) >> MAC_QOSCTRL_UP_OFT;
00256 }
00257 else
00258 {
00259 struct mac_hdr_qos *hdr = (struct mac_hdr_qos *)frame;
00260
00261 tid = (hdr->qos & MAC_QOSCTRL_UP_MSK) >> MAC_QOSCTRL_UP_OFT;
00262 }
00263
00264
00265 if (mac_ac2uapsd[mac_tid2ac[tid]] & sta->info.uapsd_queues)
00266 {
00267 TRACE_AP(PS, "{VIF-%d} received UAPSD trigger from STA-%d sn=%d",
00268 vif->index, sta_idx,
00269 ((struct mac_hdr *)frame)->seq >> MAC_SEQCTRL_NUM_OFT);
00270
00271
00272
00273 if ((sta->traffic_avail & UAPSD_TRAFFIC) &&
00274 !(sta->ps_service_period & UAPSD_SERVICE_PERIOD))
00275 {
00276 int max_sp = sta->info.max_sp_len;
00277
00278 #if (NX_BEACONING)
00279
00280 if (sta->traffic_avail & UAPSD_TRAFFIC_INT)
00281 {
00282 int nb;
00283 sta->ps_service_period = UAPSD_SERVICE_PERIOD_INT;
00284 nb = sta_mgmt_send_postponed_frame(vif, sta, max_sp);
00285
00286 if (max_sp)
00287 {
00288 max_sp -= nb;
00289 if (!max_sp)
00290 max_sp = -1;
00291 }
00292 }
00293
00294 if (max_sp < 0 || !(sta->traffic_avail & UAPSD_TRAFFIC_HOST))
00295 {
00296
00297 uint16_t qos = MAC_QOSCTRL_EOSP | (tid << MAC_QOSCTRL_UP_OFT);
00298 TRACE_AP(PS, "{VIF-%d} SP completed by fw: send EOSP to STA-%d",
00299 vif->index, sta_idx);
00300 txl_frame_send_qosnull_frame(sta->staid, qos, NULL, NULL);
00301 sta->ps_service_period = NO_SERVICE_PERIOD;
00302 }
00303 else if (sta->traffic_avail & UAPSD_TRAFFIC_HOST)
00304 #endif // (NX_BEACONING)
00305 {
00306
00307 TRACE_AP(PS, "{VIF-%d} Ask host to complete SP for STA-%d",
00308 vif->index, sta_idx);
00309 sta->ps_service_period = UAPSD_SERVICE_PERIOD_HOST;
00310 mm_traffic_req_ind(sta_idx, max_sp, true);
00311 }
00312 }
00313 else if (!(sta->ps_service_period & UAPSD_SERVICE_PERIOD))
00314 {
00315
00316
00317 uint16_t qos = MAC_QOSCTRL_EOSP | (tid << MAC_QOSCTRL_UP_OFT);
00318 sta->ps_service_period = UAPSD_SERVICE_PERIOD_INT;
00319 txl_frame_send_qosnull_frame(sta->staid, qos, NULL, NULL);
00320 TRACE_AP(PS, "{VIF-%d} no data: send EOSP to STA-%d",
00321 vif->index, sta_idx);
00322 sta->ps_service_period = NO_SERVICE_PERIOD;
00323 }
00324 }
00325 }
00326 #endif //(NX_UMAC_PRESENT)
00327 }
00328 else
00329 {
00330
00331 uint16_t test_val = frame_ctrl & (MAC_FCTRL_TYPE_MASK |
00332 MAC_FCTRL_PWRMGT | MAC_FCTRL_MOREFRAG);
00333 if ((test_val == (MAC_FCTRL_DATA_T | MAC_FCTRL_PWRMGT)) ||
00334 (test_val == (MAC_FCTRL_MGT_T | MAC_FCTRL_PWRMGT)))
00335 {
00336 #if (NX_UMAC_PRESENT)
00337 PROF_PS_PEER_STATE_SET();
00338 PROF_PS_STATE_VAL_SET(PS_MODE_ON);
00339
00340 TRACE_AP(PS, "{VIF-%d} {STA-%d} enter PS mode", vif_idx, sta_idx);
00341 mm_ps_change_ind(sta_idx, PS_MODE_ON);
00342 PROF_PS_PEER_STATE_CLR();
00343
00344
00345 if (!vif->u.ap.ps_sta_cnt)
00346 {
00347 PROF_PS_BCMC_STATE_SET();
00348 PROF_PS_STATE_VAL_SET(PS_MODE_ON);
00349 TRACE_AP(PS, "{VIF-%d} enable PS on broadcast/multicast STA", vif_idx);
00350 mm_ps_change_ind(VIF_TO_BCMC_IDX(vif_idx), PS_MODE_ON);
00351 PROF_PS_BCMC_STATE_CLR();
00352 }
00353 #else
00354 sta->ps_state = PS_MODE_ON;
00355 #endif //(NX_UMAC_PRESENT)
00356
00357
00358 vif->u.ap.ps_sta_cnt++;
00359
00360 #if (NX_P2P_GO)
00361 p2p_go_ps_state_update(vif);
00362 #endif //(NX_P2P_GO)
00363 return;
00364 }
00365 }
00366 }
00367 #endif //(NX_UMAC_PRESENT || NX_P2P_GO)
00368
00380 static uint8_t rxl_frame_handle(struct rxdesc* rxdesc, bool *dont_free)
00381 {
00382 struct sta_info_tag *sta;
00383 struct rx_dmadesc *dma_hdrdesc = rxl_dmadesc_get(rxdesc);
00384 struct rx_hd *rhd = &dma_hdrdesc->hd;
00385 struct rx_pbd *pd;
00386 uint32_t statinfo;
00387 uint16_t key_idx_hw;
00388 uint8_t sta_idx;
00389 struct vif_info_tag *vif;
00390 uint8_t *frame;
00391 uint16_t framectrl;
00392 bool upload = true;
00393
00394 do
00395 {
00396
00397 if (!rhd->frmlen)
00398 return false;
00399
00400
00401 ASSERT_REC_VAL(rhd->first_pbd_ptr != 0, false);
00402
00403
00404 pd = HW2CPU(rhd->first_pbd_ptr);
00405
00406
00407 statinfo = rhd->statinfo;
00408
00409
00410 frame = HW2CPU(pd->datastartptr);
00411
00412
00413 framectrl = co_read16(frame);
00414
00415
00416 if ((statinfo & (RX_HD_KEYIDV | RX_HD_SUCCESS)) != (RX_HD_KEYIDV | RX_HD_SUCCESS))
00417 {
00418 TRACE_LMAC(RX_ALL, "from unknown STA: SN=%d %fc",
00419 ((struct mac_hdr *)frame)->seq >> MAC_SEQCTRL_NUM_OFT, framectrl);
00420 break;
00421 }
00422
00423
00424 key_idx_hw = (uint16_t)RX_HD_KEYID_GET(statinfo);
00425
00426
00427 ASSERT_REC_VAL(key_idx_hw >= MM_SEC_DEFAULT_KEY_COUNT, false);
00428
00429
00430 sta_idx = MM_KEY_TO_STA(key_idx_hw);
00431
00432
00433 if (!sta_mgmt_is_valid(sta_idx))
00434 {
00435 rhd->statinfo &= ~RX_HD_KEYIDV;
00436 TRACE_LMAC(RX_ALL, "from invalid STA-%d: SN=%d %fc", sta_idx,
00437 ((struct mac_hdr *)frame)->seq >> MAC_SEQCTRL_NUM_OFT, framectrl);
00438 break;
00439 }
00440
00441
00442 frame = HW2CPU(pd->datastartptr);
00443
00444
00445 framectrl = co_read16(frame);
00446
00447
00448 sta = &sta_info_tab[sta_idx];
00449
00450
00451
00452 if (sta->aid == STA_REF_BSSID_AID)
00453 {
00454
00455
00456 if ((framectrl & MAC_FCTRL_TYPESUBTYPE_MASK) != MAC_FCTRL_BEACON)
00457 {
00458 rhd->statinfo &= ~RX_HD_KEYIDV;
00459 break;
00460 }
00461
00462
00463
00464
00465 sta = sta->linked_sta;
00466 rhd->statinfo &= ~RX_HD_KEYID;
00467 rhd->statinfo |= MM_STA_TO_KEY(sta->staid) << RX_HD_KEYID_LSB;
00468 }
00469
00470
00471 vif = &vif_info_tab[sta->inst_nbr];
00472
00473 TRACE_LMAC(RX, "{VIF-%d} from STA-%d: SN=%d %fc", sta->inst_nbr, sta_idx,
00474 ((struct mac_hdr *)frame)->seq >> MAC_SEQCTRL_NUM_OFT, framectrl);
00475
00476 #if (NX_UMAC_PRESENT || NX_P2P_GO)
00477 rxl_pm_check(frame, sta_idx, vif->index);
00478 #endif //(NX_UMAC_PRESENT || NX_P2P_GO)
00479
00480 #if (RW_BFMER_EN)
00481 {
00482 uint8_t bfr_status = (bfr_is_enabled()) ? bfr_rx_frame_ind(sta_idx, rxdesc, frame)
00483 : BFR_RX_STATUS_NOT_VALID;
00484
00485 if (bfr_status != BFR_RX_STATUS_NOT_VALID)
00486 {
00487
00488 upload = false;
00489
00490 if (bfr_status == BFR_RX_STATUS_VALID)
00491 {
00492 *dont_free = true;
00493 }
00494
00495 break;
00496 }
00497 }
00498 #endif //(RW_BFMER_EN)
00499
00500
00501 if (!vif->active)
00502 break;
00503
00504 #if (NX_TD)
00505 if (((framectrl & MAC_FCTRL_TYPE_MASK) == MAC_FCTRL_DATA_T) ||
00506 ((framectrl & MAC_FCTRL_TYPE_MASK) == MAC_FCTRL_MGT_T))
00507 {
00508 td_pck_ind(vif->index, sta_idx, true);
00509 }
00510 #endif //(NX_TD)
00511
00512
00513 if (vif->type == VIF_STA)
00514 {
00515
00516 if ((framectrl & MAC_FCTRL_TYPESUBTYPE_MASK) == MAC_FCTRL_BEACON)
00517 {
00518 #if NX_POWERSAVE || NX_CONNECTION_MONITOR || NX_MULTI_ROLE
00519 uint32_t tim = 0;
00520 #endif
00521
00522 TRACE_STA(BCN, "{VIF-%d} Beacon received sn=%d", vif->index,
00523 ((struct mac_hdr *)frame)->seq >> MAC_SEQCTRL_NUM_OFT);
00524
00525 #if NX_CONNECTION_MONITOR || NX_MULTI_ROLE
00526
00527 upload = mm_check_beacon(rhd, vif, sta, &tim);
00528 #elif NX_POWERSAVE
00529 tim = mac_ie_tim_find(pd->datastartptr + MAC_BEACON_VARIABLE_PART_OFT,
00530 rhd->frmlen - MAC_BEACON_VARIABLE_PART_OFT);
00531 #endif
00532
00533 #if NX_POWERSAVE
00534
00535 ps_check_beacon(tim, rhd->frmlen, vif);
00536 #endif
00537
00538 #if (NX_P2P || NX_CHNL_CTXT)
00539 vif_mgmt_bcn_recv(vif);
00540 #endif //(NX_P2P || NX_CHNL_CTXT)
00541
00542 #if (NX_P2P)
00543 if (upload)
00544 {
00545
00546 p2p_cli_bcn_check_noa(vif, pd, dma_hdrdesc);
00547 }
00548 #endif //(NX_P2P)
00549 }
00550 else if (((framectrl & MAC_FCTRL_TYPE_MASK) == MAC_FCTRL_DATA_T) ||
00551 ((framectrl & MAC_FCTRL_TYPE_MASK) == MAC_FCTRL_MGT_T))
00552 {
00553 #if NX_POWERSAVE
00554
00555 ps_check_frame(frame, statinfo, vif);
00556 #endif
00557
00558 #if (NX_P2P)
00559 if (vif->p2p)
00560 {
00561 if ((framectrl & MAC_FCTRL_TYPESUBTYPE_MASK) == MAC_FCTRL_ACTION)
00562 {
00563 p2p_cli_handle_action(vif, pd->datastartptr, rhd->frmlen, rhd->tsflo);
00564 }
00565 }
00566 #endif //(NX_P2P)
00567
00568 #if NX_UMAC_PRESENT && NX_TDLS
00569
00570 if (sta->is_tdls)
00571 {
00572 upload = tdls_check_frame(frame, vif, sta_idx);
00573 }
00574 #endif // NX_UMAC_PRESENT && NX_TDLS
00575 }
00576 }
00577 #if (RW_UMESH_EN)
00578 else if (vif->type == VIF_MESH_POINT)
00579 {
00580
00581 if ((framectrl & MAC_FCTRL_TYPESUBTYPE_MASK) == MAC_FCTRL_BEACON)
00582 {
00583 uint32_t tim;
00584
00585
00586 tim = mac_ie_tim_find(pd->datastartptr + MAC_BEACON_VARIABLE_PART_OFT,
00587 rhd->frmlen - MAC_BEACON_VARIABLE_PART_OFT);
00588 mm_tbtt_compute((struct bcn_frame *)frame, rhd->frmlen, rhd, vif,
00589 sta, tim);
00590
00591
00592 mesh_ps_rx_beacon_handle(vif->index, sta_idx,
00593 pd->datastartptr, rhd->frmlen);
00594
00595
00596 upload = false;
00597 }
00598 }
00599 #endif //(RW_UMESH_EN)
00600 } while (0);
00601
00602 return (upload);
00603 }
00604 #endif //(NX_RX_FRAME_HANDLING)
00605
00611 static void rxl_cntrl_init(void)
00612 {
00613
00614 co_list_init(&rxl_cntrl_env.upload_pending);
00615
00616
00617 rxl_cntrl_env.bridgedmacnt = dma_lli_counter_get(IPC_DMA_LLI_DATA_RX0);
00618 #if !NX_FULLY_HOSTED
00619 rxl_cntrl_env.packet_thd = macif_rx_get_packet_threshold() - 1;
00620 rxl_cntrl_env.packet_cnt = rxl_cntrl_env.packet_thd;
00621 #endif
00622 }
00623
00624 #if !NX_FULLY_HOSTED
00625
00633 static void rxl_host_irq_mitigation_timeout_set(void)
00634 {
00635
00636 if (rxl_cntrl_env.packet_cnt != rxl_cntrl_env.packet_thd)
00637 {
00638
00639 nxmac_abs_timer_set(HAL_RX_TIMER, hal_machw_time() + RX_TIMEOUT);
00640 nxmac_timers_int_event_clear(HAL_RX_TIMER_BIT);
00641 nxmac_timers_int_un_mask_set(nxmac_timers_int_un_mask_get() | HAL_RX_TIMER_BIT);
00642 }
00643 }
00644
00645 void rxl_host_irq_mitigation_update(void *env)
00646 {
00647
00648 rxl_cntrl_env.packet_cnt++;
00649
00650
00651 if (rxl_cntrl_env.packet_cnt > rxl_cntrl_env.packet_thd)
00652 {
00653
00654 macif_rx_data_ind();
00655 rxl_cntrl_env.packet_cnt = 0;
00656 }
00657 }
00658
00659 void rxl_timeout_int_handler(void)
00660 {
00661
00662
00663 if (rxl_cntrl_env.packet_cnt > 0)
00664 {
00665
00666 macif_rx_data_ind();
00667 }
00668
00669
00670
00671 rxl_cntrl_env.packet_cnt = rxl_cntrl_env.packet_thd;
00672
00673
00674 nxmac_timers_int_un_mask_set(nxmac_timers_int_un_mask_get() & ~HAL_RX_TIMER_BIT);
00675 }
00676 #endif
00677
00678 void rxl_init(void)
00679 {
00680
00681 rxl_hwdesc_init();
00682
00683
00684 rxl_cntrl_init();
00685
00686 #if NX_UMAC_PRESENT
00687
00688 rxu_cntrl_init();
00689 #endif
00690 }
00691
00692 void rxl_cntrl_evt(int dummy)
00693 {
00694 struct rxdesc *rxdesc;
00695 #if NX_RX_FRAME_HANDLING
00696 uint8_t upload;
00697 #endif
00698 int prep_cnt = 0;
00699
00700
00701 RX_CNTRL_EVT_SET();
00702
00703 while (1)
00704 {
00705
00706 rxdesc = rxl_rxdesc_get();
00707
00708 #if NX_RX_RING
00709
00710 nxmac_tx_rx_int_ack_clear(NXMAC_RX_BUFFER_1_TRIGGER_BIT);
00711 #endif
00712
00713
00714 ke_evt_clear(KE_EVT_RXREADY_BIT);
00715
00716
00717 if (rxdesc == NULL)
00718 break;
00719
00720
00721 if (prep_cnt >= RX_FRAME_PREP_THD)
00722 {
00723
00724 ke_evt_set(KE_EVT_RXREADY_BIT);
00725
00726
00727 RX_CNTRL_EVT_CLR();
00728 return;
00729 }
00730
00731 #if (NX_UMAC_PRESENT)
00732
00733 if (!macif_rx_buf_check()
00734 || !rxu_cntrl_desc_check())
00735 #else
00736
00737 if (!macif_rx_buf_check())
00738 #endif //(NX_UMAC_PRESENT)
00739 {
00740
00741
00742
00743 RX_CNTRL_EVT_CLR();
00744 return;
00745 }
00746
00747
00748 rxl_rxdesc_ready_for_processing(rxdesc);
00749
00750 do
00751 {
00752 #if (NX_RX_FRAME_HANDLING)
00753 bool dont_free = false;
00754
00755
00756 upload = rxl_frame_handle(rxdesc, &dont_free);
00757
00758 if (!upload)
00759 {
00760 if (!dont_free)
00761 {
00762
00763 rxl_mpdu_free(rxdesc);
00764 }
00765
00766 break;
00767 }
00768 #endif //(NX_RX_FRAME_HANDLING)
00769
00770 #if NX_UMAC_PRESENT
00771
00772 upload = rxu_cntrl_frame_handle(rxdesc);
00773 if (!upload)
00774 {
00775
00776 rxl_mpdu_free(rxdesc);
00777 break;
00778 }
00779 #else
00780
00781 rxl_mpdu_transfer(rxdesc);
00782 #endif
00783 } while (0);
00784
00785
00786 prep_cnt++;
00787 }
00788
00789 #if NX_RX_RING
00790 nxmac_enable_rx_buffer_1_trigger_setf(1);
00791 #endif
00792
00793
00794 RX_CNTRL_EVT_CLR();
00795 }
00796
00797 void rxl_dma_int_handler(void)
00798 {
00799
00800 PROF_RX_DMA_IRQ_SET();
00801
00802
00803 dma_lli_disable(IPC_DMA_LLI_DATA_RX0 + DMA_LLI_IRQ_LSB);
00804
00805
00806 dma_int_ack_clear(CO_BIT(IPC_DMA_LLI_DATA_RX0 + DMA_LLI_IRQ_LSB));
00807
00808 ke_evt_set(KE_EVT_RXUPLOADED_BIT);
00809
00810
00811 PROF_RX_DMA_IRQ_CLR();
00812 }
00813
00814 void rxl_dma_evt(int dummy)
00815 {
00816 struct rx_upload_cntrl_tag *upload_cntrl = rxl_upload_cntrl_pick_pending();
00817
00818
00819 PROF_RX_DMA_EVT_SET();
00820
00821 ke_evt_clear(KE_EVT_RXUPLOADED_BIT);
00822
00823
00824 dma_int_ack_clear(CO_BIT(IPC_DMA_LLI_DATA_RX0 + DMA_LLI_IRQ_LSB));
00825
00826 while (upload_cntrl)
00827 {
00828 struct rxdesc *rxdesc;
00829
00830 #if NX_RX_RING
00831
00832
00833
00834 if ((upload_cntrl->flags & RX_NO_UPLOAD) == 0)
00835 #endif
00836 {
00837
00838 uint16_t next_lli_cnt = rxl_cntrl_env.bridgedmacnt + 1;
00839
00840
00841 if (!rxl_lli_done(next_lli_cnt))
00842 {
00843 break;
00844 }
00845
00846
00847
00848 dma_int_ack_clear(CO_BIT(IPC_DMA_LLI_DATA_RX0 + DMA_LLI_IRQ_LSB));
00849
00850
00851 rxl_cntrl_env.bridgedmacnt = next_lli_cnt;
00852 }
00853
00854
00855 rxl_upload_cntrl_pop_pending();
00856
00857
00858 GLOBAL_INT_DISABLE();
00859
00860
00861 if (upload_cntrl->cb)
00862 upload_cntrl->cb(upload_cntrl->env);
00863
00864 rxdesc = upload_cntrl->rxdesc;
00865 if (rxdesc)
00866 {
00867
00868 rxl_frame_release(rxdesc);
00869 }
00870
00871
00872 GLOBAL_INT_RESTORE();
00873
00874
00875 upload_cntrl = rxl_upload_cntrl_pick_pending();
00876 }
00877
00878 #if NX_FULLY_HOSTED
00879
00880 macif_rx_desc_upload(&rxu_cntrl_env.rxdesc_ready);
00881 #else
00882 rxl_host_irq_mitigation_timeout_set();
00883 #endif
00884
00885
00886 dma_lli_enable(IPC_DMA_LLI_DATA_RX0 + DMA_LLI_IRQ_LSB);
00887
00888
00889 PROF_RX_DMA_EVT_CLR();
00890 }
00891
00892 void rxl_reset(void)
00893 {
00894 struct rx_upload_cntrl_tag *upload_cntrl = rxl_upload_cntrl_pick_pending();
00895
00896 while (upload_cntrl)
00897 {
00898
00899 uint16_t next_lli_cnt = rxl_cntrl_env.bridgedmacnt + 1;
00900
00901
00902 while (!rxl_lli_done(next_lli_cnt));
00903
00904
00905 rxl_upload_cntrl_pop_pending();
00906
00907
00908 if (upload_cntrl->cb)
00909 upload_cntrl->cb(upload_cntrl->env);
00910
00911 #if !NX_FULLY_HOSTED
00912
00913 macif_rx_data_ind();
00914 #endif
00915
00916
00917 rxl_cntrl_env.bridgedmacnt = next_lli_cnt;
00918
00919
00920 upload_cntrl = rxl_upload_cntrl_pick_pending();
00921 }
00922
00923 #if NX_FULLY_HOSTED
00924
00925 macif_rx_desc_upload(&rxu_cntrl_env.rxdesc_ready);
00926 #endif
00927
00928
00929 dma_int_ack_clear(CO_BIT(IPC_DMA_LLI_DATA_RX0 + DMA_LLI_IRQ_LSB));
00930
00931
00932 rxl_hwdesc_init();
00933 }
00934
00935