- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

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

Go to the documentation of this file.

    00001
    00020 /*
    00021  * INCLUDE FILES
    00022  ****************************************************************************************
    00023  */
    00024 // for mode
    00025 #include "scan.h"
    00026 #include "scan_task.h"
    00027 #include "mac_frame.h"
    00028 #include "hal_dma.h"
    00029 #include "mac_ie.h"
    00030 #include "vif_mgmt.h"
    00031 #include "txl_frame.h"
    00032 #include "chan.h"
    00033 #include "tpc.h"
    00034
    00035 #if NX_HW_SCAN
    00036 /*
    00037  * GLOBAL VARIABLES
    00038  ****************************************************************************************
    00039  */
    00040
    00044 struct scan_env_tag scan_env;
    00045
    00054 static void scan_search_ds(void)
    00055 {
    00056     struct scan_start_req const *param = scan_env.param;
    00057     struct scan_probe_req_ie_tag *ie_desc = &scan_probe_req_ie;
    00058
    00059     // Search for the DS IE
    00060     scan_env.ds_ie = mac_ie_ds_find(CPU2HW(ie_desc->buf), param->add_ie_len);
    00061 }
    00062
    00071 static void dma_cb(void *env, int dma_queue)
    00072 {
    00073     // Search the channel information element in the 2.4GHz IE buffer
    00074     scan_search_ds();
    00075
    00076     // Send the set channel request
    00077     scan_set_channel_request();
    00078 }
    00079
    00080
    00081 void scan_init(void)
    00082 {
    00083     struct scan_probe_req_ie_tag *ie_desc = &scan_probe_req_ie;
    00084     struct tx_pbd *pbd = &ie_desc->pbd;
    00085     struct hal_dma_desc_tag *gp_dma = &scan_env.dma_desc;
    00086
    00087     // Reset the SCAN environment
    00088     memset(&scan_env, 0, sizeof(scan_env));
    00089
    00090     // Set the state of the SCAN task
    00091     ke_state_set(TASK_SCAN, SCAN_IDLE);
    00092
    00093     // Initialize the DMA descriptors
    00094
    00095     // Initialization of the GP DMA descriptor
    00096     gp_dma->cb = dma_cb;
    00097     gp_dma->env = NULL;
    00098     gp_dma->dma_desc = &ie_desc->dma_desc;
    00099
    00100     // Initialization of the HW DMA descriptor
    00101     ie_desc->dma_desc.dest = CPU2HW(ie_desc->buf);
    00102
    00103     // Initialization of the PBD descriptor
    00104     pbd->bufctrlinfo = 0;
    00105     pbd->datastartptr = CPU2HW(ie_desc->buf);
    00106     pbd->upatterntx = TX_PAYLOAD_DESC_PATTERN;
    00107     pbd->next = 0;
    00108 }
    00109
    00110 void scan_ie_download(struct scan_start_req const *param)
    00111 {
    00112     struct scan_probe_req_ie_tag *ie_desc = &scan_probe_req_ie;
    00113     struct tx_pbd *pbd = &ie_desc->pbd;
    00114     #if !NX_UMAC_PRESENT
    00115     struct dma_desc *hw_dma = &ie_desc->dma_desc;
    00116     struct hal_dma_desc_tag *gp_dma = &scan_env.dma_desc;
    00117     #endif
    00118
    00119     do
    00120     {
    00121         #if NX_UMAC_PRESENT
    00122         // Search for the channel IE in the buffer
    00123         scan_search_ds();
    00124
    00125         // Launch the scan request
    00126         scan_set_channel_request();
    00127         #else
    00128         // Check if we have an IE buffer for this band
    00129         if (param->add_ies == 0)
    00130         {
    00131             // Send the set channel request
    00132             scan_set_channel_request();
    00133
    00134             // No IEs, so exit immediately
    00135             break;
    00136         }
    00137
    00138         // Sanity check - Ensure we have enough space in our IE buffer
    00139         ASSERT_ERR(param->add_ie_len <= SCAN_MAX_IE_LEN);
    00140
    00141         // Initialization of the HW DMA descriptor
    00142         hw_dma->src = param->add_ies;
    00143         hw_dma->length = param->add_ie_len;
    00144
    00145         // Push the DMA request
    00146         hal_dma_push(gp_dma, DMA_DL);
    00147
    00148         // Change the task state
    00149         ke_state_set(TASK_SCAN, SCAN_WAIT_IE_DWNLD);
    00150         #endif
    00151
    00152         // Initialization of the PBD descriptor
    00153         pbd->bufctrlinfo = 0;
    00154         pbd->dataendptr = pbd->datastartptr + param->add_ie_len - 1;
    00155     } while(0);
    00156 }
    00157
    00158 void scan_set_channel_request(void)
    00159 {
    00160     struct mac_chan_def const *chan = &scan_env.param->chan[scan_env.chan_idx];
    00161
    00162     // Request the scan channel to the MM channel manager
    00163     chan_scan_req(chan->band, chan->freq,  chan->tx_power,
    00164                   (chan->flags & (CHAN_NO_IR | CHAN_RADAR))?SCAN_PASSIVE_DURATION:SCAN_ACTIVE_DURATION,
    00165                   chan->flags,
    00166                   scan_env.param->vif_idx);
    00167
    00168     // Fill-in the DS information element field
    00169     if (scan_env.ds_ie != 0)
    00170     {
    00171         co_write8p(scan_env.ds_ie + MAC_DS_CHANNEL_OFT, phy_freq_to_channel(chan->band, chan->freq));
    00172     }
    00173
    00174     // Change the task state
    00175     ke_state_set(TASK_SCAN, SCAN_WAIT_CHANNEL);
    00176 }
    00177
    00178 void scan_probe_req_tx(void)
    00179 {
    00180     struct scan_start_req const *param = scan_env.param;
    00181     struct mac_chan_def const *chan = &param->chan[scan_env.chan_idx];
    00182     struct scan_probe_req_ie_tag *ie_desc = &scan_probe_req_ie;
    00183     struct vif_info_tag *vif = &vif_info_tab[param->vif_idx];
    00184     struct txl_frame_desc_tag *frame;
    00185     struct preq_frame *buf;
    00186     uint32_t ssid_addr;
    00187     int txtype;
    00188     int i;
    00189
    00190     for (i = 0; i < param->ssid_cnt; i++)
    00191     {
    00192         struct tx_hd *thd;
    00193         struct mac_ssid const *ssid = &param->ssid[i];
    00194         int length;
    00195
    00196         #if (NX_P2P)
    00197         if (vif->p2p)
    00198         {
    00199             txtype = TX_DEFAULT_5G;
    00200         }
    00201         else
    00202         #endif //(NX_P2P)
    00203         {
    00204             // Chose the right rate according to the band
    00205             txtype = ((chan->band == PHY_BAND_2G4) && (!param->no_cck))?TX_DEFAULT_24G:TX_DEFAULT_5G;
    00206         }
    00207
    00208         // Compute the ProbeReq length
    00209         length = MAC_SHORT_MAC_HDR_LEN + MAC_SSID_SSID_OFT + ssid->length +
    00210                                                          param->add_ie_len;
    00211
    00212         // Allocate a frame descriptor from the TX path
    00213         frame = txl_frame_get(txtype, length);
    00214         if (frame == NULL)
    00215             break;
    00216
    00217         // Get the buffer pointer
    00218         buf = txl_buffer_payload_get(&frame->txdesc);
    00219         thd = &frame->txdesc.lmac.hw_desc->thd;
    00220
    00221         // Prepare the MAC Header
    00222         buf->h.fctl = MAC_FCTRL_PROBEREQ;
    00223         buf->h.durid = 0;
    00224         buf->h.addr1 = mac_addr_bcst;
    00225         buf->h.addr2 = vif->mac_addr;
    00226         buf->h.addr3 = param->bssid;
    00227         buf->h.seq = txl_get_seq_ctrl();
    00228
    00229         // Copy the SSID in the packet
    00230         ssid_addr = CPU2HW(&buf->payload);
    00231         co_write8p(ssid_addr++, MAC_ELTID_SSID);
    00232         co_write8p(ssid_addr++, ssid->length);
    00233         co_pack8p(ssid_addr, ssid->array, ssid->length);
    00234
    00235         // Attach the IE buffer to the ProbeReq THD
    00236         thd->first_pbd_ptr = CPU2HW(&ie_desc->pbd);
    00237         thd->dataendptr -= param->add_ie_len;
    00238
    00239         // Fill-in the confirmation structure
    00240         frame->cfm.cfm_func = NULL;
    00241         frame->cfm.env = NULL;
    00242
    00243         #if (NX_CHNL_CTXT || NX_P2P)
    00244         // Set VIF and STA indexes
    00245         frame->txdesc.host.vif_idx = param->vif_idx;
    00246         frame->txdesc.host.staid   = 0xFF;
    00247         #endif //(NX_CHNL_CTXT || NX_P2P)
    00248
    00249         // Push the frame for TX
    00250         txl_frame_push(frame, AC_VO);
    00251     }
    00252 }
    00253
    00254 void scan_send_cancel_cfm(uint8_t status, ke_task_id_t dest_id)
    00255 {
    00256     struct scan_cancel_cfm *cfm = KE_MSG_ALLOC(SCAN_CANCEL_CFM,
    00257                                                dest_id, TASK_SCAN,
    00258                                                scan_cancel_cfm);
    00259
    00260     cfm->status = status;
    00261
    00262     // Send the response
    00263     ke_msg_send(cfm);
    00264 }
    00265
    00266 struct mac_chan_def const *scan_get_chan(void)
    00267 {
    00268     return (&scan_env.param->chan[scan_env.chan_idx]);
    00269 }
    00270 #endif //(NX_HW_SCAN)
    00271