1/*
2 * WPA Supplicant - driver interaction with TI station
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Alternatively, this software may be distributed under the terms of BSD
9 * license.
10 *
11 */
12
13/* Copyright © Texas Instruments Incorporated (Oct 2005)
14 * THIS CODE/PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
15 * EITHER EXPRESS OR IMPLIED, INCLUDED BUT NOT LIMITED TO , THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 * This program has been modified from its original operation by Texas
18 * Instruments Incorporated. These changes are covered under version 2
19 * of the GNU General Public License, dated June 1991.
20 *
21 * Copyright © Google Inc (Feb 2008)
22*/
23/*-------------------------------------------------------------------*/
24#include "includes.h"
25#include <sys/ioctl.h>
26#include <net/route.h>
27#include <net/if.h>
28#include <fcntl.h>
29#include <netpacket/packet.h>
30#include <stddef.h>
31#include "common.h"
32#include "driver.h"
33#include "eloop.h"
34#include "wpa.h"
35#include "wpa_supplicant.h"
36#include "config.h"
37#include "wpa_supplicant_i.h"
38#include "wpa_i.h"
39#include "l2_packet.h"
40#include "wpa_ctrl.h"
41/*----- STA_DK files -----*/
42#include "wspVer.h"
43#include "driver_ti.h"
44#include "scanmerge.h"
45#include "scanMngrTypes.h"
46#ifdef ANDROID
47#include <cutils/properties.h>
48#endif
49/*-------------------------------------------------------------------*/
50#define TI_DRIVER_MSG_PORT       9000
51#define RX_SELF_FILTER           0
52#define RX_BROADCAST_FILTER      1
53#define RX_IPV4_MULTICAST_FILTER 2
54#define RX_IPV6_MULTICAST_FILTER 3
55#define TI2WPA_STATUS(s)         (((s) != OK) ? -1 : 0)
56#define TI_CHECK_DRIVER(f,r)     \
57    if( !(f) ) { \
58        wpa_printf(MSG_ERROR,"TI: Driver not initialized yet...aborting..."); \
59        return( r ); \
60    }
61/*-------------------------------------------------------------------*/
62/* Lock file pointer - used to access pid-lock-file to prevent two instances of wpa_supplicant */
63#ifdef CONFIG_TI_LOCKFILE
64static int lfp;
65#endif
66/*-------------------------------------------------------------------*/
67
68/*-----------------------------------------------------------------------------
69Routine Name: check_and_get_build_channels
70Routine Description: get number of allowed channels according to a build var.
71Arguments: None
72Return Value: Number of channels
73-----------------------------------------------------------------------------*/
74static int check_and_get_build_channels( void )
75{
76#ifdef ANDROID
77    char prop_status[PROPERTY_VALUE_MAX];
78    char *prop_name = "ro.wifi.channels";
79    int i, default_channels = NUMBER_SCAN_CHANNELS_FCC;
80
81    if( property_get(prop_name, prop_status, NULL) ) {
82        i = atoi(prop_status);
83        if( i != 0 )
84            default_channels = i;
85    }
86    return( default_channels );
87#else
88    return( NUMBER_SCAN_CHANNELS_FCC );
89#endif
90}
91
92/*-----------------------------------------------------------------------------
93Routine Name: wpa_driver_tista_event_receive
94Routine Description: driver events callback, called from driver IPC
95Arguments:
96   priv - pointer to private data structure
97   pData - pointer to event information
98Return Value:
99-----------------------------------------------------------------------------*/
100void wpa_driver_tista_event_receive( IPC_EV_DATA *pData )
101{
102    struct wpa_driver_ti_data *mySuppl;
103    struct sockaddr_in echoserver;
104    int res, msg_size;
105
106    wpa_printf(MSG_DEBUG,"wpa_driver_tista_event_receive called: %d",
107               pData->uBufferSize);
108
109    mySuppl = pData->EvParams.hUserParam;
110    msg_size = (int)(pData->uBufferSize + offsetof(IPC_EV_DATA, uBuffer));
111
112    os_memset( &echoserver, 0, sizeof(echoserver) );     /* Clear struct */
113    echoserver.sin_family = AF_INET;                     /* Internet/IP */
114    echoserver.sin_addr.s_addr = inet_addr("127.0.0.1"); /* IP address */
115    echoserver.sin_port = htons(TI_DRIVER_MSG_PORT);     /* server port */
116
117    res = sendto(mySuppl->driverEventsSocket, pData, msg_size, 0, (struct sockaddr *)&echoserver, sizeof(echoserver));
118    echoserver.sin_port = htons(TI_DRIVER_MSG_PORT + 1);
119    res = sendto(mySuppl->driverEventsSocket, pData, msg_size, 0, (struct sockaddr *)&echoserver, sizeof(echoserver));
120}
121
122/*-----------------------------------------------------------------------------
123Routine Name: wpa_driver_tista_register_events
124Routine Description: register to driver events
125Arguments:
126   ctx - pointer to private data structure
127Return Value: None
128-----------------------------------------------------------------------------*/
129void wpa_driver_tista_register_events( void *ctx )
130{
131    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)ctx;
132    IPC_EVENT_PARAMS pEvent;
133    int i;
134
135    os_memset( myDrv->hEvents, 0, sizeof(ULONG) * IPC_EVENT_MAX );
136    for(i=IPC_EVENT_ASSOCIATED;( i < IPC_EVENT_MAX );i++) {
137        /* Register to receive driver events */
138        pEvent.uEventType       = i;
139        pEvent.uDeliveryType    = DELIVERY_PUSH;
140        pEvent.hUserParam       = (TI_HANDLE)myDrv;
141        pEvent.pfEventCallback  = (TI_EVENT_CALLBACK)wpa_driver_tista_event_receive;
142        TI_RegisterEvent( myDrv->hDriver, &pEvent );
143        myDrv->hEvents[i] = pEvent.uEventID;
144    }
145}
146
147/*-----------------------------------------------------------------------------
148Routine Name: wpa_driver_tista_unregister_events
149Routine Description: unregister driver events
150Arguments:
151   ctx - pointer to private data structure
152Return Value: None
153-----------------------------------------------------------------------------*/
154void wpa_driver_tista_unregister_events( void *ctx )
155{
156    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)ctx;
157    IPC_EVENT_PARAMS pEvent;
158    int idx;
159
160    for(idx=0;( idx < IPC_EVENT_MAX );idx++) {
161        if( myDrv->hEvents[idx] ) {
162            pEvent.uEventType = idx;
163            pEvent.uEventID = myDrv->hEvents[idx];
164            TI_UnRegisterEvent( myDrv->hDriver, &pEvent );
165        }
166    }
167}
168
169/*-----------------------------------------------------------------------------
170Routine Name: wpa_driver_tista_get_bssid
171Routine Description: get current BSSID from driver
172Arguments:
173   priv - pointer to private data structure
174   bssid - pointer to hold bssid
175Return Value: 0 on success, -1 on failure
176-----------------------------------------------------------------------------*/
177static int wpa_driver_tista_get_bssid( void *priv, u8 *bssid )
178{
179    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
180    OS_802_11_MAC_ADDRESS tiAPMacAddr;
181    TI_STATUS retValue;
182
183    wpa_printf(MSG_DEBUG, "wpa_driver_tista_get_bssid called");
184
185    /* If driver is not initialized yet - we cannot access it so return */
186    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
187
188    /* Get MAC address of current AP */
189    if( TI_GetBSSID( myDrv->hDriver, &tiAPMacAddr ) != TI_RESULT_OK )
190        return( -1 );
191
192    /* Copy BSSID into caller pointer provided in routine parameters */
193    os_memcpy( (void *)bssid, (void *)&tiAPMacAddr, MAC_ADDR_LEN );
194    wpa_hexdump(MSG_DEBUG, "get_bssid:", bssid, MAC_ADDR_LEN);
195    return( 0 );
196}
197
198/*-----------------------------------------------------------------------------
199Routine Name: wpa_driver_tista_get_ssid
200Routine Description: get current SSID
201Arguments:
202   priv - pointer to private data structure
203   ssid - pointer to hold current bssid
204Return Value: Length of SSID string
205-----------------------------------------------------------------------------*/
206static int wpa_driver_tista_get_ssid( void *priv, u8 *ssid )
207{
208    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
209    OS_802_11_SSID myssid;
210
211    wpa_printf(MSG_DEBUG,"wpa_driver_tista_get_ssid called");
212
213    /* If driver is not initialized yet - we cannot access it so return */
214    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
215
216    /* Get current SSID from driver */
217    if( TI_GetCurrentSSID(myDrv->hDriver, &myssid) != TI_RESULT_OK )
218        return( -1 );
219
220    /* Copy to user supplied pointer */
221    os_memcpy( (void *)ssid, (void *)&myssid.Ssid, myssid.SsidLength );
222
223    /* Return length of SSID */
224    return( myssid.SsidLength );
225}
226
227/*-----------------------------------------------------------------------------
228Routine Name: wpa_driver_tista_set_ssid
229Routine Description: sets current SSID (Associates)
230Arguments:
231   priv - pointer to private data structure
232   ssid - pointer to ssid
233   ssid_len - length of ssid
234Return Value: 0 on success, -1 on failure
235-----------------------------------------------------------------------------*/
236static int wpa_driver_tista_set_ssid( void *priv, const u8 *ssid, size_t ssid_len )
237{
238    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
239    char ssidBuf[MAX_SSID_LEN];
240    int ret;
241
242    wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_ssid called: %s", ssid);
243
244    /* If driver is not initialized yet - we cannot access it so return */
245    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
246
247    /* Copy user supplied SSID into local buffer */
248    os_memset( ssidBuf, 0, MAX_SSID_LEN );
249    os_memcpy( ssidBuf, ssid, ssid_len );
250
251    /* Set local SSID buffer to driver - triggering connection process in driver */
252    wpa_printf(MSG_DEBUG,"Associate: SSID = %s", ssidBuf); /* Dm: */
253#ifdef STA_DK_VER_5_0_0_94
254    ret = (int)TI_SetSSID( myDrv->hDriver, (char *)ssidBuf );
255#else
256    ret = (int)TI_SetSSID( myDrv->hDriver, (u8 *)ssidBuf );
257#endif
258    return( TI2WPA_STATUS(ret) );
259}
260
261/*-----------------------------------------------------------------------------
262Routine Name: wpa_driver_tista_set_wpa
263Routine Description: enable/disable WPA support in driver - not implemented since not supported in driver. also obselete for wpa-suppl core
264Arguments:
265   priv - pointer to private data structure
266   enabled - enable/disable flag
267Return Value: 0 on success, -1 on failure
268-----------------------------------------------------------------------------*/
269static int wpa_driver_tista_set_wpa(void *priv, int enabled)
270{
271    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
272
273    wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_wpa called: %d",enabled);
274    return( 0 );
275}
276
277/*-----------------------------------------------------------------------------
278Routine Name: wpa_driver_tista_set_proto
279Routine Description: set authentication protocol (WPA/WPA2(RSN))
280Arguments:
281   priv - pointer to private data structure
282   proto - authentication suite
283Return Value: 0 on success, -1 on failure
284-----------------------------------------------------------------------------*/
285static int wpa_driver_tista_set_proto( void *priv, int proto )
286{
287   struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
288
289   wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_proto called: %d", proto);
290   myDrv->proto = proto;
291
292   return( 0 );
293}
294
295/*-----------------------------------------------------------------------------
296Routine Name: wpa_driver_tista_set_wpa_options
297Routine Description: set wpa_options
298Arguments:
299   priv - pointer to private data structure
300   wpa_options - WPA options (0 - disable, 3 - enable)
301Return Value: 0 on success, -1 on failure
302-----------------------------------------------------------------------------*/
303static int wpa_driver_tista_set_wpa_options( void *priv, int key_mgmt_suite )
304{
305    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
306    UINT32 wpa_opt = WPA_OPTIONS_DISABLE;
307    int ret;
308
309    wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_wpa_options called: %d", key_mgmt_suite);
310    /* If driver is not initialized yet - we cannot access it so return */
311    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
312
313    myDrv->key_mgmt = key_mgmt_suite;
314
315    switch( key_mgmt_suite ) {
316        case KEY_MGMT_802_1X:          /* Dm: EAP */
317            wpa_opt = WPA_OPTIONS_ENABLE; /* wpa_auth = 1; */
318            break;
319
320        case KEY_MGMT_PSK:             /* Dm: PSK */
321            wpa_opt = WPA_OPTIONS_ENABLE; /* wpa_auth = 2; */
322            break;
323
324        case KEY_MGMT_802_1X_NO_WPA:   /* Dm: ??? */
325            break;
326
327        case KEY_MGMT_WPA_NONE:        /* Dm: ??? */
328            break;
329
330        case KEY_MGMT_NONE:
331        default:
332            wpa_opt = WPA_OPTIONS_DISABLE; /* wpa_auth = 255; */
333            break;
334    }
335
336    /* Set WPA Options */
337    ret = TI_SetWpaOptions( myDrv->hDriver, wpa_opt );
338    return( TI2WPA_STATUS(ret) );
339}
340
341/*-----------------------------------------------------------------------------
342Routine Name: wpa_driver_tista_set_encryption
343Routine Description: set authentication protocol (WPA/WPA2(RSN))
344Arguments:
345   priv - pointer to private data structure
346   proto - authentication suite
347Return Value: 0 on success, -1 on failure
348-----------------------------------------------------------------------------*/
349static int wpa_driver_tista_set_encryption( void *priv, int encryption )
350{
351    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
352    int ret = -1;
353    OS_802_11_ENCRYPTION_TYPES wpa_cipher = OS_ENCRYPTION_TYPE_NONE;
354
355    wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_encryption called: %d",encryption);
356    /* If driver is not initialized yet - we cannot access it so return */
357    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
358
359    myDrv->encryption = encryption;
360    switch( encryption ) {
361        case CIPHER_WEP40:
362        case CIPHER_WEP104:
363            wpa_printf(MSG_DEBUG, "encryption: OS_ENCRYPTION_TYPE_WEP");
364            wpa_cipher = OS_ENCRYPTION_TYPE_WEP;
365            break;
366
367        case CIPHER_TKIP:
368            wpa_printf(MSG_DEBUG, "encryption: OS_ENCRYPTION_TYPE_TKIP");
369            wpa_cipher = OS_ENCRYPTION_TYPE_TKIP;
370            break;
371
372        case CIPHER_CCMP:
373            wpa_printf(MSG_DEBUG, "encryption: OS_ENCRYPTION_TYPE_AES");
374            wpa_cipher = OS_ENCRYPTION_TYPE_AES;
375            break;
376
377        case CIPHER_NONE:
378        default:
379            wpa_printf(MSG_DEBUG, "encryption: OS_ENCRYPTION_TYPE_NONE");
380            wpa_cipher = OS_ENCRYPTION_TYPE_NONE;
381            break;
382    }
383    ret = TI_SetEncryptionType( myDrv->hDriver, wpa_cipher );
384    return( TI2WPA_STATUS(ret) );
385}
386
387/*---------------------------------------------------------------------------*/
388void wpa_driver_tista_print_auth_mode( OS_802_11_AUTHENTICATION_MODE myAuth )
389{
390    char *mode_name = NULL;
391
392    switch( myAuth ) {
393        case os802_11AuthModeOpen:
394            mode_name = "os802_11AuthModeOpen";
395            break;
396        case os802_11AuthModeShared:
397            mode_name = "os802_11AuthModeShared";
398            break;
399        case os802_11AuthModeAutoSwitch:
400            mode_name = "os802_11AuthModeAutoSwitch";
401            break;
402        case os802_11AuthModeWPA:
403            mode_name = "os802_11AuthModeWPA";
404            break;
405        case os802_11AuthModeWPAPSK:
406            mode_name = "os802_11AuthModeWPAPSK";
407            break;
408        case os802_11AuthModeWPANone:
409            mode_name = "os802_11AuthModeWPANone";
410            break;
411        case os802_11AuthModeWPA2:
412            mode_name = "os802_11AuthModeWPA2";
413            break;
414        case os802_11AuthModeWPA2PSK:
415            mode_name = "os802_11AuthModeWPA2PSK";
416            break;
417        case os802_11AuthModeMax:
418        default:
419            mode_name = "Unknown";
420            break;
421    }
422    wpa_printf(MSG_DEBUG, "Selected AuthMode: %s", mode_name);
423}
424
425/*-----------------------------------------------------------------------------
426Routine Name: wpa_driver_tista_set_auth_mode
427Routine Description:
428Arguments:
429   priv - pointer to private data structure
430Return Value: 0 on success, -1 on failure
431-----------------------------------------------------------------------------*/
432static int wpa_driver_tista_set_auth_mode( void *priv )
433{
434    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
435    OS_802_11_AUTHENTICATION_MODE myAuth = os802_11AuthModeAutoSwitch;
436    int ret;
437
438    wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_auth_mode called");
439
440    /* If driver is not initialized yet - we cannot access it so return */
441    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
442
443    wpa_driver_tista_set_proto( priv, ((struct wpa_supplicant *)myDrv->hWpaSupplicant)->wpa->proto );
444    wpa_printf(MSG_DEBUG, "proto: %d", myDrv->proto); /* should be set BEFORE */
445    wpa_printf(MSG_DEBUG, "auth_alg: %d",myDrv->auth_alg);
446
447    if( (myDrv->auth_alg == AUTH_ALG_OPEN_SYSTEM) ||
448        (myDrv->auth_alg == AUTH_ALG_LEAP) ) {
449        switch( myDrv->key_mgmt ) {
450            case KEY_MGMT_802_1X:
451                if( myDrv->proto & WPA_PROTO_WPA ) {
452                    myAuth = os802_11AuthModeWPA;
453                }
454                else if( myDrv->proto & WPA_PROTO_RSN ) {
455                    myAuth = os802_11AuthModeWPA2;
456                }
457                break;
458            case KEY_MGMT_PSK:
459                if( myDrv->proto & WPA_PROTO_WPA ) {
460                    myAuth = os802_11AuthModeWPAPSK;
461                }
462                else if( myDrv->proto & WPA_PROTO_RSN ) {
463                    myAuth = os802_11AuthModeWPA2PSK;
464                }
465                break;
466            case KEY_MGMT_802_1X_NO_WPA:
467            case KEY_MGMT_WPA_NONE:
468                myAuth = os802_11AuthModeWPANone;
469                break;
470            case KEY_MGMT_NONE:
471            default:
472                myAuth = os802_11AuthModeOpen;
473                break;
474        }
475    }
476    else if( myDrv->auth_alg == AUTH_ALG_SHARED_KEY ) {
477        myAuth = os802_11AuthModeShared;
478    }
479    if( myDrv->auth_alg == AUTH_ALG_LEAP ) {
480        TI_SetEAPType( myDrv->hDriver, OS_EAP_TYPE_LEAP );
481        TI_SetEAPTypeDriver( myDrv->hDriver, OS_EAP_TYPE_LEAP );
482    }
483    wpa_driver_tista_print_auth_mode( myAuth );
484    ret = TI_SetAuthenticationMode( myDrv->hDriver, myAuth );
485    return( TI2WPA_STATUS(ret) );
486}
487
488/*-----------------------------------------------------------------------------
489Routine Name: wpa_driver_tista_del_key
490Routine Description: remove key from driver
491Arguments:
492   priv - pointer to private data structure
493   key_idx - key index
494   addr - key address (unicast/broadcast)
495Return Value: 0 on success, -1 on failure
496-----------------------------------------------------------------------------*/
497static int wpa_driver_tista_del_key(void *priv, int key_idx,
498                       const unsigned char *addr)
499{
500    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
501    OS_802_11_REMOVE_KEY myKey;
502    int ret;
503
504    wpa_printf(MSG_DEBUG,"wpa_driver_tista_del_key called");
505    wpa_printf(MSG_DEBUG,"key_idx = %d, addr = " TIMACSTR, key_idx, MAC2STR(addr));
506
507    /* If driver is not initialized yet - we cannot access it so return */
508    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
509
510    /* copy parameters (MAC of key to remove, etc) to local structure */
511    myKey.Length = sizeof(OS_802_11_REMOVE_KEY);
512    os_memcpy(&myKey.BSSID,addr,MAC_ADDR_LEN);
513    myKey.KeyIndex = key_idx;
514
515    /* Call Utility adapter to remove the key */
516    ret = TI_RemoveKey( myDrv->hDriver, &myKey );
517    return( TI2WPA_STATUS(ret) );
518}
519
520/*-----------------------------------------------------------------------------
521Routine Name: wpa_driver_tista_set_key
522Routine Description: set key in driver
523Arguments:
524   priv - pointer to private data structure
525   alg - type of key
526   addr - key address (unicast/broadcast)
527   key_idx - key index
528   set_tx - use key for immidiate tx
529   seq - sequence counter (for replay detection)
530   seq_len - sequence counter buffer len
531   key - key content
532   key_len - length of key (32 for TKIP, 16 for AES)
533Return Value: 0 on success, -1 on failure
534-----------------------------------------------------------------------------*/
535static int wpa_driver_tista_set_key(void *priv, wpa_alg alg,
536                       const unsigned char *addr, int key_idx, int set_tx,
537                       const u8 *seq, size_t seq_len,
538                       const u8 *key, size_t key_len)
539{
540    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
541    OS_802_11_KEY myKey;
542    OS_802_11_WEP myWepKey;
543    UINT8 temp[TKIP_KEY_LENGTH];
544    int ret = -1;
545
546    wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_key called");
547    /* If driver is not initialized yet - we cannot access it so return */
548    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
549
550    wpa_printf(MSG_DEBUG, "add_key (addr): " MACSTR, MAC2STR(addr));
551    wpa_printf(MSG_DEBUG, "add_key (key_idx): %d", key_idx);
552    wpa_printf(MSG_DEBUG, "add_key (alg): %d", alg);
553    wpa_printf(MSG_DEBUG, "add_key (set_tx): %d", set_tx);
554    wpa_hexdump(MSG_DEBUG, "add_key (seq):", seq, seq_len);
555    wpa_hexdump(MSG_DEBUG, "add_key (key):", key, key_len);
556
557    switch( key_len ) {
558        case TKIP_KEY_LENGTH:          /* 32 */
559        case AES_KEY_LENGTH:           /* 16 */
560            /* Set key index */
561            myKey.KeyIndex = key_idx;
562            /* Set key length and content */
563            myKey.KeyLength = key_len;
564            /* Set structure size */
565            myKey.Length = sizeof(OS_802_11_KEY);
566            /* set key MAC address - FF:FF:FF:FF:FF:FF for broadcast, other for unicast */
567            os_memcpy( &myKey.BSSID, addr, MAC_ADDR_LEN );
568
569            if( seq_len ) {
570                /* Set key RSC */
571                os_memcpy( &myKey.KeyRSC, seq, seq_len );
572                myKey.KeyIndex |= TIWLAN_KEY_FLAGS_SET_KEY_RSC;
573            }
574
575            if( set_tx ) {
576                myKey.KeyIndex |= TIWLAN_KEY_FLAGS_TRANSMIT;
577            }
578
579            if( myKey.BSSID[0] != 0xFF ) {
580                myKey.KeyIndex |= TIWLAN_KEY_FLAGS_PAIRWISE;
581            }
582
583            os_memcpy( &temp, key, AES_KEY_LENGTH );
584            if( key_len == TKIP_KEY_LENGTH ) {
585                /* need to switch RX and TX MIC set with key (to match driver API) */
586                os_memcpy( (UINT8*)(((UINT8*)&temp)+24), (UINT8*)(((UINT8*)key)+16), 8 );
587                os_memcpy( (UINT8*)(((UINT8*)&temp)+16), (UINT8*)(((UINT8*)key)+24), 8 );
588            }
589            os_memcpy( &myKey.KeyMaterial, &temp, key_len );
590            ret = TI_AddKey( myDrv->hDriver, &myKey );
591            break;
592
593        case WEP_KEY_LENGTH_40:        /* 5 */
594        case WEP_KEY_LENGTH_104:       /* 13 */
595            if( key_len != 0 ) {
596                /* Set key index */
597                myWepKey.KeyIndex = key_idx;
598                /* Set key length and content */
599                myWepKey.KeyLength = key_len;
600                /* Set structure size */
601                myWepKey.Length = sizeof(OS_802_11_WEP);
602
603                if( set_tx ) {
604                    myWepKey.KeyIndex |= TIWLAN_KEY_FLAGS_TRANSMIT;
605                    wpa_printf(MSG_DEBUG, "setting this key to be the index: 0x%x", myWepKey.KeyIndex);
606                }
607
608                os_memcpy( &myWepKey.KeyMaterial, key, key_len );
609                wpa_printf(MSG_DEBUG, "Adding WEP key index: 0x%x", key_idx);
610                ret = TI_AddWEPKey( myDrv->hDriver, &myWepKey );
611            }
612            else {
613                wpa_printf(MSG_DEBUG, "Removing WEP key index: 0x%x", key_idx);
614                ret = TI_RemoveWEPKey( myDrv->hDriver, key_idx );
615            }
616            break;
617
618        default:
619            wpa_printf(MSG_ERROR,"Set_key: Wrong Key\n");
620            break;
621    }
622    return( TI2WPA_STATUS(ret) );
623}
624
625/*-----------------------------------------------------------------------------
626Routine Name: wpa_driver_tista_set_countermeasures
627Routine Description: start/stop countermeasures (drop packets due to replay attack detection)
628Arguments:
629   priv - pointer to private data structure
630   enabled - enable/disable flag
631Return Value: 0 on success, -1 on failure
632-----------------------------------------------------------------------------*/
633static int wpa_driver_tista_set_countermeasures(void *priv, int enabled)
634{
635    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
636
637    wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_countermeasures called: %d", enabled);
638    return( 0 );
639}
640
641/*-----------------------------------------------------------------------------
642Routine Name: wpa_driver_tista_set_drop_unencrypted
643Routine Description: enable/disable EAPOL-only tx by driver
644Arguments:
645   priv - pointer to private data structure
646   enabled - enable/disable flag
647Return Value: 0 on success, -1 on failure
648-----------------------------------------------------------------------------*/
649static int wpa_driver_tista_set_drop_unencrypted(void *priv, int enabled)
650{
651    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
652
653    wpa_printf(MSG_DEBUG,"TI: wpa_driver_tista_set_drop_unencrypted called: %d - not implemented", enabled);
654    return( 0 );
655}
656
657/*-----------------------------------------------------------------------------
658Routine Name: wpa_driver_tista_deauthenticate
659Routine Description: send deauthentication packet
660Arguments:
661   priv - pointer to private data structure
662   addr - address to send deauth packet to
663   reason_code - reason code supplied in deauth packet
664Return Value: 0 on success, -1 on failure
665-----------------------------------------------------------------------------*/
666static int wpa_driver_tista_deauthenticate(void *priv, const UINT8 *addr, int reason_code)
667{
668    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
669    int ret;
670
671    wpa_printf(MSG_DEBUG,"wpa_driver_tista_deauthenticate called");
672    /* If driver is not initialized yet - we cannot access it so return */
673    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
674
675    /* Block any pending disassoc event until successfully connected */
676    if( myDrv->block_disassoc_events == NO_BLOCK )
677        myDrv->block_disassoc_events = NO_BLOCK_DISASSOC_IN_PROGRESS;
678
679    ret = TI_Disassociate( myDrv->hDriver );
680    return( TI2WPA_STATUS(ret) );
681}
682
683/*-----------------------------------------------------------------------------
684Routine Name: wpa_driver_tista_disassociate
685Routine Description: disassociate from AP
686Arguments:
687   priv - pointer to private data structure
688   addr - address to send deauth packet to
689   reason_code - reason code supplied in deauth packet
690Return Value: 0 on success, -1 on failure
691-----------------------------------------------------------------------------*/
692static int wpa_driver_tista_disassociate(void *priv, const UINT8 *addr, int reason_code)
693{
694    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
695    int ret;
696
697    wpa_printf(MSG_DEBUG,"TI: wpa_driver_tista_disassociate called");
698    /* If driver is not initialized yet - we cannot access it so return */
699    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
700
701    /* Block any pending disassoc event until successfully connected */
702    if( myDrv->block_disassoc_events == NO_BLOCK )
703        myDrv->block_disassoc_events = NO_BLOCK_DISASSOC_IN_PROGRESS;
704
705    ret = TI_Disassociate( myDrv->hDriver );
706    return( TI2WPA_STATUS(ret) );
707}
708
709/*-----------------------------------------------------------------------------
710Routine Name: wpa_driver_tista_associate
711Routine Description: associate with AP
712Arguments:
713   priv - pointer to private data structure
714   params - struct wpa_driver_associate_params (ssid, bssid, etc)
715Return Value: 0 on success, -1 on failure
716-----------------------------------------------------------------------------*/
717static int wpa_driver_tista_associate(void *priv, struct wpa_driver_associate_params *params)
718{
719    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
720    OS_802_11_MAC_ADDRESS bssid = { 0xff,0xff,0xff,0xff,0xff,0xff };
721    int wpa_opt, wpa_cipher, ret;
722
723    wpa_printf(MSG_DEBUG,"TI: wpa_driver_tista_associate called");
724    /* If driver is not initialized yet - we cannot access it so return */
725    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
726
727    if( myDrv->block_disassoc_events == NO_BLOCK_DISASSOC_IN_PROGRESS )
728        myDrv->block_disassoc_events = BLOCK_DISASSOC;
729
730    if( params->bssid ) {
731        wpa_printf(MSG_DEBUG, "TI: BSSID=" MACSTR, MAC2STR(params->bssid));
732        /* if there is bssid -> set it */
733        if( os_memcmp( params->bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN ) != 0 ) {
734            os_memcpy( &bssid, params->bssid, ETH_ALEN );
735            TI_SetBSSID( myDrv->hDriver, &bssid );
736        }
737    }
738    else {
739        /* else set it to {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} */
740        TI_SetBSSID( myDrv->hDriver, &bssid );
741    }
742
743    /* Set driver network mode (Adhoc/Infrastructure) according to supplied parameters */
744    if( params->mode == IEEE80211_MODE_INFRA ) {
745        wpa_printf(MSG_DEBUG,"TI: setting os802_11Infrastructure mode...");
746        TI_SetBSSType( myDrv->hDriver, os802_11Infrastructure );
747    }
748    else if( params->mode == IEEE80211_MODE_IBSS ) {
749        wpa_printf(MSG_DEBUG,"TI: setting os802_11IBSS mode...");
750        TI_SetBSSType( myDrv->hDriver, os802_11IBSS );
751    }
752    else {
753        wpa_printf(MSG_ERROR,"TI: Associate: invalid mode specified...");
754    }
755
756    wpa_driver_tista_set_wpa_options( priv, params->key_mgmt_suite );
757    wpa_driver_tista_set_auth_mode( priv );
758    wpa_driver_tista_set_encryption( priv, params->pairwise_suite );
759
760    /* And trigger connection/association process in driver by setting SSID */
761    ret = wpa_driver_tista_set_ssid( priv, params->ssid, params->ssid_len);
762    return( ret );
763}
764
765/*-----------------------------------------------------------------------------
766Routine Name: ti_init_scan_params
767Routine Description: int scan parameters before scan command
768Arguments:
769   pScanParams - pointer to scan paramters structure
770   pScanPolicy - pointer to scan policy structure
771   scanType    - scan type
772   noOfChan    - number of allowed channels
773Return Value: None
774-----------------------------------------------------------------------------*/
775static void ti_init_scan_params( scan_Params_t *pScanParams,
776                                 scan_Policy_t *pScanPolicy,
777                                 int scan_type,
778                                 struct wpa_driver_ti_data *myDrv )
779{
780    UINT32 scanMaxDwellTime = SME_SCAN_BG_MAX_DWELL_TIME_DEF;
781    UINT32 scanMinDwellTime = SME_SCAN_BG_MIN_DWELL_TIME_DEF;
782    UINT32 chanMaxDwellTime = SME_SCAN_BG_MIN_DWELL_TIME_DEF;
783    UINT32 chanMinDwellTime = SME_SCAN_BG_MIN_DWELL_TIME_DEF / 2;
784    int scanType = scan_type;
785    int noOfChan = myDrv->scan_channels;
786    int btCoexScan = myDrv->btcoex_scan;
787    int i, j;
788    UINT8 tid = 0, probeNum = 3;
789
790    if( noOfChan > MAX_NUMBER_OF_CHANNELS_PER_SCAN )
791        noOfChan = MAX_NUMBER_OF_CHANNELS_PER_SCAN;
792    /* init application scan default params */
793    pScanParams->desiredSsid.len = 0;
794    pScanParams->band = RADIO_BAND_2_4_GHZ;
795    if( btCoexScan ) { /* Changing scan parameteres to coexist with BT A2DP */
796        if( scanType == SCAN_TYPE_NORMAL_PASSIVE )
797            scanType = SCAN_TYPE_TRIGGERED_PASSIVE;
798        else if( scanType == SCAN_TYPE_NORMAL_ACTIVE )
799            scanType = SCAN_TYPE_TRIGGERED_ACTIVE;
800        probeNum = 1;
801        tid = 0xFF;
802        scanMaxDwellTime /= 6;
803        scanMinDwellTime /= 6;
804        chanMaxDwellTime /= 6;
805        chanMinDwellTime /= 6;
806    }
807    pScanParams->scanType = scanType;
808    pScanParams->probeReqNumber = probeNum;
809    pScanParams->Tid = tid;
810    pScanParams->probeRequestRate = DRV_RATE_MASK_2_BARKER;
811    pScanParams->numOfChannels = (UINT8)noOfChan;
812    for(i=0;( i < noOfChan );i++) {
813        for(j=0;( j < MAC_ADDR_LEN );j++) {
814            pScanParams->channelEntry[ i ].normalChannelEntry.bssId.addr[ j ] = 0xff;
815        }
816        pScanParams->channelEntry[ i ].normalChannelEntry.earlyTerminationEvent = SCAN_ET_COND_DISABLE;
817        pScanParams->channelEntry[ i ].normalChannelEntry.ETMaxNumOfAPframes = 0;
818        pScanParams->channelEntry[ i ].normalChannelEntry.maxChannelDwellTime = scanMaxDwellTime;
819        pScanParams->channelEntry[ i ].normalChannelEntry.minChannelDwellTime = scanMinDwellTime;
820#ifdef STA_DK_VER_5_0_0_94
821        pScanParams->channelEntry[ i ].normalChannelEntry.txPowerLevel = 1;
822#else
823        pScanParams->channelEntry[ i ].normalChannelEntry.txPowerDbm = MAX_TX_POWER;
824#endif
825        pScanParams->channelEntry[ i ].normalChannelEntry.channel = i + 1;
826    }
827
828    /* init default scan policy */
829    pScanPolicy->normalScanInterval = 10000;
830    pScanPolicy->deterioratingScanInterval = 5000;
831    pScanPolicy->maxTrackFailures = 3;
832    pScanPolicy->BSSListSize = 4;
833    pScanPolicy->BSSNumberToStartDiscovery = 1;
834    pScanPolicy->numOfBands = 1;
835    pScanPolicy->bandScanPolicy[ 0 ].band = RADIO_BAND_2_4_GHZ;
836    pScanPolicy->bandScanPolicy[ 0 ].rxRSSIThreshold = -80;
837    pScanPolicy->bandScanPolicy[ 0 ].numOfChannles = (UINT8)noOfChan;
838    pScanPolicy->bandScanPolicy[ 0 ].numOfChannlesForDiscovery = 3;
839    for(i=0;( i < noOfChan );i++) {
840        pScanPolicy->bandScanPolicy[ 0 ].channelList[ i ] = i + 1;
841    }
842    pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.scanType = SCAN_TYPE_NO_SCAN;
843    pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.earlyTerminationEvent = SCAN_ET_COND_DISABLE;
844    pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.ETMaxNumberOfApFrames = 0;
845    pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.maxChannelDwellTime = chanMaxDwellTime;
846    pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.minChannelDwellTime = chanMinDwellTime;
847    pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.bitrate = DRV_RATE_MASK_1_BARKER;
848    pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.numOfProbeReqs = pScanParams->probeReqNumber;
849#ifdef STA_DK_VER_5_0_0_94
850    pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.txLevel = 1;
851#else
852    pScanPolicy->bandScanPolicy[ 0 ].trackingMethod.method.basicMethodParams.probReqParams.txPowerDbm = MAX_TX_POWER;
853#endif
854    pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.scanType = SCAN_TYPE_NO_SCAN;
855    pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.earlyTerminationEvent = SCAN_ET_COND_DISABLE;
856    pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.ETMaxNumberOfApFrames = 0;
857    pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.maxChannelDwellTime = chanMaxDwellTime;
858    pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.minChannelDwellTime = chanMinDwellTime;
859    pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.bitrate = DRV_RATE_MASK_2_BARKER;
860    pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.numOfProbeReqs = pScanParams->probeReqNumber;
861#ifdef STA_DK_VER_5_0_0_94
862    pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.txLevel = 1;
863#else
864    pScanPolicy->bandScanPolicy[ 0 ].discoveryMethod.method.basicMethodParams.probReqParams.txPowerDbm = MAX_TX_POWER;
865#endif
866    pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.scanType = btCoexScan ? SCAN_TYPE_TRIGGERED_ACTIVE : SCAN_TYPE_NORMAL_ACTIVE;
867    pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.earlyTerminationEvent = SCAN_ET_COND_DISABLE;
868    pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.ETMaxNumberOfApFrames = 0;
869    pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.maxChannelDwellTime = chanMaxDwellTime;
870    pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.minChannelDwellTime = chanMinDwellTime;
871    pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.probReqParams.bitrate = DRV_RATE_MASK_5_5_CCK;
872    pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.probReqParams.numOfProbeReqs = pScanParams->probeReqNumber;
873#ifdef STA_DK_VER_5_0_0_94
874    pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.probReqParams.txLevel = 1;
875#else
876    pScanPolicy->bandScanPolicy[ 0 ].immediateScanMethod.method.basicMethodParams.probReqParams.txPowerDbm = MAX_TX_POWER;
877#endif
878}
879
880/*-----------------------------------------------------------------------------
881Routine Name: wpa_driver_tista_scan
882Routine Description: request scan from driver
883Arguments:
884   priv - pointer to private data structure
885   ssid - ssid buffer
886   ssid_len - length of ssid
887Return Value: 0 on success, -1 on failure
888-----------------------------------------------------------------------------*/
889static int wpa_driver_tista_scan( void *priv, const UINT8 *ssid, size_t ssid_len )
890{
891    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
892    struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(myDrv->hWpaSupplicant);
893    struct wpa_ssid *issid;
894    scan_Params_t scanParams;
895    scan_Policy_t scanPolicy;
896    int scan_type, ret, scan_probe_flag = 0;
897
898    wpa_printf(MSG_DEBUG,"wpa_driver_tista_scan called");
899    /* If driver is not initialized yet - we cannot access it so return */
900    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
901
902    scan_type = myDrv->scan_type;
903    if (wpa_s->prev_scan_ssid != BROADCAST_SSID_SCAN) {
904        if (wpa_s->prev_scan_ssid->scan_ssid) {
905            scan_type = SCAN_TYPE_NORMAL_ACTIVE;
906            scan_probe_flag = 1;
907        }
908    }
909
910    ti_init_scan_params( &scanParams, &scanPolicy, scan_type, myDrv );
911
912    myDrv->force_merge_flag = 0; /* Set merge flag */
913
914    if ((scan_probe_flag && ssid) &&
915        (ssid_len > 0 && ssid_len <= sizeof(scanParams.desiredSsid.ssidString))) {
916        os_memcpy(scanParams.desiredSsid.ssidString, ssid, ssid_len);
917	if (ssid_len < sizeof(scanParams.desiredSsid.ssidString))
918            scanParams.desiredSsid.ssidString[ssid_len] = '\0';
919        scanParams.desiredSsid.len = ssid_len;
920        myDrv->force_merge_flag = 1;
921    }
922    TI_SetScanPolicy( myDrv->hDriver, (UINT8 *)&scanPolicy, sizeof(scan_Policy_t) );
923    myDrv->last_scan = scan_type; /* Remember scan type for last scan */
924    ret = TI_StartScan( myDrv->hDriver, (scan_Params_t *)&scanParams );
925    return( TI2WPA_STATUS(ret) );
926}
927
928/*-----------------------------------------------------------------------------
929Routine Name: wpa_driver_tista_set_auth_alg
930Routine Description: set authentication in driver
931Arguments:
932   priv - pointer to private data structure
933   auth_alg - Open/Shared/LEAP
934Return Value: 0 on success, -1 on failure
935-----------------------------------------------------------------------------*/
936static int wpa_driver_tista_set_auth_alg( void *priv, int auth_alg )
937{
938    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
939
940    wpa_printf(MSG_DEBUG,"wpa_driver_tista_set_auth_alg called: %d", auth_alg);
941    /* If driver is not initialized yet - we cannot access it so return */
942    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
943    myDrv->auth_alg = auth_alg;
944    return( 0 );
945}
946
947/*-----------------------------------------------------------------------------
948Routine Name: wpa_driver_tista_get_bssid_info
949Routine Description: retrieve bssid full info
950Arguments:
951   hDriver - pointer to driver structure
952Return Value: pointer to BSSID structure or NULL
953-----------------------------------------------------------------------------*/
954static OS_802_11_BSSID_EX *wpa_driver_tista_get_bssid_info( TI_HANDLE hDriver )
955{
956    OS_802_11_BSSID_LIST_EX *bssid_list;
957    OS_802_11_BSSID_EX *pBssid, *nBssid = NULL;
958    int i, number_items, res;
959    OS_802_11_MAC_ADDRESS bssid;
960    OS_802_11_SSID ssid;
961
962    if( TI_GetBSSIDList( hDriver, &bssid_list ) || !bssid_list )
963        return( nBssid );
964
965    if( TI_GetBSSID( hDriver, &bssid ) != TI_RESULT_OK )
966        return( nBssid );
967
968    if( TI_GetCurrentSSID( hDriver, &ssid ) != TI_RESULT_OK )
969        return( nBssid );
970
971    pBssid = &bssid_list->Bssid[0];
972    number_items = (int)(bssid_list->NumberOfItems);
973    for(i=0;( i < number_items );i++) {
974        if( !os_memcmp((void *)&bssid, pBssid->MacAddress, MAC_ADDR_LEN) &&
975            !os_memcmp(ssid.Ssid, pBssid->Ssid.Ssid, pBssid->Ssid.SsidLength) ) {
976            nBssid = (OS_802_11_BSSID_EX *)os_malloc( pBssid->Length );
977            if( nBssid != NULL )
978                os_memcpy( nBssid, pBssid, pBssid->Length );
979            break;
980        }
981        pBssid = (OS_802_11_BSSID_EX *)(((char *)pBssid) + pBssid->Length);
982    }
983    os_free( bssid_list );
984    return( nBssid );
985}
986
987/*-----------------------------------------------------------------------------
988Compare function for sorting scan results. Return >0 if @b is considered better.
989-----------------------------------------------------------------------------*/
990static int wpa_driver_tista_scan_result_compare(const void *a, const void *b)
991{
992    const struct wpa_scan_result *wa = a;
993    const struct wpa_scan_result *wb = b;
994
995    return( wb->level - wa->level );
996}
997
998/*-----------------------------------------------------------------------------
999Routine Name: wpa_driver_tista_get_scan_results
1000Routine Description: retrieve driver scan results
1001Arguments:
1002   priv - pointer to private data structure
1003   results - pointer to buffer
1004   max_size - maximum size of results buffer
1005Return Value: number of SSID on success, -1 on failure
1006-----------------------------------------------------------------------------*/
1007static int wpa_driver_tista_get_scan_results( void *priv,
1008                                     struct wpa_scan_result *results,
1009                                     size_t max_size )
1010{
1011    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
1012    OS_802_11_BSSID_LIST_EX *bssid_list;
1013    OS_802_11_BSSID_EX *pBssid;
1014    OS_802_11_FIXED_IEs *pFixedIes;
1015    OS_802_11_VARIABLE_IEs *pVarIes;
1016    unsigned int number_items, i, index;
1017
1018    wpa_printf(MSG_DEBUG,"wpa_driver_tista_get_scan_results called");
1019    /* If driver is not initialized yet - we cannot access it so return */
1020    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
1021
1022    if( TI_GetBSSIDList(myDrv->hDriver, &bssid_list) || !bssid_list )
1023        return( -1 );
1024
1025    pBssid = &bssid_list->Bssid[0];
1026    number_items = (int)(bssid_list->NumberOfItems);
1027
1028    wpa_printf(MSG_MSGDUMP, "Received %d bytes of scan results (%d BSSes)",
1029           number_items * sizeof(OS_802_11_BSSID_EX), number_items);
1030
1031    os_memset( results, 0, max_size * sizeof(struct wpa_scan_result) );
1032    number_items = MIN( number_items, max_size );
1033
1034    for(index=0; index < number_items; index++) {
1035        os_memcpy( results[index].bssid, &pBssid->MacAddress, ETH_ALEN );
1036        os_memcpy( results[index].ssid, pBssid->Ssid.Ssid, pBssid->Ssid.SsidLength );
1037        results[index].ssid_len = pBssid->Ssid.SsidLength;
1038#ifdef STA_DK_VER_5_0_0_94
1039        results[index].freq = pBssid->Configuration.channel / 1000;
1040        results[index].caps = pBssid->Capabilities;
1041#else
1042        results[index].freq = pBssid->Configuration.Union.channel / 1000;
1043        results[index].caps = pBssid->Union.Capabilities;
1044#endif
1045        results[index].level = pBssid->Rssi;
1046        results[index].maxrate = 0; /* In units of 0.5 Mb/s */
1047        for (i = 0; i < sizeof(pBssid->SupportedRates); i++) {
1048            if (pBssid->SupportedRates[i] > (unsigned)results[index].maxrate) {
1049                results[index].maxrate = pBssid->SupportedRates[i];
1050            }
1051        }
1052        wpa_printf(MSG_DEBUG,"TI: Net: %s Cap: 0x%04x Priv: 0x%x NetType: 0x%x InfraMode: 0x%x IELen: %d",
1053#ifdef STA_DK_VER_5_0_0_94
1054                   pBssid->Ssid.Ssid, pBssid->Capabilities, pBssid->Privacy, pBssid->NetworkTypeInUse,
1055#else
1056                   pBssid->Ssid.Ssid, pBssid->Union.Capabilities, pBssid->Privacy, pBssid->NetworkTypeInUse,
1057#endif
1058                   pBssid->InfrastructureMode, pBssid->IELength );
1059
1060        /* Fixed IEs from site entry - same Capabilities */
1061        pFixedIes = (OS_802_11_FIXED_IEs *)&pBssid->IEs[0];
1062        wpa_printf(MSG_DEBUG,"TI: Fixed IEs: Beacon: 0x%x Cap: 0x%x", pFixedIes->BeaconInterval, pFixedIes->Capabilities);
1063        for(i=sizeof(OS_802_11_FIXED_IEs); i < pBssid->IELength;) {
1064            pVarIes = (OS_802_11_VARIABLE_IEs *)&pBssid->IEs[i];
1065            wpa_printf(MSG_DEBUG,"TI: Variable IEs: ID: 0x%x Len: %d", pVarIes->ElementID, pVarIes->Length);
1066            wpa_hexdump(MSG_DEBUG,"TI: oui:", pVarIes->data, pVarIes->Length);
1067            switch( pVarIes->ElementID ) {
1068                case GENERIC_INFO_ELEM: /* 0xdd */
1069                    if( (pVarIes->Length > 3) && (os_memcmp(pVarIes->data, WPA_OUI, 4) == 0) ) {
1070                        results[index].wpa_ie_len = MIN((pVarIes->Length + 2), SSID_MAX_WPA_IE_LEN);
1071                        os_memcpy( results[index].wpa_ie, pVarIes, results[index].wpa_ie_len );
1072                    }
1073                    break;
1074
1075                case RSN_INFO_ELEM:     /* 0x30 */
1076                    results[index].rsn_ie_len = MIN((pVarIes->Length + 2), SSID_MAX_WPA_IE_LEN);
1077                    os_memcpy( results[index].rsn_ie, pVarIes, results[index].rsn_ie_len );
1078                    break;
1079            }
1080            i += (pVarIes->Length + (2 * sizeof(tiUINT8)));
1081        }
1082        pBssid = (OS_802_11_BSSID_EX *)(((u8 *)pBssid) + pBssid->Length);
1083    }
1084    /* Merge new results with previous */
1085    number_items = scan_merge( myDrv, results, myDrv->force_merge_flag, number_items, max_size );
1086
1087    qsort( results, number_items, sizeof(struct wpa_scan_result),
1088           wpa_driver_tista_scan_result_compare );
1089
1090    os_free( bssid_list );
1091    return( number_items );
1092}
1093
1094/*-----------------------------------------------------------------------------
1095Routine Name: wpa_driver_tista_get_scan_results
1096Routine Description: retrieve driver scan results
1097Arguments:
1098   sock - socket
1099   priv - pointer to private data structure
1100   sock_ctx - pointer to other private data
1101Return Value: None
1102-----------------------------------------------------------------------------*/
1103static void wpa_driver_tista_receive_driver_event( int sock, void *priv, void *sock_ctx )
1104{
1105    IPC_EV_DATA myBuf;
1106    UINT8 *buf;
1107    UINT32 *bufLong;
1108    union wpa_event_data myEventData;
1109    struct wpa_driver_ti_data *mySuppl;
1110    OS_802_11_ASSOCIATION_INFORMATION *pInfo = NULL;
1111    OS_802_11_AUTHENTICATION_REQUEST *pMediaSpecificBuf;
1112    OS_802_11_BSSID_EX *pSelectedBssidInfo = NULL;
1113    OS_802_11_NETWORK_MODE myBssType;
1114    IPC_EV_DATA *pData = &myBuf;
1115    int res;
1116#ifndef STA_DK_VER_5_0_0_94
1117    btCoexStatus_t *btCoexStatus;
1118#endif
1119
1120    wpa_printf(MSG_DEBUG,"wpa_driver_tista_receive_driver_event...");
1121
1122    res = recv( sock, &myBuf, sizeof(myBuf), 0 );
1123    if( res < 0 ) {
1124        wpa_printf(MSG_ERROR,"l2_packet_receive - recvfrom");
1125        return;
1126    }
1127
1128    mySuppl = pData->EvParams.hUserParam;
1129
1130    switch( ((IPC_EVENT_PARAMS*)pData)->uEventType ) {
1131        case IPC_EVENT_ASSOCIATED:
1132            /* Associated event is called after successfull ASSOC_RSP packet is received */
1133            wpa_printf(MSG_DEBUG,"wpa_supplicant - Associated");
1134
1135            TI_GetBSSType( mySuppl->hDriver, &myBssType );
1136            wpa_printf(MSG_DEBUG,"myBssType = %d",myBssType);
1137
1138            if( myBssType == os802_11Infrastructure ) {
1139                /* Get ASSOC_REQ and ASSOC_RSP IE */
1140                res = TI_GetAssociationInfo( mySuppl->hDriver, &pInfo );
1141                buf = (UINT8 *)pInfo;
1142
1143                if( buf != NULL ) {
1144                    myEventData.assoc_info.req_ies = buf + pInfo->OffsetRequestIEs;
1145                    myEventData.assoc_info.req_ies_len = pInfo->RequestIELength;
1146                    myEventData.assoc_info.resp_ies = buf + pInfo->OffsetResponseIEs;
1147                    myEventData.assoc_info.resp_ies_len = pInfo->ResponseIELength;
1148                    myEventData.assoc_info.beacon_ies = NULL;
1149                    myEventData.assoc_info.beacon_ies_len = 0;
1150
1151                    /* Get AP Beacon IEs - especially WPA/RSN IE */
1152                    pSelectedBssidInfo = wpa_driver_tista_get_bssid_info( mySuppl->hDriver );
1153                    if( pSelectedBssidInfo ) {
1154                        if( pSelectedBssidInfo->IELength && pSelectedBssidInfo->IEs ) { /* Dm: Fixed IEs */
1155                            myEventData.assoc_info.beacon_ies = (UINT8 *)pSelectedBssidInfo->IEs + sizeof(OS_802_11_FIXED_IEs);
1156                            myEventData.assoc_info.beacon_ies_len = pSelectedBssidInfo->IELength - sizeof(OS_802_11_FIXED_IEs);
1157                        }
1158                    }
1159                    wpa_printf(MSG_DEBUG,"myEventData.assoc_info.req_ies = 0x%x",(unsigned)myEventData.assoc_info.req_ies);
1160                    wpa_printf(MSG_DEBUG,"myEventData.assoc_info.req_ies_len = %d",myEventData.assoc_info.req_ies_len);
1161                    wpa_printf(MSG_DEBUG,"myEventData.assoc_info.resp_ies = 0x%x",(unsigned)myEventData.assoc_info.resp_ies);
1162                    wpa_printf(MSG_DEBUG,"myEventData.assoc_info.resp_ies_len = %d",myEventData.assoc_info.resp_ies_len);
1163                    wpa_printf(MSG_DEBUG,"myEventData.assoc_info.beacon_ies = 0x%x",(unsigned)myEventData.assoc_info.beacon_ies);
1164                    wpa_printf(MSG_DEBUG,"myEventData.assoc_info.beacon_ies_len = %d",myEventData.assoc_info.beacon_ies_len);
1165                    wpa_hexdump(MSG_DEBUG, "WPA: beacon_ies", myEventData.assoc_info.beacon_ies, myEventData.assoc_info.beacon_ies_len);
1166
1167                    /* First we notify wpa_supplicant and give it all the above IEs */
1168                    wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_ASSOCINFO, &myEventData );
1169
1170                    /* Since both ASSOC_REQ/RSP and beacon IEs are allocated dynamically by the Utility Adapter - we need to free the buffers */
1171                    os_free( pInfo );
1172                    if( pSelectedBssidInfo ) {
1173                        os_free( pSelectedBssidInfo );
1174                    }
1175                }
1176            }
1177            else {
1178                myEventData.assoc_info.req_ies = NULL;
1179                myEventData.assoc_info.req_ies_len = 0;
1180                myEventData.assoc_info.resp_ies = NULL;
1181                myEventData.assoc_info.resp_ies_len = 0;
1182                myEventData.assoc_info.beacon_ies = NULL;
1183                myEventData.assoc_info.beacon_ies_len = 0;
1184                wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_ASSOCINFO, &myEventData );
1185            }
1186            /* We now can notify wpa_supplicant of the association event so it could start key negotiation (if needed) */
1187            wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_ASSOC, NULL );
1188            /* Allow Disassociation */
1189            mySuppl->block_disassoc_events = NO_BLOCK;
1190            break;
1191
1192        case IPC_EVENT_DISASSOCIATED:
1193            if( mySuppl->block_disassoc_events != BLOCK_DISASSOC ) {
1194               wpa_printf(MSG_DEBUG,"wpa_supplicant - Disassociated");
1195               wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_DISASSOC, NULL );
1196            }
1197            else {
1198               wpa_printf(MSG_INFO,"wpa_supplicant - Disassociated (blocked)");
1199            }
1200            break;
1201
1202        case IPC_EVENT_SCAN_COMPLETE:
1203            wpa_printf(MSG_DEBUG,"wpa_supplicant - IPC_EVENT_SCAN_COMPLETE");
1204            wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_SCAN_RESULTS, NULL );
1205            break;
1206
1207        case IPC_EVENT_AUTH_SUCC:
1208            wpa_printf(MSG_INFO,"wpa_supplicant - IPC_EVENT_AUTH_SUCC");
1209            break;
1210
1211        case IPC_EVENT_EAPOL:
1212            wpa_printf(MSG_DEBUG,"wpa_supplicant - EAPOL");
1213            buf = pData->uBuffer;
1214            wpa_supplicant_rx_eapol( mySuppl->hWpaSupplicant, (UINT8 *)(buf + MAC_ADDR_LEN),
1215                                     (UINT8 *)(buf + ETHERNET_HDR_LEN), (pData->uBufferSize - ETHERNET_HDR_LEN) );
1216            break;
1217
1218        case IPC_EVENT_MEDIA_SPECIFIC:
1219            wpa_printf(MSG_DEBUG,"wpa_supplicant - Media_Specific");
1220            bufLong = (UINT32 *)pData->uBuffer;
1221            /* Check for Authentication type messages from driver */
1222            if( (*bufLong) == os802_11StatusType_Authentication ) {
1223                pMediaSpecificBuf = (OS_802_11_AUTHENTICATION_REQUEST *)(bufLong + 1);
1224                wpa_printf(MSG_DEBUG,"wpa_supplicant - Media_Specific - Authentication message detected: %u", pMediaSpecificBuf->Flags);
1225                /* Check for MIC failure event */
1226                if( (pMediaSpecificBuf->Flags == OS_802_11_REQUEST_PAIRWISE_ERROR) || (pMediaSpecificBuf->Flags == OS_802_11_REQUEST_GROUP_ERROR)) {
1227                    /* Notify wpa_supplicant of MIC failure */
1228                    myEventData.michael_mic_failure.unicast = 1;
1229                    wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_MICHAEL_MIC_FAILURE, &myEventData );
1230                }
1231                /* OS_802_11_REQUEST_REAUTH - is handled automatically */
1232                /* OS_802_11_REQUEST_KEYUPDATE - no event of this type */
1233            }
1234            break;
1235
1236        case IPC_EVENT_LINK_SPEED:
1237            bufLong = (UINT32 *)pData->uBuffer;
1238            wpa_printf(MSG_DEBUG,"wpa_supplicant - Link Speed = %u MB/s", ((*bufLong) / 2));
1239            /* wpa_msg(mySuppl->hWpaSupplicant, MSG_INFO, WPA_EVENT_LINK_SPEED "%u MB/s", ((*bufLong) / 2)); */
1240            mySuppl->link_speed = (unsigned)((*bufLong) / 2);
1241            break;
1242
1243        case IPC_EVENT_WPA2_PREAUTHENTICATION:
1244            wpa_printf(MSG_DEBUG,"wpa_supplicant - WPA2_PREAUTHENTICATION");
1245            bufLong = (UINT32 *)pData->uBuffer;
1246            wpa_printf(MSG_DEBUG,"Preauth Status Code = %u",*bufLong);
1247            /* Dm: wpa_supplicant_event( mySuppl->hWpaSupplicant, EVENT_PMKID_CANDIDATE, &data); */
1248            break;
1249
1250#ifndef STA_DK_VER_5_0_0_94
1251        case IPC_EVENT_BT_COEX_MODE:
1252            btCoexStatus = (btCoexStatus_t *)pData->uBuffer;
1253            if( (btCoexStatus != NULL) && btCoexStatus->state ) {
1254                wpa_printf(MSG_DEBUG,"wpa_supplicant - BT_COEX_MODE (SG is ON, minTxRate = %d)\n", btCoexStatus->minTxRate);
1255            }
1256            else {
1257                wpa_printf(MSG_DEBUG,"wpa_supplicant - BT_COEX_MODE (SG is OFF)\n");
1258            }
1259            break;
1260#endif
1261        case IPC_EVENT_LOW_SNR:
1262        case IPC_EVENT_LOW_RSSI:
1263            break;
1264
1265        default:
1266            wpa_printf(MSG_ERROR,"wpa_supplicant - Unhandled driver event: %d", ((IPC_EVENT_PARAMS*)pData)->uEventType);
1267            break;
1268    }
1269}
1270
1271/*-----------------------------------------------------------------------------
1272Routine Name: wpa_driver_tista_init
1273Routine Description: init driver interface
1274Arguments:
1275   priv - pointer to private data structure
1276   ifname - return interface name
1277Return Value: pointer to driver structure (to be supplied later by supplicant to wrappers)
1278-----------------------------------------------------------------------------*/
1279static void *wpa_driver_tista_init( void *priv, const char *ifname )
1280{
1281    struct wpa_driver_ti_data *myDrv;
1282    int status;
1283    UINT32 driverStatus,res;
1284    struct sockaddr_in echoserver;
1285    OS_802_11_MAC_ADDRESS myMac;
1286#ifdef CONFIG_TI_LOCKFILE
1287    char str[10];
1288#endif
1289
1290    wpa_printf(MSG_DEBUG,"Initializing STA-DK %s interface...",SW_VERSION_STR);
1291#ifdef CONFIG_TI_LOCKFILE
1292    /* Try to open the lock file */
1293    lfp = open("./.wpa_supplicant_lockfile.pid", (O_RDWR | O_CREAT | O_EXCL), 0640);
1294    if( lfp < 0 ) {
1295        wpa_printf(MSG_ERROR,"Cannot open pid-file...Aborting...\n");
1296        return( NULL );
1297    }
1298    /* Try to get a file lock on the pid-file. If another instance is running and already has a lock - we will fail */
1299#ifndef ANDROID /* Dm: !!! lockf is not implemented in Android */
1300    if( lockf(lfp,F_TLOCK,0) < 0 ) {
1301        wpa_printf(MSG_ERROR,"Another instance of wpa_supplicant is running...Aborting...\n");
1302        return( NULL );
1303    }
1304#endif
1305    /* If we got here - it means that no other instance is running - write process id to pid_file */
1306    sprintf(str, "%d\n", getpid());
1307    write(lfp,str,os_strlen(str)); /* record pid to lockfile */
1308#endif
1309
1310    /* Allocate internal data structure to manage driver */
1311    myDrv = os_malloc( sizeof(struct wpa_driver_ti_data) );
1312
1313    /* If failed to allocate */
1314    if( myDrv == NULL ) {
1315        wpa_printf(MSG_ERROR,"Failed to allocate memory for control structure...Aborting...");
1316        goto label_init_error_file;
1317    }
1318
1319    /* Zero memory */
1320    os_memset( myDrv, 0, sizeof(struct wpa_driver_ti_data) );
1321
1322    /* Initialize Utility Adapter module */
1323    myDrv->hDriver = TI_AdapterInit( TIWLAN_DRV_NAME );
1324
1325    /* If couldn't initialize - return NULL to indicate error */
1326    if( myDrv->hDriver == 0 ) {
1327        wpa_printf(MSG_ERROR,"Error: failed to initialize Utility Adapter interface...");
1328        goto label_init_error_free;
1329    }
1330
1331    /* Get WLAN interface mac address through Utility Adapter */
1332    res = TI_GetCurrentAddress( myDrv->hDriver, &myMac );
1333
1334    if( res == (UINT32)-1 ) {
1335        wpa_printf(MSG_ERROR,"Error: failed to initialize Utility Adapter interface...");
1336        goto label_init_error_free;
1337    }
1338
1339    os_memcpy( &myDrv->own_addr, &myMac, MAC_ADDR_LEN );
1340
1341    wpa_driver_tista_register_events( myDrv );
1342
1343    /* Block disassoc events until connected */
1344    if( myDrv->block_disassoc_events == NO_BLOCK )
1345        myDrv->block_disassoc_events = NO_BLOCK_DISASSOC_IN_PROGRESS;
1346
1347    /* Store wpa_supplicant context */
1348    myDrv->hWpaSupplicant = priv;
1349
1350    myDrv->driverEventsSocket = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
1351
1352    if( myDrv->driverEventsSocket < 0 ) {
1353        wpa_printf(MSG_ERROR,"Error: failed to create driver events socket... (%s)", strerror(errno));
1354        goto label_init_error_free;
1355    }
1356
1357    os_memset( &echoserver, 0, sizeof(echoserver) );  /* Clear struct */
1358    echoserver.sin_family = AF_INET;                  /* Internet/IP */
1359    echoserver.sin_addr.s_addr = htonl(INADDR_ANY);   /* IP address */
1360    echoserver.sin_port = htons(TI_DRIVER_MSG_PORT);  /* server port */
1361
1362    if( bind(myDrv->driverEventsSocket, (struct sockaddr *) &echoserver, sizeof(echoserver)) < 0 ) {
1363        wpa_printf(MSG_ERROR,"Error: failed to create driver events socket... (%s)", strerror(errno));
1364        close(myDrv->driverEventsSocket);
1365        goto label_init_error_free;
1366    }
1367
1368    status = eloop_register_read_sock( myDrv->driverEventsSocket, wpa_driver_tista_receive_driver_event, priv, myDrv );
1369
1370    if( status != 0 ) {
1371        wpa_printf(MSG_ERROR,"Error: failed to register socket handler...");
1372    }
1373
1374    wpa_printf(MSG_DEBUG,"driver events socket is 0x%x...",myDrv->driverEventsSocket);
1375
1376    /* Signal that driver is not stopped */
1377    myDrv->driver_is_loaded = TRUE;
1378
1379    /* Set default scan type */
1380    myDrv->scan_type = SCAN_TYPE_NORMAL_ACTIVE;
1381    myDrv->force_merge_flag = 0;
1382    scan_init( myDrv );
1383
1384    /* Set default amount of channels */
1385    myDrv->scan_channels = check_and_get_build_channels();
1386
1387    /* Link Speed will be set by the message from the driver */
1388    myDrv->link_speed = 0;
1389
1390    /* BtCoex mode is read from tiwlan.ini file */
1391    myDrv->btcoex_mode = 1; /* SG_DISABLE */
1392    myDrv->btcoex_scan = FALSE;
1393
1394    /* RTS Threshold is read from tiwlan.ini file */
1395    myDrv->rts_threshold = HAL_CTRL_RTS_THRESHOLD_MAX;
1396
1397    /* Return pointer to our driver structure */
1398    return( myDrv );
1399
1400label_init_error_free:
1401    os_free( myDrv );
1402label_init_error_file:
1403#ifdef CONFIG_TI_LOCKFILE
1404    /* Close and delete the pid-lock-file */
1405    close(lfp);
1406    unlink("./wpa_supplicant_lockfile.pid");
1407#endif
1408    return( NULL );
1409}
1410
1411/*-----------------------------------------------------------------------------
1412Routine Name: wpa_driver_tista_unload
1413Routine Description: unload driver
1414Arguments:
1415   priv - pointer to private data structure
1416Return Value: None
1417-----------------------------------------------------------------------------*/
1418static void wpa_driver_tista_unload( void *priv )
1419{
1420    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
1421
1422    wpa_printf(MSG_DEBUG,"wpa_driver_tista_unload called");
1423    /* Unregister driver events */
1424    wpa_driver_tista_unregister_events( priv );
1425    /* Close connection socket */
1426    close(myDrv->driverEventsSocket);
1427    /* Unload Utility Adapter */
1428    TI_AdapterDeinit( myDrv->hDriver );
1429    /* Free all allocated memory */
1430    scan_exit( myDrv );
1431    os_free( myDrv );
1432#ifdef CONFIG_TI_LOCKFILE
1433    /* Close and delete the pid-lock-file */
1434    close(lfp);
1435    unlink("./wpa_supplicant_lockfile.pid");
1436#endif
1437    wpa_printf(MSG_DEBUG,"STA-DK %s interface Deinitialized...bye!", SW_VERSION_STR);
1438}
1439
1440/*-----------------------------------------------------------------------------
1441Routine Name: wpa_driver_tista_get_mac_addr
1442Routine Description: return WLAN MAC address
1443Arguments:
1444   priv - pointer to private data structure
1445Return Value: pointer to BSSID
1446-----------------------------------------------------------------------------*/
1447const u8 *wpa_driver_tista_get_mac_addr( void *priv )
1448{
1449    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
1450
1451    wpa_printf(MSG_DEBUG,"wpa_driver_tista_get_mac_addr called");
1452    /* If driver is not initialized yet - we cannot access it so return */
1453    TI_CHECK_DRIVER( myDrv->driver_is_loaded, NULL );
1454    return( (const u8 *)&myDrv->own_addr );
1455}
1456
1457/*-----------------------------------------------------------------------------
1458Routine Name: wpa_driver_tista_send_eapol
1459Routine Description: transmit EAPOL
1460Arguments:
1461   priv - pointer to private data structure
1462   data - pointer to EAPOL data
1463   data_len - length of EAPOL data
1464Return Value: None
1465-----------------------------------------------------------------------------*/
1466static int ti_send_eapol( void *priv, const u8 *dest, u16 proto,
1467                          const u8 *data, size_t data_len )
1468{
1469    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
1470    u8* DataWithHeader = NULL;
1471    u16 protoNetwork;
1472    int ret = 0;
1473
1474    wpa_printf(MSG_DEBUG,"TI send_eapol called");
1475#ifdef IEEE8021X_EAPOL
1476    DataWithHeader = os_malloc(data_len + ETHERNET_HDR_LEN); /* 14 bytes */
1477    if( DataWithHeader == NULL ) {
1478        wpa_printf(MSG_ERROR,"TI send_eapol failed to alloc full buffer");
1479        return( -1 );
1480    }
1481
1482    os_memcpy(DataWithHeader, dest, MAC_ADDR_LEN); /* 6 bytes */
1483    os_memcpy(DataWithHeader+MAC_ADDR_LEN, myDrv->own_addr, MAC_ADDR_LEN);
1484    protoNetwork = htons(proto);
1485    os_memcpy(DataWithHeader+(MAC_ADDR_LEN<<1), &protoNetwork, sizeof(u16)); /* 2 bytes */
1486
1487    os_memcpy(DataWithHeader+ETHERNET_HDR_LEN, data, data_len);
1488    data_len += ETHERNET_HDR_LEN;
1489
1490    wpa_hexdump(MSG_DEBUG, "WPA: FULL TX EAPOL-Key", DataWithHeader, data_len);
1491
1492    /* Transmit EAPOL packet */
1493    ret = TI_Send_EAPOL_Packet( myDrv->hDriver, (void *)DataWithHeader, data_len );
1494    os_free(DataWithHeader);
1495#endif
1496    return( TI2WPA_STATUS(ret) );
1497}
1498
1499#ifndef STA_DK_VER_5_0_0_94
1500/*-----------------------------------------------------------------------------
1501Routine Name: prepare_filter_struct
1502Routine Description: fills rx data filter structure according to parameter type
1503Arguments:
1504   priv - pointer to private data structure
1505   type - type of mac address
1506   dfreq_ptr - pointer to TIWLAN_DATA_FILTER_REQUEST structure
1507Return Value: 0 - success, -1 - error
1508-----------------------------------------------------------------------------*/
1509static int prepare_filter_struct( void *priv, int type,
1510                                  TIWLAN_DATA_FILTER_REQUEST *dfreq_ptr )
1511{
1512    u8 *macaddr = NULL;
1513    size_t len = 0;
1514    u8 mask = 0;
1515    int ret = -1;
1516
1517    wpa_printf(MSG_ERROR, "%s: type=%d", __func__, type);
1518    switch (type ) {
1519      case RX_SELF_FILTER:
1520        macaddr = (u8 *)wpa_driver_tista_get_mac_addr(priv);
1521        len = MAC_ADDR_LEN;
1522        mask = 0x3F; /* 6 bytes */
1523        break;
1524      case RX_BROADCAST_FILTER:
1525        macaddr = (u8 *)"\xFF\xFF\xFF\xFF\xFF\xFF";
1526        len = MAC_ADDR_LEN;
1527        mask = 0x3F; /* 6 bytes */
1528        break;
1529      case RX_IPV4_MULTICAST_FILTER:
1530        macaddr = (u8 *)"\x01\x00\x5E";
1531        len = 3;
1532        mask = 0x7; /* 3 bytes */
1533        break;
1534      case RX_IPV6_MULTICAST_FILTER:
1535        macaddr = (u8 *)"\x33\x33";
1536        len = 2;
1537        mask = 0x3; /* 2 bytes */
1538        break;
1539    }
1540    if (len && macaddr) {
1541        dfreq_ptr->Offset = 0;
1542        dfreq_ptr->MaskLength = 1;
1543        dfreq_ptr->Mask[0] = mask;
1544        dfreq_ptr->PatternLength = len;
1545        os_memcpy( dfreq_ptr->Pattern, macaddr, len );
1546        ret = 0;
1547    }
1548    return( ret );
1549}
1550#endif
1551
1552/*-----------------------------------------------------------------------------
1553Routine Name: wpa_driver_tista_driver_cmd
1554Routine Description: executes driver-specific commands
1555Arguments:
1556   priv - pointer to private data structure
1557   cmd - command
1558   buf - return buffer
1559   buf_len - buffer length
1560Return Value: actual buffer length - success, -1 - failure
1561-----------------------------------------------------------------------------*/
1562int wpa_driver_tista_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len )
1563{
1564    struct wpa_driver_ti_data *myDrv = (struct wpa_driver_ti_data *)priv;
1565    int ret = -1, prev_events;
1566
1567    wpa_printf(MSG_DEBUG, "%s %s", __func__, cmd);
1568
1569    if( os_strcasecmp(cmd, "start") == 0 ) {
1570        wpa_printf(MSG_DEBUG,"Start command");
1571        prev_events = myDrv->block_disassoc_events;
1572        myDrv->block_disassoc_events = myDrv->block_disassoc_prev;
1573        ret = TI_Start( myDrv->hDriver );
1574        if( ret == OK ) {
1575            /* Signal that driver is not loaded yet */
1576            myDrv->driver_is_loaded = TRUE;
1577            wpa_msg(myDrv->hWpaSupplicant, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
1578        }
1579        else
1580            myDrv->block_disassoc_events = prev_events;
1581        return( TI2WPA_STATUS(ret) );
1582    }
1583
1584    /* If driver is not initialized yet - we cannot access it so return */
1585    TI_CHECK_DRIVER( myDrv->driver_is_loaded, -1 );
1586
1587    if( os_strcasecmp(cmd, "stop") == 0 ) {
1588        wpa_printf(MSG_DEBUG,"Stop command");
1589        myDrv->block_disassoc_prev = myDrv->block_disassoc_events;
1590        myDrv->block_disassoc_events = BLOCK_DISASSOC; /* Block message */
1591        ret = TI_Stop( myDrv->hDriver );
1592        if( ret == OK ) {
1593            /* Signal that driver is not loaded yet */
1594            myDrv->driver_is_loaded = FALSE;
1595            wpa_msg(myDrv->hWpaSupplicant, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
1596        }
1597        else
1598            myDrv->block_disassoc_events = myDrv->block_disassoc_prev;
1599    }
1600    else if( os_strcasecmp(cmd, "macaddr") == 0 ) {
1601        u8 *macaddr = (u8 *)wpa_driver_tista_get_mac_addr(priv);
1602        wpa_printf(MSG_DEBUG,"Macaddr command");
1603        wpa_printf(MSG_DEBUG, "   Macaddr = " MACSTR, MAC2STR(macaddr));
1604        ret = snprintf(buf, buf_len, "Macaddr = " MACSTR "\n", MAC2STR(macaddr));
1605        if (ret < (int)buf_len) {
1606            return( ret );
1607        }
1608    }
1609    else if( os_strcasecmp(cmd, "scan-passive") == 0 ) {
1610        wpa_printf(MSG_DEBUG,"Scan Passive command");
1611        myDrv->scan_type = SCAN_TYPE_NORMAL_PASSIVE;
1612        ret = 0;
1613    }
1614    else if( os_strcasecmp(cmd, "scan-active") == 0 ) {
1615        wpa_printf(MSG_DEBUG,"Scan Active command");
1616        myDrv->scan_type = SCAN_TYPE_NORMAL_ACTIVE;
1617        ret = 0;
1618    }
1619    else if( os_strcasecmp(cmd, "scan-mode") == 0 ) {
1620        wpa_printf(MSG_DEBUG,"Scan Mode command");
1621        ret = snprintf(buf, buf_len, "ScanMode = %u\n", myDrv->scan_type);
1622        if (ret < (int)buf_len) {
1623            return( ret );
1624        }
1625    }
1626    else if( os_strcasecmp(cmd, "linkspeed") == 0 ) {
1627        wpa_printf(MSG_DEBUG,"Link Speed command");
1628        ret = snprintf(buf, buf_len, "LinkSpeed %u\n", myDrv->link_speed);
1629        if (ret < (int)buf_len) {
1630            return( ret );
1631        }
1632    }
1633    else if( os_strncasecmp(cmd, "scan-channels", 13) == 0 ) {
1634        int noOfChan;
1635        char *cp = cmd + 13;
1636        char *endp;
1637
1638        if (*cp != '\0') {
1639            noOfChan = strtol(cp, &endp, 0);
1640            if (endp != cp) {
1641                wpa_printf(MSG_DEBUG,"Scan Channels command = %d", noOfChan);
1642                if( (noOfChan > 0) && (noOfChan <= MAX_NUMBER_OF_CHANNELS_PER_SCAN) ) {
1643                    myDrv->scan_channels = noOfChan;
1644                    ret = 0;
1645                }
1646            }
1647        } else {
1648            ret = snprintf(buf, buf_len, "Scan-Channels = %d\n", myDrv->scan_channels);
1649            if (ret < (int)buf_len) {
1650                return( ret );
1651            }
1652        }
1653    }
1654    else if( os_strcasecmp(cmd, "rssi-approx") == 0 ) {
1655        struct wpa_scan_result *cur_res;
1656        struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(myDrv->hWpaSupplicant);
1657        int rssi, len;
1658
1659        wpa_printf(MSG_DEBUG,"rssi-approx command");
1660
1661        if( !wpa_s )
1662            return( ret );
1663        cur_res = scan_get_by_bssid( myDrv, wpa_s->bssid );
1664        if( cur_res ) {
1665            len = (int)(cur_res->ssid_len);
1666            rssi = cur_res->level;
1667            if( (len > 0) && (len <= MAX_SSID_LEN) && (len < (int)buf_len)) {
1668                os_memcpy( (void *)buf, (void *)(cur_res->ssid), len );
1669                ret = len;
1670                ret += snprintf(&buf[ret], buf_len-len, " rssi %d\n", rssi);
1671                if (ret < (int)buf_len) {
1672                    return( ret );
1673                }
1674            }
1675        }
1676    }
1677    else if( os_strcasecmp(cmd, "rssi") == 0 ) {
1678#if 1
1679        u8 ssid[MAX_SSID_LEN];
1680        struct wpa_scan_result *cur_res;
1681        struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(myDrv->hWpaSupplicant);
1682        int rssi, len;
1683
1684        wpa_printf(MSG_DEBUG,"rssi command");
1685
1686        ret = TI_GetRSSI( myDrv->hDriver, &rssi );
1687        if( ret == OK ) {
1688            len = wpa_driver_tista_get_ssid( priv, (u8 *)ssid );
1689            if( (len > 0) && (len <= MAX_SSID_LEN) && (len < (int)buf_len)) {
1690                os_memcpy( (void *)buf, (void *)ssid, len );
1691                ret = len;
1692                ret += snprintf(&buf[ret], buf_len-len, " rssi %d\n", rssi);
1693                if( !wpa_s )
1694                    return( ret );
1695                cur_res = scan_get_by_bssid( myDrv, wpa_s->bssid );
1696                if( cur_res )
1697                    cur_res->level = rssi;
1698                return( ret );
1699            }
1700        }
1701#else
1702        OS_802_11_BSSID_EX bssidInfo;
1703
1704        wpa_printf(MSG_DEBUG,"rssi command");
1705
1706        ret = TI_GetSelectedBSSIDInfo( myDrv->hDriver, (OS_802_11_BSSID_EX *)&bssidInfo );
1707        if( ret == OK ) {
1708            if( bssidInfo.Ssid.SsidLength != 0 && bssidInfo.Ssid.SsidLength < buf_len) {
1709                os_memcpy( (void *)buf, (void *)(bssidInfo.Ssid.Ssid), bssidInfo.Ssid.SsidLength );
1710                ret = bssidInfo.Ssid.SsidLength;
1711                ret += snprintf(&buf[ret], buf_len-ret, " rssi %d\n", bssidInfo.Rssi);
1712                if (ret < (int)buf_len) {
1713                    return( ret );
1714                }
1715            }
1716            ret = -1;
1717        }
1718#endif
1719    }
1720    else if( os_strncasecmp(cmd, "powermode", 9) == 0 ) {
1721        u32 rtsThreshold = myDrv->rts_threshold;
1722        u32 mode;
1723        char *cp = cmd + 9;
1724        char *endp;
1725
1726        if (*cp != '\0') {
1727            mode = (u32)strtol(cp, &endp, 0);
1728            if (endp != cp) {
1729                wpa_printf(MSG_DEBUG,"Power Mode command = %u", mode);
1730                if( mode <= OS_POWER_MODE_LONG_DOZE )
1731                    ret = TI_ConfigPowerManagement( myDrv->hDriver, mode );
1732                if( mode == OS_POWER_MODE_ACTIVE )
1733                    rtsThreshold = 0;
1734                if( TI_SetRTSThreshold( myDrv->hDriver, rtsThreshold ) != OK )
1735                    wpa_printf(MSG_DEBUG,"Set RTS threshold = %u failed", rtsThreshold);
1736            }
1737        }
1738    }
1739    else if( os_strncasecmp(cmd, "getpower", 8) == 0 ) {
1740        u32 mode;
1741
1742        ret = TI_GetPowerMode( myDrv->hDriver, (OS_802_11_POWER_PROFILE *)&mode);
1743        if( ret == OK ) {
1744            ret = snprintf(buf, buf_len, "powermode = %u\n", mode);
1745            if (ret < (int)buf_len) {
1746                return( ret );
1747            }
1748        }
1749    }
1750    else if( os_strncasecmp(cmd, "get-rts-threshold", 17) == 0 ) {
1751        tiUINT32 rtsThreshold = 0;
1752
1753        ret = TI_GetRTSThreshold( myDrv->hDriver, &rtsThreshold );
1754        wpa_printf(MSG_DEBUG,"Get RTS Threshold command = %d", rtsThreshold);
1755        if( ret == OK ) {
1756            ret = snprintf(buf, buf_len, "rts-threshold = %u\n", rtsThreshold);
1757            if (ret < (int)buf_len) {
1758                return( ret );
1759            }
1760        }
1761    }
1762    else if( os_strncasecmp(cmd, "set-rts-threshold", 17) == 0 ) {
1763        tiUINT32 rtsThreshold = 0;
1764        char *cp = cmd + 17;
1765        char *endp;
1766
1767        if (*cp != '\0') {
1768            rtsThreshold = (tiUINT32)strtol(cp, &endp, 0);
1769            if (endp != cp) {
1770                wpa_printf(MSG_DEBUG,"RTS Threshold command = %d", rtsThreshold);
1771                if( rtsThreshold <= HAL_CTRL_RTS_THRESHOLD_MAX ) {
1772                    ret = TI_SetRTSThreshold( myDrv->hDriver, rtsThreshold );
1773                    if( ret == OK ) {
1774                        myDrv->rts_threshold = rtsThreshold;
1775                    }
1776                }
1777            }
1778        }
1779    }
1780    else if( os_strcasecmp(cmd, "btcoexscan-start") == 0 ) {
1781        wpa_printf(MSG_DEBUG,"BT Coex Scan Start command");
1782        myDrv->btcoex_scan = TRUE;
1783        ret = 0;
1784    }
1785    else if( os_strcasecmp(cmd, "btcoexscan-stop") == 0 ) {
1786        wpa_printf(MSG_DEBUG,"BT Coex Scan Stop command");
1787        myDrv->btcoex_scan = FALSE;
1788        ret = 0;
1789    }
1790#ifndef STA_DK_VER_5_0_0_94
1791    else if( os_strcasecmp(cmd, "rxfilter-start") == 0 ) {
1792        wpa_printf(MSG_DEBUG,"Rx Data Filter Start command");
1793        ret = TI_EnableDisableRxDataFilters( myDrv->hDriver, TRUE );
1794    }
1795    else if( os_strcasecmp(cmd, "rxfilter-stop") == 0 ) {
1796        wpa_printf(MSG_DEBUG,"Rx Data Filter Stop command");
1797        ret = TI_EnableDisableRxDataFilters( myDrv->hDriver, FALSE );
1798    }
1799    else if( os_strcasecmp(cmd, "rxfilter-statistics") == 0 ) {
1800        TIWLAN_DATA_FILTER_STATISTICS stats;
1801        int len, i;
1802
1803        wpa_printf(MSG_DEBUG,"Rx Data Filter Statistics command");
1804        ret = TI_GetRxDataFiltersStatistics( myDrv->hDriver, &stats );
1805        if( ret == OK ) {
1806            ret = snprintf(buf, buf_len, "RxFilterStat: %u",
1807                           stats.UnmatchedPacketsCount);
1808            for(i=0;( i < MAX_NUM_DATA_FILTERS );i++) {
1809                ret += snprintf(&buf[ret], buf_len-ret, " %u",
1810                           stats.MatchedPacketsCount[i]);
1811            }
1812            ret += snprintf(&buf[ret], buf_len-ret, "\n");
1813            if (ret < (int)buf_len) {
1814                return( ret );
1815            }
1816        }
1817    }
1818    else if( os_strncasecmp(cmd, "rxfilter-add", 12) == 0 ) {
1819        TIWLAN_DATA_FILTER_REQUEST dfreq;
1820        char *cp = cmd + 12;
1821        char *endp;
1822        int type;
1823
1824        if (*cp != '\0') {
1825            type = (int)strtol(cp, &endp, 0);
1826            if (endp != cp) {
1827                wpa_printf(MSG_DEBUG,"Rx Data Filter Add [%d] command", type);
1828                ret = prepare_filter_struct( priv, type, &dfreq );
1829                if( ret == 0 ) {
1830                    ret = TI_AddRxDataFilter( myDrv->hDriver, &dfreq );
1831                }
1832            }
1833        }
1834    }
1835    else if( os_strncasecmp(cmd, "rxfilter-remove",15) == 0 ) {
1836        wpa_printf(MSG_DEBUG,"Rx Data Filter Remove command");
1837        TIWLAN_DATA_FILTER_REQUEST dfreq;
1838        char *cp = cmd + 15;
1839        char *endp;
1840        int type;
1841
1842        if (*cp != '\0') {
1843            type = (int)strtol(cp, &endp, 0);
1844            if (endp != cp) {
1845                wpa_printf(MSG_DEBUG,"Rx Data Filter Remove [%d] command", type);
1846                ret = prepare_filter_struct( priv, type, &dfreq );
1847                if( ret == 0 ) {
1848                    ret = TI_RemoveRxDataFilter( myDrv->hDriver, &dfreq );
1849                }
1850            }
1851        }
1852    }
1853    else if( os_strcasecmp(cmd, "snr") == 0 ) {
1854        u32 snr;
1855
1856        ret = TI_GetSNR( myDrv->hDriver, &snr );
1857        if( ret == OK ) {
1858            ret = snprintf(buf, buf_len, "snr = %u\n", snr);
1859            if (ret < (int)buf_len) {
1860                return( ret );
1861            }
1862        }
1863    }
1864    else if( os_strncasecmp(cmd, "btcoexmode", 10) == 0 ) {
1865        u32 mode;
1866        char *cp = cmd + 10;
1867        char *endp;
1868
1869        if (*cp != '\0') {
1870            mode = (u32)strtol(cp, &endp, 0);
1871            if (endp != cp) {
1872                wpa_printf(MSG_DEBUG,"BtCoex Mode command = %u", mode);
1873                ret = TI_SetBtCoeEnable( myDrv->hDriver, mode );
1874                if( ret == OK ) {
1875                    myDrv->btcoex_mode = mode;
1876                }
1877            }
1878        }
1879    }
1880    else if( os_strcasecmp(cmd, "btcoexstat") == 0 ) {
1881        u32 status = myDrv->btcoex_mode;
1882
1883        wpa_printf(MSG_DEBUG,"BtCoex Status");
1884        ret = TI_SetBtCoeGetStatus( myDrv->hDriver, (tiUINT32 *)&status );
1885        if( ret == OK ) {
1886            ret = snprintf(buf, buf_len, "btcoexstatus = 0x%x\n", status);
1887            if (ret < (int)buf_len) {
1888                return( ret );
1889            }
1890        }
1891    }
1892#endif
1893    else {
1894        wpa_printf(MSG_DEBUG,"Unsupported command");
1895    }
1896    return( TI2WPA_STATUS(ret) );
1897}
1898
1899/* Fill driver_ops structure to provide wpa_supplicant core with wrapper routines */
1900struct wpa_driver_ops wpa_driver_custom_ops = {
1901    .name           = TIWLAN_DRV_NAME,
1902    .desc           = "TI Station Driver",
1903    .init           = wpa_driver_tista_init,
1904    .deinit         = wpa_driver_tista_unload,
1905    .get_bssid      = wpa_driver_tista_get_bssid,
1906    .get_ssid       = wpa_driver_tista_get_ssid,
1907    .set_wpa        = wpa_driver_tista_set_wpa,
1908    .set_key        = wpa_driver_tista_set_key,
1909    .set_param      = NULL,
1910    .set_countermeasures    = wpa_driver_tista_set_countermeasures,
1911    .set_drop_unencrypted   = wpa_driver_tista_set_drop_unencrypted,
1912    .scan                   = wpa_driver_tista_scan,
1913    .get_scan_results       = wpa_driver_tista_get_scan_results,
1914    .deauthenticate = wpa_driver_tista_deauthenticate,
1915    .disassociate   = wpa_driver_tista_disassociate,
1916    .associate      = wpa_driver_tista_associate,
1917    .set_auth_alg   = wpa_driver_tista_set_auth_alg,
1918    .get_mac_addr   = wpa_driver_tista_get_mac_addr,
1919    .send_eapol     = ti_send_eapol,
1920    .add_pmkid      = NULL,
1921    .remove_pmkid   = NULL,
1922    .flush_pmkid    = NULL,
1923    .get_capa       = NULL,
1924    .poll           = NULL,
1925    .get_ifname     = NULL, /* Not nesessary */
1926    .set_operstate  = NULL,
1927#ifdef CONFIG_CLIENT_MLME
1928    .get_hw_modes   = NULL,
1929    .set_channel    = NULL,
1930    .set_ssid       = wpa_driver_tista_set_ssid,
1931    .set_bssid      = NULL,
1932    .send_mlme      = NULL,
1933    .mlme_add_sta   = NULL,
1934    .mlme_remove_sta    = NULL,
1935    .mlme_setprotection = NULL,
1936#endif /* CONFIG_CLIENT_MLME */
1937    .driver_cmd     = wpa_driver_tista_driver_cmd
1938};
1939