Home | History | Annotate | Download | only in wpa_supplicant_lib
      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 -----------------------------------------------------------------------------*/
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 -----------------------------------------------------------------------------*/
    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 -----------------------------------------------------------------------------*/
    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 
    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 
    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 
    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 
    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 -----------------------------------------------------------------------------*/
    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 
    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 
    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 
    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 
    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 -----------------------------------------------------------------------------*/
    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 -----------------------------------------------------------------------------*/
    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  */
    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  */
    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 
    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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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 
   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
   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 
   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 -----------------------------------------------------------------------------*/
   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 
   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 
   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 
   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