- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# /space/home/slher/rel/Beken/v6_4_5/macsw/ip/lmac/src/rx/rxl/rxl_cntrl.c

Go to the documentation of this file.

    00001
    00019 /*
    00020  * INCLUDE FILES
    00021  ****************************************************************************************
    00022  */
    00023 #include "co_int.h"
    00024 // For bool
    00025 #include "co_bool.h"
    00026 // For NULL
    00027 #include <string.h>
    00028 // For INLINE
    00029 #include "compiler.h"
    00030 // RX control inclusions
    00031 #include "rxl_cntrl.h"
    00032 // For KE Event calls
    00033 #include "ke_event.h"
    00034 // For frame type
    00035 #include "mac_frame.h"
    00036 // For power-save processing
    00037 #include "ps.h"
    00038 #include "sta_mgmt.h"
    00039 #include "vif_mgmt.h"
    00040 // Communication with upper layers
    00041 #include "macif.h"
    00042 // IPC DMA descriptor allocation
    00043 #include "dma.h"
    00044 // IPC host buffer allocation
    00045 #include "hal_machw.h"
    00046 // STA Info table
    00047 #include "mm.h"
    00048 // Function prototypes and HW desc macros
    00049 #include "rxl_hwdesc.h"
    00050 // For debug functions
    00051 #include "dbg.h"
    00052 // For IE access functions
    00053 #include "mac_ie.h"
    00054
    00055 #if (NX_P2P)
    00056 // P2P Definitions and Functions
    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  * DEFINES
    00084  ****************************************************************************************
    00085  */
    00087 #define RX_TIMEOUT       200
    00088
    00090 #define RX_FRAME_PREP_THD     4
    00091
    00092 /*
    00093  * GLOBAL VARIABLES
    00094  ****************************************************************************************
    00095  */
    00096 struct rxl_cntrl_env_tag rxl_cntrl_env;
    00097
    00098 /*
    00099  * FUNCTION DEFINITIONS
    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     // Check the PM state only in AP mode
    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     // Get the frame control field from the packet
    00173     frame_ctrl = co_read16(frame);
    00174
    00175     // Check if the station is in PS or not
    00176     if (sta->ps_state == PS_MODE_ON)
    00177     {
    00178         // Check if the peer device is waking up: PWRMGMT bit and MOREFRAG bit have to
    00179         // be set to 0 in a Data or Management frame
    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             // Indicate the PS mode change to the upper layers
    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             // Update the number of PS stations
    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         // Check if the received frame shall trigger some transmissions from us
    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                 // U-APSD service period may be already on going
    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         // Check if the received frame shall trigger some transmissions from us
    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             // Get the TID
    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                 // Get the QoS control field in the frame and the TID
    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                 // Get the QoS control field in the frame and the TID
    00261                 tid = (hdr->qos & MAC_QOSCTRL_UP_MSK) >> MAC_QOSCTRL_UP_OFT;
    00262             }
    00263
    00264             // Check if the received frame is a UAPSD trigger frame
    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                 // Check if UAPSD traffic is available and
    00272                 // no SP is already ongoing
    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                     // First transmit internal frames if any
    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                         // If no more space or no host traffic end service period.
    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                         // Ask host for packets
    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                     // No traffic available. Reply with a QoS NULL frame
    00316                     // indicating the end of service period
    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         // Check if the peer device is going to sleep
    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             // Indicate the PS mode change to the upper layers
    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             // Update the number of PS stations
    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             // Update the number of PS stations
    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         // Ensure the packet has a length
    00397         if (!rhd->frmlen)
    00398             return false;
    00399
    00400         // Sanity check: frames with length not NULL have at least 1 buffer descriptor
    00401         ASSERT_REC_VAL(rhd->first_pbd_ptr != 0, false);
    00402
    00403         // Get value of the buffer descriptor pointer
    00404         pd = HW2CPU(rhd->first_pbd_ptr);
    00405
    00406         // Get the status information from the RX header descriptor
    00407         statinfo = rhd->statinfo;
    00408
    00409         // Get the pointer to the frame data
    00410         frame = HW2CPU(pd->datastartptr);
    00411
    00412         // Get the frame control
    00413         framectrl = co_read16(frame);
    00414
    00415         // Check if the frame comes from a known device and is valid
    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         // Get the HW key index
    00424         key_idx_hw = (uint16_t)RX_HD_KEYID_GET(statinfo);
    00425
    00426         // Sanity check
    00427         ASSERT_REC_VAL(key_idx_hw >= MM_SEC_DEFAULT_KEY_COUNT, false);
    00428
    00429         // Retrieve the station index and instance number
    00430         sta_idx = MM_KEY_TO_STA(key_idx_hw);
    00431
    00432         // Check if the STA is registered
    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         // Get the pointer to the frame data
    00442         frame = HW2CPU(pd->datastartptr);
    00443
    00444         // Get the frame control
    00445         framectrl = co_read16(frame);
    00446
    00447         // Retrieve the associated STA entry
    00448         sta = &sta_info_tab[sta_idx];
    00449
    00450         // Check if we received this packet from the reference BSSID, while we are
    00451         // connected to a nonTransmittedBSSID of the same Multiple BSSID set
    00452         if (sta->aid == STA_REF_BSSID_AID)
    00453         {
    00454             // We received such a packet - we handle only the beacon case, because we
    00455             // need to synchronize our TBTT and check the TIM element on this beacon
    00456             if ((framectrl & MAC_FCTRL_TYPESUBTYPE_MASK) != MAC_FCTRL_BEACON)
    00457             {
    00458                 rhd->statinfo &= ~RX_HD_KEYIDV;
    00459                 break;
    00460             }
    00461
    00462             // Replace the key index and station pointer by the one of the nonTransmitted
    00463             // BSSID - This will allow handling the beacon as if it would have been sent
    00464             // by our BSSID
    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         // Retrieve the associated VIF entry
    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                 // Frame is well a beamforming report, not needed to upload the whole frame.
    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         // Check if this STA interface is associated with an AP
    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         // Check if this interface is a STA or a MP interface
    00513         if (vif->type == VIF_STA)
    00514         {
    00515             // Decode the frame control to know if we have to handle the frame internally
    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                 // Let the MM handle the connection monitoring procedures
    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                 // Let the PS module check if it has something to do with this beacon
    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                     // Look for NOA Attribute only if beacon has been modified
    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                 // Let the PS module check if it has something to do with this frame
    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                 // Check if the frame comes from a TDLS STA and if TDLS STA exists
    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             // Decode the frame control to know if we have to handle the frame internally
    00581             if ((framectrl & MAC_FCTRL_TYPESUBTYPE_MASK) == MAC_FCTRL_BEACON)
    00582             {
    00583                 uint32_t tim;
    00584
    00585                 // Extract the TIM
    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                 // Provide the beacon to the Mesh PS Module
    00592                 mesh_ps_rx_beacon_handle(vif->index, sta_idx,
    00593                                          pd->datastartptr, rhd->frmlen);
    00594
    00595                 // Do not upload the beacon
    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     // List for frames pending for upload.
    00614     co_list_init(&rxl_cntrl_env.upload_pending);
    00615
    00616     // Initialize the bridge DMA counts
    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     // Check if we need to trigger an interrupt to the host
    00636     if (rxl_cntrl_env.packet_cnt != rxl_cntrl_env.packet_thd)
    00637     {
    00638         // Restart the RX IRQ mitigation timeout
    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     // Update the uploaded packet count
    00648     rxl_cntrl_env.packet_cnt++;
    00649
    00650     // Check if we need to trigger an interrupt to the host
    00651     if (rxl_cntrl_env.packet_cnt > rxl_cntrl_env.packet_thd)
    00652     {
    00653         // Indicate the packets to the host
    00654         macif_rx_data_ind();
    00655         rxl_cntrl_env.packet_cnt = 0;
    00656     }
    00657 }
    00658
    00659 void rxl_timeout_int_handler(void)
    00660 {
    00661     // Current A-MPDU reception is considered as finished
    00662     // Check if we have some packets to indicate to the host
    00663     if (rxl_cntrl_env.packet_cnt > 0)
    00664     {
    00665         // Some packets are available, so indicate them
    00666         macif_rx_data_ind();
    00667     }
    00668
    00669     // Reset the packet counter in order to force the host to be warned upon the next
    00670     // A-MPDU reception start
    00671     rxl_cntrl_env.packet_cnt = rxl_cntrl_env.packet_thd;
    00672
    00673     // Disable the RX timeout interrupt
    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     // initialize the header descriptors
    00681     rxl_hwdesc_init();
    00682
    00683     // initialize the RX environment
    00684     rxl_cntrl_init();
    00685
    00686     #if NX_UMAC_PRESENT
    00687     // initialize the RXU environment
    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     // for profiling
    00701     RX_CNTRL_EVT_SET();
    00702
    00703     while (1)
    00704     {
    00705         // Pick the first SW descriptor ready for processing
    00706         rxdesc = rxl_rxdesc_get();
    00707
    00708         #if NX_RX_RING
    00709         // clear the interrupt
    00710         nxmac_tx_rx_int_ack_clear(NXMAC_RX_BUFFER_1_TRIGGER_BIT);
    00711         #endif
    00712
    00713         // Clear the kernel event
    00714         ke_evt_clear(KE_EVT_RXREADY_BIT);
    00715
    00716         // Check if we still have ready descriptors
    00717         if (rxdesc == NULL)
    00718             break;
    00719
    00720         // Check if we reached the threshold for DMA interrupt handling
    00721         if (prep_cnt >= RX_FRAME_PREP_THD)
    00722         {
    00723             // Set the kernel event to handle next frames immediately after the DMA
    00724             ke_evt_set(KE_EVT_RXREADY_BIT);
    00725
    00726             // for profiling
    00727             RX_CNTRL_EVT_CLR();
    00728             return;
    00729         }
    00730
    00731         #if (NX_UMAC_PRESENT)
    00732         // Check if a host buffer and a descriptor are available for DMA transfer
    00733         if (!macif_rx_buf_check()
    00734          || !rxu_cntrl_desc_check())
    00735         #else
    00736         // Check if a host buffer is available for DMA transfer
    00737         if (!macif_rx_buf_check())
    00738         #endif //(NX_UMAC_PRESENT)
    00739         {
    00740             // No host buffers available, so stop the handling of this packet.
    00741             // The IPC will then call again the RX data handler once a buffer is available
    00742             // for profiling
    00743             RX_CNTRL_EVT_CLR();
    00744             return;
    00745         }
    00746
    00747         // Upload is possible, indicate that the RX descriptor will be processed
    00748         rxl_rxdesc_ready_for_processing(rxdesc);
    00749
    00750         do
    00751         {
    00752             #if (NX_RX_FRAME_HANDLING)
    00753             bool dont_free = false;
    00754
    00755             // Check if the packet is of interest for the LMAC
    00756             upload = rxl_frame_handle(rxdesc, &dont_free);
    00757
    00758             if (!upload)
    00759             {
    00760                 if (!dont_free)
    00761                 {
    00762                     // No need to upload this packet, free it immediately
    00763                     rxl_mpdu_free(rxdesc);
    00764                 }
    00765
    00766                 break;
    00767             }
    00768             #endif //(NX_RX_FRAME_HANDLING)
    00769
    00770             #if NX_UMAC_PRESENT
    00771             // Perform the UMAC related handling
    00772             upload = rxu_cntrl_frame_handle(rxdesc);
    00773             if (!upload)
    00774             {
    00775                 // No need to upload this packet, free it immediately
    00776                 rxl_mpdu_free(rxdesc);
    00777                 break;
    00778             }
    00779             #else
    00780             // Try to upload the frame
    00781             rxl_mpdu_transfer(rxdesc);
    00782             #endif
    00783         } while (0);
    00784
    00785         // Increase the counter
    00786         prep_cnt++;
    00787     }
    00788
    00789     #if NX_RX_RING
    00790     nxmac_enable_rx_buffer_1_trigger_setf(1);
    00791     #endif
    00792
    00793     // for profiling
    00794     RX_CNTRL_EVT_CLR();
    00795 }
    00796
    00797 void rxl_dma_int_handler(void)
    00798 {
    00799     // For profiling
    00800     PROF_RX_DMA_IRQ_SET();
    00801
    00802     // Disable DMA IRQ for the RX. It will be reenabled by the associated event
    00803     dma_lli_disable(IPC_DMA_LLI_DATA_RX0 + DMA_LLI_IRQ_LSB);
    00804
    00805     // Acknowledge the interrupt
    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     // For profiling
    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     // For profiling
    00819     PROF_RX_DMA_EVT_SET();
    00820
    00821     ke_evt_clear(KE_EVT_RXUPLOADED_BIT);
    00822
    00823     // Acknowledge the interrupt at least once in case no SW descriptor is pending
    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         // When a RX ring buffer is used, the freeing of buffers must be done in order.
    00832         // We might get here buffers that were not uploaded to upper layers and therefore
    00833         // did not trigger any LLI counter increment, but that we need to free anyway.
    00834         if ((upload_cntrl->flags & RX_NO_UPLOAD) == 0)
    00835         #endif
    00836         {
    00837             // Compute the target LLI count of the current descriptor
    00838             uint16_t next_lli_cnt = rxl_cntrl_env.bridgedmacnt + 1;
    00839
    00840             // if there are no more descriptors to handle
    00841             if (!rxl_lli_done(next_lli_cnt))
    00842             {
    00843                 break;
    00844             }
    00845
    00846             // Acknowledge the interrupt each time we get an LLI done to avoid getting it
    00847             // again later
    00848             dma_int_ack_clear(CO_BIT(IPC_DMA_LLI_DATA_RX0 + DMA_LLI_IRQ_LSB));
    00849
    00850             // increment the handled LLI counter
    00851             rxl_cntrl_env.bridgedmacnt = next_lli_cnt;
    00852         }
    00853
    00854         // Pop the descriptor
    00855         rxl_upload_cntrl_pop_pending();
    00856
    00857         // Both HW descriptor release and access on packet_cnt need to be protected
    00858         GLOBAL_INT_DISABLE();
    00859
    00860         // Call the appropriate function
    00861         if (upload_cntrl->cb)
    00862             upload_cntrl->cb(upload_cntrl->env);
    00863
    00864         rxdesc = upload_cntrl->rxdesc;
    00865         if (rxdesc)
    00866         {
    00867             // Release the descriptors associated with this SW descriptor
    00868             rxl_frame_release(rxdesc);
    00869         }
    00870
    00871         // Re-enable the interrupts
    00872         GLOBAL_INT_RESTORE();
    00873
    00874         // Handle next descriptor
    00875         upload_cntrl = rxl_upload_cntrl_pick_pending();
    00876     }
    00877
    00878     #if NX_FULLY_HOSTED
    00879     // Forward the RX descriptors that are ready for that
    00880     macif_rx_desc_upload(&rxu_cntrl_env.rxdesc_ready);
    00881     #else
    00882     rxl_host_irq_mitigation_timeout_set();
    00883     #endif
    00884
    00885     // Enable DMA LLI RX IRQ to get an interrupt once payloads are transfered
    00886     dma_lli_enable(IPC_DMA_LLI_DATA_RX0 + DMA_LLI_IRQ_LSB);
    00887
    00888     // For profiling
    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         // Compute the target LLI count of the current descriptor
    00899         uint16_t next_lli_cnt = rxl_cntrl_env.bridgedmacnt + 1;
    00900
    00901         // Wait for the DMA transfer to be finished
    00902         while (!rxl_lli_done(next_lli_cnt));
    00903
    00904         // Pop the descriptor
    00905         rxl_upload_cntrl_pop_pending();
    00906
    00907         // Call the appropriate function
    00908         if (upload_cntrl->cb)
    00909             upload_cntrl->cb(upload_cntrl->env);
    00910
    00911         #if !NX_FULLY_HOSTED
    00912         // call the LMAC-UMAC interface function to handle the frame
    00913         macif_rx_data_ind();
    00914         #endif
    00915
    00916         // increment the handled LLI counter
    00917         rxl_cntrl_env.bridgedmacnt = next_lli_cnt;
    00918
    00919         // handle next descriptor
    00920         upload_cntrl = rxl_upload_cntrl_pick_pending();
    00921     }
    00922
    00923     #if NX_FULLY_HOSTED
    00924     // Forward the RX descriptors that are ready for that
    00925     macif_rx_desc_upload(&rxu_cntrl_env.rxdesc_ready);
    00926     #endif
    00927
    00928     // Acknowledge the DMA interrupt
    00929     dma_int_ack_clear(CO_BIT(IPC_DMA_LLI_DATA_RX0 + DMA_LLI_IRQ_LSB));
    00930
    00931     // Re-initialize the HW descriptor lists
    00932     rxl_hwdesc_init();
    00933 }
    00934
    00935