• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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