00001
00020
00021
00022
00023
00024
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
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
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
00074 scan_search_ds();
00075
00076
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
00088 memset(&scan_env, 0, sizeof(scan_env));
00089
00090
00091 ke_state_set(TASK_SCAN, SCAN_IDLE);
00092
00093
00094
00095
00096 gp_dma->cb = dma_cb;
00097 gp_dma->env = NULL;
00098 gp_dma->dma_desc = &ie_desc->dma_desc;
00099
00100
00101 ie_desc->dma_desc.dest = CPU2HW(ie_desc->buf);
00102
00103
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
00123 scan_search_ds();
00124
00125
00126 scan_set_channel_request();
00127 #else
00128
00129 if (param->add_ies == 0)
00130 {
00131
00132 scan_set_channel_request();
00133
00134
00135 break;
00136 }
00137
00138
00139 ASSERT_ERR(param->add_ie_len <= SCAN_MAX_IE_LEN);
00140
00141
00142 hw_dma->src = param->add_ies;
00143 hw_dma->length = param->add_ie_len;
00144
00145
00146 hal_dma_push(gp_dma, DMA_DL);
00147
00148
00149 ke_state_set(TASK_SCAN, SCAN_WAIT_IE_DWNLD);
00150 #endif
00151
00152
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
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
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
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 = ¶m->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 = ¶m->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
00205 txtype = ((chan->band == PHY_BAND_2G4) && (!param->no_cck))?TX_DEFAULT_24G:TX_DEFAULT_5G;
00206 }
00207
00208
00209 length = MAC_SHORT_MAC_HDR_LEN + MAC_SSID_SSID_OFT + ssid->length +
00210 param->add_ie_len;
00211
00212
00213 frame = txl_frame_get(txtype, length);
00214 if (frame == NULL)
00215 break;
00216
00217
00218 buf = txl_buffer_payload_get(&frame->txdesc);
00219 thd = &frame->txdesc.lmac.hw_desc->thd;
00220
00221
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
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
00236 thd->first_pbd_ptr = CPU2HW(&ie_desc->pbd);
00237 thd->dataendptr -= param->add_ie_len;
00238
00239
00240 frame->cfm.cfm_func = NULL;
00241 frame->cfm.env = NULL;
00242
00243 #if (NX_CHNL_CTXT || NX_P2P)
00244
00245 frame->txdesc.host.vif_idx = param->vif_idx;
00246 frame->txdesc.host.staid = 0xFF;
00247 #endif //(NX_CHNL_CTXT || NX_P2P)
00248
00249
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
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