• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/staging/wlags49_h2/
1/*******************************************************************************
2 * Agere Systems Inc.
3 * Wireless device driver for Linux (wlags49).
4 *
5 * Copyright (c) 1998-2003 Agere Systems Inc.
6 * All rights reserved.
7 *   http://www.agere.com
8 *
9 * Initially developed by TriplePoint, Inc.
10 *   http://www.triplepoint.com
11 *
12 *------------------------------------------------------------------------------
13 *
14 *   This file defines handling routines for the private IOCTLs
15 *
16 *------------------------------------------------------------------------------
17 *
18 * SOFTWARE LICENSE
19 *
20 * This software is provided subject to the following terms and conditions,
21 * which you should read carefully before using the software.  Using this
22 * software indicates your acceptance of these terms and conditions.  If you do
23 * not agree with these terms and conditions, do not use the software.
24 *
25 * Copyright � 2003 Agere Systems Inc.
26 * All rights reserved.
27 *
28 * Redistribution and use in source or binary forms, with or without
29 * modifications, are permitted provided that the following conditions are met:
30 *
31 * . Redistributions of source code must retain the above copyright notice, this
32 *    list of conditions and the following Disclaimer as comments in the code as
33 *    well as in the documentation and/or other materials provided with the
34 *    distribution.
35 *
36 * . Redistributions in binary form must reproduce the above copyright notice,
37 *    this list of conditions and the following Disclaimer in the documentation
38 *    and/or other materials provided with the distribution.
39 *
40 * . Neither the name of Agere Systems Inc. nor the names of the contributors
41 *    may be used to endorse or promote products derived from this software
42 *    without specific prior written permission.
43 *
44 * Disclaimer
45 *
46 * THIS SOFTWARE IS PROVIDED �AS IS� AND ANY EXPRESS OR IMPLIED WARRANTIES,
47 * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF
48 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  ANY
49 * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN
50 * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY
51 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
52 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
53 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
54 * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
56 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
57 * DAMAGE.
58 *
59 ******************************************************************************/
60
61/*******************************************************************************
62 * include files
63 ******************************************************************************/
64#include <wl_version.h>
65
66#include <linux/if_arp.h>
67#include <linux/ioport.h>
68#include <linux/slab.h>
69#include <linux/delay.h>
70#include <asm/uaccess.h>
71
72#include <debug.h>
73#include <hcf.h>
74#include <hcfdef.h>
75
76#include <wl_if.h>
77#include <wl_internal.h>
78#include <wl_enc.h>
79#include <wl_main.h>
80#include <wl_priv.h>
81#include <wl_util.h>
82#include <wl_netdev.h>
83
84int wvlan_uil_connect( struct uilreq *urq, struct wl_private *lp );
85int wvlan_uil_disconnect( struct uilreq *urq, struct wl_private *lp );
86int wvlan_uil_action( struct uilreq *urq, struct wl_private *lp );
87int wvlan_uil_block( struct uilreq *urq, struct wl_private *lp );
88int wvlan_uil_unblock( struct uilreq *urq, struct wl_private *lp );
89int wvlan_uil_send_diag_msg( struct uilreq *urq, struct wl_private *lp );
90int wvlan_uil_put_info( struct uilreq *urq, struct wl_private *lp );
91int wvlan_uil_get_info( struct uilreq *urq, struct wl_private *lp );
92
93int cfg_driver_info( struct uilreq *urq, struct wl_private *lp );
94int cfg_driver_identity( struct uilreq *urq, struct wl_private *lp );
95
96
97/*******************************************************************************
98 * global variables
99 ******************************************************************************/
100#if DBG
101extern dbg_info_t *DbgInfo;
102#endif  // DBG
103
104
105
106
107/* If USE_UIL is not defined, then none of the UIL Interface code below will
108   be included in the build */
109#ifdef USE_UIL
110
111/*******************************************************************************
112 *	wvlan_uil()
113 *******************************************************************************
114 *
115 *  DESCRIPTION:
116 *
117 *      The handler function for the UIL interface.
118 *
119 *  PARAMETERS:
120 *
121 *      urq - a pointer to the UIL request buffer
122 *      lp  - a pointer to the device's private adapter structure
123 *
124 *  RETURNS:
125 *
126 *      0 on success
127 *      errno value otherwise
128 *
129 ******************************************************************************/
130int wvlan_uil( struct uilreq *urq, struct wl_private *lp )
131{
132	int ioctl_ret = 0;
133	/*------------------------------------------------------------------------*/
134
135	DBG_FUNC( "wvlan_uil" );
136	DBG_ENTER( DbgInfo );
137
138	switch( urq->command ) {
139	  case UIL_FUN_CONNECT:
140		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_CONNECT\n");
141		ioctl_ret = wvlan_uil_connect( urq, lp );
142		break;
143	  case UIL_FUN_DISCONNECT:
144		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_DISCONNECT\n");
145		ioctl_ret = wvlan_uil_disconnect( urq, lp );
146		break;
147	  case UIL_FUN_ACTION:
148		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_ACTION\n" );
149		ioctl_ret = wvlan_uil_action( urq, lp );
150		break;
151	  case UIL_FUN_SEND_DIAG_MSG:
152		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_SEND_DIAG_MSG\n");
153		ioctl_ret = wvlan_uil_send_diag_msg( urq, lp );
154		break;
155	  case UIL_FUN_GET_INFO:
156		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_GET_INFO\n");
157		ioctl_ret = wvlan_uil_get_info( urq, lp );
158		break;
159	  case UIL_FUN_PUT_INFO:
160		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_PUT_INFO\n");
161		ioctl_ret = wvlan_uil_put_info( urq, lp );
162		break;
163	default:
164		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- UNSUPPORTED UIL CODE: 0x%X", urq->command );
165		ioctl_ret = -EOPNOTSUPP;
166		break;
167	}
168	DBG_LEAVE( DbgInfo );
169	return ioctl_ret;
170} // wvlan_uil
171/*============================================================================*/
172
173
174
175
176/*******************************************************************************
177 *	wvlan_uil_connect()
178 *******************************************************************************
179 *
180 *  DESCRIPTION:
181 *
182 *      Connect to the UIL in order to make a request.
183 *
184 *  PARAMETERS:
185 *
186 *      urq - a pointer to the UIL request buffer
187 *      lp  - a pointer to the device's private adapter structure
188 *
189 *  RETURNS:
190 *
191 *      UIL_SUCCESS
192 *      UIL_ERR_xxx value otherwise
193 *
194 ******************************************************************************/
195int wvlan_uil_connect( struct uilreq *urq, struct wl_private *lp )
196{
197	int result = 0;
198	/*------------------------------------------------------------------------*/
199
200
201	DBG_FUNC( "wvlan_uil_connect" );
202	DBG_ENTER( DbgInfo );
203
204
205	if( !( lp->flags & WVLAN2_UIL_CONNECTED )) {
206		lp->flags |= WVLAN2_UIL_CONNECTED;
207		urq->hcfCtx = &( lp->hcfCtx );
208		urq->result = UIL_SUCCESS;
209	} else {
210		DBG_WARNING( DbgInfo, "UIL_ERR_IN_USE\n" );
211		urq->result = UIL_ERR_IN_USE;
212	}
213
214	DBG_LEAVE( DbgInfo );
215	return result;
216} // wvlan_uil_connect
217/*============================================================================*/
218
219
220
221
222/*******************************************************************************
223 *	wvlan_uil_disconnect()
224 *******************************************************************************
225 *
226 *  DESCRIPTION:
227 *
228 *      Disonnect from the UIL after a request has been completed.
229 *
230 *  PARAMETERS:
231 *
232 *      urq - a pointer to the UIL request buffer
233 *      lp  - a pointer to the device's private adapter structure
234 *
235 *  RETURNS:
236 *
237 *      UIL_SUCCESS
238 *      UIL_ERR_xxx value otherwise
239 *
240 ******************************************************************************/
241int wvlan_uil_disconnect( struct uilreq *urq, struct wl_private *lp )
242{
243	int result = 0;
244	/*------------------------------------------------------------------------*/
245
246
247	DBG_FUNC( "wvlan_uil_disconnect" );
248	DBG_ENTER( DbgInfo );
249
250
251	if( urq->hcfCtx == &( lp->hcfCtx )) {
252		if (lp->flags & WVLAN2_UIL_CONNECTED) {
253			lp->flags &= ~WVLAN2_UIL_CONNECTED;
254			/*
255			if (lp->flags & WVLAN2_UIL_BUSY) {
256				lp->flags &= ~WVLAN2_UIL_BUSY;
257				netif_start_queue(lp->dev);
258			}
259			*/
260		}
261
262		urq->hcfCtx = NULL;
263		urq->result = UIL_SUCCESS;
264	} else {
265		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
266		urq->result = UIL_ERR_WRONG_IFB;
267	}
268
269	DBG_LEAVE( DbgInfo );
270	return result;
271} // wvlan_uil_disconnect
272/*============================================================================*/
273
274
275
276
277/*******************************************************************************
278 *	wvlan_uil_action()
279 *******************************************************************************
280 *
281 *  DESCRIPTION:
282 *
283 *      Handler for the UIL_ACT_xxx subcodes associated with UIL_FUN_ACTION
284 *
285 *  PARAMETERS:
286 *
287 *      urq - a pointer to the UIL request buffer
288 *      lp  - a pointer to the device's private adapter structure
289 *
290 *  RETURNS:
291 *
292 *      UIL_SUCCESS
293 *      UIL_ERR_xxx value otherwise
294 *
295 ******************************************************************************/
296int wvlan_uil_action( struct uilreq *urq, struct wl_private *lp )
297{
298	int     result = 0;
299	ltv_t   *ltv;
300	/*------------------------------------------------------------------------*/
301
302
303	DBG_FUNC( "wvlan_uil_action" );
304	DBG_ENTER( DbgInfo );
305
306
307	if( urq->hcfCtx == &( lp->hcfCtx )) {
308		/* Make sure there's an LTV in the request buffer */
309		ltv = (ltv_t *)urq->data;
310		if( ltv != NULL ) {
311			/* Switch on the Type field of the LTV contained in the request
312			   buffer */
313			switch( ltv->typ ) {
314			case UIL_ACT_BLOCK:
315				DBG_TRACE( DbgInfo, "UIL_ACT_BLOCK\n" );
316				result = wvlan_uil_block( urq, lp );
317				break;
318			case UIL_ACT_UNBLOCK:
319				DBG_TRACE( DbgInfo, "UIL_ACT_UNBLOCK\n" );
320				result = wvlan_uil_unblock( urq, lp );
321				break;
322			case UIL_ACT_SCAN:
323				DBG_TRACE( DbgInfo, "UIL_ACT_SCAN\n" );
324				urq->result = hcf_action( &( lp->hcfCtx ), MDD_ACT_SCAN );
325				break;
326			case UIL_ACT_APPLY:
327				DBG_TRACE( DbgInfo, "UIL_ACT_APPLY\n" );
328				urq->result = wl_apply( lp );
329				break;
330			case UIL_ACT_RESET:
331				DBG_TRACE( DbgInfo, "UIL_ACT_RESET\n" );
332				urq->result = wl_go( lp );
333				break;
334			default:
335				DBG_WARNING( DbgInfo, "Unknown action code: 0x%x\n", ltv->typ );
336				break;
337			}
338		} else {
339			DBG_ERROR( DbgInfo, "Bad LTV for this action\n" );
340			urq->result = UIL_ERR_LEN;
341		}
342	} else {
343		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
344		urq->result = UIL_ERR_WRONG_IFB;
345	}
346
347	DBG_LEAVE( DbgInfo );
348	return result;
349} // wvlan_uil_action
350/*============================================================================*/
351
352
353
354
355/*******************************************************************************
356 *	wvlan_uil_block()
357 *******************************************************************************
358 *
359 *  DESCRIPTION:
360 *
361 *      Sets a block in the driver to prevent access to the card by other
362 *  processes.
363 *
364 *  PARAMETERS:
365 *
366 *      urq - a pointer to the UIL request buffer
367 *      lp  - a pointer to the device's private adapter structure
368 *
369 *  RETURNS:
370 *
371 *      UIL_SUCCESS
372 *      UIL_ERR_xxx value otherwise
373 *
374 ******************************************************************************/
375
376int wvlan_uil_block( struct uilreq *urq, struct wl_private *lp )
377{
378	int result = 0;
379	/*------------------------------------------------------------------------*/
380
381
382	DBG_FUNC( "wvlan_uil_block" );
383	DBG_ENTER( DbgInfo );
384
385	if( urq->hcfCtx == &( lp->hcfCtx )) {
386		if( capable( CAP_NET_ADMIN )) {
387			lp->flags |= WVLAN2_UIL_BUSY;
388			netif_stop_queue(lp->dev);
389			WL_WDS_NETIF_STOP_QUEUE( lp );
390			urq->result = UIL_SUCCESS;
391		} else {
392			DBG_ERROR( DbgInfo, "EPERM\n" );
393			urq->result = UIL_FAILURE;
394			result = -EPERM;
395		}
396	} else {
397		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
398		urq->result = UIL_ERR_WRONG_IFB;
399	}
400
401	DBG_LEAVE( DbgInfo );
402	return result;
403} // wvlan_uil_block
404/*============================================================================*/
405
406
407
408
409/*******************************************************************************
410 *	wvlan_uil_unblock()
411 *******************************************************************************
412 *
413 *  DESCRIPTION:
414 *
415 *      Unblocks the driver to restore access to the card by other processes.
416 *
417 *  PARAMETERS:
418 *
419 *      urq - a pointer to the UIL request buffer
420 *      lp  - a pointer to the device's private adapter structure
421 *
422 *  RETURNS:
423 *
424 *      UIL_SUCCESS
425 *      UIL_ERR_xxx value otherwise
426 *
427 ******************************************************************************/
428int wvlan_uil_unblock( struct uilreq *urq, struct wl_private *lp )
429{
430	int result = 0;
431	/*------------------------------------------------------------------------*/
432
433
434	DBG_FUNC( "wvlan_uil_unblock" );
435	DBG_ENTER( DbgInfo );
436
437	if( urq->hcfCtx == &( lp->hcfCtx )) {
438		if( capable( CAP_NET_ADMIN )) {
439			if (lp->flags & WVLAN2_UIL_BUSY) {
440				lp->flags &= ~WVLAN2_UIL_BUSY;
441				netif_wake_queue(lp->dev);
442				WL_WDS_NETIF_WAKE_QUEUE( lp );
443			}
444		} else {
445			DBG_ERROR( DbgInfo, "EPERM\n" );
446			urq->result = UIL_FAILURE;
447			result = -EPERM;
448		}
449	} else {
450		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
451		urq->result = UIL_ERR_WRONG_IFB;
452	}
453
454	DBG_LEAVE( DbgInfo );
455	return result;
456} // wvlan_uil_unblock
457/*============================================================================*/
458
459
460
461
462/*******************************************************************************
463 *	wvlan_uil_send_diag_msg()
464 *******************************************************************************
465 *
466 *  DESCRIPTION:
467 *
468 *      Sends a diagnostic message to the card.
469 *
470 *  PARAMETERS:
471 *
472 *      urq - a pointer to the UIL request buffer
473 *      lp  - a pointer to the device's private adapter structure
474 *
475 *  RETURNS:
476 *
477 *      UIL_SUCCESS
478 *      UIL_ERR_xxx value otherwise
479 *
480 ******************************************************************************/
481int wvlan_uil_send_diag_msg( struct uilreq *urq, struct wl_private *lp )
482{
483	int         result = 0;
484	DESC_STRCT  Descp[1];
485	/*------------------------------------------------------------------------*/
486
487
488	DBG_FUNC( "wvlan_uil_send_diag_msg" );
489	DBG_ENTER( DbgInfo );
490
491	if( urq->hcfCtx == &( lp->hcfCtx )) {
492		if( capable( CAP_NET_ADMIN )) {
493			if ((urq->data != NULL) && (urq->len != 0)) {
494				if (lp->hcfCtx.IFB_RscInd != 0) {
495					u_char *data;
496
497					// Verify the user buffer
498					result = verify_area(VERIFY_READ, urq->data, urq->len);
499					if (result != 0) {
500						DBG_ERROR( DbgInfo, "verify_area failed, result: %d\n", result );
501						urq->result = UIL_FAILURE;
502						DBG_LEAVE( DbgInfo );
503						return result;
504					}
505
506					data = kmalloc(urq->len, GFP_KERNEL);
507					if (data != NULL) {
508						memset( Descp, 0, sizeof( DESC_STRCT ));
509						memcpy( data, urq->data, urq->len );
510
511						Descp[0].buf_addr       = (wci_bufp)data;
512						Descp[0].BUF_CNT        = urq->len;
513						Descp[0].next_desc_addr = 0;    // terminate list
514
515						hcf_send_msg( &(lp->hcfCtx),  &Descp[0], HCF_PORT_0 );
516						kfree( data );
517					} else {
518						DBG_ERROR( DbgInfo, "ENOMEM\n" );
519						urq->result = UIL_FAILURE;
520						result = -ENOMEM;
521						DBG_LEAVE( DbgInfo );
522						return result;
523					}
524
525				} else {
526					urq->result = UIL_ERR_BUSY;
527				}
528
529			} else {
530				urq->result = UIL_FAILURE;
531			}
532		} else {
533			DBG_ERROR( DbgInfo, "EPERM\n" );
534			urq->result = UIL_FAILURE;
535			result = -EPERM;
536		}
537	} else {
538		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
539		urq->result = UIL_ERR_WRONG_IFB;
540	}
541
542	DBG_LEAVE( DbgInfo );
543	return result;
544} // wvlan_uil_send_diag_msg
545/*============================================================================*/
546
547
548/*******************************************************************************
549 *	wvlan_uil_put_info()
550 *******************************************************************************
551 *
552 *  DESCRIPTION:
553 *
554 *      Sends a specific RID directly to the driver to set configuration info.
555 *
556 *  PARAMETERS:
557 *
558 *      urq - a pointer to the UIL request buffer
559 *      lp  - a pointer to the device's private adapter structure
560 *
561 *  RETURNS:
562 *
563 *      UIL_SUCCESS
564 *      UIL_ERR_xxx value otherwise
565 *
566 ******************************************************************************/
567int wvlan_uil_put_info( struct uilreq *urq, struct wl_private *lp )
568{
569	int                     result = 0;
570	ltv_t                   *pLtv;
571	bool_t                  ltvAllocated = FALSE;
572	ENCSTRCT                sEncryption;
573
574#ifdef USE_WDS
575	hcf_16                  hcfPort  = HCF_PORT_0;
576#endif  /* USE_WDS */
577	/*------------------------------------------------------------------------*/
578	DBG_FUNC( "wvlan_uil_put_info" );
579	DBG_ENTER( DbgInfo );
580
581
582	if( urq->hcfCtx == &( lp->hcfCtx )) {
583		if( capable( CAP_NET_ADMIN )) {
584			if(( urq->data != NULL ) && ( urq->len != 0 )) {
585				/* Make sure that we have at least a command and length to send. */
586				if( urq->len < ( sizeof( hcf_16 ) * 2 )) {
587					urq->len = sizeof( lp->ltvRecord );
588					urq->result = UIL_ERR_LEN;
589					DBG_ERROR( DbgInfo, "No Length/Type in LTV!!!\n" );
590					DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" );
591					DBG_LEAVE( DbgInfo );
592					return result;
593				}
594
595				/* Verify the user buffer */
596				result = verify_area( VERIFY_READ, urq->data, urq->len );
597				if( result != 0 ) {
598					urq->result = UIL_FAILURE;
599					DBG_ERROR( DbgInfo, "verify_area(), VERIFY_READ FAILED\n" );
600					DBG_LEAVE( DbgInfo );
601					return result;
602				}
603
604				/* Get only the command and length information. */
605				copy_from_user( &( lp->ltvRecord ), urq->data, sizeof( hcf_16 ) * 2 );
606
607				/* Make sure the incoming LTV record length is within the bounds of the
608				   IOCTL length */
609				if((( lp->ltvRecord.len + 1 ) * sizeof( hcf_16 )) > urq->len ) {
610					urq->len = sizeof( lp->ltvRecord );
611					urq->result = UIL_ERR_LEN;
612					DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" );
613					DBG_LEAVE( DbgInfo );
614					return result;
615				}
616
617				/* If the requested length is greater than the size of our local
618				   LTV record, try to allocate it from the kernel stack.
619				   Otherwise, we just use our local LTV record. */
620				if( urq->len > sizeof( lp->ltvRecord )) {
621					pLtv = kmalloc(urq->len, GFP_KERNEL);
622					if (pLtv != NULL) {
623						ltvAllocated = TRUE;
624					} else {
625						DBG_ERROR( DbgInfo, "Alloc FAILED\n" );
626						urq->len = sizeof( lp->ltvRecord );
627						urq->result = UIL_ERR_LEN;
628						result = -ENOMEM;
629						DBG_LEAVE( DbgInfo );
630						return result;
631					}
632				} else {
633					pLtv = &( lp->ltvRecord );
634				}
635
636				/* Copy the data from the user's buffer into the local LTV
637				   record data area. */
638				copy_from_user( pLtv, urq->data, urq->len );
639
640
641				/* We need to snoop the commands to see if there is anything we
642				   need to store for the purposes of a reset or start/stop
643				   sequence. Perform endian translation as needed */
644				switch( pLtv->typ ) {
645				case CFG_CNF_PORT_TYPE:
646					lp->PortType    = pLtv->u.u16[0];
647					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
648					break;
649				case CFG_CNF_OWN_MAC_ADDR:
650					/* TODO: determine if we are going to store anything based on this */
651					break;
652				case CFG_CNF_OWN_CHANNEL:
653					lp->Channel     = pLtv->u.u16[0];
654					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
655					break;
656				/* CFG_CNF_OWN_SSID currently same as CNF_DESIRED_SSID. Do we
657				   need separate storage for this? */
658				//case CFG_CNF_OWN_SSID:
659				case CFG_CNF_OWN_ATIM_WINDOW:
660					lp->atimWindow  = pLtv->u.u16[0];
661					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
662					break;
663				case CFG_CNF_SYSTEM_SCALE:
664					lp->DistanceBetweenAPs  = pLtv->u.u16[0];
665					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
666
667				case CFG_CNF_MAX_DATA_LEN:
668					/* TODO: determine if we are going to store anything based
669					   on this */
670					break;
671				case CFG_CNF_PM_ENABLED:
672					lp->PMEnabled   = pLtv->u.u16[0];
673					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
674					break;
675				case CFG_CNF_MCAST_RX:
676					lp->MulticastReceive    = pLtv->u.u16[0];
677					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
678					break;
679				case CFG_CNF_MAX_SLEEP_DURATION:
680					lp->MaxSleepDuration    = pLtv->u.u16[0];
681					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
682					break;
683				case CFG_CNF_HOLDOVER_DURATION:
684					lp->holdoverDuration    = pLtv->u.u16[0];
685					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
686					break;
687				case CFG_CNF_OWN_NAME:
688					memset( lp->StationName, 0, sizeof( lp->StationName ));
689					memcpy( (void *)lp->StationName, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0]);
690					pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
691					break;
692				case CFG_CNF_LOAD_BALANCING:
693					lp->loadBalancing       = pLtv->u.u16[0];
694					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
695					break;
696				case CFG_CNF_MEDIUM_DISTRIBUTION:
697					lp->mediumDistribution  = pLtv->u.u16[0];
698					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
699					break;
700#ifdef WARP
701				case CFG_CNF_TX_POW_LVL:
702					lp->txPowLevel          = pLtv->u.u16[0];
703					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
704					break;
705				//case CFG_CNF_SHORT_RETRY_LIMIT:    // Short Retry Limit
706				//case 0xFC33:    // Long Retry Limit
707				case CFG_SUPPORTED_RATE_SET_CNTL:        // Supported Rate Set Control
708					lp->srsc[0]             = pLtv->u.u16[0];
709					lp->srsc[1]             = pLtv->u.u16[1];
710					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
711					pLtv->u.u16[1]          = CNV_INT_TO_LITTLE( pLtv->u.u16[1] );
712					break;
713				case CFG_BASIC_RATE_SET_CNTL:        // Basic Rate Set Control
714					lp->brsc[0]             = pLtv->u.u16[0];
715					lp->brsc[1]             = pLtv->u.u16[1];
716					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
717					pLtv->u.u16[1]          = CNV_INT_TO_LITTLE( pLtv->u.u16[1] );
718					break;
719				case CFG_CNF_CONNECTION_CNTL:
720					lp->connectionControl   = pLtv->u.u16[0];
721					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
722					break;
723				//case CFG_PROBE_DATA_RATE:
724#endif  // HERMES25
725
726		//;?should we restore this to allow smaller memory footprint
727
728				case CFG_CNF_OWN_DTIM_PERIOD:
729					lp->DTIMPeriod  = pLtv->u.u16[0];
730					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
731					break;
732#ifdef WARP
733				case CFG_CNF_OWN_BEACON_INTERVAL:        // Own Beacon Interval
734					lp->ownBeaconInterval   = pLtv->u.u16[0];
735					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
736					break;
737#endif // WARP
738				case CFG_COEXISTENSE_BEHAVIOUR:         // Coexistence behavior
739					lp->coexistence         = pLtv->u.u16[0];
740					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
741					break;
742#ifdef USE_WDS
743				case CFG_CNF_WDS_ADDR1:
744					memcpy( &lp->wds_port[0].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
745					hcfPort = HCF_PORT_1;
746					break;
747				case CFG_CNF_WDS_ADDR2:
748					memcpy( &lp->wds_port[1].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
749					hcfPort = HCF_PORT_2;
750					break;
751				case CFG_CNF_WDS_ADDR3:
752					memcpy( &lp->wds_port[2].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
753					hcfPort = HCF_PORT_3;
754					break;
755				case CFG_CNF_WDS_ADDR4:
756					memcpy( &lp->wds_port[3].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
757					hcfPort = HCF_PORT_4;
758					break;
759				case CFG_CNF_WDS_ADDR5:
760					memcpy( &lp->wds_port[4].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
761					hcfPort = HCF_PORT_5;
762					break;
763				case CFG_CNF_WDS_ADDR6:
764					memcpy( &lp->wds_port[5].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
765					hcfPort = HCF_PORT_6;
766					break;
767#endif  /* USE_WDS */
768
769				case CFG_CNF_MCAST_PM_BUF:
770					lp->multicastPMBuffering    = pLtv->u.u16[0];
771					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
772					break;
773				case CFG_CNF_REJECT_ANY:
774					lp->RejectAny   = pLtv->u.u16[0];
775					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
776					break;
777
778				case CFG_CNF_ENCRYPTION:
779					lp->EnableEncryption    = pLtv->u.u16[0];
780					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
781					break;
782				case CFG_CNF_AUTHENTICATION:
783					lp->authentication  = pLtv->u.u16[0];
784					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
785					break;
786		//;?should we restore this to allow smaller memory footprint
787
788				//case CFG_CNF_EXCL_UNENCRYPTED:
789					//lp->ExcludeUnencrypted  = pLtv->u.u16[0];
790					//pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
791					//break;
792				case CFG_CNF_MCAST_RATE:
793					/* TODO: determine if we are going to store anything based on this */
794					break;
795				case CFG_CNF_INTRA_BSS_RELAY:
796					lp->intraBSSRelay   = pLtv->u.u16[0];
797					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
798					break;
799
800				case CFG_CNF_MICRO_WAVE:
801					/* TODO: determine if we are going to store anything based on this */
802					break;
803				//case CFG_CNF_LOAD_BALANCING:
804					/* TODO: determine if we are going to store anything based on this */
805					//break;
806				//case CFG_CNF_MEDIUM_DISTRIBUTION:
807					/* TODO: determine if we are going to store anything based on this */
808					//break;
809				//case CFG_CNF_RX_ALL_GROUP_ADDRESS:
810					// TODO: determine if we are going to store anything based on this
811					//break;
812				//case CFG_CNF_COUNTRY_INFO:
813					/* TODO: determine if we are going to store anything based on this */
814					//break;
815				case CFG_CNF_OWN_SSID:
816				//case CNF_DESIRED_SSID:
817				case CFG_DESIRED_SSID:
818					memset( lp->NetworkName, 0, sizeof( lp->NetworkName ));
819					memcpy( (void *)lp->NetworkName, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0] );
820					pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
821
822					/* take care of the special network name "ANY" case */
823					if(( strlen( &pLtv->u.u8[2]        ) == 0 ) ||
824					   ( strcmp( &pLtv->u.u8[2], "ANY" ) == 0 ) ||
825					   ( strcmp( &pLtv->u.u8[2], "any" ) == 0 )) {
826						/* set the SSID_STRCT llen field (u16[0]) to zero, and the
827						effectually null the string u8[2] */
828						pLtv->u.u16[0] = 0;
829						pLtv->u.u8[2]  = 0;
830					}
831					break;
832				case CFG_GROUP_ADDR:
833					/* TODO: determine if we are going to store anything based on this */
834					break;
835				case CFG_CREATE_IBSS:
836					lp->CreateIBSS  = pLtv->u.u16[0];
837					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
838					break;
839				case CFG_RTS_THRH:
840					lp->RTSThreshold    = pLtv->u.u16[0];
841					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
842					break;
843				case CFG_TX_RATE_CNTL:
844					lp->TxRateControl[0]    = pLtv->u.u16[0];
845					lp->TxRateControl[1]    = pLtv->u.u16[1];
846					pLtv->u.u16[0]          = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
847					pLtv->u.u16[1]          = CNV_INT_TO_LITTLE( pLtv->u.u16[1] );
848					break;
849				case CFG_PROMISCUOUS_MODE:
850					/* TODO: determine if we are going to store anything based on this */
851					break;
852				//case CFG_WAKE_ON_LAN:
853					/* TODO: determine if we are going to store anything based on this */
854					//break;
855		//;?should we restore this to allow smaller memory footprint
856				case CFG_RTS_THRH0:
857					lp->RTSThreshold    = pLtv->u.u16[0];
858					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
859					break;
860				case CFG_TX_RATE_CNTL0:
861//;?no idea what this should be, get going so comment it out					lp->TxRateControl   = pLtv->u.u16[0];
862					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
863					break;
864#ifdef USE_WDS
865				case CFG_RTS_THRH1:
866					lp->wds_port[0].rtsThreshold    = pLtv->u.u16[0];
867					pLtv->u.u16[0]                  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
868					hcfPort                         = HCF_PORT_1;
869					break;
870				case CFG_RTS_THRH2:
871					lp->wds_port[1].rtsThreshold    = pLtv->u.u16[0];
872					pLtv->u.u16[0]                  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
873					hcfPort                         = HCF_PORT_2;
874					break;
875				case CFG_RTS_THRH3:
876					lp->wds_port[2].rtsThreshold    = pLtv->u.u16[0];
877					pLtv->u.u16[0]                  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
878					hcfPort                         = HCF_PORT_3;
879					break;
880				case CFG_RTS_THRH4:
881					lp->wds_port[3].rtsThreshold    = pLtv->u.u16[0];
882					pLtv->u.u16[0]                  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
883					hcfPort                         = HCF_PORT_4;
884					break;
885				case CFG_RTS_THRH5:
886					lp->wds_port[4].rtsThreshold    = pLtv->u.u16[0];
887					pLtv->u.u16[0]                  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
888					hcfPort                         = HCF_PORT_5;
889					break;
890				case CFG_RTS_THRH6:
891					lp->wds_port[5].rtsThreshold    = pLtv->u.u16[0];
892					pLtv->u.u16[0]                  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
893					hcfPort                         = HCF_PORT_6;
894					break;
895				case CFG_TX_RATE_CNTL1:
896					lp->wds_port[0].txRateCntl  = pLtv->u.u16[0];
897					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
898					hcfPort                     = HCF_PORT_1;
899					break;
900				case CFG_TX_RATE_CNTL2:
901					lp->wds_port[1].txRateCntl  = pLtv->u.u16[0];
902					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
903					hcfPort                     = HCF_PORT_2;
904					break;
905				case CFG_TX_RATE_CNTL3:
906					lp->wds_port[2].txRateCntl  = pLtv->u.u16[0];
907					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
908					hcfPort                     = HCF_PORT_3;
909					break;
910				case CFG_TX_RATE_CNTL4:
911					lp->wds_port[3].txRateCntl  = pLtv->u.u16[0];
912					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
913					hcfPort                     = HCF_PORT_4;
914					break;
915				case CFG_TX_RATE_CNTL5:
916					lp->wds_port[4].txRateCntl  = pLtv->u.u16[0];
917					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
918					hcfPort                     = HCF_PORT_5;
919					break;
920				case CFG_TX_RATE_CNTL6:
921					lp->wds_port[5].txRateCntl  = pLtv->u.u16[0];
922					pLtv->u.u16[0]              = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
923					hcfPort                     = HCF_PORT_6;
924					break;
925#endif  /* USE_WDS */
926
927				case CFG_DEFAULT_KEYS:
928					{
929						CFG_DEFAULT_KEYS_STRCT *pKeys = (CFG_DEFAULT_KEYS_STRCT *)pLtv;
930
931						pKeys->key[0].len = CNV_INT_TO_LITTLE( pKeys->key[0].len );
932						pKeys->key[1].len = CNV_INT_TO_LITTLE( pKeys->key[1].len );
933						pKeys->key[2].len = CNV_INT_TO_LITTLE( pKeys->key[2].len );
934						pKeys->key[3].len = CNV_INT_TO_LITTLE( pKeys->key[3].len );
935
936						memcpy( (void *)&(lp->DefaultKeys), (void *)pKeys,
937								sizeof( CFG_DEFAULT_KEYS_STRCT ));
938					}
939					break;
940				case CFG_TX_KEY_ID:
941					lp->TransmitKeyID   = pLtv->u.u16[0];
942					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
943					break;
944				case CFG_SCAN_SSID:
945					/* TODO: determine if we are going to store anything based on this */
946					break;
947				case CFG_TICK_TIME:
948					/* TODO: determine if we are going to store anything based on this */
949					break;
950				/* these RIDS are Info RIDs, and should they be allowed for puts??? */
951				case CFG_MAX_LOAD_TIME:
952				case CFG_DL_BUF:
953				//case CFG_HSI_SUP_RANGE:
954				case CFG_NIC_SERIAL_NUMBER:
955				case CFG_NIC_IDENTITY:
956				case CFG_NIC_MFI_SUP_RANGE:
957				case CFG_NIC_CFI_SUP_RANGE:
958				case CFG_NIC_TEMP_TYPE:
959				case CFG_NIC_PROFILE:
960				case CFG_FW_IDENTITY:
961				case CFG_FW_SUP_RANGE:
962				case CFG_MFI_ACT_RANGES_STA:
963				case CFG_CFI_ACT_RANGES_STA:
964				case CFG_PORT_STAT:
965				case CFG_CUR_SSID:
966				case CFG_CUR_BSSID:
967				case CFG_COMMS_QUALITY:
968				case CFG_CUR_TX_RATE:
969				case CFG_CUR_BEACON_INTERVAL:
970				case CFG_CUR_SCALE_THRH:
971				case CFG_PROTOCOL_RSP_TIME:
972				case CFG_CUR_SHORT_RETRY_LIMIT:
973				case CFG_CUR_LONG_RETRY_LIMIT:
974				case CFG_MAX_TX_LIFETIME:
975				case CFG_MAX_RX_LIFETIME:
976				case CFG_CF_POLLABLE:
977				case CFG_AUTHENTICATION_ALGORITHMS:
978				case CFG_PRIVACY_OPT_IMPLEMENTED:
979				//case CFG_CURRENT_REMOTE_RATES:
980				//case CFG_CURRENT_USED_RATES:
981				//case CFG_CURRENT_SYSTEM_SCALE:
982				//case CFG_CURRENT_TX_RATE1:
983				//case CFG_CURRENT_TX_RATE2:
984				//case CFG_CURRENT_TX_RATE3:
985				//case CFG_CURRENT_TX_RATE4:
986				//case CFG_CURRENT_TX_RATE5:
987				//case CFG_CURRENT_TX_RATE6:
988				case CFG_NIC_MAC_ADDR:
989				case CFG_PCF_INFO:
990				//case CFG_CURRENT_COUNTRY_INFO:
991				case CFG_PHY_TYPE:
992				case CFG_CUR_CHANNEL:
993				//case CFG_CURRENT_POWER_STATE:
994				//case CFG_CCAMODE:
995				case CFG_SUPPORTED_DATA_RATES:
996					break;
997				case CFG_AP_MODE:
998//;?				lp->DownloadFirmware = ( pLtv->u.u16[0] ) + 1;
999					DBG_ERROR( DbgInfo, "set CFG_AP_MODE no longer supported\n" );
1000					break;
1001				case CFG_ENCRYPT_STRING:
1002					/* TODO: ENDIAN TRANSLATION HERE??? */
1003					memset( lp->szEncryption, 0, sizeof( lp->szEncryption ));
1004					memcpy( (void *)lp->szEncryption,  (void *)&pLtv->u.u8[0],
1005							( pLtv->len * sizeof( hcf_16 )) );
1006					wl_wep_decode( CRYPT_CODE, &sEncryption,
1007								    lp->szEncryption );
1008
1009					/* the Linux driver likes to use 1-4 for the key IDs, and then
1010					convert to 0-3 when sending to the card.  The Windows code
1011					base used 0-3 in the API DLL, which was ported to Linux.  For
1012					the sake of the user experience, we decided to keep 0-3 as the
1013					numbers used in the DLL; and will perform the +1 conversion here.
1014					We could have converted  the entire Linux driver, but this is
1015					less obtrusive.  This may be a "todo" to convert the whole driver */
1016					lp->TransmitKeyID    = sEncryption.wTxKeyID + 1;
1017					lp->EnableEncryption = sEncryption.wEnabled;
1018
1019					memcpy( &lp->DefaultKeys, &sEncryption.EncStr,
1020							sizeof( CFG_DEFAULT_KEYS_STRCT ));
1021					break;
1022				/*case CFG_COUNTRY_STRING:
1023					memset( lp->countryString, 0, sizeof( lp->countryString ));
1024					memcpy( (void *)lp->countryString, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0]);
1025					break;
1026				*/
1027
1028				case CFG_DRIVER_ENABLE:
1029					lp->driverEnable    = pLtv->u.u16[0];
1030					pLtv->u.u16[0]      = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
1031					break;
1032				case CFG_WOLAS_ENABLE:
1033					lp->wolasEnable = pLtv->u.u16[0];
1034					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
1035					break;
1036				case CFG_SET_WPA_AUTH_KEY_MGMT_SUITE:
1037					lp->AuthKeyMgmtSuite = pLtv->u.u16[0];
1038					pLtv->u.u16[0]  = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
1039					break;
1040				case CFG_DISASSOCIATE_ADDR:
1041					pLtv->u.u16[ETH_ALEN / 2] = CNV_INT_TO_LITTLE( pLtv->u.u16[ETH_ALEN / 2] );
1042					break;
1043				case CFG_ADD_TKIP_DEFAULT_KEY:
1044				case CFG_REMOVE_TKIP_DEFAULT_KEY:
1045					/* Endian convert the Tx Key Information */
1046					pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
1047					break;
1048				case CFG_ADD_TKIP_MAPPED_KEY:
1049					break;
1050				case CFG_REMOVE_TKIP_MAPPED_KEY:
1051					break;
1052				/* some RIDs just can't be put */
1053				case CFG_MB_INFO:
1054				case CFG_IFB:
1055				default:
1056					break;
1057				}
1058
1059				/* This code will prevent Static Configuration Entities from
1060				   being sent to the card, as they require a call to
1061				   UIL_ACT_APPLY to take effect. Dynamic Entities will be sent
1062				   immediately */
1063				switch( pLtv->typ ) {
1064				case CFG_CNF_PORT_TYPE:
1065				case CFG_CNF_OWN_MAC_ADDR:
1066				case CFG_CNF_OWN_CHANNEL:
1067				case CFG_CNF_OWN_SSID:
1068				case CFG_CNF_OWN_ATIM_WINDOW:
1069				case CFG_CNF_SYSTEM_SCALE:
1070				case CFG_CNF_MAX_DATA_LEN:
1071				case CFG_CNF_PM_ENABLED:
1072				case CFG_CNF_MCAST_RX:
1073				case CFG_CNF_MAX_SLEEP_DURATION:
1074				case CFG_CNF_HOLDOVER_DURATION:
1075				case CFG_CNF_OWN_NAME:
1076				case CFG_CNF_LOAD_BALANCING:
1077				case CFG_CNF_MEDIUM_DISTRIBUTION:
1078#ifdef WARP
1079				case CFG_CNF_TX_POW_LVL:
1080				case CFG_CNF_CONNECTION_CNTL:
1081				//case CFG_PROBE_DATA_RATE:
1082#endif // HERMES25
1083		//;?should we restore this to allow smaller memory footprint
1084				case CFG_CNF_OWN_DTIM_PERIOD:
1085#ifdef WARP
1086				case CFG_CNF_OWN_BEACON_INTERVAL:                    // Own Beacon Interval
1087#endif // WARP
1088#ifdef USE_WDS
1089				case CFG_CNF_WDS_ADDR1:
1090				case CFG_CNF_WDS_ADDR2:
1091				case CFG_CNF_WDS_ADDR3:
1092				case CFG_CNF_WDS_ADDR4:
1093				case CFG_CNF_WDS_ADDR5:
1094				case CFG_CNF_WDS_ADDR6:
1095#endif
1096				case CFG_CNF_MCAST_PM_BUF:
1097				case CFG_CNF_REJECT_ANY:
1098
1099				case CFG_CNF_ENCRYPTION:
1100				case CFG_CNF_AUTHENTICATION:
1101		//;?should we restore this to allow smaller memory footprint
1102
1103				case CFG_CNF_EXCL_UNENCRYPTED:
1104				case CFG_CNF_MCAST_RATE:
1105				case CFG_CNF_INTRA_BSS_RELAY:
1106
1107				case CFG_CNF_MICRO_WAVE:
1108				//case CFG_CNF_LOAD_BALANCING:
1109				//case CFG_CNF_MEDIUM_DISTRIBUTION:
1110				//case CFG_CNF_RX_ALL_GROUP_ADDRESS:
1111				//case CFG_CNF_COUNTRY_INFO:
1112				//case CFG_COUNTRY_STRING:
1113				case CFG_AP_MODE:
1114				case CFG_ENCRYPT_STRING:
1115				//case CFG_DRIVER_ENABLE:
1116				case CFG_WOLAS_ENABLE:
1117				case CFG_MB_INFO:
1118				case CFG_IFB:
1119					break;
1120				/* Deal with this dynamic MSF RID, as it's required for WPA */
1121				case CFG_DRIVER_ENABLE:
1122					if( lp->driverEnable ) {
1123						//hcf_cntl_port( &( lp->hcfCtx ),
1124						//               HCF_PORT_ENABLE | HCF_PORT_0 );
1125						// //hcf_cntl( &( lp->hcfCtx ),
1126						// //         HCF_PORT_ENABLE | HCF_PORT_0 );
1127						//hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_ENABLE );
1128						// //hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_CONNECT );
1129
1130						hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_ENABLE | HCF_PORT_0 );
1131						hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_CONNECT );
1132					} else {
1133						//hcf_cntl_port( &( lp->hcfCtx ),
1134						//               HCF_PORT_DISABLE | HCF_PORT_0 );
1135						// //hcf_cntl( &( lp->hcfCtx ),
1136						// //         HCF_PORT_DISABLE | HCF_PORT_0 );
1137						//hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISABLE );
1138						// //hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISCONNECT );
1139
1140						hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISABLE | HCF_PORT_0 );
1141						hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISCONNECT );
1142					}
1143					break;
1144				default:
1145    					wl_act_int_off( lp );
1146					urq->result = hcf_put_info(&(lp->hcfCtx), (LTVP) pLtv);
1147    					wl_act_int_on( lp );
1148					break;
1149				}
1150
1151				if( ltvAllocated ) {
1152					kfree( pLtv );
1153				}
1154			} else {
1155				urq->result = UIL_FAILURE;
1156			}
1157		} else {
1158			DBG_ERROR( DbgInfo, "EPERM\n" );
1159			urq->result = UIL_FAILURE;
1160			result = -EPERM;
1161		}
1162	} else {
1163		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
1164		urq->result = UIL_ERR_WRONG_IFB;
1165	}
1166
1167	DBG_LEAVE( DbgInfo );
1168	return result;
1169} // wvlan_uil_put_info
1170/*============================================================================*/
1171
1172/*******************************************************************************
1173 *	wvlan_uil_get_info()
1174 *******************************************************************************
1175 *
1176 *  DESCRIPTION:
1177 *
1178 *      Sends a specific RID directly to the driver to retrieve configuration
1179 *      info.
1180 *
1181 *  PARAMETERS:
1182 *
1183 *      urq - a pointer to the UIL request buffer
1184 *      lp  - a pointer to the device's private adapter structure
1185 *
1186 *  RETURNS:
1187 *
1188 *      UIL_SUCCESS
1189 *      UIL_ERR_xxx value otherwise
1190 *
1191 ******************************************************************************/
1192int wvlan_uil_get_info( struct uilreq *urq, struct wl_private *lp )
1193{
1194	int result = 0;
1195	int i;
1196	/*------------------------------------------------------------------------*/
1197
1198	DBG_FUNC( "wvlan_uil_get_info" );
1199	DBG_ENTER( DbgInfo );
1200
1201	if( urq->hcfCtx == &( lp->hcfCtx )) {
1202		if(( urq->data != NULL ) && ( urq->len != 0 )) {
1203			ltv_t      *pLtv;
1204			bool_t      ltvAllocated = FALSE;
1205
1206			/* Make sure that we have at least a command and length */
1207			if( urq->len < ( sizeof( hcf_16 ) * 2 )) {
1208				urq->len = sizeof( lp->ltvRecord );
1209				DBG_ERROR( DbgInfo, "No Length/Type in LTV!!!\n" );
1210				DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" );
1211				urq->result = UIL_ERR_LEN;
1212				DBG_LEAVE( DbgInfo );
1213				return result;
1214			}
1215
1216			/* Verify the user's LTV record header. */
1217			result = verify_area( VERIFY_READ, urq->data, sizeof( hcf_16 ) * 2 );
1218			if( result != 0 ) {
1219				DBG_ERROR( DbgInfo, "verify_area(), VERIFY_READ FAILED\n" );
1220				urq->result = UIL_FAILURE;
1221				DBG_LEAVE( DbgInfo );
1222				return result;
1223			}
1224
1225			/* Get only the command and length information. */
1226			result = copy_from_user( &( lp->ltvRecord ), urq->data, sizeof( hcf_16 ) * 2 );
1227
1228			/* Make sure the incoming LTV record length is within the bounds of
1229			   the IOCTL length. */
1230			if((( lp->ltvRecord.len + 1 ) * sizeof( hcf_16 )) > urq->len ) {
1231				DBG_ERROR( DbgInfo, "Incoming LTV too big\n" );
1232				urq->len = sizeof( lp->ltvRecord );
1233				urq->result = UIL_ERR_LEN;
1234				DBG_LEAVE( DbgInfo );
1235				return result;
1236			}
1237
1238			/* Determine if hcf_get_info() is needed or not */
1239			switch ( lp->ltvRecord.typ ) {
1240			case CFG_NIC_IDENTITY:
1241				memcpy( &lp->ltvRecord.u.u8[0], &lp->NICIdentity, sizeof( lp->NICIdentity ));
1242				break;
1243			case CFG_PRI_IDENTITY:
1244				memcpy( &lp->ltvRecord.u.u8[0], &lp->PrimaryIdentity, sizeof( lp->PrimaryIdentity ));
1245				break;
1246			case CFG_AP_MODE:
1247				DBG_ERROR( DbgInfo, "set CFG_AP_MODE no longer supported, so is get useful ????\n" );
1248				lp->ltvRecord.u.u16[0] =
1249					CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP;
1250				break;
1251			//case CFG_DRV_INFO:
1252			case CFG_ENCRYPT_STRING:
1253			case CFG_COUNTRY_STRING:
1254			case CFG_DRIVER_ENABLE:
1255			case CFG_WOLAS_ENABLE:
1256				// TODO: determine if we're going to support these
1257				urq->result = UIL_FAILURE;
1258				break;
1259			case CFG_DRV_INFO:
1260				DBG_TRACE( DbgInfo, "Intercept CFG_DRV_INFO\n" );
1261				result = cfg_driver_info( urq, lp );
1262				break;
1263			case CFG_DRV_IDENTITY:
1264				DBG_TRACE( DbgInfo, "Intercept CFG_DRV_IDENTITY\n" );
1265				result = cfg_driver_identity( urq, lp );
1266				break;
1267			case CFG_IFB:
1268				/* IFB can be a security hole */
1269				if( !capable( CAP_NET_ADMIN )) {
1270					result = -EPERM;
1271					break;
1272				}
1273
1274				/* Else fall through to the default */
1275
1276			case CFG_FW_IDENTITY:   // For Hermes-1, this is cached
1277			default:
1278
1279				/* Verify the user buffer */
1280				result = verify_area( VERIFY_WRITE, urq->data, urq->len );
1281				if( result != 0 ) {
1282					DBG_ERROR( DbgInfo, "verify_area(), VERIFY_WRITE FAILED\n" );
1283					urq->result = UIL_FAILURE;
1284					break;
1285				}
1286
1287				/* If the requested length is greater than the size of our local
1288				   LTV record, try to allocate it from the kernel stack.
1289				   Otherwise, we just use our local LTV record. */
1290				if( urq->len > sizeof( lp->ltvRecord )) {
1291					pLtv = kmalloc(urq->len, GFP_KERNEL);
1292					if (pLtv != NULL) {
1293						ltvAllocated = TRUE;
1294
1295						/* Copy the command/length information into the new buffer. */
1296						memcpy( pLtv, &( lp->ltvRecord ), sizeof( hcf_16 ) * 2 );
1297					} else {
1298						urq->len = sizeof( lp->ltvRecord );
1299						urq->result = UIL_ERR_LEN;
1300						DBG_ERROR( DbgInfo, "kmalloc FAILED\n" );
1301						DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" );
1302						result = -ENOMEM;
1303						break;
1304					}
1305				} else {
1306					pLtv = &( lp->ltvRecord );
1307				}
1308
1309    				wl_act_int_off( lp );
1310				urq->result = hcf_get_info( &( lp->hcfCtx ), (LTVP) pLtv );
1311    				wl_act_int_on( lp );
1312
1313				// Copy the LTV into the user's buffer.
1314				//copy_to_user( urq->data, pLtv, urq->len );
1315
1316				//if( ltvAllocated )
1317				//{
1318				//    kfree( pLtv );
1319				//}
1320
1321				//urq->result = UIL_SUCCESS;
1322				break;
1323			}
1324
1325			/* Handle endian conversion of special fields */
1326			switch( lp->ltvRecord.typ ) {
1327			/* simple int gets just need the first hcf_16 byte flipped */
1328			case CFG_CNF_PORT_TYPE:
1329			case CFG_CNF_OWN_CHANNEL:
1330			case CFG_CNF_OWN_ATIM_WINDOW:
1331			case CFG_CNF_SYSTEM_SCALE:
1332			case CFG_CNF_MAX_DATA_LEN:
1333			case CFG_CNF_PM_ENABLED:
1334			case CFG_CNF_MCAST_RX:
1335			case CFG_CNF_MAX_SLEEP_DURATION:
1336			case CFG_CNF_HOLDOVER_DURATION:
1337			case CFG_CNF_OWN_DTIM_PERIOD:
1338			case CFG_CNF_MCAST_PM_BUF:
1339			case CFG_CNF_REJECT_ANY:
1340			case CFG_CNF_ENCRYPTION:
1341			case CFG_CNF_AUTHENTICATION:
1342			case CFG_CNF_EXCL_UNENCRYPTED:
1343			case CFG_CNF_INTRA_BSS_RELAY:
1344			case CFG_CNF_MICRO_WAVE:
1345			case CFG_CNF_LOAD_BALANCING:
1346			case CFG_CNF_MEDIUM_DISTRIBUTION:
1347#ifdef WARP
1348			case CFG_CNF_TX_POW_LVL:
1349			case CFG_CNF_CONNECTION_CNTL:
1350			case CFG_CNF_OWN_BEACON_INTERVAL:                          // Own Beacon Interval
1351			case CFG_COEXISTENSE_BEHAVIOUR:                            // Coexistence Behavior
1352			//case CFG_CNF_RX_ALL_GROUP_ADDRESS:
1353#endif // HERMES25
1354			case CFG_CREATE_IBSS:
1355			case CFG_RTS_THRH:
1356			case CFG_PROMISCUOUS_MODE:
1357			//case CFG_WAKE_ON_LAN:
1358			case CFG_RTS_THRH0:
1359			case CFG_RTS_THRH1:
1360			case CFG_RTS_THRH2:
1361			case CFG_RTS_THRH3:
1362			case CFG_RTS_THRH4:
1363			case CFG_RTS_THRH5:
1364			case CFG_RTS_THRH6:
1365			case CFG_TX_RATE_CNTL0:
1366			case CFG_TX_RATE_CNTL1:
1367			case CFG_TX_RATE_CNTL2:
1368			case CFG_TX_RATE_CNTL3:
1369			case CFG_TX_RATE_CNTL4:
1370			case CFG_TX_RATE_CNTL5:
1371			case CFG_TX_RATE_CNTL6:
1372			case CFG_TX_KEY_ID:
1373			case CFG_TICK_TIME:
1374			case CFG_MAX_LOAD_TIME:
1375			case CFG_NIC_TEMP_TYPE:
1376			case CFG_PORT_STAT:
1377			case CFG_CUR_TX_RATE:
1378			case CFG_CUR_BEACON_INTERVAL:
1379			case CFG_PROTOCOL_RSP_TIME:
1380			case CFG_CUR_SHORT_RETRY_LIMIT:
1381			case CFG_CUR_LONG_RETRY_LIMIT:
1382			case CFG_MAX_TX_LIFETIME:
1383			case CFG_MAX_RX_LIFETIME:
1384			case CFG_CF_POLLABLE:
1385			case CFG_PRIVACY_OPT_IMPLEMENTED:
1386			//case CFG_CURRENT_REMOTE_RATES:
1387			//case CFG_CURRENT_USED_RATES:
1388			//case CFG_CURRENT_SYSTEM_SCALE:
1389			//case CFG_CURRENT_TX_RATE1:
1390			//case CFG_CURRENT_TX_RATE2:
1391			//case CFG_CURRENT_TX_RATE3:
1392			//case CFG_CURRENT_TX_RATE4:
1393			//case CFG_CURRENT_TX_RATE5:
1394			//case CFG_CURRENT_TX_RATE6:
1395			case CFG_PHY_TYPE:
1396			case CFG_CUR_CHANNEL:
1397			//case CFG_CURRENT_POWER_STATE:
1398			//case CFG_CCAMODE:
1399			//    lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
1400			//    break;
1401			/* name string gets just need the first hcf_16 byte flipped (length of string) */
1402			case CFG_CNF_OWN_SSID:
1403			case CFG_CNF_OWN_NAME:
1404			//case CNF_DESIRED_SSID:
1405			case CFG_DESIRED_SSID:
1406			case CFG_SCAN_SSID:
1407			case CFG_CUR_SSID:
1408				lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
1409				break;
1410			/* non-length counted strings need no byte flipping */
1411			case CFG_CNF_OWN_MAC_ADDR:
1412			/* this case is no longer valid: CFG_CNF_WDS_ADDR */
1413			case CFG_CNF_WDS_ADDR1:
1414			case CFG_CNF_WDS_ADDR2:
1415			case CFG_CNF_WDS_ADDR3:
1416			case CFG_CNF_WDS_ADDR4:
1417			case CFG_CNF_WDS_ADDR5:
1418			case CFG_CNF_WDS_ADDR6:
1419			case CFG_GROUP_ADDR:
1420			case CFG_NIC_SERIAL_NUMBER:
1421			case CFG_CUR_BSSID:
1422			case CFG_NIC_MAC_ADDR:
1423			case CFG_SUPPORTED_DATA_RATES:  /* need to ensure we can treat this as a string */
1424				break;
1425			//case CFG_CNF_COUNTRY_INFO:      /* special case, see page 75  of 022486, Rev C. */
1426			//case CFG_CURRENT_COUNTRY_INFO:  /* special case, see page 101 of 022486, Rev C. */
1427			/*
1428				lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
1429				lp->ltvRecord.u.u16[3] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[3] );
1430
1431				for( i = 4; i < lp->ltvRecord.len; i++ ) {
1432					lp->ltvRecord.u.u16[i] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[i] );
1433				}
1434				break;
1435			*/
1436
1437			case CFG_DEFAULT_KEYS:
1438				{
1439					CFG_DEFAULT_KEYS_STRCT *pKeys = (CFG_DEFAULT_KEYS_STRCT *)&lp->ltvRecord.u.u8[0];
1440
1441					pKeys[0].len = CNV_INT_TO_LITTLE( pKeys[0].len );
1442					pKeys[1].len = CNV_INT_TO_LITTLE( pKeys[1].len );
1443					pKeys[2].len = CNV_INT_TO_LITTLE( pKeys[2].len );
1444					pKeys[3].len = CNV_INT_TO_LITTLE( pKeys[3].len );
1445				}
1446				break;
1447			case CFG_CNF_MCAST_RATE:
1448			case CFG_TX_RATE_CNTL:
1449			case CFG_SUPPORTED_RATE_SET_CNTL:    // Supported Rate Set Control
1450			case CFG_BASIC_RATE_SET_CNTL:    // Basic Rate Set Control
1451				lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
1452				lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] );
1453				break;
1454			case CFG_DL_BUF:
1455			case CFG_NIC_IDENTITY:
1456			case CFG_COMMS_QUALITY:
1457			case CFG_PCF_INFO:
1458				lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
1459				lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] );
1460				lp->ltvRecord.u.u16[2] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[2] );
1461				break;
1462			case CFG_FW_IDENTITY:
1463				lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
1464				lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] );
1465				lp->ltvRecord.u.u16[2] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[2] );
1466				lp->ltvRecord.u.u16[3] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[3] );
1467				break;
1468			//case CFG_HSI_SUP_RANGE:
1469			case CFG_NIC_MFI_SUP_RANGE:
1470			case CFG_NIC_CFI_SUP_RANGE:
1471			case CFG_NIC_PROFILE:
1472			case CFG_FW_SUP_RANGE:
1473				lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
1474				lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] );
1475				lp->ltvRecord.u.u16[2] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[2] );
1476				lp->ltvRecord.u.u16[3] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[3] );
1477				lp->ltvRecord.u.u16[4] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[4] );
1478				break;
1479			case CFG_MFI_ACT_RANGES_STA:
1480			case CFG_CFI_ACT_RANGES_STA:
1481			case CFG_CUR_SCALE_THRH:
1482			case CFG_AUTHENTICATION_ALGORITHMS:
1483				for( i = 0; i < ( lp->ltvRecord.len - 1 ); i++ ) {
1484					lp->ltvRecord.u.u16[i] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[i] );
1485				}
1486				break;
1487			/* done at init time, and endian handled then */
1488			case CFG_PRI_IDENTITY:
1489				break;
1490			case CFG_MB_INFO:
1491				//wvlanEndianTranslateMailbox( pLtv );
1492				break;
1493			/* MSF and HCF RIDS */
1494			case CFG_IFB:
1495			case CFG_DRV_INFO:
1496			case CFG_AP_MODE:
1497			case CFG_ENCRYPT_STRING:
1498			case CFG_COUNTRY_STRING:
1499			case CFG_DRIVER_ENABLE:
1500			case CFG_WOLAS_ENABLE:
1501			default:
1502				break;
1503			}
1504
1505			// Copy the LTV into the user's buffer.
1506			copy_to_user( urq->data, &( lp->ltvRecord ), urq->len );
1507
1508			if( ltvAllocated ) {
1509				kfree( &( lp->ltvRecord ));
1510			}
1511
1512			urq->result = UIL_SUCCESS;
1513		} else {
1514			urq->result = UIL_FAILURE;
1515		}
1516	} else {
1517		DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
1518		urq->result = UIL_ERR_WRONG_IFB;
1519	}
1520
1521	DBG_LEAVE( DbgInfo );
1522	return result;
1523} // wvlan_uil_get_info
1524/*============================================================================*/
1525
1526
1527
1528
1529
1530/*******************************************************************************
1531 *	cfg_driver_info()
1532 *******************************************************************************
1533 *
1534 *  DESCRIPTION:
1535 *
1536 *      Retrieves driver information.
1537 *
1538 *  PARAMETERS:
1539 *
1540 *      urq - a pointer to the UIL request buffer
1541 *      lp  - a pointer to the device's private adapter structure
1542 *
1543 *  RETURNS:
1544 *
1545 *      UIL_SUCCESS
1546 *      UIL_ERR_xxx value otherwise
1547 *
1548 ******************************************************************************/
1549int cfg_driver_info( struct uilreq *urq, struct wl_private *lp )
1550{
1551	int result = 0;
1552	/*------------------------------------------------------------------------*/
1553
1554
1555	DBG_FUNC( "cfg_driver_info" );
1556	DBG_ENTER( DbgInfo );
1557
1558
1559	/* Make sure that user buffer can handle the driver information buffer */
1560	if( urq->len < sizeof( lp->driverInfo )) {
1561		urq->len = sizeof( lp->driverInfo );
1562		urq->result = UIL_ERR_LEN;
1563		DBG_LEAVE( DbgInfo );
1564		return result;
1565	}
1566
1567	/* Verify the user buffer. */
1568	result = verify_area( VERIFY_WRITE, urq->data, sizeof( lp->driverInfo ));
1569	if( result != 0 ) {
1570		urq->result = UIL_FAILURE;
1571		DBG_LEAVE( DbgInfo );
1572		return result;
1573	}
1574
1575	lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat;
1576
1577	// Copy the driver information into the user's buffer.
1578	urq->result = UIL_SUCCESS;
1579	copy_to_user( urq->data, &( lp->driverInfo ), sizeof( lp->driverInfo ));
1580
1581	DBG_LEAVE( DbgInfo );
1582	return result;
1583} // cfg_driver_info
1584/*============================================================================*/
1585
1586
1587
1588
1589/*******************************************************************************
1590 *	cfg_driver_identity()
1591 *******************************************************************************
1592 *
1593 *  DESCRIPTION:
1594 *
1595 *      Retrieves ID information from the card.
1596 *
1597 *  PARAMETERS:
1598 *
1599 *      urq - a pointer to the UIL request buffer
1600 *      lp  - a pointer to the device's private adapter structure
1601 *
1602 *  RETURNS:
1603 *
1604 *      UIL_SUCCESS
1605 *      UIL_ERR_xxx value otherwise
1606 *
1607 ******************************************************************************/
1608int cfg_driver_identity( struct uilreq *urq, struct wl_private *lp )
1609{
1610	int result = 0;
1611	/*------------------------------------------------------------------------*/
1612
1613
1614	DBG_FUNC( "wvlan_driver_identity" );
1615	DBG_ENTER( DbgInfo );
1616
1617
1618	/* Make sure that user buffer can handle the driver identity structure. */
1619	if( urq->len < sizeof( lp->driverIdentity )) {
1620		urq->len = sizeof( lp->driverIdentity );
1621		urq->result = UIL_ERR_LEN;
1622		DBG_LEAVE( DbgInfo );
1623		return result;
1624	}
1625
1626	/* Verify the user buffer. */
1627	result = verify_area( VERIFY_WRITE, urq->data, sizeof( lp->driverIdentity ));
1628	if( result != 0 ) {
1629		urq->result = UIL_FAILURE;
1630		DBG_LEAVE( DbgInfo );
1631		return result;
1632	}
1633
1634	/* Copy the driver identity into the user's buffer. */
1635	urq->result = UIL_SUCCESS;
1636	copy_to_user( urq->data, &( lp->driverIdentity ), sizeof( lp->driverIdentity ));
1637
1638	DBG_LEAVE( DbgInfo );
1639	return result;
1640} // cfg_driver_identity
1641/*============================================================================*/
1642
1643
1644#endif  /* USE_UIL */
1645
1646
1647/* If WIRELESS_EXT is not defined, then the functions that follow will not be
1648   included in the build. */
1649/* NOTE: Are these still even needed? */
1650#ifdef WIRELESS_EXT
1651
1652
1653/*******************************************************************************
1654 *	wvlan_set_netname()
1655 *******************************************************************************
1656 *
1657 *  DESCRIPTION:
1658 *
1659 *      Set the ESSID of the card.
1660 *
1661 *  PARAMETERS:
1662 *
1663 *      wrq - a pointer to the wireless request buffer
1664 *      lp  - a pointer to the device's private adapter structure
1665 *
1666 *  RETURNS:
1667 *
1668 *      0 on success
1669 *      errno value otherwise
1670 *
1671 ******************************************************************************/
1672int wvlan_set_netname(struct net_device *dev,
1673		      struct iw_request_info *info,
1674		      union iwreq_data *wrqu,
1675		      char *extra)
1676{
1677        struct wl_private *lp = wl_priv(dev);
1678        unsigned long flags;
1679	int ret = 0;
1680	/*------------------------------------------------------------------------*/
1681
1682
1683	DBG_FUNC( "wvlan_set_netname" );
1684	DBG_ENTER( DbgInfo );
1685
1686        wl_lock(lp, &flags);
1687
1688        memset( lp->NetworkName, 0, sizeof( lp->NetworkName ));
1689        memcpy( lp->NetworkName, extra, wrqu->data.length);
1690
1691	/* Commit the adapter parameters */
1692	wl_apply(lp);
1693        wl_unlock(lp, &flags);
1694
1695	DBG_LEAVE( DbgInfo );
1696	return ret;
1697} // wvlan_set_netname
1698/*============================================================================*/
1699
1700
1701
1702
1703/*******************************************************************************
1704 *	wvlan_get_netname()
1705 *******************************************************************************
1706 *
1707 *  DESCRIPTION:
1708 *
1709 *      Get the ESSID of the card.
1710 *
1711 *  PARAMETERS:
1712 *
1713 *      wrq - a pointer to the wireless request buffer
1714 *      lp  - a pointer to the device's private adapter structure
1715 *
1716 *  RETURNS:
1717 *
1718 *      0 on success
1719 *      errno value otherwise
1720 *
1721 ******************************************************************************/
1722int wvlan_get_netname(struct net_device *dev,
1723		      struct iw_request_info *info,
1724		      union iwreq_data *wrqu,
1725		      char *extra)
1726{
1727        struct wl_private *lp = wl_priv(dev);
1728        unsigned long flags;
1729        int         ret = 0;
1730        int         status = -1;
1731        wvName_t   *pName;
1732	/*------------------------------------------------------------------------*/
1733
1734
1735        DBG_FUNC( "wvlan_get_netname" );
1736        DBG_ENTER( DbgInfo );
1737
1738        wl_lock(lp, &flags);
1739
1740        /* Get the current network name */
1741        lp->ltvRecord.len = 1 + ( sizeof( *pName ) / sizeof( hcf_16 ));
1742        lp->ltvRecord.typ = CFG_CUR_SSID;
1743
1744        status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1745
1746        if( status == HCF_SUCCESS ) {
1747                pName = (wvName_t *)&( lp->ltvRecord.u.u32 );
1748
1749		memset(extra, '\0', HCF_MAX_NAME_LEN);
1750		wrqu->data.length = pName->length;
1751
1752                memcpy(extra, pName->name, pName->length);
1753        } else {
1754                ret = -EFAULT;
1755	}
1756
1757        wl_unlock(lp, &flags);
1758
1759        DBG_LEAVE( DbgInfo );
1760        return ret;
1761} // wvlan_get_netname
1762/*============================================================================*/
1763
1764
1765
1766
1767/*******************************************************************************
1768 *	wvlan_set_station_nickname()
1769 *******************************************************************************
1770 *
1771 *  DESCRIPTION:
1772 *
1773 *      Set the card's station nickname.
1774 *
1775 *  PARAMETERS:
1776 *
1777 *      wrq - a pointer to the wireless request buffer
1778 *      lp  - a pointer to the device's private adapter structure
1779 *
1780 *  RETURNS:
1781 *
1782 *      0 on success
1783 *      errno value otherwise
1784 *
1785 ******************************************************************************/
1786int wvlan_set_station_nickname(struct net_device *dev,
1787		      struct iw_request_info *info,
1788		      union iwreq_data *wrqu,
1789		      char *extra)
1790{
1791        struct wl_private *lp = wl_priv(dev);
1792        unsigned long flags;
1793        int         ret = 0;
1794	/*------------------------------------------------------------------------*/
1795
1796
1797        DBG_FUNC( "wvlan_set_station_nickname" );
1798        DBG_ENTER( DbgInfo );
1799
1800        wl_lock(lp, &flags);
1801
1802        memset( lp->StationName, 0, sizeof( lp->StationName ));
1803
1804        memcpy( lp->StationName, extra, wrqu->data.length);
1805
1806        /* Commit the adapter parameters */
1807        wl_apply( lp );
1808        wl_unlock(lp, &flags);
1809
1810        DBG_LEAVE( DbgInfo );
1811        return ret;
1812} // wvlan_set_station_nickname
1813/*============================================================================*/
1814
1815
1816
1817
1818/*******************************************************************************
1819 *	wvlan_get_station_nickname()
1820 *******************************************************************************
1821 *
1822 *  DESCRIPTION:
1823 *
1824 *      Get the card's station nickname.
1825 *
1826 *  PARAMETERS:
1827 *
1828 *      wrq - a pointer to the wireless request buffer
1829 *      lp  - a pointer to the device's private adapter structure
1830 *
1831 *  RETURNS:
1832 *
1833 *      0 on success
1834 *      errno value otherwise
1835 *
1836 ******************************************************************************/
1837int wvlan_get_station_nickname(struct net_device *dev,
1838		      struct iw_request_info *info,
1839		      union iwreq_data *wrqu,
1840		      char *extra)
1841{
1842        struct wl_private *lp = wl_priv(dev);
1843        unsigned long flags;
1844	int         ret = 0;
1845	int         status = -1;
1846	wvName_t   *pName;
1847	/*------------------------------------------------------------------------*/
1848
1849
1850        DBG_FUNC( "wvlan_get_station_nickname" );
1851        DBG_ENTER( DbgInfo );
1852
1853        wl_lock( lp, &flags );
1854
1855        /* Get the current station name */
1856        lp->ltvRecord.len = 1 + ( sizeof( *pName ) / sizeof( hcf_16 ));
1857        lp->ltvRecord.typ = CFG_CNF_OWN_NAME;
1858
1859        status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1860
1861        if( status == HCF_SUCCESS ) {
1862                pName = (wvName_t *)&( lp->ltvRecord.u.u32 );
1863
1864		memset(extra, '\0', HCF_MAX_NAME_LEN);
1865		wrqu->data.length = pName->length;
1866		memcpy(extra, pName->name, pName->length);
1867        } else {
1868                ret = -EFAULT;
1869        }
1870
1871        wl_unlock(lp, &flags);
1872
1873//out:
1874        DBG_LEAVE( DbgInfo );
1875	return ret;
1876} // wvlan_get_station_nickname
1877/*============================================================================*/
1878
1879
1880
1881
1882/*******************************************************************************
1883 *	wvlan_set_porttype()
1884 *******************************************************************************
1885 *
1886 *  DESCRIPTION:
1887 *
1888 *      Set the card's porttype
1889 *
1890 *  PARAMETERS:
1891 *
1892 *      wrq - a pointer to the wireless request buffer
1893 *      lp  - a pointer to the device's private adapter structure
1894 *
1895 *  RETURNS:
1896 *
1897 *      0 on success
1898 *      errno value otherwise
1899 *
1900 ******************************************************************************/
1901int wvlan_set_porttype(struct net_device *dev,
1902		      struct iw_request_info *info,
1903		      union iwreq_data *wrqu,
1904		      char *extra)
1905{
1906        struct wl_private *lp = wl_priv(dev);
1907        unsigned long flags;
1908        int     ret = 0;
1909	hcf_16  portType;
1910	/*------------------------------------------------------------------------*/
1911
1912
1913        DBG_FUNC( "wvlan_set_porttype" );
1914        DBG_ENTER( DbgInfo );
1915
1916        wl_lock(lp, &flags);
1917
1918        /* Validate the new value */
1919        portType = *((__u32 *)extra);
1920
1921        if( !(( portType == 1 ) || ( portType == 3 ))) {
1922                ret = -EINVAL;
1923		goto out_unlock;
1924        }
1925
1926        lp->PortType = portType;
1927
1928        /* Commit the adapter parameters */
1929        wl_apply( lp );
1930
1931out_unlock:
1932        wl_unlock(lp, &flags);
1933
1934//out:
1935        DBG_LEAVE( DbgInfo );
1936        return ret;
1937}
1938
1939/*============================================================================*/
1940
1941
1942/*******************************************************************************
1943 *	wvlan_get_porttype()
1944 *******************************************************************************
1945 *
1946 *  DESCRIPTION:
1947 *
1948 *      Get the card's porttype
1949 *
1950 *  PARAMETERS:
1951 *
1952 *      wrq - a pointer to the wireless request buffer
1953 *      lp  - a pointer to the device's private adapter structure
1954 *
1955 *  RETURNS:
1956 *
1957 *      0 on success
1958 *      errno value otherwise
1959 *
1960 ******************************************************************************/
1961int wvlan_get_porttype(struct net_device *dev,
1962		      struct iw_request_info *info,
1963		      union iwreq_data *wrqu,
1964		      char *extra)
1965{
1966        struct wl_private *lp = wl_priv(dev);
1967        unsigned long flags;
1968        int     ret = 0;
1969        int     status = -1;
1970        hcf_16  *pPortType;
1971        __u32 *pData = (__u32 *)extra;
1972	/*------------------------------------------------------------------------*/
1973
1974
1975        DBG_FUNC( "wvlan_get_porttype" );
1976        DBG_ENTER( DbgInfo );
1977
1978        wl_lock( lp, &flags );
1979
1980        /* Get the current port type */
1981        lp->ltvRecord.len = 1 + ( sizeof( *pPortType ) / sizeof( hcf_16 ));
1982        lp->ltvRecord.typ = CFG_CNF_PORT_TYPE;
1983
1984        status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1985
1986        if( status == HCF_SUCCESS ) {
1987                pPortType = (hcf_16 *)&( lp->ltvRecord.u.u32 );
1988
1989                *pData = CNV_LITTLE_TO_INT( *pPortType );
1990        } else {
1991            ret = -EFAULT;
1992	}
1993
1994        wl_unlock(lp, &flags);
1995
1996//out:
1997        DBG_LEAVE( DbgInfo );
1998        return ret;
1999} // wvlan_get_porttype
2000/*============================================================================*/
2001
2002#endif  // WIRELESS_EXT
2003
2004
2005
2006
2007#ifdef USE_RTS
2008/*******************************************************************************
2009 *	wvlan_rts()
2010 *******************************************************************************
2011 *
2012 *  DESCRIPTION:
2013 *
2014 *      IOCTL handler for RTS commands
2015 *
2016 *  PARAMETERS:
2017 *
2018 *      rrq - a pointer to the rts request buffer
2019 *      lp  - a pointer to the device's private adapter structure
2020 *
2021 *  RETURNS:
2022 *
2023 *      0 on success
2024 *      errno value otherwise
2025 *
2026 ******************************************************************************/
2027int wvlan_rts( struct rtsreq *rrq, __u32 io_base )
2028{
2029	int ioctl_ret = 0;
2030	/*------------------------------------------------------------------------*/
2031
2032
2033	DBG_FUNC( "wvlan_rts" );
2034	DBG_ENTER( DbgInfo );
2035
2036
2037	DBG_PRINT( "io_base: 0x%08x\n", io_base );
2038
2039	switch( rrq->typ ) {
2040	  case WL_IOCTL_RTS_READ:
2041		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_READ\n");
2042		rrq->data[0] = IN_PORT_WORD( io_base + rrq->reg );
2043		DBG_TRACE( DbgInfo, "  reg 0x%04x ==> 0x%04x\n", rrq->reg, CNV_LITTLE_TO_SHORT( rrq->data[0] ) );
2044		break;
2045	  case WL_IOCTL_RTS_WRITE:
2046		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_WRITE\n");
2047		OUT_PORT_WORD( io_base + rrq->reg, rrq->data[0] );
2048		DBG_TRACE( DbgInfo, "  reg 0x%04x <== 0x%04x\n", rrq->reg, CNV_LITTLE_TO_SHORT( rrq->data[0] ) );
2049		break;
2050	  case WL_IOCTL_RTS_BATCH_READ:
2051		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_BATCH_READ\n");
2052		IN_PORT_STRING_16( io_base + rrq->reg, rrq->data, rrq->len );
2053		DBG_TRACE( DbgInfo, "  reg 0x%04x ==> %d bytes\n", rrq->reg, rrq->len * sizeof (__u16 ) );
2054		break;
2055	  case WL_IOCTL_RTS_BATCH_WRITE:
2056		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_BATCH_WRITE\n");
2057		OUT_PORT_STRING_16( io_base + rrq->reg, rrq->data, rrq->len );
2058		DBG_TRACE( DbgInfo, "  reg 0x%04x <== %d bytes\n", rrq->reg, rrq->len * sizeof (__u16) );
2059		break;
2060	default:
2061
2062		DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- UNSUPPORTED RTS CODE: 0x%X", rrq->typ );
2063		ioctl_ret = -EOPNOTSUPP;
2064		break;
2065	}
2066
2067	DBG_LEAVE( DbgInfo );
2068	return ioctl_ret;
2069} // wvlan_rts
2070/*============================================================================*/
2071
2072#endif  /* USE_RTS */
2073