1 /*
2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that the following conditions
4 * are met:
5 * 1. Redistributions of source code must retain the above copyright
6 * notice, this list of conditions and the following disclaimer.
7 * 2. Redistributions in binary form must reproduce the above copyright
8 * notice, this list of conditions and the following disclaimer in the
9 * documentation and/or other materials provided with the distribution.
10 *
11 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
12 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
13 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
14 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
15 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
16 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
17 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
19 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
20 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
21 * SUCH DAMAGE.
22 *
23 */
24
25 #include "includes.h"
26 #include <sys/ioctl.h>
27 #include <net/if_arp.h>
28 #ifdef ANDROID
29 #include <cutils/properties.h>
30 #endif
31 #include "driver_ti.h"
32 #include "scanmerge.h"
33 #ifdef CONFIG_WPS
34 #include "wps_defs.h"
35 #endif
36
37 /*-------------------------------------------------------------------*/
38 #define TI2WPA_STATUS(s) (((s) != 0) ? -1 : 0)
39 #define TI_CHECK_DRIVER(f,r) \
40 if( !(f) ) { \
41 wpa_printf(MSG_ERROR,"TI: Driver not initialized yet"); \
42 return( r ); \
43 }
44
45 /*-----------------------------------------------------------------------------
46 Routine Name: check_and_get_build_channels
47 Routine Description: get number of allowed channels according to a build var.
48 Arguments: None
49 Return Value: Number of channels
50 -----------------------------------------------------------------------------*/
check_and_get_build_channels(void)51 static int check_and_get_build_channels( void )
52 {
53 #ifdef ANDROID
54 char prop_status[PROPERTY_VALUE_MAX];
55 char *prop_name = "ro.wifi.channels";
56 int i, default_channels = NUMBER_SCAN_CHANNELS_FCC;
57
58 if( property_get(prop_name, prop_status, NULL) ) {
59 i = atoi(prop_status);
60 if( i != 0 )
61 default_channels = i;
62 }
63 return( default_channels );
64 #else
65 return( NUMBER_SCAN_CHANNELS_FCC );
66 #endif
67 }
68
wpa_driver_tista_cipher2wext(int cipher)69 static int wpa_driver_tista_cipher2wext(int cipher)
70 {
71 switch (cipher) {
72 case CIPHER_NONE:
73 return IW_AUTH_CIPHER_NONE;
74 case CIPHER_WEP40:
75 return IW_AUTH_CIPHER_WEP40;
76 case CIPHER_TKIP:
77 return IW_AUTH_CIPHER_TKIP;
78 case CIPHER_CCMP:
79 return IW_AUTH_CIPHER_CCMP;
80 case CIPHER_WEP104:
81 return IW_AUTH_CIPHER_WEP104;
82 default:
83 return 0;
84 }
85 }
86
wpa_driver_tista_keymgmt2wext(int keymgmt)87 static int wpa_driver_tista_keymgmt2wext(int keymgmt)
88 {
89 switch (keymgmt) {
90 case KEY_MGMT_802_1X:
91 case KEY_MGMT_802_1X_NO_WPA:
92 #ifdef CONFIG_WPS
93 case KEY_MGMT_WPS:
94 #endif
95 return IW_AUTH_KEY_MGMT_802_1X;
96 case KEY_MGMT_PSK:
97 return IW_AUTH_KEY_MGMT_PSK;
98 default:
99 return 0;
100 }
101 }
102
wpa_driver_tista_get_bssid(void * priv,u8 * bssid)103 static int wpa_driver_tista_get_bssid(void *priv, u8 *bssid)
104 {
105 struct wpa_driver_ti_data *drv = priv;
106 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
107 return wpa_driver_wext_get_bssid(drv->wext, bssid);
108 }
109
wpa_driver_tista_get_ssid(void * priv,u8 * ssid)110 static int wpa_driver_tista_get_ssid(void *priv, u8 *ssid)
111 {
112 struct wpa_driver_ti_data *drv = priv;
113 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
114 return wpa_driver_wext_get_ssid(drv->wext, ssid);
115 }
116
wpa_driver_tista_private_send(void * priv,u32 ioctl_cmd,void * bufIn,u32 sizeIn,void * bufOut,u32 sizeOut)117 static int wpa_driver_tista_private_send( void *priv, u32 ioctl_cmd, void *bufIn, u32 sizeIn, void *bufOut, u32 sizeOut )
118 {
119 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
120 ti_private_cmd_t private_cmd;
121 struct iwreq iwr;
122 s32 res;
123
124 private_cmd.cmd = ioctl_cmd;
125 if(bufOut == NULL)
126 private_cmd.flags = PRIVATE_CMD_SET_FLAG;
127 else
128 private_cmd.flags = PRIVATE_CMD_GET_FLAG;
129
130 private_cmd.in_buffer = bufIn;
131 private_cmd.in_buffer_len = sizeIn;
132 private_cmd.out_buffer = bufOut;
133 private_cmd.out_buffer_len = sizeOut;
134
135 os_memset(&iwr, 0, sizeof(iwr));
136 os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
137
138 iwr.u.data.pointer = &private_cmd;
139 iwr.u.data.length = sizeof(ti_private_cmd_t);
140 iwr.u.data.flags = 0;
141
142 res = ioctl(drv->ioctl_sock, SIOCIWFIRSTPRIV, &iwr);
143 if (0 != res)
144 {
145 wpa_printf(MSG_ERROR, "ERROR - wpa_driver_tista_private_send - error sending Wext private IOCTL to STA driver (ioctl_cmd = %x, res = %d, errno = %d)", ioctl_cmd, res, errno);
146 drv->errors++;
147 if (drv->errors > MAX_NUMBER_SEQUENTIAL_ERRORS) {
148 drv->errors = 0;
149 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
150 }
151 return -1;
152 }
153 drv->errors = 0;
154 wpa_printf(MSG_DEBUG, "wpa_driver_tista_private_send ioctl_cmd = %x res = %d", ioctl_cmd, res);
155
156 return 0;
157 }
158
wpa_driver_tista_driver_start(void * priv)159 static int wpa_driver_tista_driver_start( void *priv )
160 {
161 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
162 u32 uDummyBuf;
163 s32 res;
164
165 res = wpa_driver_tista_private_send(priv, DRIVER_START_PARAM, &uDummyBuf, sizeof(uDummyBuf), NULL, 0);
166
167 if (0 != res) {
168 wpa_printf(MSG_ERROR, "ERROR - Failed to start driver!");
169 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
170 }
171 else {
172 os_sleep(0, WPA_DRIVER_WEXT_WAIT_US); /* delay 400 ms */
173 wpa_printf(MSG_DEBUG, "wpa_driver_tista_driver_start success");
174 }
175 return res;
176 }
177
wpa_driver_tista_driver_stop(void * priv)178 static int wpa_driver_tista_driver_stop( void *priv )
179 {
180 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
181 u32 uDummyBuf;
182 s32 res;
183
184 res = wpa_driver_tista_private_send(priv, DRIVER_STOP_PARAM, &uDummyBuf, sizeof(uDummyBuf), NULL, 0);
185
186 if (0 != res) {
187 wpa_printf(MSG_ERROR, "ERROR - Failed to stop driver!");
188 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
189 }
190 else
191 wpa_printf(MSG_DEBUG, "wpa_driver_tista_driver_stop success");
192
193 return res;
194 }
195
wpa_driver_tista_parse_custom(void * ctx,const void * custom)196 int wpa_driver_tista_parse_custom(void *ctx, const void *custom)
197 {
198 IPC_EV_DATA * pData = NULL;
199
200 pData = (IPC_EV_DATA *)custom;
201 wpa_printf(MSG_DEBUG, "uEventType %d", pData->EvParams.uEventType);
202 switch (pData->EvParams.uEventType) {
203 case IPC_EVENT_LINK_SPEED:
204 wpa_printf(MSG_DEBUG, "IPC_EVENT_LINK_SPEED");
205 if(pData->uBufferSize == sizeof(u32))
206 {
207 wpa_printf(MSG_DEBUG, "update link_speed");
208 /* Dm: pStaDrv->link_speed = *((u32 *)pData->uBuffer) / 2; */
209 }
210
211 /* Dm: wpa_printf(MSG_INFO,"wpa_supplicant - Link Speed = %u", pStaDrv->link_speed ); */
212 break;
213 default:
214 wpa_printf(MSG_DEBUG, "Unknown event");
215 break;
216 }
217
218 return 0;
219 }
220
ti_init_scan_params(scan_Params_t * pScanParams,int scanType,int noOfChan,int scan_probe_flag)221 static void ti_init_scan_params( scan_Params_t *pScanParams, int scanType,
222 int noOfChan, int scan_probe_flag )
223 {
224 u8 i,j;
225 int maxDwellTime = 110000;
226
227 /* init application scan default params */
228 pScanParams->desiredSsid.len = 0;
229 /* all scan, we will use active scan */
230 pScanParams->scanType = scanType;
231 if ((scanType == SCAN_TYPE_NORMAL_ACTIVE) && scan_probe_flag)
232 maxDwellTime = 30000;
233
234 pScanParams->band = RADIO_BAND_2_4_GHZ;
235 pScanParams->probeReqNumber = 3;
236 pScanParams->probeRequestRate = RATE_MASK_UNSPECIFIED; /* Let the FW select */;
237 pScanParams->Tid = 0;
238 pScanParams->numOfChannels = noOfChan;
239 for ( i = 0; i < noOfChan; i++ )
240 {
241 for ( j = 0; j < 6; j++ )
242 {
243 pScanParams->channelEntry[ i ].normalChannelEntry.bssId[ j ] = 0xff;
244 }
245 pScanParams->channelEntry[ i ].normalChannelEntry.earlyTerminationEvent = SCAN_ET_COND_DISABLE;
246 pScanParams->channelEntry[ i ].normalChannelEntry.ETMaxNumOfAPframes = 0;
247 pScanParams->channelEntry[ i ].normalChannelEntry.maxChannelDwellTime = maxDwellTime;
248 pScanParams->channelEntry[ i ].normalChannelEntry.minChannelDwellTime = maxDwellTime;
249 pScanParams->channelEntry[ i ].normalChannelEntry.txPowerDbm = DEF_TX_POWER;
250 pScanParams->channelEntry[ i ].normalChannelEntry.channel = i + 1;
251 }
252 }
253
254 /*-----------------------------------------------------------------------------
255 Routine Name: wpa_driver_tista_scan
256 Routine Description: request scan from driver
257 Arguments:
258 priv - pointer to private data structure
259 ssid - ssid buffer
260 ssid_len - length of ssid
261 Return Value: 0 on success, -1 on failure
262 -----------------------------------------------------------------------------*/
wpa_driver_tista_scan(void * priv,const u8 * ssid,size_t ssid_len)263 static int wpa_driver_tista_scan( void *priv, const u8 *ssid, size_t ssid_len )
264 {
265 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
266 struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
267 struct wpa_ssid *issid;
268 scan_Params_t scanParams;
269 int scan_type, res, timeout, scan_probe_flag = 0;
270
271 wpa_printf(MSG_DEBUG, "%s", __func__);
272 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
273
274 #if 1
275 os_memset(&scanParams, 0, sizeof(scan_Params_t));
276 /* Initialize scan parameters */
277 scan_type = drv->scan_type;
278 if (wpa_s->prev_scan_ssid != BROADCAST_SSID_SCAN) {
279 if (wpa_s->prev_scan_ssid->scan_ssid) {
280 scan_type = SCAN_TYPE_NORMAL_ACTIVE;
281 scan_probe_flag = 1;
282 }
283 }
284 ti_init_scan_params(&scanParams, scan_type, drv->scan_channels,
285 scan_probe_flag);
286
287 drv->force_merge_flag = 0; /* Set merge flag */
288
289 if ((scan_probe_flag && ssid) &&
290 (ssid_len > 0 && ssid_len <= sizeof(scanParams.desiredSsid.str))) {
291 os_memcpy(scanParams.desiredSsid.str, ssid, ssid_len);
292 if (ssid_len < sizeof(scanParams.desiredSsid.str))
293 scanParams.desiredSsid.str[ssid_len] = '\0';
294 scanParams.desiredSsid.len = ssid_len;
295 drv->force_merge_flag = 1;
296 }
297
298 drv->last_scan = scan_type; /* Remember scan type for last scan */
299
300 res = wpa_driver_tista_private_send(priv, TIWLN_802_11_START_APP_SCAN_SET, &scanParams, sizeof(scanParams), NULL, 0);
301
302 if (0 != res) {
303 wpa_printf(MSG_ERROR, "ERROR - Failed to do tista scan!");
304 if (wpa_s->scanning) {
305 res = 0;
306 wpa_printf(MSG_ERROR, "Ongoing Scan action...");
307 }
308 } else {
309 wpa_printf(MSG_DEBUG, "wpa_driver_tista_scan success");
310 }
311 timeout = 30;
312 wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d sec",
313 res, timeout);
314 eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv->wext, drv->ctx);
315 eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout,
316 drv->wext, drv->ctx);
317 return res;
318 #else
319 return wpa_driver_wext_scan(drv->wext, ssid, ssid_len);
320 #endif
321 }
322
323 /*-----------------------------------------------------------------------------
324 Routine Name: wpa_driver_tista_get_mac_addr
325 Routine Description: return WLAN MAC address
326 Arguments:
327 priv - pointer to private data structure
328 Return Value: pointer to BSSID
329 -----------------------------------------------------------------------------*/
wpa_driver_tista_get_mac_addr(void * priv)330 const u8 *wpa_driver_tista_get_mac_addr( void *priv )
331 {
332 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
333 u8 mac[ETH_ALEN] = {0};
334
335 TI_CHECK_DRIVER( drv->driver_is_loaded, NULL );
336 if(0 != wpa_driver_tista_private_send(priv, CTRL_DATA_MAC_ADDRESS, NULL, 0,
337 mac, ETH_ALEN))
338 {
339 wpa_printf(MSG_ERROR, "ERROR - Failed to get mac address!");
340 os_memset(drv->own_addr, 0, ETH_ALEN);
341 }
342 else
343 {
344 os_memcpy(drv->own_addr, mac, ETH_ALEN);
345 wpa_printf(MSG_DEBUG, "Macaddr = " MACSTR, MAC2STR(drv->own_addr));
346 }
347 wpa_printf(MSG_DEBUG, "wpa_driver_tista_get_mac_addr success");
348
349 return (const u8 *)&drv->own_addr;
350 }
351
wpa_driver_tista_get_rssi(void * priv,int * rssi_data,int * rssi_beacon)352 static int wpa_driver_tista_get_rssi(void *priv, int *rssi_data, int *rssi_beacon)
353 {
354 u8 bssid[ETH_ALEN];
355 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
356 TCuCommon_RoamingStatisticsTable buffer;
357
358 os_memset(&buffer, 0, sizeof(TCuCommon_RoamingStatisticsTable));
359 *rssi_data = 0;
360 *rssi_beacon = 0;
361 if (wpa_driver_tista_get_bssid(priv, bssid) == 0 &&
362 os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0) {
363 if(0 != wpa_driver_tista_private_send(priv, TIWLN_802_11_RSSI, NULL, 0,
364 &buffer, sizeof(TCuCommon_RoamingStatisticsTable))) {
365 wpa_printf(MSG_ERROR, "ERROR - Failed to get rssi level");
366 return -1;
367 }
368 *rssi_data = (s8)buffer.rssi;
369 *rssi_beacon = (s8)buffer.rssiBeacon;
370 wpa_printf(MSG_DEBUG, "wpa_driver_tista_get_rssi data %d beacon %d success",
371 *rssi_data, *rssi_beacon);
372 }
373 else {
374 wpa_printf(MSG_DEBUG, "no WiFi link.");
375 return -1;
376 }
377 return 0;
378 }
379
wpa_driver_tista_config_power_management(void * priv,TPowerMgr_PowerMode * mode,u8 is_set)380 static int wpa_driver_tista_config_power_management(void *priv, TPowerMgr_PowerMode *mode, u8 is_set)
381 {
382 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
383
384 if(is_set) /* set power mode */
385 {
386 if((mode->PowerMode) < POWER_MODE_MAX)
387 {
388 if(0 != wpa_driver_tista_private_send(priv, TIWLN_802_11_POWER_MODE_SET,
389 mode, sizeof(TPowerMgr_PowerMode), NULL, 0))
390 {
391 wpa_printf(MSG_ERROR, "ERROR - Failed to set power mode");
392 return -1;
393 }
394 }
395 else
396 {
397 wpa_printf(MSG_ERROR, "ERROR - Invalid Power Mode");
398 return -1;
399 }
400 }
401 else /* get power mode */
402 {
403 if(0 != wpa_driver_tista_private_send(priv, TIWLN_802_11_POWER_MODE_GET, NULL, 0,
404 mode, sizeof(TPowerMgr_PowerMode)))
405 {
406 wpa_printf(MSG_ERROR, "ERROR - Failed to get power mode");
407 return -1;
408 }
409 }
410 wpa_printf(MSG_DEBUG, "wpa_driver_tista_config_power_management success");
411
412 return 0;
413 }
414
wpa_driver_tista_enable_bt_coe(void * priv,u32 mode)415 static int wpa_driver_tista_enable_bt_coe(void *priv, u32 mode)
416 {
417 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
418 u32 mode_set = mode;
419
420 /* Mapping the mode between UI enum and driver enum */
421 switch(mode_set)
422 {
423 case BLUETOOTH_COEXISTENCE_MODE_ENABLED:
424 mode_set = SG_OPPORTUNISTIC;
425 break;
426 case BLUETOOTH_COEXISTENCE_MODE_SENSE:
427 mode_set = SG_PROTECTIVE;
428 break;
429 case BLUETOOTH_COEXISTENCE_MODE_DISABLED:
430 mode_set = SG_DISABLE;
431 break;
432 default:
433 wpa_printf(MSG_DEBUG, "wpa_driver_tista_enable_bt_coe - Unknown Mode");
434 return -1;
435 break;
436 }
437
438 if(0 != wpa_driver_tista_private_send(priv, SOFT_GEMINI_SET_ENABLE,
439 &mode_set, sizeof(u32), NULL, 0))
440 {
441 wpa_printf(MSG_ERROR, "ERROR - Failed to enable BtCoe");
442 return -1;
443 }
444 wpa_printf(MSG_DEBUG, "wpa_driver_tista_enable_bt_coe success");
445
446 return 0;
447 }
448
wpa_driver_tista_get_bt_coe_status(void * priv,u32 * mode)449 static int wpa_driver_tista_get_bt_coe_status(void *priv, u32 *mode)
450 {
451 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
452 u32 mode_get = 0;
453
454 if(0 != wpa_driver_tista_private_send(priv, SOFT_GEMINI_GET_CONFIG, NULL, 0,
455 &mode_get, sizeof(u32)))
456 {
457 wpa_printf(MSG_ERROR, "ERROR - Failed to get bt coe status");
458 return -1;
459 }
460 *mode = mode_get;
461 wpa_printf(MSG_DEBUG, "wpa_driver_tista_get_bt_coe_status mode %d success", *mode);
462
463 return 0;
464 }
465
466 /*-----------------------------------------------------------------------------
467 Routine Name: prepare_filter_struct
468 Routine Description: fills rx data filter structure according to parameter type
469 Arguments:
470 priv - pointer to private data structure
471 type - type of mac address
472 dfreq_ptr - pointer to TRxDataFilterRequest structure
473 Return Value: 0 - success, -1 - error
474 -----------------------------------------------------------------------------*/
prepare_filter_struct(void * priv,int type,TRxDataFilterRequest * dfreq_ptr)475 static int prepare_filter_struct( void *priv, int type,
476 TRxDataFilterRequest *dfreq_ptr )
477 {
478 const u8 *macaddr = NULL;
479 size_t len = 0;
480 u8 mask;
481 int ret = -1;
482
483 wpa_printf(MSG_DEBUG, "filter type=%d", type);
484 switch (type) {
485 case RX_SELF_FILTER:
486 macaddr = wpa_driver_tista_get_mac_addr(priv);
487 len = MAC_ADDR_LEN;
488 mask = 0x3F; /* 6 bytes */
489 break;
490 case RX_BROADCAST_FILTER:
491 macaddr = (const u8 *)"\xFF\xFF\xFF\xFF\xFF\xFF";
492 len = MAC_ADDR_LEN;
493 mask = 0x3F; /* 6 bytes */
494 break;
495 case RX_IPV4_MULTICAST_FILTER:
496 macaddr = (const u8 *)"\x01\x00\x5E";
497 len = 3;
498 mask = 0x7; /* 3 bytes */
499 break;
500 case RX_IPV6_MULTICAST_FILTER:
501 macaddr = (const u8 *)"\x33\x33";
502 len = 2;
503 mask = 0x3; /* 2 bytes */
504 break;
505 }
506
507 if (macaddr != NULL) {
508 dfreq_ptr->offset = 0;
509 dfreq_ptr->maskLength = 1;
510 dfreq_ptr->mask[0] = mask;
511 dfreq_ptr->patternLength = len;
512 os_memcpy( dfreq_ptr->pattern, macaddr, MAC_ADDR_LEN );
513 ret = 0;
514 }
515 return ret;
516 }
517
wpa_driver_tista_driver_rx_data_filter(void * priv,TRxDataFilterRequest * dfreq_ptr,u8 is_add)518 static int wpa_driver_tista_driver_rx_data_filter( void *priv, TRxDataFilterRequest *dfreq_ptr, u8 is_add )
519 {
520 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
521 int cmd, res;
522
523 if (is_add) { /* add rx data filter */
524 cmd = TIWLN_ADD_RX_DATA_FILTER;
525 wpa_printf(MSG_DEBUG, "Add RX data filter");
526 }
527 else { /* remove rx data filter */
528 cmd = TIWLN_REMOVE_RX_DATA_FILTER;
529 wpa_printf(MSG_DEBUG, "Remove RX data filter");
530 }
531
532 res = wpa_driver_tista_private_send(priv, cmd, dfreq_ptr, sizeof(TRxDataFilterRequest), NULL, 0);
533 if (0 != res)
534 wpa_printf(MSG_ERROR, "ERROR - Failed to handle rx data filter command!");
535 else
536 wpa_printf(MSG_DEBUG, "%s success", __func__);
537 return res;
538 }
539
wpa_driver_tista_driver_enable_rx_data_filter(void * priv)540 static int wpa_driver_tista_driver_enable_rx_data_filter( void *priv )
541 {
542 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
543 u32 val = TRUE;
544 int res;
545
546 res = wpa_driver_tista_private_send(priv, TIWLN_ENABLE_DISABLE_RX_DATA_FILTERS,
547 &val, sizeof(u32), NULL, 0);
548 if (0 != res)
549 wpa_printf(MSG_ERROR, "ERROR - Failed to enable RX data filter!");
550 else
551 wpa_printf(MSG_DEBUG, "%s success", __func__);
552 return res;
553 }
554
wpa_driver_tista_driver_disable_rx_data_filter(void * priv)555 static int wpa_driver_tista_driver_disable_rx_data_filter( void *priv )
556 {
557 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
558 u32 val = FALSE;
559 int res;
560
561 res = wpa_driver_tista_private_send(priv, TIWLN_ENABLE_DISABLE_RX_DATA_FILTERS,
562 &val, sizeof(u32), NULL, 0);
563 if (0 != res)
564 wpa_printf(MSG_ERROR, "ERROR - Failed to disable RX data filter!");
565 else
566 wpa_printf(MSG_DEBUG, "%s success", __func__);
567 return res;
568 }
569
wpa_driver_tista_driver_rx_data_filter_statistics(void * priv,TCuCommon_RxDataFilteringStatistics * stats)570 static int wpa_driver_tista_driver_rx_data_filter_statistics( void *priv,
571 TCuCommon_RxDataFilteringStatistics *stats )
572 {
573 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
574 int res;
575
576 res = wpa_driver_tista_private_send(priv, TIWLN_GET_RX_DATA_FILTERS_STATISTICS,
577 NULL, 0, stats, sizeof(TCuCommon_RxDataFilteringStatistics));
578 if (0 != res)
579 wpa_printf(MSG_ERROR, "ERROR - Failed to get RX data filter statistics!");
580 else
581 wpa_printf(MSG_DEBUG, "%s success", __func__);
582 return res;
583 }
584
get_num_of_channels(char * country)585 static int get_num_of_channels(char *country)
586 {
587 int channels = NUMBER_SCAN_CHANNELS_FCC;
588
589 if (os_strcasecmp(country, "EU"))
590 channels = NUMBER_SCAN_CHANNELS_ETSI;
591 else if (os_strcasecmp(country, "JP"))
592 channels = NUMBER_SCAN_CHANNELS_MKK1;
593 return channels;
594 }
595
596 /*-----------------------------------------------------------------------------
597 Routine Name: wpa_driver_tista_driver_cmd
598 Routine Description: executes driver-specific commands
599 Arguments:
600 priv - pointer to private data structure
601 cmd - command
602 buf - return buffer
603 buf_len - buffer length
604 Return Value: actual buffer length - success, -1 - failure
605 -----------------------------------------------------------------------------*/
wpa_driver_tista_driver_cmd(void * priv,char * cmd,char * buf,size_t buf_len)606 static int wpa_driver_tista_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len )
607 {
608 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
609 int ret = -1, prev_events, flags;
610
611 wpa_printf(MSG_DEBUG, "%s %s", __func__, cmd);
612
613 if( os_strcasecmp(cmd, "start") == 0 ) {
614 wpa_printf(MSG_DEBUG,"Start command");
615 ret = wpa_driver_tista_driver_start(priv);
616 if( ret == 0 ) {
617 drv->driver_is_loaded = TRUE;
618 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
619 }
620 return( TI2WPA_STATUS(ret) );
621 }
622
623 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
624
625 if( os_strcasecmp(cmd, "stop") == 0 ) {
626 wpa_printf(MSG_DEBUG,"Stop command");
627 if ((wpa_driver_wext_get_ifflags(drv->wext, &flags) == 0) &&
628 (flags & IFF_UP)) {
629 wpa_printf(MSG_ERROR, "TI: %s when iface is UP", cmd);
630 wpa_driver_wext_set_ifflags(drv->wext, flags & ~IFF_UP);
631 }
632 ret = wpa_driver_tista_driver_stop(priv);
633 if( ret == 0 ) {
634 scan_exit(drv); /* Clear scan cache */
635 drv->driver_is_loaded = FALSE;
636 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
637 }
638 }
639 if( os_strcasecmp(cmd, "reload") == 0 ) {
640 wpa_printf(MSG_DEBUG,"Reload command");
641 ret = 0;
642 wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
643 }
644 else if( os_strcasecmp(cmd, "macaddr") == 0 ) {
645 wpa_driver_tista_get_mac_addr(priv);
646 wpa_printf(MSG_DEBUG, "Macaddr command");
647 ret = sprintf(buf, "Macaddr = " MACSTR "\n", MAC2STR(drv->own_addr));
648 wpa_printf(MSG_DEBUG, "buf %s", buf);
649 }
650 else if( os_strcasecmp(cmd, "scan-passive") == 0 ) {
651 wpa_printf(MSG_DEBUG,"Scan Passive command");
652 drv->scan_type = SCAN_TYPE_NORMAL_PASSIVE;
653 ret = 0;
654 }
655 else if( os_strcasecmp(cmd, "scan-active") == 0 ) {
656 wpa_printf(MSG_DEBUG,"Scan Active command");
657 drv->scan_type = SCAN_TYPE_NORMAL_ACTIVE;
658 ret = 0;
659 }
660 else if( os_strcasecmp(cmd, "scan-mode") == 0 ) {
661 wpa_printf(MSG_DEBUG,"Scan Mode command");
662 ret = snprintf(buf, buf_len, "ScanMode = %u\n", drv->scan_type);
663 if (ret < (int)buf_len) {
664 return( ret );
665 }
666 }
667 else if( os_strcasecmp(cmd, "linkspeed") == 0 ) {
668 struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
669
670 wpa_printf(MSG_DEBUG,"Link Speed command");
671 drv->link_speed = wpa_s->link_speed / 1000000;
672 ret = sprintf(buf,"LinkSpeed %u\n", drv->link_speed);
673 wpa_printf(MSG_DEBUG, "buf %s", buf);
674 }
675 else if( os_strncasecmp(cmd, "country", 7) == 0 ) {
676 drv->scan_channels = get_num_of_channels(cmd + 8);
677 ret = sprintf(buf,"Scan-Channels = %d\n", drv->scan_channels);
678 wpa_printf(MSG_DEBUG, "buf %s", buf);
679 }
680 else if( os_strncasecmp(cmd, "scan-channels", 13) == 0 ) {
681 int noOfChan;
682
683 noOfChan = atoi(cmd + 13);
684 wpa_printf(MSG_DEBUG,"Scan Channels command = %d", noOfChan);
685 if( (noOfChan > 0) && (noOfChan <= MAX_NUMBER_OF_CHANNELS_PER_SCAN) )
686 drv->scan_channels = noOfChan;
687 ret = sprintf(buf,"Scan-Channels = %d\n", drv->scan_channels);
688 wpa_printf(MSG_DEBUG, "buf %s", buf);
689 }
690 else if( os_strcasecmp(cmd, "rssi-approx") == 0 ) {
691 scan_result_t *cur_res;
692 struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
693 scan_ssid_t *p_ssid;
694 int rssi, len;
695
696 wpa_printf(MSG_DEBUG,"rssi-approx command");
697
698 if( !wpa_s )
699 return( ret );
700 cur_res = scan_get_by_bssid(drv, wpa_s->bssid);
701 if( cur_res ) {
702 p_ssid = scan_get_ssid(cur_res);
703 len = (int)(p_ssid->ssid_len);
704 rssi = cur_res->level;
705 if( (len > 0) && (len <= MAX_SSID_LEN) && (len < (int)buf_len)) {
706 os_memcpy((void *)buf, (void *)(p_ssid->ssid), len);
707 ret = len;
708 ret += snprintf(&buf[ret], buf_len-len, " rssi %d\n", rssi);
709 }
710 }
711 }
712 else if( os_strcasecmp(cmd, "rssi") == 0 ) {
713 u8 ssid[MAX_SSID_LEN];
714 scan_result_t *cur_res;
715 struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
716 int rssi_data, rssi_beacon, len;
717
718 wpa_printf(MSG_DEBUG,"rssi command");
719
720 ret = wpa_driver_tista_get_rssi(priv, &rssi_data, &rssi_beacon);
721 if( ret == 0 ) {
722 len = wpa_driver_tista_get_ssid(priv, (u8 *)ssid);
723 wpa_printf(MSG_DEBUG,"rssi_data %d rssi_beacon %d", rssi_data, rssi_beacon);
724 if( (len > 0) && (len <= MAX_SSID_LEN) ) {
725 os_memcpy((void *)buf, (void *)ssid, len);
726 ret = len;
727 ret += sprintf(&buf[ret], " rssi %d\n", rssi_beacon);
728 wpa_printf(MSG_DEBUG, "buf %s", buf);
729 /* Update cached value */
730 if( !wpa_s )
731 return( ret );
732 cur_res = scan_get_by_bssid(drv, wpa_s->bssid);
733 if( cur_res )
734 cur_res->level = rssi_beacon;
735 }
736 else
737 {
738 wpa_printf(MSG_DEBUG, "Fail to get ssid when reporting rssi");
739 ret = -1;
740 }
741 }
742 }
743 else if( os_strncasecmp(cmd, "powermode", 9) == 0 ) {
744 u32 mode;
745 TPowerMgr_PowerMode tMode;
746
747 mode = (u32)atoi(cmd + 9);
748 wpa_printf(MSG_DEBUG,"Power Mode command = %u", mode);
749 if( mode < POWER_MODE_MAX )
750 {
751 tMode.PowerMode = (PowerMgr_PowerMode_e)mode;
752 tMode.PowerMngPriority = POWER_MANAGER_USER_PRIORITY;
753 ret = wpa_driver_tista_config_power_management( priv, &tMode, 1 );
754 }
755 }
756 else if (os_strncasecmp(cmd, "getpower", 8) == 0 ) {
757 u32 mode;
758 TPowerMgr_PowerMode tMode;
759
760 os_memset(&tMode, 0, sizeof(TPowerMgr_PowerMode));
761 ret = wpa_driver_tista_config_power_management( priv, &tMode, 0 );
762 if( ret == 0 ) {
763 ret = sprintf(buf, "powermode = %u\n", tMode.PowerMode);
764 wpa_printf(MSG_DEBUG, "buf %s", buf);
765 }
766 }
767 else if( os_strncasecmp(cmd, "btcoexmode", 10) == 0 ) {
768 u32 mode;
769
770 mode = (u32)atoi(cmd + 10);
771 wpa_printf(MSG_DEBUG,"BtCoex Mode command = %u", mode);
772 ret = wpa_driver_tista_enable_bt_coe( priv, mode );
773 if( ret == 0 ) {
774 drv->btcoex_mode = mode;
775 }
776 }
777 else if( os_strcasecmp(cmd, "btcoexstat") == 0 ) {
778 u32 status = drv->btcoex_mode;
779
780 wpa_printf(MSG_DEBUG,"BtCoex Status");
781 ret = wpa_driver_tista_get_bt_coe_status( priv, &status );
782 if( ret == 0 ) {
783 ret = sprintf(buf, "btcoexstatus = 0x%x\n", status);
784 wpa_printf(MSG_DEBUG, "buf %s", buf);
785 }
786 }
787 else if( os_strcasecmp(cmd, "rxfilter-start") == 0 ) {
788 wpa_printf(MSG_DEBUG,"Rx Data Filter Start command");
789 ret = wpa_driver_tista_driver_enable_rx_data_filter( priv );
790 }
791 else if( os_strcasecmp(cmd, "rxfilter-stop") == 0 ) {
792 wpa_printf(MSG_DEBUG,"Rx Data Filter Stop command");
793 ret = wpa_driver_tista_driver_disable_rx_data_filter( priv );
794 }
795 else if( os_strcasecmp(cmd, "rxfilter-statistics") == 0 ) {
796 TCuCommon_RxDataFilteringStatistics stats;
797 int len, i;
798
799 os_memset(&stats, 0, sizeof(TCuCommon_RxDataFilteringStatistics));
800 wpa_printf(MSG_DEBUG,"Rx Data Filter Statistics command");
801 ret = wpa_driver_tista_driver_rx_data_filter_statistics( priv, &stats );
802 if( ret == 0 ) {
803 ret = snprintf(buf, buf_len, "RxFilterStat: %u", (u32)stats.unmatchedPacketsCount);
804 for(i=0;( i < MAX_DATA_FILTERS );i++) {
805 ret += snprintf(&buf[ret], buf_len-ret, " %u", (u32)stats.matchedPacketsCount[i]);
806 }
807 ret += snprintf(&buf[ret], buf_len-ret, "\n");
808 if (ret >= (int)buf_len) {
809 ret = -1;
810 }
811 }
812 }
813 else if( os_strncasecmp(cmd, "rxfilter-add", 12) == 0 ) {
814 TRxDataFilterRequest dfreq;
815 char *cp = cmd + 12;
816 char *endp;
817 int type;
818
819 if (*cp != '\0') {
820 type = (int)strtol(cp, &endp, 0);
821 if (endp != cp) {
822 wpa_printf(MSG_DEBUG,"Rx Data Filter Add [%d] command", type);
823 ret = prepare_filter_struct( priv, type, &dfreq );
824 if( ret == 0 ) {
825 ret = wpa_driver_tista_driver_rx_data_filter( priv, &dfreq, 1 );
826 }
827 }
828 }
829 }
830 else if( os_strncasecmp(cmd, "rxfilter-remove",15) == 0 ) {
831 TRxDataFilterRequest dfreq;
832 char *cp = cmd + 15;
833 char *endp;
834 int type;
835
836 if (*cp != '\0') {
837 type = (int)strtol(cp, &endp, 0);
838 if (endp != cp) {
839 wpa_printf(MSG_DEBUG,"Rx Data Filter remove [%d] command", type);
840 ret = prepare_filter_struct( priv, type, &dfreq );
841 if( ret == 0 ) {
842 ret = wpa_driver_tista_driver_rx_data_filter( priv, &dfreq, 0 );
843 }
844 }
845 }
846 }
847 else {
848 wpa_printf(MSG_DEBUG,"Unsupported command");
849 }
850 return ret;
851 }
852
853 #ifdef WPA_SUPPLICANT_VER_0_6_X
854 /*-----------------------------------------------------------------------------
855 Routine Name: wpa_driver_tista_set_probe_req_ie
856 Routine Description: set probe request ie for WSC mode change
857 Arguments:
858 priv - pointer to private data structure
859 ies - probe_req_ie data
860 ies_len - ie data length
861 Return Value: actual buffer length - success, -1 - failure
862 -----------------------------------------------------------------------------*/
wpa_driver_tista_set_probe_req_ie(void * priv,const u8 * ies,size_t ies_len)863 static int wpa_driver_tista_set_probe_req_ie(void *priv, const u8* ies, size_t ies_len)
864 {
865 struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
866 #ifdef CONFIG_WPS
867 TWscMode WscModeStruct;
868
869 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
870
871 if ((!ies || (0 == ies_len)) && (NULL == drv->probe_req_ie)) {
872 return 0;
873 }
874
875 if (ies && drv->probe_req_ie) {
876 size_t len = wpabuf_len(drv->probe_req_ie);
877 u8* data = (u8*)wpabuf_head(drv->probe_req_ie);
878 if ((ies_len == len) && (0 == os_memcmp(ies, data, ies_len))) {
879 return 0;
880 }
881 }
882
883 os_memset(&WscModeStruct, 0, sizeof(TWscMode));
884
885 if (!ies || (0 == ies_len)) {
886 WscModeStruct.WSCMode = TIWLN_SIMPLE_CONFIG_OFF;
887 } else {
888 const size_t head_len = 6; /* probeReqIe head: dd xx 00 50 f2 04 */
889 u8 *pos, *end;
890 u16 password_id = 0;
891 size_t min_len = 0;
892
893 pos = (u8*)ies + head_len; /* Find the WSC mode in probe_req_ie by password_id */
894 end = (u8*)ies + ies_len;
895 while (pos < end) {
896 if (ATTR_DEV_PASSWORD_ID == WPA_GET_BE16(pos)) {
897 password_id = WPA_GET_BE16(pos+4);
898 break;
899 }
900 pos += (4 + WPA_GET_BE16(pos+2));
901 }
902 WscModeStruct.WSCMode = (DEV_PW_PUSHBUTTON == password_id)?TIWLN_SIMPLE_CONFIG_PBC_METHOD:TIWLN_SIMPLE_CONFIG_PIN_METHOD;
903
904 pos = (u8*)ies + head_len;
905 min_len = ies_len - head_len;
906 if (min_len > sizeof(WscModeStruct.probeReqWSCIE)) {
907 min_len = sizeof(WscModeStruct.probeReqWSCIE);
908 }
909 os_memcpy(WscModeStruct.probeReqWSCIE, pos, min_len);
910 }
911
912 wpa_hexdump(MSG_DEBUG, "SetProbeReqIe:WscModeStruct", (u8*)&WscModeStruct, sizeof(TWscMode));
913 if(0 == wpa_driver_tista_private_send(priv, SITE_MGR_SIMPLE_CONFIG_MODE, (void*)&WscModeStruct, sizeof(TWscMode), NULL, 0)) {
914 /* Update the cached probe req ie */
915 wpabuf_free(drv->probe_req_ie);
916 drv->probe_req_ie = NULL;
917
918 if (ies && ies_len) {
919 drv->probe_req_ie = wpabuf_alloc(sizeof(WscModeStruct.probeReqWSCIE));
920 if (drv->probe_req_ie) {
921 wpabuf_put_data(drv->probe_req_ie, ies, ies_len);
922 }
923 }
924 } else {
925 wpa_printf(MSG_ERROR, "ERROR - Failed to set wsc mode!");
926 return -1;
927 }
928 #endif
929 return 0;
930 }
931 #endif
932
933 /**
934 * wpa_driver_tista_init - Initialize WE driver interface
935 * @ctx: context to be used when calling wpa_supplicant functions,
936 * e.g., wpa_supplicant_event()
937 * @ifname: interface name, e.g., wlan0
938 * Returns: Pointer to private data, %NULL on failure
939 */
wpa_driver_tista_init(void * ctx,const char * ifname)940 void * wpa_driver_tista_init(void *ctx, const char *ifname)
941 {
942 struct wpa_driver_ti_data *drv;
943
944 drv = os_zalloc(sizeof(*drv));
945 if (drv == NULL)
946 return NULL;
947 drv->wext = wpa_driver_wext_init(ctx, ifname);
948 if (drv->wext == NULL) {
949 os_free(drv);
950 return NULL;
951 }
952
953 drv->ctx = ctx;
954 os_strncpy(drv->ifname, ifname, sizeof(drv->ifname));
955 drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
956 if (drv->ioctl_sock < 0) {
957 perror("socket");
958 wpa_driver_wext_deinit(drv->wext);
959 os_free(drv);
960 return NULL;
961 }
962
963 /* Signal that driver is not stopped */
964 drv->driver_is_loaded = TRUE;
965
966 /* Set default scan type */
967 drv->scan_type = SCAN_TYPE_NORMAL_ACTIVE;
968 drv->force_merge_flag = 0;
969 scan_init(drv);
970
971 /* Set default amount of channels */
972 drv->scan_channels = check_and_get_build_channels();
973
974 /* Link Speed will be set by the message from the driver */
975 drv->link_speed = 0;
976
977 /* BtCoex mode is read from tiwlan.ini file */
978 drv->btcoex_mode = 0; /* SG_DISABLE */
979
980 #ifdef CONFIG_WPS
981 /* The latest probe_req_ie for WSC */
982 drv->probe_req_ie = NULL;
983 #endif
984
985 /* Number of sequential errors */
986 drv->errors = 0;
987 return drv;
988 }
989
990 /**
991 * wpa_driver_tista_deinit - Deinitialize WE driver interface
992 * @priv: Pointer to private wext data from wpa_driver_tista_init()
993 *
994 * Shut down driver interface and processing of driver events. Free
995 * private data buffer if one was allocated in wpa_driver_tista_init().
996 */
wpa_driver_tista_deinit(void * priv)997 void wpa_driver_tista_deinit(void *priv)
998 {
999 struct wpa_driver_ti_data *drv = priv;
1000
1001 wpa_driver_wext_deinit(drv->wext);
1002 close(drv->ioctl_sock);
1003 scan_exit(drv);
1004 #ifdef CONFIG_WPS
1005 wpabuf_free(drv->probe_req_ie);
1006 drv->probe_req_ie = NULL;
1007 #endif
1008 os_free(drv);
1009 }
1010
wpa_driver_tista_set_auth_param(struct wpa_driver_ti_data * drv,int idx,u32 value)1011 static int wpa_driver_tista_set_auth_param(struct wpa_driver_ti_data *drv,
1012 int idx, u32 value)
1013 {
1014 struct iwreq iwr;
1015 int ret = 0;
1016
1017 os_memset(&iwr, 0, sizeof(iwr));
1018 os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1019 iwr.u.param.flags = idx & IW_AUTH_INDEX;
1020 iwr.u.param.value = value;
1021
1022 if (ioctl(drv->ioctl_sock, SIOCSIWAUTH, &iwr) < 0) {
1023 perror("ioctl[SIOCSIWAUTH]");
1024 wpa_printf(MSG_ERROR, "WEXT auth param %d value 0x%x - ",
1025 idx, value);
1026 ret = errno == EOPNOTSUPP ? -2 : -1;
1027 }
1028
1029 return ret;
1030 }
1031
wpa_driver_tista_set_wpa(void * priv,int enabled)1032 static int wpa_driver_tista_set_wpa(void *priv, int enabled)
1033 {
1034 struct wpa_driver_ti_data *drv = priv;
1035 int ret;
1036
1037 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1038 ret = wpa_driver_tista_set_auth_param(drv, IW_AUTH_WPA_ENABLED,
1039 enabled);
1040 return ret;
1041 }
1042
wpa_driver_tista_set_auth_alg(void * priv,int auth_alg)1043 static int wpa_driver_tista_set_auth_alg(void *priv, int auth_alg)
1044 {
1045 struct wpa_driver_ti_data *drv = priv;
1046 int algs = 0, res;
1047
1048 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1049 if (auth_alg & AUTH_ALG_OPEN_SYSTEM)
1050 algs |= IW_AUTH_ALG_OPEN_SYSTEM;
1051 if (auth_alg & AUTH_ALG_SHARED_KEY)
1052 algs |= IW_AUTH_ALG_SHARED_KEY;
1053 if (auth_alg & AUTH_ALG_LEAP)
1054 algs |= IW_AUTH_ALG_LEAP;
1055 if (algs == 0) {
1056 /* at least one algorithm should be set */
1057 algs = IW_AUTH_ALG_OPEN_SYSTEM;
1058 }
1059
1060 res = wpa_driver_tista_set_auth_param(drv, IW_AUTH_80211_AUTH_ALG,
1061 algs);
1062
1063 return res;
1064 }
1065
wpa_driver_tista_set_countermeasures(void * priv,int enabled)1066 static int wpa_driver_tista_set_countermeasures(void *priv, int enabled)
1067 {
1068 struct wpa_driver_ti_data *drv = priv;
1069 int ret;
1070
1071 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1072 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1073 ret = wpa_driver_tista_set_auth_param(drv,
1074 IW_AUTH_TKIP_COUNTERMEASURES,
1075 enabled);
1076 return ret;
1077 }
1078
wpa_driver_tista_set_drop_unencrypted(void * priv,int enabled)1079 static int wpa_driver_tista_set_drop_unencrypted(void *priv,
1080 int enabled)
1081 {
1082 struct wpa_driver_ti_data *drv = priv;
1083 int ret;
1084
1085 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1086 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1087 /* Dm: drv->use_crypt = enabled; */
1088 ret = wpa_driver_tista_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED,
1089 enabled);
1090 return ret;
1091 }
1092
wpa_driver_tista_pmksa(struct wpa_driver_ti_data * drv,u32 cmd,const u8 * bssid,const u8 * pmkid)1093 static int wpa_driver_tista_pmksa(struct wpa_driver_ti_data *drv,
1094 u32 cmd, const u8 *bssid, const u8 *pmkid)
1095 {
1096 struct iwreq iwr;
1097 struct iw_pmksa pmksa;
1098 int ret = 0;
1099
1100 os_memset(&iwr, 0, sizeof(iwr));
1101 os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1102 os_memset(&pmksa, 0, sizeof(pmksa));
1103 pmksa.cmd = cmd;
1104 pmksa.bssid.sa_family = ARPHRD_ETHER;
1105 if (bssid)
1106 os_memcpy(pmksa.bssid.sa_data, bssid, ETH_ALEN);
1107 if (pmkid) {
1108 os_memcpy(pmksa.pmkid, pmkid, IW_PMKID_LEN);
1109 wpa_printf(MSG_DEBUG, "pmkid %s", pmkid);
1110 }
1111 iwr.u.data.pointer = (caddr_t)&pmksa;
1112 iwr.u.data.length = sizeof(pmksa);
1113
1114 if (ioctl(drv->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) {
1115 if (errno != EOPNOTSUPP)
1116 perror("ioctl[SIOCSIWPMKSA]");
1117 ret = -1;
1118 }
1119 return ret;
1120 }
1121
wpa_driver_tista_add_pmkid(void * priv,const u8 * bssid,const u8 * pmkid)1122 static int wpa_driver_tista_add_pmkid(void *priv, const u8 *bssid,
1123 const u8 *pmkid)
1124 {
1125 struct wpa_driver_ti_data *drv = priv;
1126 int ret;
1127
1128 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1129 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1130 ret = wpa_driver_tista_pmksa(drv, IW_PMKSA_ADD, bssid, pmkid);
1131 return ret;
1132 }
1133
wpa_driver_tista_remove_pmkid(void * priv,const u8 * bssid,const u8 * pmkid)1134 static int wpa_driver_tista_remove_pmkid(void *priv, const u8 *bssid,
1135 const u8 *pmkid)
1136 {
1137 struct wpa_driver_ti_data *drv = priv;
1138 int ret;
1139
1140 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1141 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1142 ret = wpa_driver_tista_pmksa(drv, IW_PMKSA_REMOVE, bssid, pmkid);
1143 return ret;
1144 }
1145
wpa_driver_tista_flush_pmkid(void * priv)1146 static int wpa_driver_tista_flush_pmkid(void *priv)
1147 {
1148 struct wpa_driver_ti_data *drv = priv;
1149 int ret;
1150
1151 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1152 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1153 ret = wpa_driver_tista_pmksa(drv, IW_PMKSA_FLUSH, NULL, NULL);
1154 return ret;
1155 }
1156
wpa_driver_tista_mlme(struct wpa_driver_ti_data * drv,const u8 * addr,int cmd,int reason_code)1157 static int wpa_driver_tista_mlme(struct wpa_driver_ti_data *drv,
1158 const u8 *addr, int cmd, int reason_code)
1159 {
1160 struct iwreq iwr;
1161 struct iw_mlme mlme;
1162 int ret = 0;
1163
1164 os_memset(&iwr, 0, sizeof(iwr));
1165 os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1166 os_memset(&mlme, 0, sizeof(mlme));
1167 mlme.cmd = cmd;
1168 mlme.reason_code = reason_code;
1169 mlme.addr.sa_family = ARPHRD_ETHER;
1170 os_memcpy(mlme.addr.sa_data, addr, ETH_ALEN);
1171 iwr.u.data.pointer = (caddr_t) &mlme;
1172 iwr.u.data.length = sizeof(mlme);
1173
1174 if (ioctl(drv->ioctl_sock, SIOCSIWMLME, &iwr) < 0) {
1175 perror("ioctl[SIOCSIWMLME]");
1176 ret = -1;
1177 }
1178
1179 return ret;
1180 }
1181
wpa_driver_tista_deauthenticate(void * priv,const u8 * addr,int reason_code)1182 static int wpa_driver_tista_deauthenticate(void *priv, const u8 *addr,
1183 int reason_code)
1184 {
1185 struct wpa_driver_ti_data *drv = priv;
1186 int ret;
1187
1188 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1189 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1190 ret = wpa_driver_tista_mlme(drv, addr, IW_MLME_DEAUTH, reason_code);
1191 return ret;
1192 }
1193
1194
wpa_driver_tista_disassociate(void * priv,const u8 * addr,int reason_code)1195 static int wpa_driver_tista_disassociate(void *priv, const u8 *addr,
1196 int reason_code)
1197 {
1198 struct wpa_driver_ti_data *drv = priv;
1199 int ret;
1200
1201 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1202 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1203 ret = wpa_driver_tista_mlme(drv, addr, IW_MLME_DISASSOC, reason_code);
1204 return ret;
1205 }
1206
wpa_driver_tista_set_key(void * priv,wpa_alg alg,const u8 * addr,int key_idx,int set_tx,const u8 * seq,size_t seq_len,const u8 * key,size_t key_len)1207 static int wpa_driver_tista_set_key(void *priv, wpa_alg alg,
1208 const u8 *addr, int key_idx,
1209 int set_tx, const u8 *seq, size_t seq_len,
1210 const u8 *key, size_t key_len)
1211 {
1212 struct wpa_driver_ti_data *drv = priv;
1213 int ret;
1214
1215 wpa_printf(MSG_DEBUG, "%s", __func__);
1216 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1217 ret = wpa_driver_wext_set_key(drv->wext, alg, addr, key_idx, set_tx,
1218 seq, seq_len, key, key_len);
1219 return ret;
1220 }
1221
wpa_driver_tista_set_gen_ie(void * priv,const u8 * ie,size_t ie_len)1222 static int wpa_driver_tista_set_gen_ie(void *priv, const u8 *ie, size_t ie_len)
1223 {
1224 struct wpa_driver_ti_data *drv = priv;
1225 struct iwreq iwr;
1226 int ret = 0;
1227
1228 os_memset(&iwr, 0, sizeof(iwr));
1229 os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1230 iwr.u.data.pointer = (caddr_t)ie;
1231 iwr.u.data.length = ie_len;
1232
1233 if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) {
1234 perror("ioctl[SIOCSIWGENIE]");
1235 ret = -1;
1236 }
1237
1238 return ret;
1239 }
1240
1241 #ifdef WPA_SUPPLICANT_VER_0_6_X
wpa_driver_tista_get_scan_results(void * priv)1242 static struct wpa_scan_results *wpa_driver_tista_get_scan_results(void *priv)
1243 {
1244 struct wpa_driver_ti_data *drv = priv;
1245 struct wpa_scan_results *res;
1246 struct wpa_scan_res **tmp;
1247 unsigned ap_num;
1248
1249 TI_CHECK_DRIVER( drv->driver_is_loaded, NULL );
1250 res = wpa_driver_wext_get_scan_results(drv->wext);
1251 if (res == NULL) {
1252 return NULL;
1253 }
1254
1255 wpa_printf(MSG_DEBUG, "Actual APs number %d", res->num);
1256 ap_num = (unsigned)scan_count(drv) + res->num;
1257 tmp = os_realloc(res->res, ap_num * sizeof(struct wpa_scan_res *));
1258 if (tmp == NULL)
1259 return res;
1260 res->num = scan_merge(drv, tmp, drv->force_merge_flag, res->num, ap_num);
1261 wpa_printf(MSG_DEBUG, "After merge, APs number %d", res->num);
1262 tmp = os_realloc(tmp, res->num * sizeof(struct wpa_scan_res *));
1263 res->res = tmp;
1264 return res;
1265 }
1266
wpa_driver_tista_set_mode(void * priv,int mode)1267 int wpa_driver_tista_set_mode(void *priv, int mode)
1268 {
1269 struct wpa_driver_ti_data *drv = priv;
1270 int ret;
1271
1272 wpa_printf(MSG_DEBUG, "%s", __func__);
1273 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1274 ret = wpa_driver_wext_set_mode(drv->wext, mode);
1275 return ret;
1276 }
1277 #else
1278 /*-----------------------------------------------------------------------------
1279 Compare function for sorting scan results. Return >0 if @b is considered better.
1280 -----------------------------------------------------------------------------*/
wpa_driver_tista_scan_result_compare(const void * a,const void * b)1281 static int wpa_driver_tista_scan_result_compare(const void *a, const void *b)
1282 {
1283 const struct wpa_scan_result *wa = a;
1284 const struct wpa_scan_result *wb = b;
1285
1286 return( wb->level - wa->level );
1287 }
1288
wpa_driver_tista_get_scan_results(void * priv,struct wpa_scan_result * results,size_t max_size)1289 static int wpa_driver_tista_get_scan_results(void *priv,
1290 struct wpa_scan_result *results,
1291 size_t max_size)
1292 {
1293 struct wpa_driver_ti_data *drv = priv;
1294 int ap_num = 0;
1295
1296 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1297 ap_num = wpa_driver_wext_get_scan_results(drv->wext, results, max_size);
1298 wpa_printf(MSG_DEBUG, "Actual APs number %d", ap_num);
1299
1300 if (ap_num < 0)
1301 return -1;
1302
1303 /* Merge new results with previous */
1304 ap_num = scan_merge(drv, results, drv->force_merge_flag, ap_num, max_size);
1305 wpa_printf(MSG_DEBUG, "After merge, APs number %d", ap_num);
1306 qsort(results, ap_num, sizeof(struct wpa_scan_result),
1307 wpa_driver_tista_scan_result_compare);
1308 return ap_num;
1309 }
1310 #endif
1311
wpa_driver_tista_associate(void * priv,struct wpa_driver_associate_params * params)1312 static int wpa_driver_tista_associate(void *priv,
1313 struct wpa_driver_associate_params *params)
1314 {
1315 struct wpa_driver_ti_data *drv = priv;
1316 int allow_unencrypted_eapol;
1317 int value, flags, ret = 0;
1318
1319 wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1320 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1321
1322 #ifdef WPA_SUPPLICANT_VER_0_6_X
1323 #ifdef ANDROID
1324 ((struct wpa_driver_wext_data *)(drv->wext))->skip_disconnect = 0;
1325 #endif
1326 #endif
1327
1328 if (wpa_driver_wext_get_ifflags(drv->wext, &flags) == 0) {
1329 if (!(flags & IFF_UP)) {
1330 wpa_driver_wext_set_ifflags(drv->wext, flags | IFF_UP);
1331 }
1332 }
1333
1334 #if 0
1335 if (!params->bssid)
1336 wpa_driver_wext_set_bssid(drv->wext, NULL);
1337 #endif
1338
1339 #ifdef WPA_SUPPLICANT_VER_0_5_X
1340 /* Set driver network mode (Adhoc/Infrastructure) according to supplied parameters */
1341 wpa_driver_wext_set_mode(drv->wext, params->mode);
1342 #endif
1343 wpa_driver_tista_set_gen_ie(drv, params->wpa_ie, params->wpa_ie_len);
1344
1345 if (params->wpa_ie == NULL || params->wpa_ie_len == 0)
1346 value = IW_AUTH_WPA_VERSION_DISABLED;
1347 #ifdef WPA_SUPPLICANT_VER_0_6_X
1348 else if (params->wpa_ie[0] == WLAN_EID_RSN)
1349 #else
1350 else if (params->wpa_ie[0] == RSN_INFO_ELEM)
1351 #endif
1352 value = IW_AUTH_WPA_VERSION_WPA2;
1353 #ifdef CONFIG_WPS
1354 else if (params->key_mgmt_suite == KEY_MGMT_WPS)
1355 value = IW_AUTH_WPA_VERSION_DISABLED;
1356 #endif
1357 else
1358 value = IW_AUTH_WPA_VERSION_WPA;
1359 wpa_driver_tista_set_auth_param(drv, IW_AUTH_WPA_VERSION, value);
1360 value = wpa_driver_tista_cipher2wext(params->pairwise_suite);
1361 wpa_driver_tista_set_auth_param(drv, IW_AUTH_CIPHER_PAIRWISE, value);
1362 value = wpa_driver_tista_cipher2wext(params->group_suite);
1363 wpa_driver_tista_set_auth_param(drv, IW_AUTH_CIPHER_GROUP, value);
1364 value = wpa_driver_tista_keymgmt2wext(params->key_mgmt_suite);
1365 wpa_driver_tista_set_auth_param(drv, IW_AUTH_KEY_MGMT, value);
1366 value = params->key_mgmt_suite != KEY_MGMT_NONE ||
1367 params->pairwise_suite != CIPHER_NONE ||
1368 params->group_suite != CIPHER_NONE ||
1369 #ifdef WPA_SUPPLICANT_VER_0_6_X
1370 (params->wpa_ie_len && (params->key_mgmt_suite != KEY_MGMT_WPS));
1371 #else
1372 params->wpa_ie_len;
1373 #endif
1374 wpa_driver_tista_set_auth_param(drv, IW_AUTH_PRIVACY_INVOKED, value);
1375
1376 /* Allow unencrypted EAPOL messages even if pairwise keys are set when
1377 * not using WPA. IEEE 802.1X specifies that these frames are not
1378 * encrypted, but WPA encrypts them when pairwise keys are in use. */
1379 if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
1380 params->key_mgmt_suite == KEY_MGMT_PSK)
1381 allow_unencrypted_eapol = 0;
1382 else
1383 allow_unencrypted_eapol = 1;
1384
1385 wpa_driver_tista_set_auth_param(drv,
1386 IW_AUTH_RX_UNENCRYPTED_EAPOL,
1387 allow_unencrypted_eapol);
1388
1389 if (params->freq)
1390 wpa_driver_wext_set_freq(drv->wext, params->freq);
1391
1392 if (params->bssid) {
1393 wpa_printf(MSG_DEBUG, "wpa_driver_tista_associate: BSSID=" MACSTR,
1394 MAC2STR(params->bssid));
1395 /* if there is bssid -> set it */
1396 if (os_memcmp(params->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0) {
1397 wpa_driver_wext_set_bssid(drv->wext, params->bssid);
1398 }
1399 }
1400 ret = wpa_driver_wext_set_ssid(drv->wext, params->ssid, params->ssid_len);
1401 return ret;
1402 }
1403
wpa_driver_tista_set_operstate(void * priv,int state)1404 static int wpa_driver_tista_set_operstate(void *priv, int state)
1405 {
1406 struct wpa_driver_ti_data *drv = priv;
1407
1408 wpa_printf(MSG_DEBUG, "%s: operstate %d (%s)",
1409 __func__, /*drv->operstate,*/ state, state ? "UP" : "DORMANT");
1410 TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1411 /* Dm: drv->operstate = state; */
1412 return wpa_driver_wext_set_operstate(drv->wext, state);
1413 }
1414
1415 const struct wpa_driver_ops wpa_driver_custom_ops = {
1416 .name = TIWLAN_DRV_NAME,
1417 .desc = "TI Station Driver (1271)",
1418 .get_bssid = wpa_driver_tista_get_bssid,
1419 .get_ssid = wpa_driver_tista_get_ssid,
1420 .set_wpa = wpa_driver_tista_set_wpa,
1421 .set_key = wpa_driver_tista_set_key,
1422 .set_countermeasures = wpa_driver_tista_set_countermeasures,
1423 .set_drop_unencrypted = wpa_driver_tista_set_drop_unencrypted,
1424 .scan = wpa_driver_tista_scan,
1425 #ifdef WPA_SUPPLICANT_VER_0_6_X
1426 .get_scan_results2 = wpa_driver_tista_get_scan_results,
1427 .combo_scan = NULL,
1428 #else
1429 .get_scan_results = wpa_driver_tista_get_scan_results,
1430 #endif
1431 .deauthenticate = wpa_driver_tista_deauthenticate,
1432 .disassociate = wpa_driver_tista_disassociate,
1433 .associate = wpa_driver_tista_associate,
1434 .set_auth_alg = wpa_driver_tista_set_auth_alg,
1435 .get_mac_addr = wpa_driver_tista_get_mac_addr,
1436 .init = wpa_driver_tista_init,
1437 .deinit = wpa_driver_tista_deinit,
1438 .add_pmkid = wpa_driver_tista_add_pmkid,
1439 .remove_pmkid = wpa_driver_tista_remove_pmkid,
1440 .flush_pmkid = wpa_driver_tista_flush_pmkid,
1441 .set_operstate = wpa_driver_tista_set_operstate,
1442 #ifdef WPA_SUPPLICANT_VER_0_6_X
1443 .set_mode = wpa_driver_tista_set_mode,
1444 .set_probe_req_ie = wpa_driver_tista_set_probe_req_ie,
1445 #endif
1446 .driver_cmd = wpa_driver_tista_driver_cmd
1447 };
1448