- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# /space/home/slher/rel/Beken/v6_4_5/macsw/ip/lmac/src/hal/hal_machw.c

Go to the documentation of this file.

    00001
    00021 /*
    00022  * INCLUDE FILES
    00023  ****************************************************************************************
    00024  */
    00025 #include "dbg_assert.h"
    00026
    00027 #include "co_endian.h"
    00028 #include "mm.h"
    00029 #include "ke_event.h"
    00030
    00031 #include "hal_machw.h"
    00032
    00033 #include "rxl_cntrl.h"
    00034 #include "rxl_hwdesc.h"
    00035
    00036 #include "reg_mac_core.h"
    00037 #include "reg_mac_pl.h"
    00038
    00039 #include "ps.h"
    00040
    00041 #include "dbg.h"
    00042
    00043 #include "macif.h"
    00044 #include "crm.h"
    00045
    00047 #define HW_ERROR_IRQ (NXMAC_RX_FIFO_OVER_FLOW_BIT | NXMAC_MAC_PHYIF_OVERFLOW_BIT |      \
    00048                       NXMAC_PT_ERROR_BIT | NXMAC_HW_ERR_BIT | NXMAC_PHY_ERR_BIT |       \
    00049                       NXMAC_AC_0_TX_DMA_DEAD_BIT | NXMAC_AC_1_TX_DMA_DEAD_BIT |         \
    00050                       NXMAC_AC_2_TX_DMA_DEAD_BIT | NXMAC_AC_3_TX_DMA_DEAD_BIT |         \
    00051                       NXMAC_BCN_TX_DMA_DEAD_BIT | NXMAC_MAC_PHYIF_UNDER_RUN_BIT |       \
    00052                       NXMAC_RX_HEADER_DMA_DEAD_BIT | NXMAC_RX_PAYLOAD_DMA_DEAD_BIT)
    00053
    00055 #if NX_MAC_HE
    00056 #define HE_TIMER_BIT HAL_HE_TB_TIMER_BIT
    00057 #else
    00058 #define HE_TIMER_BIT 0
    00059 #endif
    00060
    00062 #define TIMEOUT_IRQ  (HAL_AC0_TIMER_BIT | HAL_AC1_TIMER_BIT | HAL_AC2_TIMER_BIT |       \
    00063                       HAL_AC3_TIMER_BIT | HAL_BCN_TIMER_BIT | HAL_IDLE_TIMER_BIT |      \
    00064                       HE_TIMER_BIT)
    00065
    00067 #if NX_AMSDU_TX
    00068 #define TX_IRQ (NXMAC_AC_0_TX_TRIGGER_BIT | NXMAC_AC_1_TX_TRIGGER_BIT |                 \
    00069                 NXMAC_AC_2_TX_TRIGGER_BIT | NXMAC_AC_3_TX_TRIGGER_BIT |                 \
    00070                 NXMAC_BCN_TX_TRIGGER_BIT | NXMAC_AC_0_TX_BUF_TRIGGER_BIT |              \
    00071                 NXMAC_AC_1_TX_BUF_TRIGGER_BIT | NXMAC_AC_2_TX_BUF_TRIGGER_BIT |         \
    00072                 NXMAC_AC_3_TX_BUF_TRIGGER_BIT | NXMAC_BCN_TX_BUF_TRIGGER_BIT | MU_MIMO_MASTER_TX_IRQ)
    00073 #else
    00074 #define TX_IRQ (NXMAC_AC_0_TX_TRIGGER_BIT | NXMAC_AC_1_TX_TRIGGER_BIT |                 \
    00075                 NXMAC_AC_2_TX_TRIGGER_BIT | NXMAC_AC_3_TX_TRIGGER_BIT |                 \
    00076                 NXMAC_BCN_TX_TRIGGER_BIT | MU_MIMO_MASTER_TX_IRQ)
    00077 #endif
    00078
    00079 #if NX_RX_RING
    00081 #define NXMAC_ENCR_RX_FIFO_RESET_BIT 0
    00083 #define RX_IRQ (NXMAC_RX_BUFFER_1_TRIGGER_BIT)
    00084 #else
    00086 #define RX_IRQ (NXMAC_COUNTER_RX_TRIGGER_BIT | NXMAC_TIMER_RX_TRIGGER_BIT)
    00087 #endif
    00088
    00090 #if (NX_BW_LEN_ADAPT)
    00091 #define BW_DROP_IRQ (NXMAC_AC_0BW_DROP_TRIGGER_BIT | NXMAC_AC_1BW_DROP_TRIGGER_BIT |    \
    00092                      NXMAC_AC_2BW_DROP_TRIGGER_BIT | NXMAC_AC_3BW_DROP_TRIGGER_BIT)
    00093 #else
    00094 #define BW_DROP_IRQ  0
    00095 #endif
    00096
    00098 #define MAC_HW_RESET (NXMAC_HW_FSM_RESET_BIT | NXMAC_RX_FIFO_RESET_BIT |                \
    00099                       NXMAC_TX_FIFO_RESET_BIT | NXMAC_MAC_PHYIFFIFO_RESET_BIT |         \
    00100                       NXMAC_ENCR_RX_FIFO_RESET_BIT)
    00101
    00103 #define IDLE_REQ_TIMEOUT  50000
    00104
    00115 #define TIMING_UPDATE(param, old, new)                                         \
    00116                      (nxmac_ ## param ## _in_mac_clk_setf((uint32_t)           \
    00117                                         nxmac_ ## param ## _in_mac_clk_getf()  \
    00118                                           * (uint32_t)(new) / (uint32_t)(old)))
    00119
    00120 #if NX_MULTI_ROLE
    00122 const uint8_t rxv2macrate[] = {
    00123     0,                          /* 0 */
    00124     1,                          /* 1 */
    00125     2,                          /* 2 */
    00126     3,                          /* 3 */
    00127     -1,                         /* 4 */
    00128     -1,                         /* 5 */
    00129     -1,                         /* 6 */
    00130     -1,                         /* 7 */
    00131     10,                         /* 8 */
    00132     8,                          /* 9 */
    00133     6,                          /* 10 */
    00134     4,                          /* 11 */
    00135     11,                         /* 12 */
    00136     9,                          /* 13 */
    00137     7,                          /* 14 */
    00138     5                           /* 15 */
    00139 };
    00140 #endif
    00141
    00142 /*
    00143  * FUNCTION DEFINITIONS
    00144  ****************************************************************************************
    00145  */
    00156 static void hal_machw_idle_irq_handler(void)
    00157 {
    00158     // Sanity check: Ensure that the HW is effectively in IDLE state
    00159     ASSERT_REC(nxmac_current_state_getf() == HW_IDLE);
    00160
    00161     // For profiling
    00162     PROF_MM_HW_IDLE_CLR();
    00163
    00164     // Disable the go to IDLE timer interrupt
    00165     nxmac_timers_int_un_mask_set(nxmac_timers_int_un_mask_get() & ~HAL_IDLE_TIMER_BIT);
    00166
    00167     #if NX_POWERSAVE
    00168     // We can sleep again
    00169     ps_env.prevent_sleep &= ~PS_IDLE_REQ_PENDING;
    00170     #endif
    00171
    00172     // Trigger the IDLE state event
    00173     ke_evt_set(KE_EVT_HW_IDLE_BIT);
    00174 }
    00175
    00183 static void hal_machw_setfreq(uint8_t newfreq)
    00184 {
    00185     uint8_t oldfreq;
    00186
    00187     oldfreq = nxmac_mac_core_clk_freq_getf();
    00188
    00189     // TIMINGS_1
    00190     nxmac_mac_core_clk_freq_setf(newfreq);
    00191     TIMING_UPDATE(tx_rf_delay, oldfreq, newfreq);
    00192     TIMING_UPDATE(tx_chain_delay, oldfreq, newfreq);
    00193     #if NX_MAC_HE
    00194     // Temporary - Will have to be removed once MAC HW has the correct default value
    00195     nxmac_tx_chain_delay_in_mac_clk_setf(0x112);
    00196     #endif
    00197
    00198     // TIMINGS_2
    00199     TIMING_UPDATE(slot_time, oldfreq, newfreq);
    00200
    00201     // TIMINGS_3
    00202     TIMING_UPDATE(rx_rf_delay, oldfreq, newfreq);
    00203     #if !NX_MAC_HE
    00204     TIMING_UPDATE(tx_delay_rf_on, oldfreq, newfreq);
    00205     #endif
    00206     TIMING_UPDATE(mac_proc_delay, oldfreq, newfreq);
    00207
    00208     // TIMINGS_4
    00209     if (newfreq<30)
    00210         // WTClk running at 3x macCoreClk freq
    00211         nxmac_wt_2_crypt_clk_ratio_setf(3);
    00212     else if (newfreq<60)
    00213         // WTClk running at 2x macCoreClk freq
    00214         nxmac_wt_2_crypt_clk_ratio_setf(2);
    00215     else
    00216         // WTClk running at macCoreClk freq
    00217         nxmac_wt_2_crypt_clk_ratio_setf(1);
    00218
    00219     // TIMINGS_5
    00220     TIMING_UPDATE(sifs_b, oldfreq, newfreq);
    00221
    00222     // TIMINGS_6
    00223     TIMING_UPDATE(sifs_a, oldfreq, newfreq);
    00224
    00225     // TIMINGS_7
    00226     // Nothing to do
    00227
    00228     // TIMINGS_8
    00229     // Nothing to do
    00230
    00231     // TIMINGS_9
    00232     TIMING_UPDATE(rifs_to, oldfreq, newfreq);
    00233     #if !NX_MAC_HE
    00234     TIMING_UPDATE(rifs, oldfreq, newfreq);
    00235     #endif
    00236     TIMING_UPDATE(tx_dma_proc_dly, oldfreq, newfreq);
    00237 }
    00238
    00239 void hal_machw_idle_req(void)
    00240 {
    00241     uint32_t curr_time;
    00242
    00243     // Sanity check: HW state is not supposed to be IDLE to handle this request
    00244     ASSERT_REC(nxmac_current_state_getf() != HW_IDLE);
    00245
    00246     // For profiling
    00247     PROF_MM_HW_IDLE_SET();
    00248
    00249     // Enable timer irq
    00250     GLOBAL_INT_DISABLE();
    00251     curr_time = hal_machw_time();
    00252     nxmac_abs_timer_set(HAL_IDLE_TIMER, curr_time + IDLE_REQ_TIMEOUT);
    00253
    00254     nxmac_timers_int_event_clear(HAL_IDLE_TIMER_BIT);
    00255     nxmac_timers_int_un_mask_set(nxmac_timers_int_un_mask_get() | HAL_IDLE_TIMER_BIT);
    00256
    00257     // Request to MAC HW to switch to IDLE state
    00258     nxmac_next_state_setf(HW_IDLE);
    00259
    00260     #if NX_POWERSAVE
    00261     // Prevent from sleeping during the switch to IDLE
    00262     ps_env.prevent_sleep |= PS_IDLE_REQ_PENDING;
    00263     #endif
    00264
    00265     GLOBAL_INT_RESTORE();
    00266 }
    00267
    00268
    00269 void hal_machw_stop(void)
    00270 {
    00271     // Reset all the MAC HW state machines and registers
    00272     nxmac_soft_reset_setf(1);
    00273     while (nxmac_soft_reset_getf());
    00274 }
    00275
    00276 void hal_machw_init(void)
    00277 {
    00278     #if NX_MAC_HE
    00279     int8_t min, max;
    00280     #endif
    00281
    00282     // Soft Reset
    00283     nxmac_soft_reset_setf(1);
    00284     while (nxmac_soft_reset_getf());
    00285
    00286     // Update the timing registers of the MAC according to the MAC core clock
    00287     hal_machw_setfreq(crm_get_mac_freq());
    00288
    00289     // enable MAC HW general interrupt events
    00290     nxmac_gen_int_enable_set(NXMAC_MASTER_GEN_INT_EN_BIT | NXMAC_IDLE_INTERRUPT_BIT |
    00291                              NXMAC_ABS_GEN_TIMERS_BIT | HW_ERROR_IRQ);
    00292
    00293     #if !NX_MAC_HE
    00294     // On old MAC HW version this error could happen from time to time, but does not
    00295     // require any special handling from SW, so we disable it
    00296     nxmac_enable_mac_phyif_overflow_setf(0);
    00297     #endif
    00298
    00299     #if NX_MDM_VER >= 20
    00300     // delegate MPIF interface flow control to PHY
    00301     nxmac_rate_controller_mpif_setf(0);
    00302     #else
    00303     // On old versions of the Modem enable the rxEndForTiming Error Recovery
    00304     nxmac_rx_end_for_timing_err_rec_setf(1);
    00305     #endif
    00306
    00307     #if NX_KEY_RAM_CONFIG
    00308     ASSERT_ERR(MM_STA_TO_KEY(NX_REMOTE_STA_MAX - 1) <= nxmac_sta_key_max_index_getf());
    00309     nxmac_encr_ram_config_pack(NX_VIRT_DEV_MAX, MM_STA_TO_KEY(NX_REMOTE_STA_MAX - 1),
    00310                                MM_STA_TO_KEY(0));
    00311     #endif
    00312
    00313     // enable MAC HW TX and RX interrupt events
    00314     nxmac_tx_rx_int_enable_set(TX_IRQ | BW_DROP_IRQ | RX_IRQ | NXMAC_MASTER_TX_RX_INT_EN_BIT);
    00315
    00316     #if RW_MUMIMO_TX_EN
    00317     nxmac_sec_users_tx_int_event_un_mask_set(TX_SEC_IRQ_BITS | NXMAC_MASTER_SEC_USERS_TX_INT_EN_BIT);
    00318     #endif
    00319
    00320     // At initialization we are not supposed to reply to any frame (in case monitor mode
    00321     // would be used), so disable the auto-reply capabilities of the HW
    00322     nxmac_mac_cntrl_1_set(nxmac_mac_cntrl_1_get() | NXMAC_DISABLE_ACK_RESP_BIT |
    00323                                                     NXMAC_DISABLE_CTS_RESP_BIT |
    00324                                                     NXMAC_DISABLE_BA_RESP_BIT |
    00325                                                     NXMAC_ACTIVE_CLK_GATING_BIT |
    00326                                                     NXMAC_ENABLE_LP_CLK_SWITCH_BIT |
    00327                                                     NXMAC_RX_RIFS_EN_BIT);
    00328     #if NX_MAC_HE
    00329     // RIFS not supported in HE
    00330     nxmac_rx_rifs_en_setf(0);
    00331     #endif
    00332
    00333     // enable the RX flow control
    00334     nxmac_rx_flow_cntrl_en_setf(1);
    00335
    00336     // enable reception of all frames (i.e. monitor mode)
    00337     nxmac_rx_cntrl_set(MM_RX_FILTER_MONITOR);
    00338
    00339     // put default values of the beacon timings
    00340     nxmac_bcn_cntrl_1_pack(255, 1, HAL_MACHW_BCN_TX_DELAY_US / 128, 100);
    00341
    00342     // limit the maximum RX size to the maximum A-MSDU size we support
    00343     nxmac_max_rx_length_set(RWNX_MAX_AMSDU_RX);
    00344
    00345     // configure the EDCA control register
    00346     nxmac_edca_cntrl_pack(0, 0, 0, 0);
    00347
    00348     // Default power level
    00349     #if NX_MAC_HE
    00350     phy_get_rf_gain_capab(&max, &min);
    00351     nxmac_max_power_level_pack(min, max, max);
    00352     #else
    00353     nxmac_max_power_level_pack(0x20, 0x20);
    00354     #endif
    00355
    00356     // reset MIB Table
    00357     nxmac_mib_table_reset_setf(1);
    00358
    00359     // reset Key storage RAM
    00360     nxmac_key_sto_ram_reset_setf(1);
    00361
    00362     // Initialize diagnostic ports
    00363     nxmac_debug_port_sel_pack(0x1C, 0x25);
    00364
    00365     // Enable the dynamic bandwidth feature
    00366     nxmac_dyn_bw_en_setf(1);
    00367
    00368     // Set the number of TX chains the HW shall use for immediate responses
    00369     nxmac_max_phy_ntx_setf(phy_get_ntx() + 1);
    00370
    00371     #if NX_MULTI_ROLE
    00372     // If Multi-role is enabled, the SW manages by itself the STA TSF. It it
    00373     // therefore necessary to disable the corresponding HW feature.
    00374     nxmac_tsf_mgt_disable_setf(1);
    00375     #endif
    00376
    00377     #if RW_BFMEE_EN
    00378     // Check if beamformee is supported by the MAC HW and PHY
    00379     if (hal_machw_bfmee_support())
    00380     {
    00381         // Initialize beamformee registers
    00382         nxmac_bfmee_nc_setf(phy_get_nss());
    00383         nxmac_bfmee_nr_setf(3);
    00384         nxmac_bfmee_codebook_setf(1);
    00385         nxmac_bfmee_enable_setf(1);
    00386         #if NX_MAC_HE
    00387         if (hal_machw_he_support())
    00388         {
    00389             nxmac_disable_svd_rx_pause_setf(1);
    00390             nxmac_bfr_format_mod_setf(FORMATMOD_HT_MF);
    00391         }
    00392         #endif
    00393         #if (RW_MUMIMO_RX_EN)
    00394         if (hal_machw_mu_mimo_rx_support())
    00395             nxmac_bfmee_mu_support_setf(1);
    00396         #endif
    00397     }
    00398     #endif
    00399 }
    00400
    00401 void hal_machw_disable_int(void)
    00402 {
    00403     nxmac_enable_master_gen_int_en_setf(0);
    00404     nxmac_enable_master_tx_rx_int_en_setf(0);
    00405 }
    00406
    00407 #if NX_DEBUG_DUMP
    00408 void hal_machw_get_diag_state(void)
    00409 {
    00410     int i;
    00411     uint8_t diag;
    00412     struct dbg_debug_info_tag *dbg_info = &(debug_info.dbg_info);
    00413
    00414     // Get RX status pointers
    00415     #if NX_RX_RING
    00416     dbg_info->rhd_hw_ptr = 0;
    00417     dbg_info->rbd_hw_ptr = 0;
    00418     #else
    00419     dbg_info->rhd_hw_ptr = nxmac_debug_rx_hdr_c_ptr_get();
    00420     dbg_info->rbd_hw_ptr = nxmac_debug_rx_pay_c_ptr_get();
    00421     #endif
    00422
    00423     // Get diagnostic port state for the MAC
    00424     diag = nxmac_debug_port_sel_1_getf();
    00425     for (i = 0; i < DBG_DIAGS_MAC_MAX; i++)
    00426     {
    00427         // Go through the different banks and copies the diag values
    00428         nxmac_debug_port_sel_1_setf(i);
    00429         dbg_info->diags_mac[i] = nxmac_debug_port_value_get() & 0xFFFF;
    00430     }
    00431     nxmac_debug_port_sel_1_setf(diag);
    00432
    00433     // Get diagnostic port state for the PHY
    00434     phy_get_diag_state(dbg_info);
    00435 }
    00436 #endif
    00437
    00438 void hal_machw_reset(void)
    00439 {
    00440     // Disable clock gating during SW reset
    00441     nxmac_active_clk_gating_setf(0);
    00442
    00443     // Request to MAC HW to switch to IDLE state, in order to ensure that it will be
    00444     // IDLE after reset of state machines and FIFOs
    00445     nxmac_next_state_setf(HW_IDLE);
    00446
    00447     // Reset state machines and FIFOs
    00448     nxmac_mac_err_rec_cntrl_set(MAC_HW_RESET);
    00449     //while (nxmac_mac_err_rec_cntrl_get() & MAC_HW_RESET);
    00450     while (nxmac_current_state_getf() != HW_IDLE);
    00451
    00452     #if NX_POWERSAVE
    00453     // We are in IDLE so no need to wait anymore for the IDLE interrupt
    00454     ps_env.prevent_sleep &= ~PS_IDLE_REQ_PENDING;
    00455     #endif
    00456
    00457     // Reenable the RX flow control
    00458     nxmac_rx_flow_cntrl_en_setf(1);
    00459
    00460     // Disable the timeout error interrupts
    00461     nxmac_timers_int_un_mask_set(nxmac_timers_int_un_mask_get() & ~TIMEOUT_IRQ);
    00462
    00463     // Acknowledge possibly pending interrupts
    00464     nxmac_tx_rx_int_ack_clear(0xFFFFFFFF);
    00465     nxmac_gen_int_ack_clear(NXMAC_IDLE_INTERRUPT_BIT | HW_ERROR_IRQ);
    00466
    00467     nxmac_enable_master_gen_int_en_setf(1);
    00468     nxmac_enable_master_tx_rx_int_en_setf(1);
    00469
    00470     // Re-enable clock gating during SW reset
    00471     nxmac_active_clk_gating_setf(1);
    00472 }
    00473
    00474 uint8_t hal_machw_search_addr(struct mac_addr *addr)
    00475 {
    00476     uint8_t sta_idx = INVALID_STA_IDX;
    00477     uint32_t enc_cntrl;
    00478
    00479     // Copy the MAC addr
    00480     nxmac_encr_mac_addr_low_set(addr->array[0] | (((uint32_t)addr->array[1]) << 16));
    00481     nxmac_encr_mac_addr_high_set(addr->array[2]);
    00482
    00483     // Write the control field
    00484     nxmac_encr_cntrl_set(NXMAC_NEW_SEARCH_BIT);
    00485
    00486     // Poll for the completion of the search
    00487     do
    00488     {
    00489         enc_cntrl = nxmac_encr_cntrl_get();
    00490     } while(enc_cntrl & NXMAC_NEW_SEARCH_BIT);
    00491
    00492     // Check if the search was successful or not
    00493     if (!(enc_cntrl & NXMAC_SEARCH_ERROR_BIT))
    00494         // Compute the SW STA index from the HW index
    00495         sta_idx = ((enc_cntrl & NXMAC_KEY_INDEX_RAM_MASK) >> NXMAC_KEY_INDEX_RAM_LSB)
    00496                     - MM_SEC_DEFAULT_KEY_COUNT;
    00497
    00498     return (sta_idx);
    00499 }
    00500
    00501 void hal_machw_monitor_mode(void)
    00502 {
    00503     // Disable the TBTT interrupts
    00504     nxmac_enable_imp_pri_tbtt_setf(0);
    00505     nxmac_enable_imp_sec_tbtt_setf(0);
    00506
    00507     // Disable the auto-reply capabilities of the HW
    00508     nxmac_mac_cntrl_1_set(nxmac_mac_cntrl_1_get() | NXMAC_DISABLE_ACK_RESP_BIT |
    00509                                                     NXMAC_DISABLE_CTS_RESP_BIT |
    00510                                                     NXMAC_DISABLE_BA_RESP_BIT);
    00511
    00512     // Enable reception of all frames (i.e. monitor mode)
    00513     mm_rx_filter_umac_set(MM_RX_FILTER_MONITOR);
    00514
    00515     // Configure RX path for monitor mode
    00516     rxl_hwdesc_monitor(true);
    00517
    00518     // set default mode of operation
    00519     nxmac_abgn_mode_setf(MODE_802_11N_5);
    00520
    00521     // reset Key storage RAM
    00522     nxmac_key_sto_ram_reset_setf(1);
    00523 }
    00524
    00525 int hal_machw_tsf_move(int32_t offset)
    00526 {
    00527     int err = 0;
    00528     uint32_t abs_offset = co_abs(offset);
    00529
    00530     GLOBAL_INT_DISABLE();
    00531     uint32_t macctrl1 = nxmac_mac_cntrl_1_get() | NXMAC_TSF_UPDATED_BY_SW_BIT;
    00532     uint32_t tsf_lo = nxmac_tsf_lo_get();
    00533
    00534     // Check if the offset could cause a wrap of the tsf_lo
    00535     if (((offset > 0) && (tsf_lo < abs_offset)) ||
    00536         ((offset < 0) && ((0xFFFFFFFF - tsf_lo) < (abs_offset + 32))))
    00537     {
    00538         // Not a good time to move the TSF
    00539         err = -1;
    00540     }
    00541     else
    00542     {
    00543         // Read again the TSF LO to get the latest value
    00544         tsf_lo = nxmac_tsf_lo_get();
    00545         tsf_lo -= offset;
    00546         // Do the operation thrice to ensure it is taken into account by the MAC HW
    00547         nxmac_tsf_lo_set(tsf_lo);
    00548         nxmac_mac_cntrl_1_set(macctrl1);
    00549         nxmac_tsf_lo_set(tsf_lo);
    00550         nxmac_mac_cntrl_1_set(macctrl1);
    00551         nxmac_tsf_lo_set(tsf_lo);
    00552         nxmac_mac_cntrl_1_set(macctrl1);
    00553     }
    00554     GLOBAL_INT_RESTORE();
    00555
    00556     return err;
    00557 }
    00558
    00559 bool hal_machw_sleep_check(void)
    00560 {
    00561     uint32_t timer_msk = nxmac_timers_int_un_mask_get();
    00562
    00563     #if !NX_MULTI_ROLE
    00564     uint32_t tbtt = hal_machw_time() + ((uint32_t)nxmac_next_tbtt_get() << 5);
    00565
    00566     if (hal_machw_time_past(tbtt - 2000))
    00567         return false;
    00568     #endif
    00569
    00570     // Go through all the enabled timer to check if one will expire too soon to sleep
    00571     for (int i = 0; i < HAL_TIMER_MAX; i++)
    00572     {
    00573         uint32_t timer_bit = CO_BIT(i);
    00574
    00575         if ((timer_msk & timer_bit) && (hal_machw_time_past(nxmac_abs_timer_get(i) - 2000)))
    00576         {
    00577             ASSERT_ERR(!hal_machw_time_past(nxmac_abs_timer_get(i) + 5000));
    00578             return false;
    00579         }
    00580     }
    00581
    00582     return true;
    00583 }
    00584
    00585
    00594 static void hal_machw_abs_timer_handler(void)
    00595 {
    00596     uint32_t timer_pending = nxmac_timers_int_event_get();
    00597
    00598     // Acknowledge the timer interrupt
    00599     nxmac_timers_int_event_clear(timer_pending);
    00600
    00601     if (timer_pending & HAL_KE_TIMER_BIT)
    00602         // Set the kernel timer event
    00603         ke_evt_set(KE_EVT_KE_TIMER_BIT);
    00604
    00605     #if !NX_FULLY_HOSTED
    00606     if (timer_pending & HAL_RX_TIMER_BIT)
    00607         rxl_timeout_int_handler();
    00608     #endif
    00609
    00610     #if NX_MM_TIMER
    00611     if (timer_pending & HAL_MM_TIMER_BIT)
    00612         // Trigger the primary TBTT event.
    00613         ke_evt_set(KE_EVT_MM_TIMER_BIT);
    00614     #endif
    00615
    00616     // Check for timeout errors
    00617     ASSERT_REC(!(timer_pending & HAL_AC0_TIMER_BIT));
    00618     ASSERT_REC(!(timer_pending & HAL_AC1_TIMER_BIT));
    00619     ASSERT_REC(!(timer_pending & HAL_AC2_TIMER_BIT));
    00620     ASSERT_REC(!(timer_pending & HAL_AC3_TIMER_BIT));
    00621     ASSERT_REC(!(timer_pending & HAL_BCN_TIMER_BIT));
    00622     ASSERT_REC(!(timer_pending & HAL_IDLE_TIMER_BIT));
    00623     #if NX_MAC_HE
    00624     ASSERT_REC(!(timer_pending & HAL_HE_TB_TIMER_BIT));
    00625     #endif
    00626 }
    00627
    00628 void hal_machw_gen_handler(void)
    00629 {
    00630     uint32_t genirq_pending = nxmac_gen_int_status_get() & nxmac_gen_int_enable_get();
    00631
    00632     // clear all the interrupts
    00633     nxmac_gen_int_ack_clear(genirq_pending);
    00634
    00635     #if NX_BEACONING || ((NX_POWERSAVE || NX_CONNECTION_MONITOR || NX_REORD || NX_UMAC_PRESENT) & !NX_MULTI_ROLE)
    00636     // Check for primary TBTT interrupts
    00637     if (genirq_pending & (NXMAC_IMP_PRI_TBTT_BIT | NXMAC_IMP_PRI_DTIM_BIT))
    00638     {
    00639         // For profiling
    00640         PROF_BCN_PRIM_TBTT_IRQ_SET();
    00641
    00642         #if !NX_BCN_AUTONOMOUS_TX
    00643         // Trigger the interrupt to the host
    00644         macif_prim_tbtt_ind();
    00645         #endif
    00646
    00647         // Trigger the primary TBTT event.
    00648         ke_evt_set(KE_EVT_PRIMARY_TBTT_BIT);
    00649
    00650         // For profiling
    00651         PROF_BCN_PRIM_TBTT_IRQ_CLR();
    00652     }
    00653     #endif
    00654
    00655     #if NX_BEACONING
    00656     // Check for secondary TBTT interrupts
    00657     if (genirq_pending & (NXMAC_IMP_SEC_TBTT_BIT | NXMAC_IMP_SEC_DTIM_BIT))
    00658     {
    00659         // For profiling
    00660         PROF_BCN_SEC_TBTT_IRQ_SET();
    00661
    00662         #if !NX_BCN_AUTONOMOUS_TX
    00663         // Trigger the interrupt to the host
    00664         macif_sec_tbtt_ind();
    00665         #endif
    00666
    00667         // Trigger the secondary TBTT event.
    00668         ke_evt_set(KE_EVT_SECONDARY_TBTT_BIT);
    00669
    00670         // For profiling
    00671         PROF_BCN_SEC_TBTT_IRQ_CLR();
    00672     }
    00673     #endif
    00674
    00675     // Check for IDLE interrupt Handler
    00676     if (genirq_pending & NXMAC_IDLE_INTERRUPT_BIT)
    00677     {
    00678         // Call Idle interrupt handler
    00679         hal_machw_idle_irq_handler();
    00680     }
    00681
    00682     // Check for TIMER interrupt Handler
    00683     if (genirq_pending & NXMAC_ABS_GEN_TIMERS_BIT)
    00684     {
    00685         // Handle the timer interrupt in a specific handler
    00686         hal_machw_abs_timer_handler();
    00687     }
    00688
    00689     // Check for HW errors
    00690     ASSERT_REC(!(genirq_pending & NXMAC_PHY_ERR_BIT));
    00691     ASSERT_REC(!(genirq_pending & NXMAC_MAC_PHYIF_UNDER_RUN_BIT));
    00692     ASSERT_REC(!(genirq_pending & NXMAC_MAC_PHYIF_OVERFLOW_BIT));
    00693     ASSERT_REC(!(genirq_pending & NXMAC_RX_FIFO_OVER_FLOW_BIT));
    00694     ASSERT_REC(!(genirq_pending & NXMAC_PT_ERROR_BIT));
    00695     ASSERT_REC(!(genirq_pending & NXMAC_AC_0_TX_DMA_DEAD_BIT));
    00696     ASSERT_REC(!(genirq_pending & NXMAC_AC_1_TX_DMA_DEAD_BIT));
    00697     ASSERT_REC(!(genirq_pending & NXMAC_AC_2_TX_DMA_DEAD_BIT));
    00698     ASSERT_REC(!(genirq_pending & NXMAC_AC_3_TX_DMA_DEAD_BIT));
    00699     ASSERT_REC(!(genirq_pending & NXMAC_BCN_TX_DMA_DEAD_BIT));
    00700     ASSERT_REC(!(genirq_pending & NXMAC_RX_HEADER_DMA_DEAD_BIT));
    00701     ASSERT_REC(!(genirq_pending & NXMAC_RX_PAYLOAD_DMA_DEAD_BIT));
    00702     ASSERT_REC(!(genirq_pending & NXMAC_HW_ERR_BIT));
    00703 }
    00704