• 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 	else
305 		wpa_printf(MSG_DEBUG, "wpa_driver_tista_scan success");
306 
307 	timeout = 30;
308 	wpa_printf(MSG_DEBUG, "Scan requested (ret=%d) - scan timeout %d sec",
309 			res, timeout);
310 	eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv->wext, drv->ctx);
311 	eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout,
312 				drv->wext, drv->ctx);
313 	return res;
314 #else
315 	return wpa_driver_wext_scan(drv->wext, ssid, ssid_len);
316 #endif
317 }
318 
319 /*-----------------------------------------------------------------------------
320 Routine Name: wpa_driver_tista_get_mac_addr
321 Routine Description: return WLAN MAC address
322 Arguments:
323    priv - pointer to private data structure
324 Return Value: pointer to BSSID
325 -----------------------------------------------------------------------------*/
wpa_driver_tista_get_mac_addr(void * priv)326 const u8 *wpa_driver_tista_get_mac_addr( void *priv )
327 {
328 	struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
329 	u8 mac[ETH_ALEN];
330 
331 	TI_CHECK_DRIVER( drv->driver_is_loaded, NULL );
332 	if(0 != wpa_driver_tista_private_send(priv, CTRL_DATA_MAC_ADDRESS, NULL, 0,
333 		mac, ETH_ALEN))
334 	{
335 		wpa_printf(MSG_ERROR, "ERROR - Failed to get mac address!");
336 		os_memset(drv->own_addr, 0, ETH_ALEN);
337 	}
338 	else
339 	{
340 		os_memcpy(drv->own_addr, mac, ETH_ALEN);
341 		wpa_printf(MSG_DEBUG, "Macaddr = " MACSTR, MAC2STR(drv->own_addr));
342 	}
343 	wpa_printf(MSG_DEBUG, "wpa_driver_tista_get_mac_addr success");
344 
345 	return (const u8 *)&drv->own_addr;
346 }
347 
wpa_driver_tista_get_rssi(void * priv,int * rssi_data,int * rssi_beacon)348 static int wpa_driver_tista_get_rssi(void *priv, int *rssi_data, int *rssi_beacon)
349 {
350 	u8 bssid[ETH_ALEN];
351 	struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
352 	TCuCommon_RoamingStatisticsTable buffer;
353 
354 	*rssi_data = 0;
355 	*rssi_beacon = 0;
356 	if (wpa_driver_tista_get_bssid(priv, bssid) == 0 &&
357 		os_memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0) {
358 		if(0 != wpa_driver_tista_private_send(priv, TIWLN_802_11_RSSI, NULL, 0,
359 				&buffer, sizeof(TCuCommon_RoamingStatisticsTable))) {
360 			wpa_printf(MSG_ERROR, "ERROR - Failed to get rssi level");
361 			return -1;
362 		}
363 		*rssi_data = (s8)buffer.rssi;
364 		*rssi_beacon = (s8)buffer.rssiBeacon;
365 		wpa_printf(MSG_DEBUG, "wpa_driver_tista_get_rssi data %d beacon %d success",
366 						*rssi_data, *rssi_beacon);
367 	}
368 	else {
369 		wpa_printf(MSG_DEBUG, "no WiFi link.");
370 		return -1;
371 	}
372 	return 0;
373 }
374 
wpa_driver_tista_config_power_management(void * priv,TPowerMgr_PowerMode * mode,u8 is_set)375 static int wpa_driver_tista_config_power_management(void *priv, TPowerMgr_PowerMode *mode, u8 is_set)
376 {
377 	struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
378 
379 	if(is_set) /* set power mode */
380 	{
381 		if((mode->PowerMode) < POWER_MODE_MAX)
382 		{
383 			if(0 != wpa_driver_tista_private_send(priv, TIWLN_802_11_POWER_MODE_SET,
384 				mode, sizeof(TPowerMgr_PowerMode), NULL, 0))
385 			{
386 				wpa_printf(MSG_ERROR, "ERROR - Failed to set power mode");
387 				return -1;
388 			}
389 		}
390 		else
391 		{
392 			wpa_printf(MSG_ERROR, "ERROR - Invalid Power Mode");
393 			return -1;
394 		}
395 	}
396 	else /* get power mode */
397 	{
398 		if(0 != wpa_driver_tista_private_send(priv, TIWLN_802_11_POWER_MODE_GET, NULL, 0,
399 			mode, sizeof(TPowerMgr_PowerMode)))
400 		{
401 			wpa_printf(MSG_ERROR, "ERROR - Failed to get power mode");
402 			return -1;
403 		}
404 	}
405 	wpa_printf(MSG_DEBUG, "wpa_driver_tista_config_power_management success");
406 
407 	return 0;
408 }
409 
wpa_driver_tista_enable_bt_coe(void * priv,u32 mode)410 static int wpa_driver_tista_enable_bt_coe(void *priv, u32 mode)
411 {
412 	struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
413 	u32 mode_set = mode;
414 
415 	/* Mapping the mode between UI enum and driver enum */
416 	switch(mode_set)
417 	{
418 		case BLUETOOTH_COEXISTENCE_MODE_ENABLED:
419 			mode_set = SG_OPPORTUNISTIC;
420 			break;
421 		case BLUETOOTH_COEXISTENCE_MODE_SENSE:
422 			mode_set = SG_PROTECTIVE;
423 			break;
424 		case BLUETOOTH_COEXISTENCE_MODE_DISABLED:
425 			mode_set = SG_DISABLE;
426 			break;
427 		default:
428 			wpa_printf(MSG_DEBUG, "wpa_driver_tista_enable_bt_coe - Unknown Mode");
429 			return -1;
430 			break;
431 	}
432 
433 	if(0 != wpa_driver_tista_private_send(priv, SOFT_GEMINI_SET_ENABLE,
434 		&mode_set, sizeof(u32), NULL, 0))
435 	{
436 		wpa_printf(MSG_ERROR, "ERROR - Failed to enable BtCoe");
437 		return -1;
438 	}
439 	wpa_printf(MSG_DEBUG, "wpa_driver_tista_enable_bt_coe success");
440 
441 	return 0;
442 }
443 
wpa_driver_tista_get_bt_coe_status(void * priv,u32 * mode)444 static int wpa_driver_tista_get_bt_coe_status(void *priv, u32 *mode)
445 {
446 	struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
447 	u32 mode_get;
448 
449 	if(0 != wpa_driver_tista_private_send(priv, SOFT_GEMINI_GET_CONFIG, NULL, 0,
450 		&mode_get, sizeof(u32)))
451 	{
452 		wpa_printf(MSG_ERROR, "ERROR - Failed to get bt coe status");
453 		return -1;
454 	}
455 	*mode = mode_get;
456 	wpa_printf(MSG_DEBUG, "wpa_driver_tista_get_bt_coe_status mode %d success", *mode);
457 
458 	return 0;
459 }
460 
461 /*-----------------------------------------------------------------------------
462 Routine Name: prepare_filter_struct
463 Routine Description: fills rx data filter structure according to parameter type
464 Arguments:
465    priv - pointer to private data structure
466    type - type of mac address
467    dfreq_ptr - pointer to TRxDataFilterRequest structure
468 Return Value: 0 - success, -1 - error
469 -----------------------------------------------------------------------------*/
prepare_filter_struct(void * priv,int type,TRxDataFilterRequest * dfreq_ptr)470 static int prepare_filter_struct( void *priv, int type,
471 					TRxDataFilterRequest *dfreq_ptr )
472 {
473 	const u8 *macaddr = NULL;
474 	size_t len = 0;
475 	u8 mask;
476 	int ret = -1;
477 
478 	wpa_printf(MSG_DEBUG, "filter type=%d", type);
479 	switch (type) {
480 	case RX_SELF_FILTER:
481 		macaddr = wpa_driver_tista_get_mac_addr(priv);
482 		len = MAC_ADDR_LEN;
483 		mask = 0x3F; /* 6 bytes */
484 		break;
485 	case RX_BROADCAST_FILTER:
486 		macaddr = (const u8 *)"\xFF\xFF\xFF\xFF\xFF\xFF";
487 		len = MAC_ADDR_LEN;
488 		mask = 0x3F; /* 6 bytes */
489 		break;
490 	case RX_IPV4_MULTICAST_FILTER:
491 		macaddr = (const u8 *)"\x01\x00\x5E";
492 		len = 3;
493 		mask = 0x7; /* 3 bytes */
494 		break;
495 	case RX_IPV6_MULTICAST_FILTER:
496 		macaddr = (const u8 *)"\x33\x33";
497 		len = 2;
498 		mask = 0x3; /* 2 bytes */
499 		break;
500 	}
501 
502 	if (macaddr != NULL) {
503 		dfreq_ptr->offset = 0;
504 		dfreq_ptr->maskLength = 1;
505 		dfreq_ptr->mask[0] = mask;
506 		dfreq_ptr->patternLength = len;
507 		os_memcpy( dfreq_ptr->pattern, macaddr, MAC_ADDR_LEN );
508 		ret = 0;
509 	}
510 	return ret;
511 }
512 
wpa_driver_tista_driver_rx_data_filter(void * priv,TRxDataFilterRequest * dfreq_ptr,u8 is_add)513 static int wpa_driver_tista_driver_rx_data_filter( void *priv, TRxDataFilterRequest *dfreq_ptr, u8 is_add )
514 {
515 	struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
516 	int cmd, res;
517 
518 	if (is_add) { /* add rx data filter */
519 		cmd = TIWLN_ADD_RX_DATA_FILTER;
520 		wpa_printf(MSG_DEBUG, "Add RX data filter");
521 	}
522 	else { /* remove rx data filter */
523 		cmd = TIWLN_REMOVE_RX_DATA_FILTER;
524 		wpa_printf(MSG_DEBUG, "Remove RX data filter");
525 	}
526 
527 	res = wpa_driver_tista_private_send(priv, cmd, dfreq_ptr, sizeof(TRxDataFilterRequest), NULL, 0);
528 	if (0 != res)
529 		wpa_printf(MSG_ERROR, "ERROR - Failed to handle rx data filter command!");
530 	else
531 		wpa_printf(MSG_DEBUG, "%s success", __func__);
532 	return res;
533 }
534 
wpa_driver_tista_driver_enable_rx_data_filter(void * priv)535 static int wpa_driver_tista_driver_enable_rx_data_filter( void *priv )
536 {
537 	struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
538 	u32 val = TRUE;
539 	int res;
540 
541 	res = wpa_driver_tista_private_send(priv, TIWLN_ENABLE_DISABLE_RX_DATA_FILTERS,
542 						&val, sizeof(u32), NULL, 0);
543 	if (0 != res)
544 		wpa_printf(MSG_ERROR, "ERROR - Failed to enable RX data filter!");
545 	else
546 		wpa_printf(MSG_DEBUG, "%s success", __func__);
547 	return res;
548 }
549 
wpa_driver_tista_driver_disable_rx_data_filter(void * priv)550 static int wpa_driver_tista_driver_disable_rx_data_filter( void *priv )
551 {
552 	struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
553 	u32 val = FALSE;
554 	int res;
555 
556 	res = wpa_driver_tista_private_send(priv, TIWLN_ENABLE_DISABLE_RX_DATA_FILTERS,
557 						&val, sizeof(u32), NULL, 0);
558 	if (0 != res)
559 		wpa_printf(MSG_ERROR, "ERROR - Failed to disable RX data filter!");
560 	else
561 		wpa_printf(MSG_DEBUG, "%s success", __func__);
562 	return res;
563 }
564 
wpa_driver_tista_driver_rx_data_filter_statistics(void * priv,TCuCommon_RxDataFilteringStatistics * stats)565 static int wpa_driver_tista_driver_rx_data_filter_statistics( void *priv,
566 				TCuCommon_RxDataFilteringStatistics *stats )
567 {
568 	struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
569 	int res;
570 
571 	res = wpa_driver_tista_private_send(priv, TIWLN_GET_RX_DATA_FILTERS_STATISTICS,
572 		NULL, 0, stats, sizeof(TCuCommon_RxDataFilteringStatistics));
573 	if (0 != res)
574 		wpa_printf(MSG_ERROR, "ERROR - Failed to get RX data filter statistics!");
575 	else
576 		wpa_printf(MSG_DEBUG, "%s success", __func__);
577 	return res;
578 }
579 
580 /*-----------------------------------------------------------------------------
581 Routine Name: wpa_driver_tista_driver_cmd
582 Routine Description: executes driver-specific commands
583 Arguments:
584    priv - pointer to private data structure
585    cmd - command
586    buf - return buffer
587    buf_len - buffer length
588 Return Value: actual buffer length - success, -1 - failure
589 -----------------------------------------------------------------------------*/
wpa_driver_tista_driver_cmd(void * priv,char * cmd,char * buf,size_t buf_len)590 static int wpa_driver_tista_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len )
591 {
592 	struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
593 	int ret = -1, prev_events, flags;
594 
595 	wpa_printf(MSG_DEBUG, "%s %s", __func__, cmd);
596 
597 	if( os_strcasecmp(cmd, "start") == 0 ) {
598 		wpa_printf(MSG_DEBUG,"Start command");
599 		ret = wpa_driver_tista_driver_start(priv);
600 		if( ret == 0 ) {
601 			drv->driver_is_loaded = TRUE;
602 			wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
603 		}
604 		return( TI2WPA_STATUS(ret) );
605 	}
606 
607         TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
608 
609 	if( os_strcasecmp(cmd, "stop") == 0 ) {
610 		wpa_printf(MSG_DEBUG,"Stop command");
611 		if ((wpa_driver_wext_get_ifflags(drv->wext, &flags) == 0) &&
612 		    (flags & IFF_UP)) {
613 			wpa_printf(MSG_ERROR, "TI: %s when iface is UP", cmd);
614 			wpa_driver_wext_set_ifflags(drv->wext, flags & ~IFF_UP);
615 		}
616 		ret = wpa_driver_tista_driver_stop(priv);
617 		if( ret == 0 ) {
618 			scan_exit(drv); /* clear scan cache */
619 			drv->driver_is_loaded = FALSE;
620 			wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
621 		}
622 	}
623 	if( os_strcasecmp(cmd, "reload") == 0 ) {
624 		wpa_printf(MSG_DEBUG,"Reload command");
625 		ret = 0;
626 		wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
627 	}
628 	else if( os_strcasecmp(cmd, "macaddr") == 0 ) {
629 		wpa_driver_tista_get_mac_addr(priv);
630 		wpa_printf(MSG_DEBUG, "Macaddr command");
631 		ret = sprintf(buf, "Macaddr = " MACSTR "\n", MAC2STR(drv->own_addr));
632 		wpa_printf(MSG_DEBUG, "buf %s", buf);
633 	}
634 	else if( os_strcasecmp(cmd, "scan-passive") == 0 ) {
635 		wpa_printf(MSG_DEBUG,"Scan Passive command");
636 		drv->scan_type =  SCAN_TYPE_NORMAL_PASSIVE;
637 		ret = 0;
638 	}
639 	else if( os_strcasecmp(cmd, "scan-active") == 0 ) {
640 		wpa_printf(MSG_DEBUG,"Scan Active command");
641 		drv->scan_type =  SCAN_TYPE_NORMAL_ACTIVE;
642 		ret = 0;
643 	}
644 	else if( os_strcasecmp(cmd, "scan-mode") == 0 ) {
645 		wpa_printf(MSG_DEBUG,"Scan Mode command");
646 		ret = snprintf(buf, buf_len, "ScanMode = %u\n", drv->scan_type);
647 		if (ret < (int)buf_len) {
648 			return( ret );
649 		}
650 	}
651 	else if( os_strcasecmp(cmd, "linkspeed") == 0 ) {
652 		struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
653 
654  		wpa_printf(MSG_DEBUG,"Link Speed command");
655 		drv->link_speed = wpa_s->link_speed / 1000000;
656 		ret = sprintf(buf,"LinkSpeed %u\n", drv->link_speed);
657 		wpa_printf(MSG_DEBUG, "buf %s", buf);
658 	}
659 	else if( os_strncasecmp(cmd, "scan-channels", 13) == 0 ) {
660 		int noOfChan;
661 
662 		noOfChan = atoi(cmd + 13);
663 		wpa_printf(MSG_DEBUG,"Scan Channels command = %d", noOfChan);
664 		if( (noOfChan > 0) && (noOfChan <= MAX_NUMBER_OF_CHANNELS_PER_SCAN) )
665 			drv->scan_channels = noOfChan;
666 		ret = sprintf(buf,"Scan-Channels = %d\n", drv->scan_channels);
667 		wpa_printf(MSG_DEBUG, "buf %s", buf);
668 	}
669 	else if( os_strcasecmp(cmd, "rssi-approx") == 0 ) {
670 		scan_result_t *cur_res;
671 		struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
672 		scan_ssid_t *p_ssid;
673 		int rssi, len;
674 
675 		wpa_printf(MSG_DEBUG,"rssi-approx command");
676 
677 		if( !wpa_s )
678 			return( ret );
679 		cur_res = scan_get_by_bssid(drv, wpa_s->bssid);
680 		if( cur_res ) {
681 			p_ssid = scan_get_ssid(cur_res);
682 			len = (int)(p_ssid->ssid_len);
683 			rssi = cur_res->level;
684 			if( (len > 0) && (len <= MAX_SSID_LEN) && (len < (int)buf_len)) {
685 				os_memcpy((void *)buf, (void *)(p_ssid->ssid), len);
686 				ret = len;
687 				ret += snprintf(&buf[ret], buf_len-len, " rssi %d\n", rssi);
688 			}
689 		}
690 	}
691 	else if( os_strcasecmp(cmd, "rssi") == 0 ) {
692 		u8 ssid[MAX_SSID_LEN];
693 		scan_result_t *cur_res;
694 		struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
695 		int rssi_data, rssi_beacon, len;
696 
697 		wpa_printf(MSG_DEBUG,"rssi command");
698 
699 		ret = wpa_driver_tista_get_rssi(priv, &rssi_data, &rssi_beacon);
700 		if( ret == 0 ) {
701 			len = wpa_driver_tista_get_ssid(priv, (u8 *)ssid);
702 			wpa_printf(MSG_DEBUG,"rssi_data %d rssi_beacon %d", rssi_data, rssi_beacon);
703 			if( (len > 0) && (len <= MAX_SSID_LEN) ) {
704 				os_memcpy((void *)buf, (void *)ssid, len);
705 				ret = len;
706 				ret += sprintf(&buf[ret], " rssi %d\n", rssi_beacon);
707 				wpa_printf(MSG_DEBUG, "buf %s", buf);
708 				/* Update cached value */
709 				if( !wpa_s )
710 					return( ret );
711 				cur_res = scan_get_by_bssid(drv, wpa_s->bssid);
712 				if( cur_res )
713 					cur_res->level = rssi_beacon;
714 			}
715 			else
716 			{
717 				wpa_printf(MSG_DEBUG, "Fail to get ssid when reporting rssi");
718 				ret = -1;
719 			}
720 		}
721 	}
722 	else if( os_strncasecmp(cmd, "powermode", 9) == 0 ) {
723 		u32 mode;
724 		TPowerMgr_PowerMode tMode;
725 
726 		mode = (u32)atoi(cmd + 9);
727 		wpa_printf(MSG_DEBUG,"Power Mode command = %u", mode);
728 		if( mode < POWER_MODE_MAX )
729 		{
730 			tMode.PowerMode = (PowerMgr_PowerMode_e)mode;
731 			tMode.PowerMngPriority = POWER_MANAGER_USER_PRIORITY;
732 			ret = wpa_driver_tista_config_power_management( priv, &tMode, 1 );
733 		}
734 	}
735 	else if (os_strncasecmp(cmd, "getpower", 8) == 0 ) {
736 		u32 mode;
737 		TPowerMgr_PowerMode tMode;
738 
739 		ret = wpa_driver_tista_config_power_management( priv, &tMode, 0 );
740 		if( ret == 0 ) {
741 			ret = sprintf(buf, "powermode = %u\n", tMode.PowerMode);
742 			wpa_printf(MSG_DEBUG, "buf %s", buf);
743 		}
744 	}
745 	else if( os_strncasecmp(cmd, "btcoexmode", 10) == 0 ) {
746 		u32 mode;
747 
748 		mode = (u32)atoi(cmd + 10);
749 		wpa_printf(MSG_DEBUG,"BtCoex Mode command = %u", mode);
750 		ret = wpa_driver_tista_enable_bt_coe( priv, mode );
751 		if( ret == 0 ) {
752 			drv->btcoex_mode = mode;
753 		}
754 	}
755 	else if( os_strcasecmp(cmd, "btcoexstat") == 0 ) {
756 		u32 status = drv->btcoex_mode;
757 
758 		wpa_printf(MSG_DEBUG,"BtCoex Status");
759 		ret = wpa_driver_tista_get_bt_coe_status( priv, &status );
760 		if( ret == 0 ) {
761 			ret = sprintf(buf, "btcoexstatus = 0x%x\n", status);
762 			wpa_printf(MSG_DEBUG, "buf %s", buf);
763 		}
764 	}
765 	else if( os_strcasecmp(cmd, "rxfilter-start") == 0 ) {
766 		wpa_printf(MSG_DEBUG,"Rx Data Filter Start command");
767 		ret = wpa_driver_tista_driver_enable_rx_data_filter( priv );
768 	}
769 	else if( os_strcasecmp(cmd, "rxfilter-stop") == 0 ) {
770 		wpa_printf(MSG_DEBUG,"Rx Data Filter Stop command");
771 		ret = wpa_driver_tista_driver_disable_rx_data_filter( priv );
772 	}
773 	else if( os_strcasecmp(cmd, "rxfilter-statistics") == 0 ) {
774 		TCuCommon_RxDataFilteringStatistics stats;
775 		int len, i;
776 
777 		wpa_printf(MSG_DEBUG,"Rx Data Filter Statistics command");
778 		ret = wpa_driver_tista_driver_rx_data_filter_statistics( priv, &stats );
779 		if( ret == 0 ) {
780 			ret = snprintf(buf, buf_len, "RxFilterStat: %u", (u32)stats.unmatchedPacketsCount);
781 			for(i=0;( i < MAX_DATA_FILTERS );i++) {
782 				ret += snprintf(&buf[ret], buf_len-ret, " %u", (u32)stats.matchedPacketsCount[i]);
783 			}
784 			ret += snprintf(&buf[ret], buf_len-ret, "\n");
785 			if (ret >= (int)buf_len) {
786 				ret = -1;
787 			}
788 		}
789 	}
790 	else if( os_strncasecmp(cmd, "rxfilter-add", 12) == 0 ) {
791 		TRxDataFilterRequest dfreq;
792 		char *cp = cmd + 12;
793 		char *endp;
794 		int type;
795 
796 		if (*cp != '\0') {
797 			type = (int)strtol(cp, &endp, 0);
798 			if (endp != cp) {
799 				wpa_printf(MSG_DEBUG,"Rx Data Filter Add [%d] command", type);
800 				ret = prepare_filter_struct( priv, type, &dfreq );
801 				if( ret == 0 ) {
802 					ret = wpa_driver_tista_driver_rx_data_filter( priv, &dfreq, 1 );
803 				}
804 			}
805 		}
806 	}
807 	else if( os_strncasecmp(cmd, "rxfilter-remove",15) == 0 ) {
808 		TRxDataFilterRequest dfreq;
809 		char *cp = cmd + 15;
810 		char *endp;
811 		int type;
812 
813 		if (*cp != '\0') {
814 			type = (int)strtol(cp, &endp, 0);
815 			if (endp != cp) {
816 				wpa_printf(MSG_DEBUG,"Rx Data Filter remove [%d] command", type);
817 				ret = prepare_filter_struct( priv, type, &dfreq );
818 				if( ret == 0 ) {
819 					ret = wpa_driver_tista_driver_rx_data_filter( priv, &dfreq, 0 );
820 				}
821 			}
822 		}
823 	}
824 	else {
825 		wpa_printf(MSG_DEBUG,"Unsupported command");
826 	}
827 	return ret;
828 }
829 
830 #ifdef WPA_SUPPLICANT_VER_0_6_X
831 /*-----------------------------------------------------------------------------
832 Routine Name: wpa_driver_tista_set_probe_req_ie
833 Routine Description: set probe request ie for WSC mode change
834 Arguments:
835    priv - pointer to private data structure
836    ies - probe_req_ie data
837    ies_len - ie data length
838 Return Value: actual buffer length - success, -1 - failure
839 -----------------------------------------------------------------------------*/
wpa_driver_tista_set_probe_req_ie(void * priv,const u8 * ies,size_t ies_len)840 static int wpa_driver_tista_set_probe_req_ie(void *priv, const u8* ies, size_t ies_len)
841 {
842 	struct wpa_driver_ti_data *drv = (struct wpa_driver_ti_data *)priv;
843 #ifdef CONFIG_WPS
844 	TWscMode WscModeStruct;
845 
846         TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
847 
848 	if ((!ies || (0 == ies_len)) && (NULL == drv->probe_req_ie)) {
849 		return 0;
850 	}
851 
852 	if (ies && drv->probe_req_ie) {
853 		size_t len = wpabuf_len(drv->probe_req_ie);
854 		u8* data = (u8*)wpabuf_head(drv->probe_req_ie);
855 		if ((ies_len == len) && (0 == os_memcmp(ies, data, ies_len))) {
856 			return 0;
857 		}
858 	}
859 
860 	os_memset(&WscModeStruct, 0, sizeof(TWscMode));
861 
862 	if (!ies || (0 == ies_len)) {
863 		WscModeStruct.WSCMode = TIWLN_SIMPLE_CONFIG_OFF;
864 	} else {
865 		const size_t head_len = 6; /* probeReqIe head: dd xx 00 50 f2 04 */
866 		u8 *pos, *end;
867 		u16 password_id = 0;
868 		size_t min_len = 0;
869 
870 		pos = (u8*)ies + head_len; /* Find the WSC mode in probe_req_ie by password_id */
871 		end = (u8*)ies + ies_len;
872 		while (pos < end) {
873 			if (ATTR_DEV_PASSWORD_ID == WPA_GET_BE16(pos)) {
874 				password_id = WPA_GET_BE16(pos+4);
875 				break;
876 			}
877 			pos += (4 + WPA_GET_BE16(pos+2));
878 		}
879 		WscModeStruct.WSCMode = (DEV_PW_PUSHBUTTON == password_id)?TIWLN_SIMPLE_CONFIG_PBC_METHOD:TIWLN_SIMPLE_CONFIG_PIN_METHOD;
880 
881 		pos = (u8*)ies + head_len;
882 		min_len = ies_len - head_len;
883 		if (min_len > sizeof(WscModeStruct.probeReqWSCIE)) {
884 			min_len = sizeof(WscModeStruct.probeReqWSCIE);
885 		}
886 		os_memcpy(WscModeStruct.probeReqWSCIE, pos, min_len);
887 	}
888 
889 	wpa_hexdump(MSG_DEBUG, "SetProbeReqIe:WscModeStruct", (u8*)&WscModeStruct, sizeof(TWscMode));
890 	if(0 == wpa_driver_tista_private_send(priv, SITE_MGR_SIMPLE_CONFIG_MODE, (void*)&WscModeStruct, sizeof(TWscMode), NULL, 0)) {
891 		/* Update the cached probe req ie */
892 		wpabuf_free(drv->probe_req_ie);
893 		drv->probe_req_ie = NULL;
894 
895 		if (ies && ies_len) {
896 			drv->probe_req_ie = wpabuf_alloc(sizeof(WscModeStruct.probeReqWSCIE));
897 			if (drv->probe_req_ie) {
898 				wpabuf_put_data(drv->probe_req_ie, ies, ies_len);
899 			}
900 		}
901 	} else {
902 		wpa_printf(MSG_ERROR, "ERROR - Failed to set wsc mode!");
903 		return -1;
904 	}
905 #endif
906 	return 0;
907 }
908 #endif
909 
910 /**
911  * wpa_driver_tista_init - Initialize WE driver interface
912  * @ctx: context to be used when calling wpa_supplicant functions,
913  * e.g., wpa_supplicant_event()
914  * @ifname: interface name, e.g., wlan0
915  * Returns: Pointer to private data, %NULL on failure
916  */
wpa_driver_tista_init(void * ctx,const char * ifname)917 void * wpa_driver_tista_init(void *ctx, const char *ifname)
918 {
919 	struct wpa_driver_ti_data *drv;
920 
921 	drv = os_zalloc(sizeof(*drv));
922 	if (drv == NULL)
923 		return NULL;
924 	drv->wext = wpa_driver_wext_init(ctx, ifname);
925 	if (drv->wext == NULL) {
926 		os_free(drv);
927 		return NULL;
928 	}
929 
930 	drv->ctx = ctx;
931 	os_strncpy(drv->ifname, ifname, sizeof(drv->ifname));
932 	drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
933 	if (drv->ioctl_sock < 0) {
934 		perror("socket");
935 		wpa_driver_wext_deinit(drv->wext);
936 		os_free(drv);
937 		return NULL;
938 	}
939 
940 	/* Signal that driver is not stopped */
941 	drv->driver_is_loaded = TRUE;
942 
943 	/* Set default scan type */
944 	drv->scan_type = SCAN_TYPE_NORMAL_ACTIVE;
945 	drv->force_merge_flag = 0;
946 	scan_init(drv);
947 
948 	/* Set default amount of channels */
949 	drv->scan_channels = check_and_get_build_channels();
950 
951 	/* Link Speed will be set by the message from the driver */
952 	drv->link_speed = 0;
953 
954 	/* BtCoex mode is read from tiwlan.ini file */
955 	drv->btcoex_mode = 0; /* SG_DISABLE */
956 
957 #ifdef CONFIG_WPS
958 	/* The latest probe_req_ie for WSC */
959 	drv->probe_req_ie = NULL;
960 #endif
961 
962 	/* Number of sequential errors */
963 	drv->errors = 0;
964 	return drv;
965 }
966 
967 /**
968  * wpa_driver_tista_deinit - Deinitialize WE driver interface
969  * @priv: Pointer to private wext data from wpa_driver_tista_init()
970  *
971  * Shut down driver interface and processing of driver events. Free
972  * private data buffer if one was allocated in wpa_driver_tista_init().
973  */
wpa_driver_tista_deinit(void * priv)974 void wpa_driver_tista_deinit(void *priv)
975 {
976 	struct wpa_driver_ti_data *drv = priv;
977 
978 	wpa_driver_wext_deinit(drv->wext);
979 	close(drv->ioctl_sock);
980 	scan_exit(drv);
981 #ifdef CONFIG_WPS
982 	wpabuf_free(drv->probe_req_ie);
983 	drv->probe_req_ie = NULL;
984 #endif
985 	os_free(drv);
986 }
987 
wpa_driver_tista_set_auth_param(struct wpa_driver_ti_data * drv,int idx,u32 value)988 static int wpa_driver_tista_set_auth_param(struct wpa_driver_ti_data *drv,
989 					  int idx, u32 value)
990 {
991 	struct iwreq iwr;
992 	int ret = 0;
993 
994 	os_memset(&iwr, 0, sizeof(iwr));
995 	os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
996 	iwr.u.param.flags = idx & IW_AUTH_INDEX;
997 	iwr.u.param.value = value;
998 
999 	if (ioctl(drv->ioctl_sock, SIOCSIWAUTH, &iwr) < 0) {
1000 		perror("ioctl[SIOCSIWAUTH]");
1001 		wpa_printf(MSG_ERROR, "WEXT auth param %d value 0x%x - ",
1002 			idx, value);
1003 		ret = errno == EOPNOTSUPP ? -2 : -1;
1004 	}
1005 
1006 	return ret;
1007 }
1008 
wpa_driver_tista_set_wpa(void * priv,int enabled)1009 static int wpa_driver_tista_set_wpa(void *priv, int enabled)
1010 {
1011 	struct wpa_driver_ti_data *drv = priv;
1012 	int ret;
1013 
1014         TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1015 	ret = wpa_driver_tista_set_auth_param(drv, IW_AUTH_WPA_ENABLED,
1016 					      enabled);
1017 	return ret;
1018 }
1019 
wpa_driver_tista_set_auth_alg(void * priv,int auth_alg)1020 static int wpa_driver_tista_set_auth_alg(void *priv, int auth_alg)
1021 {
1022 	struct wpa_driver_ti_data *drv = priv;
1023 	int algs = 0, res;
1024 
1025         TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1026 	if (auth_alg & AUTH_ALG_OPEN_SYSTEM)
1027 		algs |= IW_AUTH_ALG_OPEN_SYSTEM;
1028 	if (auth_alg & AUTH_ALG_SHARED_KEY)
1029 		algs |= IW_AUTH_ALG_SHARED_KEY;
1030 	if (auth_alg & AUTH_ALG_LEAP)
1031 		algs |= IW_AUTH_ALG_LEAP;
1032 	if (algs == 0) {
1033 		/* at least one algorithm should be set */
1034 		algs = IW_AUTH_ALG_OPEN_SYSTEM;
1035 	}
1036 
1037 	res = wpa_driver_tista_set_auth_param(drv, IW_AUTH_80211_AUTH_ALG,
1038 					     algs);
1039 
1040 	return res;
1041 }
1042 
wpa_driver_tista_set_countermeasures(void * priv,int enabled)1043 static int wpa_driver_tista_set_countermeasures(void *priv, int enabled)
1044 {
1045 	struct wpa_driver_ti_data *drv = priv;
1046 	int ret;
1047 
1048 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1049         TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1050 	ret = wpa_driver_tista_set_auth_param(drv,
1051 					      IW_AUTH_TKIP_COUNTERMEASURES,
1052 					      enabled);
1053 	return ret;
1054 }
1055 
wpa_driver_tista_set_drop_unencrypted(void * priv,int enabled)1056 static int wpa_driver_tista_set_drop_unencrypted(void *priv,
1057 						int enabled)
1058 {
1059 	struct wpa_driver_ti_data *drv = priv;
1060 	int ret;
1061 
1062 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1063         TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1064 	/* Dm: drv->use_crypt = enabled; */
1065 	ret = wpa_driver_tista_set_auth_param(drv, IW_AUTH_DROP_UNENCRYPTED,
1066 					      enabled);
1067 	return ret;
1068 }
1069 
wpa_driver_tista_pmksa(struct wpa_driver_ti_data * drv,u32 cmd,const u8 * bssid,const u8 * pmkid)1070 static int wpa_driver_tista_pmksa(struct wpa_driver_ti_data *drv,
1071 				 u32 cmd, const u8 *bssid, const u8 *pmkid)
1072 {
1073 	struct iwreq iwr;
1074 	struct iw_pmksa pmksa;
1075 	int ret = 0;
1076 
1077 	os_memset(&iwr, 0, sizeof(iwr));
1078 	os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1079 	os_memset(&pmksa, 0, sizeof(pmksa));
1080 	pmksa.cmd = cmd;
1081 	pmksa.bssid.sa_family = ARPHRD_ETHER;
1082 	if (bssid)
1083 		os_memcpy(pmksa.bssid.sa_data, bssid, ETH_ALEN);
1084 	if (pmkid) {
1085 		os_memcpy(pmksa.pmkid, pmkid, IW_PMKID_LEN);
1086 		wpa_printf(MSG_DEBUG, "pmkid %s", pmkid);
1087 	}
1088 	iwr.u.data.pointer = (caddr_t)&pmksa;
1089 	iwr.u.data.length = sizeof(pmksa);
1090 
1091 	if (ioctl(drv->ioctl_sock, SIOCSIWPMKSA, &iwr) < 0) {
1092 		if (errno != EOPNOTSUPP)
1093 			perror("ioctl[SIOCSIWPMKSA]");
1094 		ret = -1;
1095 	}
1096 	return ret;
1097 }
1098 
wpa_driver_tista_add_pmkid(void * priv,const u8 * bssid,const u8 * pmkid)1099 static int wpa_driver_tista_add_pmkid(void *priv, const u8 *bssid,
1100 				     const u8 *pmkid)
1101 {
1102 	struct wpa_driver_ti_data *drv = priv;
1103 	int ret;
1104 
1105 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1106 	TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1107 	ret = wpa_driver_tista_pmksa(drv, IW_PMKSA_ADD, bssid, pmkid);
1108 	return ret;
1109 }
1110 
wpa_driver_tista_remove_pmkid(void * priv,const u8 * bssid,const u8 * pmkid)1111 static int wpa_driver_tista_remove_pmkid(void *priv, const u8 *bssid,
1112 		 			const u8 *pmkid)
1113 {
1114 	struct wpa_driver_ti_data *drv = priv;
1115 	int ret;
1116 
1117 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1118 	TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1119 	ret = wpa_driver_tista_pmksa(drv, IW_PMKSA_REMOVE, bssid, pmkid);
1120 	return ret;
1121 }
1122 
wpa_driver_tista_flush_pmkid(void * priv)1123 static int wpa_driver_tista_flush_pmkid(void *priv)
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_FLUSH, NULL, NULL);
1131 	return ret;
1132 }
1133 
wpa_driver_tista_mlme(struct wpa_driver_ti_data * drv,const u8 * addr,int cmd,int reason_code)1134 static int wpa_driver_tista_mlme(struct wpa_driver_ti_data *drv,
1135 				const u8 *addr, int cmd, int reason_code)
1136 {
1137 	struct iwreq iwr;
1138 	struct iw_mlme mlme;
1139 	int ret = 0;
1140 
1141 	os_memset(&iwr, 0, sizeof(iwr));
1142 	os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1143 	os_memset(&mlme, 0, sizeof(mlme));
1144 	mlme.cmd = cmd;
1145 	mlme.reason_code = reason_code;
1146 	mlme.addr.sa_family = ARPHRD_ETHER;
1147 	os_memcpy(mlme.addr.sa_data, addr, ETH_ALEN);
1148 	iwr.u.data.pointer = (caddr_t) &mlme;
1149 	iwr.u.data.length = sizeof(mlme);
1150 
1151 	if (ioctl(drv->ioctl_sock, SIOCSIWMLME, &iwr) < 0) {
1152 		perror("ioctl[SIOCSIWMLME]");
1153 		ret = -1;
1154 	}
1155 
1156 	return ret;
1157 }
1158 
wpa_driver_tista_deauthenticate(void * priv,const u8 * addr,int reason_code)1159 static int wpa_driver_tista_deauthenticate(void *priv, const u8 *addr,
1160 					  int reason_code)
1161 {
1162 	struct wpa_driver_ti_data *drv = priv;
1163 	int ret;
1164 
1165 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1166         TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1167 	ret = wpa_driver_tista_mlme(drv, addr, IW_MLME_DEAUTH, reason_code);
1168 	return ret;
1169 }
1170 
1171 
wpa_driver_tista_disassociate(void * priv,const u8 * addr,int reason_code)1172 static int wpa_driver_tista_disassociate(void *priv, const u8 *addr,
1173 					int reason_code)
1174 {
1175 	struct wpa_driver_ti_data *drv = priv;
1176 	int ret;
1177 
1178 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1179         TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1180 	ret = wpa_driver_tista_mlme(drv, addr, IW_MLME_DISASSOC, reason_code);
1181 	return ret;
1182 }
1183 
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)1184 static int wpa_driver_tista_set_key(void *priv, wpa_alg alg,
1185 			    const u8 *addr, int key_idx,
1186 			    int set_tx, const u8 *seq, size_t seq_len,
1187 			    const u8 *key, size_t key_len)
1188 {
1189 	struct wpa_driver_ti_data *drv = priv;
1190 	int ret;
1191 
1192 	wpa_printf(MSG_DEBUG, "%s", __func__);
1193 	TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1194 	ret = wpa_driver_wext_set_key(drv->wext, alg, addr, key_idx, set_tx,
1195 					seq, seq_len, key, key_len);
1196 	return ret;
1197 }
1198 
wpa_driver_tista_set_gen_ie(void * priv,const u8 * ie,size_t ie_len)1199 static int wpa_driver_tista_set_gen_ie(void *priv, const u8 *ie, size_t ie_len)
1200 {
1201 	struct wpa_driver_ti_data *drv = priv;
1202 	struct iwreq iwr;
1203 	int ret = 0;
1204 
1205 	os_memset(&iwr, 0, sizeof(iwr));
1206 	os_strncpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1207 	iwr.u.data.pointer = (caddr_t)ie;
1208 	iwr.u.data.length = ie_len;
1209 
1210 	if (ioctl(drv->ioctl_sock, SIOCSIWGENIE, &iwr) < 0) {
1211 		perror("ioctl[SIOCSIWGENIE]");
1212 		ret = -1;
1213 	}
1214 
1215 	return ret;
1216 }
1217 
1218 #ifdef WPA_SUPPLICANT_VER_0_6_X
wpa_driver_tista_get_scan_results(void * priv)1219 static struct wpa_scan_results *wpa_driver_tista_get_scan_results(void *priv)
1220 {
1221 	struct wpa_driver_ti_data *drv = priv;
1222 	struct wpa_scan_results *res;
1223 	struct wpa_scan_res **tmp;
1224 	unsigned ap_num;
1225 
1226 	TI_CHECK_DRIVER( drv->driver_is_loaded, NULL );
1227 	res = wpa_driver_wext_get_scan_results(drv->wext);
1228 	if (res == NULL) {
1229 		return NULL;
1230 	}
1231 
1232 	wpa_printf(MSG_DEBUG, "Actual APs number %d", res->num);
1233 	ap_num = (unsigned)scan_count(drv) + res->num;
1234 	tmp = os_realloc(res->res, ap_num * sizeof(struct wpa_scan_res *));
1235 	if (tmp == NULL)
1236 		return res;
1237 	res->num = scan_merge(drv, tmp, drv->force_merge_flag, res->num, ap_num);
1238 	wpa_printf(MSG_DEBUG, "After merge, APs number %d", res->num);
1239 	tmp = os_realloc(tmp, res->num * sizeof(struct wpa_scan_res *));
1240 	res->res = tmp;
1241 	return res;
1242 }
1243 
wpa_driver_tista_set_mode(void * priv,int mode)1244 int wpa_driver_tista_set_mode(void *priv, int mode)
1245 {
1246 	struct wpa_driver_ti_data *drv = priv;
1247 	int ret;
1248 
1249 	wpa_printf(MSG_DEBUG, "%s", __func__);
1250 	TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1251 	ret = wpa_driver_wext_set_mode(drv->wext, mode);
1252 	return ret;
1253 }
1254 #else
1255 /*-----------------------------------------------------------------------------
1256 Compare function for sorting scan results. Return >0 if @b is considered better.
1257 -----------------------------------------------------------------------------*/
wpa_driver_tista_scan_result_compare(const void * a,const void * b)1258 static int wpa_driver_tista_scan_result_compare(const void *a, const void *b)
1259 {
1260 	const struct wpa_scan_result *wa = a;
1261 	const struct wpa_scan_result *wb = b;
1262 
1263 	return( wb->level - wa->level );
1264 }
1265 
wpa_driver_tista_get_scan_results(void * priv,struct wpa_scan_result * results,size_t max_size)1266 static int wpa_driver_tista_get_scan_results(void *priv,
1267 					      struct wpa_scan_result *results,
1268 					      size_t max_size)
1269 {
1270 	struct wpa_driver_ti_data *drv = priv;
1271 	int ap_num = 0;
1272 
1273         TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1274 	ap_num = wpa_driver_wext_get_scan_results(drv->wext, results, max_size);
1275 	wpa_printf(MSG_DEBUG, "Actual APs number %d", ap_num);
1276 
1277 	if (ap_num < 0)
1278 		return -1;
1279 
1280 	/* Merge new results with previous */
1281         ap_num = scan_merge(drv, results, drv->force_merge_flag, ap_num, max_size);
1282 	wpa_printf(MSG_DEBUG, "After merge, APs number %d", ap_num);
1283 	qsort(results, ap_num, sizeof(struct wpa_scan_result),
1284 		wpa_driver_tista_scan_result_compare);
1285 	return ap_num;
1286 }
1287 #endif
1288 
wpa_driver_tista_associate(void * priv,struct wpa_driver_associate_params * params)1289 static int wpa_driver_tista_associate(void *priv,
1290 			  struct wpa_driver_associate_params *params)
1291 {
1292 	struct wpa_driver_ti_data *drv = priv;
1293 	int allow_unencrypted_eapol;
1294 	int value, flags, ret = 0;
1295 
1296 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
1297 	TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1298 
1299 #ifdef WPA_SUPPLICANT_VER_0_6_X
1300 #ifdef ANDROID
1301 	((struct wpa_driver_wext_data *)(drv->wext))->skip_disconnect = 0;
1302 #endif
1303 #endif
1304 
1305 	if (wpa_driver_wext_get_ifflags(drv->wext, &flags) == 0) {
1306 		if (!(flags & IFF_UP)) {
1307 			wpa_driver_wext_set_ifflags(drv->wext, flags | IFF_UP);
1308 		}
1309 	}
1310 
1311 #if 0
1312 	if (!params->bssid)
1313 		wpa_driver_wext_set_bssid(drv->wext, NULL);
1314 #endif
1315 
1316 #ifdef WPA_SUPPLICANT_VER_0_5_X
1317 	/* Set driver network mode (Adhoc/Infrastructure) according to supplied parameters */
1318 	wpa_driver_wext_set_mode(drv->wext, params->mode);
1319 #endif
1320 	wpa_driver_tista_set_gen_ie(drv, params->wpa_ie, params->wpa_ie_len);
1321 
1322 	if (params->wpa_ie == NULL || params->wpa_ie_len == 0)
1323 		value = IW_AUTH_WPA_VERSION_DISABLED;
1324 #ifdef WPA_SUPPLICANT_VER_0_6_X
1325 	else if (params->wpa_ie[0] == WLAN_EID_RSN)
1326 #else
1327 	else if (params->wpa_ie[0] == RSN_INFO_ELEM)
1328 #endif
1329 		value = IW_AUTH_WPA_VERSION_WPA2;
1330 #ifdef CONFIG_WPS
1331 	else if (params->key_mgmt_suite == KEY_MGMT_WPS)
1332 		value = IW_AUTH_WPA_VERSION_DISABLED;
1333 #endif
1334 	else
1335 		value = IW_AUTH_WPA_VERSION_WPA;
1336 	wpa_driver_tista_set_auth_param(drv, IW_AUTH_WPA_VERSION, value);
1337 	value = wpa_driver_tista_cipher2wext(params->pairwise_suite);
1338 	wpa_driver_tista_set_auth_param(drv, IW_AUTH_CIPHER_PAIRWISE, value);
1339 	value = wpa_driver_tista_cipher2wext(params->group_suite);
1340 	wpa_driver_tista_set_auth_param(drv, IW_AUTH_CIPHER_GROUP, value);
1341 	value = wpa_driver_tista_keymgmt2wext(params->key_mgmt_suite);
1342 	wpa_driver_tista_set_auth_param(drv, IW_AUTH_KEY_MGMT, value);
1343 	value = params->key_mgmt_suite != KEY_MGMT_NONE ||
1344 		params->pairwise_suite != CIPHER_NONE ||
1345 		params->group_suite != CIPHER_NONE ||
1346 #ifdef WPA_SUPPLICANT_VER_0_6_X
1347 		(params->wpa_ie_len && (params->key_mgmt_suite != KEY_MGMT_WPS));
1348 #else
1349 		params->wpa_ie_len;
1350 #endif
1351 	wpa_driver_tista_set_auth_param(drv, IW_AUTH_PRIVACY_INVOKED, value);
1352 
1353 	/* Allow unencrypted EAPOL messages even if pairwise keys are set when
1354 	 * not using WPA. IEEE 802.1X specifies that these frames are not
1355 	 * encrypted, but WPA encrypts them when pairwise keys are in use. */
1356 	if (params->key_mgmt_suite == KEY_MGMT_802_1X ||
1357 	    params->key_mgmt_suite == KEY_MGMT_PSK)
1358 		allow_unencrypted_eapol = 0;
1359 	else
1360 		allow_unencrypted_eapol = 1;
1361 
1362 	wpa_driver_tista_set_auth_param(drv,
1363 					   IW_AUTH_RX_UNENCRYPTED_EAPOL,
1364 					   allow_unencrypted_eapol);
1365 
1366 	if (params->freq)
1367 		wpa_driver_wext_set_freq(drv->wext, params->freq);
1368 
1369 	if (params->bssid) {
1370 		wpa_printf(MSG_DEBUG, "wpa_driver_tista_associate: BSSID=" MACSTR,
1371 			            MAC2STR(params->bssid));
1372 		/* if there is bssid -> set it */
1373 		if (os_memcmp(params->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) != 0) {
1374 			wpa_driver_wext_set_bssid(drv->wext, params->bssid);
1375 		}
1376 	}
1377 
1378 	ret = wpa_driver_wext_set_ssid(drv->wext, params->ssid, params->ssid_len);
1379 	return ret;
1380 }
1381 
wpa_driver_tista_set_operstate(void * priv,int state)1382 static int wpa_driver_tista_set_operstate(void *priv, int state)
1383 {
1384 	struct wpa_driver_ti_data *drv = priv;
1385 
1386 	wpa_printf(MSG_DEBUG, "%s: operstate %d (%s)",
1387 		   __func__, /*drv->operstate,*/ state, state ? "UP" : "DORMANT");
1388         TI_CHECK_DRIVER( drv->driver_is_loaded, -1 );
1389 	/* Dm: drv->operstate = state; */
1390 	return wpa_driver_wext_set_operstate(drv->wext, state);
1391 }
1392 
1393 const struct wpa_driver_ops wpa_driver_custom_ops = {
1394 	.name = TIWLAN_DRV_NAME,
1395 	.desc = "TI Station Driver (1271)",
1396 	.get_bssid = wpa_driver_tista_get_bssid,
1397 	.get_ssid = wpa_driver_tista_get_ssid,
1398 	.set_wpa = wpa_driver_tista_set_wpa,
1399 	.set_key = wpa_driver_tista_set_key,
1400 	.set_countermeasures = wpa_driver_tista_set_countermeasures,
1401 	.set_drop_unencrypted = wpa_driver_tista_set_drop_unencrypted,
1402 	.scan = wpa_driver_tista_scan,
1403 #ifdef WPA_SUPPLICANT_VER_0_6_X
1404 	.get_scan_results2 = wpa_driver_tista_get_scan_results,
1405 #else
1406 	.get_scan_results = wpa_driver_tista_get_scan_results,
1407 #endif
1408 	.deauthenticate = wpa_driver_tista_deauthenticate,
1409 	.disassociate = wpa_driver_tista_disassociate,
1410 	.associate = wpa_driver_tista_associate,
1411 	.set_auth_alg = wpa_driver_tista_set_auth_alg,
1412 	.get_mac_addr = wpa_driver_tista_get_mac_addr,
1413 	.init = wpa_driver_tista_init,
1414 	.deinit = wpa_driver_tista_deinit,
1415 	.add_pmkid = wpa_driver_tista_add_pmkid,
1416 	.remove_pmkid = wpa_driver_tista_remove_pmkid,
1417 	.flush_pmkid = wpa_driver_tista_flush_pmkid,
1418 	.set_operstate = wpa_driver_tista_set_operstate,
1419 #ifdef WPA_SUPPLICANT_VER_0_6_X
1420 	.set_mode = wpa_driver_tista_set_mode,
1421 	.set_probe_req_ie = wpa_driver_tista_set_probe_req_ie,
1422 #endif
1423 	.driver_cmd = wpa_driver_tista_driver_cmd
1424 };
1425