Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
wl_priv.c
Go to the documentation of this file.
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 
84 int wvlan_uil_connect( struct uilreq *urq, struct wl_private *lp );
85 int wvlan_uil_disconnect( struct uilreq *urq, struct wl_private *lp );
86 int wvlan_uil_action( struct uilreq *urq, struct wl_private *lp );
87 int wvlan_uil_block( struct uilreq *urq, struct wl_private *lp );
88 int wvlan_uil_unblock( struct uilreq *urq, struct wl_private *lp );
89 int wvlan_uil_send_diag_msg( struct uilreq *urq, struct wl_private *lp );
90 int wvlan_uil_put_info( struct uilreq *urq, struct wl_private *lp );
91 int wvlan_uil_get_info( struct uilreq *urq, struct wl_private *lp );
92 
93 int cfg_driver_info( struct uilreq *urq, struct wl_private *lp );
94 int cfg_driver_identity( struct uilreq *urq, struct wl_private *lp );
95 
96 
97 /*******************************************************************************
98  * global variables
99  ******************************************************************************/
100 #if DBG
101 extern 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  ******************************************************************************/
130 int 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;
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  ******************************************************************************/
195 int 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 )) {
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  * Disconnect 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  ******************************************************************************/
241 int 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  ******************************************************************************/
296 int 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 
376 int 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);
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  ******************************************************************************/
428 int 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);
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  ******************************************************************************/
481 int 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  ******************************************************************************/
567 int 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;
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:
660  lp->atimWindow = pLtv->u.u16[0];
661  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
662  break;
664  lp->DistanceBetweenAPs = pLtv->u.u16[0];
665  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
666 
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;
680  lp->MaxSleepDuration = pLtv->u.u16[0];
681  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
682  break;
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;
693  lp->loadBalancing = pLtv->u.u16[0];
694  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
695  break;
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 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
727  //;?should we restore this to allow smaller memory footprint
728 
730  lp->DTIMPeriod = pLtv->u.u16[0];
731  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
732  break;
733 #ifdef WARP
734  case CFG_CNF_OWN_BEACON_INTERVAL: // Own Beacon Interval
735  lp->ownBeaconInterval = pLtv->u.u16[0];
736  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
737  break;
738 #endif // WARP
739  case CFG_COEXISTENSE_BEHAVIOUR: // Coexistence behavior
740  lp->coexistence = pLtv->u.u16[0];
741  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
742  break;
743 #ifdef USE_WDS
744  case CFG_CNF_WDS_ADDR1:
745  memcpy( &lp->wds_port[0].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
746  hcfPort = HCF_PORT_1;
747  break;
748  case CFG_CNF_WDS_ADDR2:
749  memcpy( &lp->wds_port[1].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
750  hcfPort = HCF_PORT_2;
751  break;
752  case CFG_CNF_WDS_ADDR3:
753  memcpy( &lp->wds_port[2].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
754  hcfPort = HCF_PORT_3;
755  break;
756  case CFG_CNF_WDS_ADDR4:
757  memcpy( &lp->wds_port[3].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
758  hcfPort = HCF_PORT_4;
759  break;
760  case CFG_CNF_WDS_ADDR5:
761  memcpy( &lp->wds_port[4].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
762  hcfPort = HCF_PORT_5;
763  break;
764  case CFG_CNF_WDS_ADDR6:
765  memcpy( &lp->wds_port[5].wdsAddress, &pLtv->u.u8[0], ETH_ALEN );
766  hcfPort = HCF_PORT_6;
767  break;
768 #endif /* USE_WDS */
769 
771  lp->multicastPMBuffering = pLtv->u.u16[0];
772  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
773  break;
774  case CFG_CNF_REJECT_ANY:
775  lp->RejectAny = pLtv->u.u16[0];
776  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
777  break;
778 #endif
779 
780  case CFG_CNF_ENCRYPTION:
781  lp->EnableEncryption = pLtv->u.u16[0];
782  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
783  break;
785  lp->authentication = pLtv->u.u16[0];
786  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
787  break;
788 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
789  //;?should we restore this to allow smaller memory footprint
790 
791  //case CFG_CNF_EXCL_UNENCRYPTED:
792  //lp->ExcludeUnencrypted = pLtv->u.u16[0];
793  //pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
794  //break;
795  case CFG_CNF_MCAST_RATE:
796  /* TODO: determine if we are going to store anything based on this */
797  break;
799  lp->intraBSSRelay = pLtv->u.u16[0];
800  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
801  break;
802 #endif
803 
804  case CFG_CNF_MICRO_WAVE:
805  /* TODO: determine if we are going to store anything based on this */
806  break;
807  //case CFG_CNF_LOAD_BALANCING:
808  /* TODO: determine if we are going to store anything based on this */
809  //break;
810  //case CFG_CNF_MEDIUM_DISTRIBUTION:
811  /* TODO: determine if we are going to store anything based on this */
812  //break;
813  //case CFG_CNF_RX_ALL_GROUP_ADDRESS:
814  // TODO: determine if we are going to store anything based on this
815  //break;
816  //case CFG_CNF_COUNTRY_INFO:
817  /* TODO: determine if we are going to store anything based on this */
818  //break;
819  case CFG_CNF_OWN_SSID:
820  //case CNF_DESIRED_SSID:
821  case CFG_DESIRED_SSID:
822  memset( lp->NetworkName, 0, sizeof( lp->NetworkName ));
823  memcpy( (void *)lp->NetworkName, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0] );
824  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
825 
826  /* take care of the special network name "ANY" case */
827  if(( strlen( &pLtv->u.u8[2] ) == 0 ) ||
828  ( strcmp( &pLtv->u.u8[2], "ANY" ) == 0 ) ||
829  ( strcmp( &pLtv->u.u8[2], "any" ) == 0 )) {
830  /* set the SSID_STRCT llen field (u16[0]) to zero, and the
831  effectually null the string u8[2] */
832  pLtv->u.u16[0] = 0;
833  pLtv->u.u8[2] = 0;
834  }
835  break;
836  case CFG_GROUP_ADDR:
837  /* TODO: determine if we are going to store anything based on this */
838  break;
839  case CFG_CREATE_IBSS:
840  lp->CreateIBSS = pLtv->u.u16[0];
841  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
842  break;
843  case CFG_RTS_THRH:
844  lp->RTSThreshold = pLtv->u.u16[0];
845  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
846  break;
847  case CFG_TX_RATE_CNTL:
848  lp->TxRateControl[0] = pLtv->u.u16[0];
849  lp->TxRateControl[1] = pLtv->u.u16[1];
850  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
851  pLtv->u.u16[1] = CNV_INT_TO_LITTLE( pLtv->u.u16[1] );
852  break;
854  /* TODO: determine if we are going to store anything based on this */
855  break;
856  //case CFG_WAKE_ON_LAN:
857  /* TODO: determine if we are going to store anything based on this */
858  //break;
859 #if 1 //;? #if (HCF_TYPE) & HCF_TYPE_AP
860  //;?should we restore this to allow smaller memory footprint
861  case CFG_RTS_THRH0:
862  lp->RTSThreshold = pLtv->u.u16[0];
863  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
864  break;
865  case CFG_TX_RATE_CNTL0:
866 //;?no idea what this should be, get going so comment it out lp->TxRateControl = pLtv->u.u16[0];
867  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
868  break;
869 #ifdef USE_WDS
870  case CFG_RTS_THRH1:
871  lp->wds_port[0].rtsThreshold = pLtv->u.u16[0];
872  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
873  hcfPort = HCF_PORT_1;
874  break;
875  case CFG_RTS_THRH2:
876  lp->wds_port[1].rtsThreshold = pLtv->u.u16[0];
877  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
878  hcfPort = HCF_PORT_2;
879  break;
880  case CFG_RTS_THRH3:
881  lp->wds_port[2].rtsThreshold = pLtv->u.u16[0];
882  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
883  hcfPort = HCF_PORT_3;
884  break;
885  case CFG_RTS_THRH4:
886  lp->wds_port[3].rtsThreshold = pLtv->u.u16[0];
887  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
888  hcfPort = HCF_PORT_4;
889  break;
890  case CFG_RTS_THRH5:
891  lp->wds_port[4].rtsThreshold = pLtv->u.u16[0];
892  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
893  hcfPort = HCF_PORT_5;
894  break;
895  case CFG_RTS_THRH6:
896  lp->wds_port[5].rtsThreshold = pLtv->u.u16[0];
897  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
898  hcfPort = HCF_PORT_6;
899  break;
900  case CFG_TX_RATE_CNTL1:
901  lp->wds_port[0].txRateCntl = pLtv->u.u16[0];
902  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
903  hcfPort = HCF_PORT_1;
904  break;
905  case CFG_TX_RATE_CNTL2:
906  lp->wds_port[1].txRateCntl = pLtv->u.u16[0];
907  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
908  hcfPort = HCF_PORT_2;
909  break;
910  case CFG_TX_RATE_CNTL3:
911  lp->wds_port[2].txRateCntl = pLtv->u.u16[0];
912  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
913  hcfPort = HCF_PORT_3;
914  break;
915  case CFG_TX_RATE_CNTL4:
916  lp->wds_port[3].txRateCntl = pLtv->u.u16[0];
917  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
918  hcfPort = HCF_PORT_4;
919  break;
920  case CFG_TX_RATE_CNTL5:
921  lp->wds_port[4].txRateCntl = pLtv->u.u16[0];
922  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
923  hcfPort = HCF_PORT_5;
924  break;
925  case CFG_TX_RATE_CNTL6:
926  lp->wds_port[5].txRateCntl = pLtv->u.u16[0];
927  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
928  hcfPort = HCF_PORT_6;
929  break;
930 #endif /* USE_WDS */
931 #endif /* (HCF_TYPE) & HCF_TYPE_AP */
932 
933  case CFG_DEFAULT_KEYS:
934  {
935  CFG_DEFAULT_KEYS_STRCT *pKeys = (CFG_DEFAULT_KEYS_STRCT *)pLtv;
936 
937  pKeys->key[0].len = CNV_INT_TO_LITTLE( pKeys->key[0].len );
938  pKeys->key[1].len = CNV_INT_TO_LITTLE( pKeys->key[1].len );
939  pKeys->key[2].len = CNV_INT_TO_LITTLE( pKeys->key[2].len );
940  pKeys->key[3].len = CNV_INT_TO_LITTLE( pKeys->key[3].len );
941 
942  memcpy( (void *)&(lp->DefaultKeys), (void *)pKeys,
943  sizeof( CFG_DEFAULT_KEYS_STRCT ));
944  }
945  break;
946  case CFG_TX_KEY_ID:
947  lp->TransmitKeyID = pLtv->u.u16[0];
948  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
949  break;
950  case CFG_SCAN_SSID:
951  /* TODO: determine if we are going to store anything based on this */
952  break;
953  case CFG_TICK_TIME:
954  /* TODO: determine if we are going to store anything based on this */
955  break;
956  /* these RIDS are Info RIDs, and should they be allowed for puts??? */
957  case CFG_MAX_LOAD_TIME:
958  case CFG_DL_BUF:
959  //case CFG_HSI_SUP_RANGE:
961  case CFG_NIC_IDENTITY:
964  case CFG_NIC_TEMP_TYPE:
965  case CFG_NIC_PROFILE:
966  case CFG_FW_IDENTITY:
967  case CFG_FW_SUP_RANGE:
970  case CFG_PORT_STAT:
971  case CFG_CUR_SSID:
972  case CFG_CUR_BSSID:
973  case CFG_COMMS_QUALITY:
974  case CFG_CUR_TX_RATE:
976  case CFG_CUR_SCALE_THRH:
980  case CFG_MAX_TX_LIFETIME:
981  case CFG_MAX_RX_LIFETIME:
982  case CFG_CF_POLLABLE:
985  //case CFG_CURRENT_REMOTE_RATES:
986  //case CFG_CURRENT_USED_RATES:
987  //case CFG_CURRENT_SYSTEM_SCALE:
988  //case CFG_CURRENT_TX_RATE1:
989  //case CFG_CURRENT_TX_RATE2:
990  //case CFG_CURRENT_TX_RATE3:
991  //case CFG_CURRENT_TX_RATE4:
992  //case CFG_CURRENT_TX_RATE5:
993  //case CFG_CURRENT_TX_RATE6:
994  case CFG_NIC_MAC_ADDR:
995  case CFG_PCF_INFO:
996  //case CFG_CURRENT_COUNTRY_INFO:
997  case CFG_PHY_TYPE:
998  case CFG_CUR_CHANNEL:
999  //case CFG_CURRENT_POWER_STATE:
1000  //case CFG_CCAMODE:
1002  break;
1003  case CFG_AP_MODE:
1004 //;? lp->DownloadFirmware = ( pLtv->u.u16[0] ) + 1;
1005  DBG_ERROR( DbgInfo, "set CFG_AP_MODE no longer supported\n" );
1006  break;
1007  case CFG_ENCRYPT_STRING:
1008  /* TODO: ENDIAN TRANSLATION HERE??? */
1009  memset( lp->szEncryption, 0, sizeof( lp->szEncryption ));
1010  memcpy( (void *)lp->szEncryption, (void *)&pLtv->u.u8[0],
1011  ( pLtv->len * sizeof( hcf_16 )) );
1012  wl_wep_decode( CRYPT_CODE, &sEncryption,
1013  lp->szEncryption );
1014 
1015  /* the Linux driver likes to use 1-4 for the key IDs, and then
1016  convert to 0-3 when sending to the card. The Windows code
1017  base used 0-3 in the API DLL, which was ported to Linux. For
1018  the sake of the user experience, we decided to keep 0-3 as the
1019  numbers used in the DLL; and will perform the +1 conversion here.
1020  We could have converted the entire Linux driver, but this is
1021  less obtrusive. This may be a "todo" to convert the whole driver */
1022  lp->TransmitKeyID = sEncryption.wTxKeyID + 1;
1023  lp->EnableEncryption = sEncryption.wEnabled;
1024 
1025  memcpy( &lp->DefaultKeys, &sEncryption.EncStr,
1026  sizeof( CFG_DEFAULT_KEYS_STRCT ));
1027  break;
1028  /*case CFG_COUNTRY_STRING:
1029  memset( lp->countryString, 0, sizeof( lp->countryString ));
1030  memcpy( (void *)lp->countryString, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0]);
1031  break;
1032  */
1033 
1034  case CFG_DRIVER_ENABLE:
1035  lp->driverEnable = pLtv->u.u16[0];
1036  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
1037  break;
1038  case CFG_WOLAS_ENABLE:
1039  lp->wolasEnable = pLtv->u.u16[0];
1040  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
1041  break;
1043  lp->AuthKeyMgmtSuite = pLtv->u.u16[0];
1044  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
1045  break;
1046  case CFG_DISASSOCIATE_ADDR:
1047  pLtv->u.u16[ETH_ALEN / 2] = CNV_INT_TO_LITTLE( pLtv->u.u16[ETH_ALEN / 2] );
1048  break;
1051  /* Endian convert the Tx Key Information */
1052  pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] );
1053  break;
1055  break;
1057  break;
1058  /* some RIDs just can't be put */
1059  case CFG_MB_INFO:
1060  case CFG_IFB:
1061  default:
1062  break;
1063  }
1064 
1065  /* This code will prevent Static Configuration Entities from
1066  being sent to the card, as they require a call to
1067  UIL_ACT_APPLY to take effect. Dynamic Entities will be sent
1068  immediately */
1069  switch( pLtv->typ ) {
1070  case CFG_CNF_PORT_TYPE:
1071  case CFG_CNF_OWN_MAC_ADDR:
1072  case CFG_CNF_OWN_CHANNEL:
1073  case CFG_CNF_OWN_SSID:
1075  case CFG_CNF_SYSTEM_SCALE:
1076  case CFG_CNF_MAX_DATA_LEN:
1077  case CFG_CNF_PM_ENABLED:
1078  case CFG_CNF_MCAST_RX:
1081  case CFG_CNF_OWN_NAME:
1084 #ifdef WARP
1085  case CFG_CNF_TX_POW_LVL:
1086  case CFG_CNF_CONNECTION_CNTL:
1087  //case CFG_PROBE_DATA_RATE:
1088 #endif // HERMES25
1089 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
1090  //;?should we restore this to allow smaller memory footprint
1092 #ifdef WARP
1093  case CFG_CNF_OWN_BEACON_INTERVAL: // Own Beacon Interval
1094 #endif // WARP
1095 #ifdef USE_WDS
1096  case CFG_CNF_WDS_ADDR1:
1097  case CFG_CNF_WDS_ADDR2:
1098  case CFG_CNF_WDS_ADDR3:
1099  case CFG_CNF_WDS_ADDR4:
1100  case CFG_CNF_WDS_ADDR5:
1101  case CFG_CNF_WDS_ADDR6:
1102 #endif
1103  case CFG_CNF_MCAST_PM_BUF:
1104  case CFG_CNF_REJECT_ANY:
1105 #endif
1106 
1107  case CFG_CNF_ENCRYPTION:
1109 #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP
1110  //;?should we restore this to allow smaller memory footprint
1111 
1113  case CFG_CNF_MCAST_RATE:
1115 #endif
1116 
1117  case CFG_CNF_MICRO_WAVE:
1118  //case CFG_CNF_LOAD_BALANCING:
1119  //case CFG_CNF_MEDIUM_DISTRIBUTION:
1120  //case CFG_CNF_RX_ALL_GROUP_ADDRESS:
1121  //case CFG_CNF_COUNTRY_INFO:
1122  //case CFG_COUNTRY_STRING:
1123  case CFG_AP_MODE:
1124  case CFG_ENCRYPT_STRING:
1125  //case CFG_DRIVER_ENABLE:
1126  case CFG_WOLAS_ENABLE:
1127  case CFG_MB_INFO:
1128  case CFG_IFB:
1129  break;
1130  /* Deal with this dynamic MSF RID, as it's required for WPA */
1131  case CFG_DRIVER_ENABLE:
1132  if( lp->driverEnable ) {
1133  //hcf_cntl_port( &( lp->hcfCtx ),
1134  // HCF_PORT_ENABLE | HCF_PORT_0 );
1135  // //hcf_cntl( &( lp->hcfCtx ),
1136  // // HCF_PORT_ENABLE | HCF_PORT_0 );
1137  //hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_ENABLE );
1138  // //hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_CONNECT );
1139 
1140  hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_ENABLE | HCF_PORT_0 );
1141  hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_CONNECT );
1142  } else {
1143  //hcf_cntl_port( &( lp->hcfCtx ),
1144  // HCF_PORT_DISABLE | HCF_PORT_0 );
1145  // //hcf_cntl( &( lp->hcfCtx ),
1146  // // HCF_PORT_DISABLE | HCF_PORT_0 );
1147  //hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISABLE );
1148  // //hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISCONNECT );
1149 
1150  hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISABLE | HCF_PORT_0 );
1151  hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISCONNECT );
1152  }
1153  break;
1154  default:
1155  wl_act_int_off( lp );
1156  urq->result = hcf_put_info(&(lp->hcfCtx), (LTVP) pLtv);
1157  wl_act_int_on( lp );
1158  break;
1159  }
1160 
1161  if( ltvAllocated ) {
1162  kfree( pLtv );
1163  }
1164  } else {
1165  urq->result = UIL_FAILURE;
1166  }
1167  } else {
1168  DBG_ERROR( DbgInfo, "EPERM\n" );
1169  urq->result = UIL_FAILURE;
1170  result = -EPERM;
1171  }
1172  } else {
1173  DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
1174  urq->result = UIL_ERR_WRONG_IFB;
1175  }
1176 
1177  DBG_LEAVE( DbgInfo );
1178  return result;
1179 } // wvlan_uil_put_info
1180 /*============================================================================*/
1181 
1182 /*******************************************************************************
1183  * wvlan_uil_get_info()
1184  *******************************************************************************
1185  *
1186  * DESCRIPTION:
1187  *
1188  * Sends a specific RID directly to the driver to retrieve configuration
1189  * info.
1190  *
1191  * PARAMETERS:
1192  *
1193  * urq - a pointer to the UIL request buffer
1194  * lp - a pointer to the device's private adapter structure
1195  *
1196  * RETURNS:
1197  *
1198  * UIL_SUCCESS
1199  * UIL_ERR_xxx value otherwise
1200  *
1201  ******************************************************************************/
1202 int wvlan_uil_get_info( struct uilreq *urq, struct wl_private *lp )
1203 {
1204  int result = 0;
1205  int i;
1206  /*------------------------------------------------------------------------*/
1207 
1208  DBG_FUNC( "wvlan_uil_get_info" );
1209  DBG_ENTER( DbgInfo );
1210 
1211  if( urq->hcfCtx == &( lp->hcfCtx )) {
1212  if(( urq->data != NULL ) && ( urq->len != 0 )) {
1213  ltv_t *pLtv;
1214  bool_t ltvAllocated = FALSE;
1215 
1216  /* Make sure that we have at least a command and length */
1217  if( urq->len < ( sizeof( hcf_16 ) * 2 )) {
1218  urq->len = sizeof( lp->ltvRecord );
1219  DBG_ERROR( DbgInfo, "No Length/Type in LTV!!!\n" );
1220  DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" );
1221  urq->result = UIL_ERR_LEN;
1222  DBG_LEAVE( DbgInfo );
1223  return result;
1224  }
1225 
1226  /* Verify the user's LTV record header. */
1227  result = verify_area( VERIFY_READ, urq->data, sizeof( hcf_16 ) * 2 );
1228  if( result != 0 ) {
1229  DBG_ERROR( DbgInfo, "verify_area(), VERIFY_READ FAILED\n" );
1230  urq->result = UIL_FAILURE;
1231  DBG_LEAVE( DbgInfo );
1232  return result;
1233  }
1234 
1235  /* Get only the command and length information. */
1236  result = copy_from_user( &( lp->ltvRecord ), urq->data, sizeof( hcf_16 ) * 2 );
1237 
1238  /* Make sure the incoming LTV record length is within the bounds of
1239  the IOCTL length. */
1240  if((( lp->ltvRecord.len + 1 ) * sizeof( hcf_16 )) > urq->len ) {
1241  DBG_ERROR( DbgInfo, "Incoming LTV too big\n" );
1242  urq->len = sizeof( lp->ltvRecord );
1243  urq->result = UIL_ERR_LEN;
1244  DBG_LEAVE( DbgInfo );
1245  return result;
1246  }
1247 
1248  /* Determine if hcf_get_info() is needed or not */
1249  switch ( lp->ltvRecord.typ ) {
1250  case CFG_NIC_IDENTITY:
1251  memcpy( &lp->ltvRecord.u.u8[0], &lp->NICIdentity, sizeof( lp->NICIdentity ));
1252  break;
1253  case CFG_PRI_IDENTITY:
1254  memcpy( &lp->ltvRecord.u.u8[0], &lp->PrimaryIdentity, sizeof( lp->PrimaryIdentity ));
1255  break;
1256  case CFG_AP_MODE:
1257  DBG_ERROR( DbgInfo, "set CFG_AP_MODE no longer supported, so is get useful ????\n" );
1258  lp->ltvRecord.u.u16[0] =
1259  CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP;
1260  break;
1261  //case CFG_DRV_INFO:
1262  case CFG_ENCRYPT_STRING:
1263  case CFG_COUNTRY_STRING:
1264  case CFG_DRIVER_ENABLE:
1265  case CFG_WOLAS_ENABLE:
1266  // TODO: determine if we're going to support these
1267  urq->result = UIL_FAILURE;
1268  break;
1269  case CFG_DRV_INFO:
1270  DBG_TRACE( DbgInfo, "Intercept CFG_DRV_INFO\n" );
1271  result = cfg_driver_info( urq, lp );
1272  break;
1273  case CFG_DRV_IDENTITY:
1274  DBG_TRACE( DbgInfo, "Intercept CFG_DRV_IDENTITY\n" );
1275  result = cfg_driver_identity( urq, lp );
1276  break;
1277  case CFG_IFB:
1278  /* IFB can be a security hole */
1279  if( !capable( CAP_NET_ADMIN )) {
1280  result = -EPERM;
1281  break;
1282  }
1283 
1284  /* Else fall through to the default */
1285 
1286  case CFG_FW_IDENTITY: // For Hermes-1, this is cached
1287  default:
1288 
1289  /* Verify the user buffer */
1290  result = verify_area( VERIFY_WRITE, urq->data, urq->len );
1291  if( result != 0 ) {
1292  DBG_ERROR( DbgInfo, "verify_area(), VERIFY_WRITE FAILED\n" );
1293  urq->result = UIL_FAILURE;
1294  break;
1295  }
1296 
1297  /* If the requested length is greater than the size of our local
1298  LTV record, try to allocate it from the kernel stack.
1299  Otherwise, we just use our local LTV record. */
1300  if( urq->len > sizeof( lp->ltvRecord )) {
1301  pLtv = kmalloc(urq->len, GFP_KERNEL);
1302  if (pLtv != NULL) {
1303  ltvAllocated = TRUE;
1304 
1305  /* Copy the command/length information into the new buffer. */
1306  memcpy( pLtv, &( lp->ltvRecord ), sizeof( hcf_16 ) * 2 );
1307  } else {
1308  urq->len = sizeof( lp->ltvRecord );
1309  urq->result = UIL_ERR_LEN;
1310  DBG_ERROR( DbgInfo, "kmalloc FAILED\n" );
1311  DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" );
1312  result = -ENOMEM;
1313  break;
1314  }
1315  } else {
1316  pLtv = &( lp->ltvRecord );
1317  }
1318 
1319  wl_act_int_off( lp );
1320  urq->result = hcf_get_info( &( lp->hcfCtx ), (LTVP) pLtv );
1321  wl_act_int_on( lp );
1322 
1323  // Copy the LTV into the user's buffer.
1324  //copy_to_user( urq->data, pLtv, urq->len );
1325 
1326  //if( ltvAllocated )
1327  //{
1328  // kfree( pLtv );
1329  //}
1330 
1331  //urq->result = UIL_SUCCESS;
1332  break;
1333  }
1334 
1335  /* Handle endian conversion of special fields */
1336  switch( lp->ltvRecord.typ ) {
1337  /* simple int gets just need the first hcf_16 byte flipped */
1338  case CFG_CNF_PORT_TYPE:
1339  case CFG_CNF_OWN_CHANNEL:
1341  case CFG_CNF_SYSTEM_SCALE:
1342  case CFG_CNF_MAX_DATA_LEN:
1343  case CFG_CNF_PM_ENABLED:
1344  case CFG_CNF_MCAST_RX:
1348  case CFG_CNF_MCAST_PM_BUF:
1349  case CFG_CNF_REJECT_ANY:
1350  case CFG_CNF_ENCRYPTION:
1354  case CFG_CNF_MICRO_WAVE:
1357 #ifdef WARP
1358  case CFG_CNF_TX_POW_LVL:
1359  case CFG_CNF_CONNECTION_CNTL:
1360  case CFG_CNF_OWN_BEACON_INTERVAL: // Own Beacon Interval
1361  case CFG_COEXISTENSE_BEHAVIOUR: // Coexistence Behavior
1362  //case CFG_CNF_RX_ALL_GROUP_ADDRESS:
1363 #endif // HERMES25
1364  case CFG_CREATE_IBSS:
1365  case CFG_RTS_THRH:
1366  case CFG_PROMISCUOUS_MODE:
1367  //case CFG_WAKE_ON_LAN:
1368  case CFG_RTS_THRH0:
1369  case CFG_RTS_THRH1:
1370  case CFG_RTS_THRH2:
1371  case CFG_RTS_THRH3:
1372  case CFG_RTS_THRH4:
1373  case CFG_RTS_THRH5:
1374  case CFG_RTS_THRH6:
1375  case CFG_TX_RATE_CNTL0:
1376  case CFG_TX_RATE_CNTL1:
1377  case CFG_TX_RATE_CNTL2:
1378  case CFG_TX_RATE_CNTL3:
1379  case CFG_TX_RATE_CNTL4:
1380  case CFG_TX_RATE_CNTL5:
1381  case CFG_TX_RATE_CNTL6:
1382  case CFG_TX_KEY_ID:
1383  case CFG_TICK_TIME:
1384  case CFG_MAX_LOAD_TIME:
1385  case CFG_NIC_TEMP_TYPE:
1386  case CFG_PORT_STAT:
1387  case CFG_CUR_TX_RATE:
1389  case CFG_PROTOCOL_RSP_TIME:
1392  case CFG_MAX_TX_LIFETIME:
1393  case CFG_MAX_RX_LIFETIME:
1394  case CFG_CF_POLLABLE:
1396  //case CFG_CURRENT_REMOTE_RATES:
1397  //case CFG_CURRENT_USED_RATES:
1398  //case CFG_CURRENT_SYSTEM_SCALE:
1399  //case CFG_CURRENT_TX_RATE1:
1400  //case CFG_CURRENT_TX_RATE2:
1401  //case CFG_CURRENT_TX_RATE3:
1402  //case CFG_CURRENT_TX_RATE4:
1403  //case CFG_CURRENT_TX_RATE5:
1404  //case CFG_CURRENT_TX_RATE6:
1405  case CFG_PHY_TYPE:
1406  case CFG_CUR_CHANNEL:
1407  //case CFG_CURRENT_POWER_STATE:
1408  //case CFG_CCAMODE:
1409  // lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
1410  // break;
1411  /* name string gets just need the first hcf_16 byte flipped (length of string) */
1412  case CFG_CNF_OWN_SSID:
1413  case CFG_CNF_OWN_NAME:
1414  //case CNF_DESIRED_SSID:
1415  case CFG_DESIRED_SSID:
1416  case CFG_SCAN_SSID:
1417  case CFG_CUR_SSID:
1418  lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
1419  break;
1420  /* non-length counted strings need no byte flipping */
1421  case CFG_CNF_OWN_MAC_ADDR:
1422  /* this case is no longer valid: CFG_CNF_WDS_ADDR */
1423  case CFG_CNF_WDS_ADDR1:
1424  case CFG_CNF_WDS_ADDR2:
1425  case CFG_CNF_WDS_ADDR3:
1426  case CFG_CNF_WDS_ADDR4:
1427  case CFG_CNF_WDS_ADDR5:
1428  case CFG_CNF_WDS_ADDR6:
1429  case CFG_GROUP_ADDR:
1430  case CFG_NIC_SERIAL_NUMBER:
1431  case CFG_CUR_BSSID:
1432  case CFG_NIC_MAC_ADDR:
1433  case CFG_SUPPORTED_DATA_RATES: /* need to ensure we can treat this as a string */
1434  break;
1435  //case CFG_CNF_COUNTRY_INFO: /* special case, see page 75 of 022486, Rev C. */
1436  //case CFG_CURRENT_COUNTRY_INFO: /* special case, see page 101 of 022486, Rev C. */
1437  /*
1438  lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
1439  lp->ltvRecord.u.u16[3] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[3] );
1440 
1441  for( i = 4; i < lp->ltvRecord.len; i++ ) {
1442  lp->ltvRecord.u.u16[i] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[i] );
1443  }
1444  break;
1445  */
1446 
1447  case CFG_DEFAULT_KEYS:
1448  {
1449  CFG_DEFAULT_KEYS_STRCT *pKeys = (CFG_DEFAULT_KEYS_STRCT *)&lp->ltvRecord.u.u8[0];
1450 
1451  pKeys[0].len = CNV_INT_TO_LITTLE( pKeys[0].len );
1452  pKeys[1].len = CNV_INT_TO_LITTLE( pKeys[1].len );
1453  pKeys[2].len = CNV_INT_TO_LITTLE( pKeys[2].len );
1454  pKeys[3].len = CNV_INT_TO_LITTLE( pKeys[3].len );
1455  }
1456  break;
1457  case CFG_CNF_MCAST_RATE:
1458  case CFG_TX_RATE_CNTL:
1459  case CFG_SUPPORTED_RATE_SET_CNTL: // Supported Rate Set Control
1460  case CFG_BASIC_RATE_SET_CNTL: // Basic Rate Set Control
1461  lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
1462  lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] );
1463  break;
1464  case CFG_DL_BUF:
1465  case CFG_NIC_IDENTITY:
1466  case CFG_COMMS_QUALITY:
1467  case CFG_PCF_INFO:
1468  lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
1469  lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] );
1470  lp->ltvRecord.u.u16[2] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[2] );
1471  break;
1472  case CFG_FW_IDENTITY:
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  break;
1478  //case CFG_HSI_SUP_RANGE:
1479  case CFG_NIC_MFI_SUP_RANGE:
1480  case CFG_NIC_CFI_SUP_RANGE:
1481  case CFG_NIC_PROFILE:
1482  case CFG_FW_SUP_RANGE:
1483  lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] );
1484  lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] );
1485  lp->ltvRecord.u.u16[2] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[2] );
1486  lp->ltvRecord.u.u16[3] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[3] );
1487  lp->ltvRecord.u.u16[4] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[4] );
1488  break;
1491  case CFG_CUR_SCALE_THRH:
1493  for( i = 0; i < ( lp->ltvRecord.len - 1 ); i++ ) {
1494  lp->ltvRecord.u.u16[i] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[i] );
1495  }
1496  break;
1497  /* done at init time, and endian handled then */
1498  case CFG_PRI_IDENTITY:
1499  break;
1500  case CFG_MB_INFO:
1501  //wvlanEndianTranslateMailbox( pLtv );
1502  break;
1503  /* MSF and HCF RIDS */
1504  case CFG_IFB:
1505  case CFG_DRV_INFO:
1506  case CFG_AP_MODE:
1507  case CFG_ENCRYPT_STRING:
1508  case CFG_COUNTRY_STRING:
1509  case CFG_DRIVER_ENABLE:
1510  case CFG_WOLAS_ENABLE:
1511  default:
1512  break;
1513  }
1514 
1515  // Copy the LTV into the user's buffer.
1516  copy_to_user( urq->data, &( lp->ltvRecord ), urq->len );
1517 
1518  if( ltvAllocated ) {
1519  kfree( &( lp->ltvRecord ));
1520  }
1521 
1522  urq->result = UIL_SUCCESS;
1523  } else {
1524  urq->result = UIL_FAILURE;
1525  }
1526  } else {
1527  DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" );
1528  urq->result = UIL_ERR_WRONG_IFB;
1529  }
1530 
1531  DBG_LEAVE( DbgInfo );
1532  return result;
1533 } // wvlan_uil_get_info
1534 /*============================================================================*/
1535 
1536 
1537 
1538 
1539 
1540 /*******************************************************************************
1541  * cfg_driver_info()
1542  *******************************************************************************
1543  *
1544  * DESCRIPTION:
1545  *
1546  * Retrieves driver information.
1547  *
1548  * PARAMETERS:
1549  *
1550  * urq - a pointer to the UIL request buffer
1551  * lp - a pointer to the device's private adapter structure
1552  *
1553  * RETURNS:
1554  *
1555  * UIL_SUCCESS
1556  * UIL_ERR_xxx value otherwise
1557  *
1558  ******************************************************************************/
1559 int cfg_driver_info( struct uilreq *urq, struct wl_private *lp )
1560 {
1561  int result = 0;
1562  /*------------------------------------------------------------------------*/
1563 
1564 
1565  DBG_FUNC( "cfg_driver_info" );
1566  DBG_ENTER( DbgInfo );
1567 
1568 
1569  /* Make sure that user buffer can handle the driver information buffer */
1570  if( urq->len < sizeof( lp->driverInfo )) {
1571  urq->len = sizeof( lp->driverInfo );
1572  urq->result = UIL_ERR_LEN;
1573  DBG_LEAVE( DbgInfo );
1574  return result;
1575  }
1576 
1577  /* Verify the user buffer. */
1578  result = verify_area( VERIFY_WRITE, urq->data, sizeof( lp->driverInfo ));
1579  if( result != 0 ) {
1580  urq->result = UIL_FAILURE;
1581  DBG_LEAVE( DbgInfo );
1582  return result;
1583  }
1584 
1586 
1587  // Copy the driver information into the user's buffer.
1588  urq->result = UIL_SUCCESS;
1589  copy_to_user( urq->data, &( lp->driverInfo ), sizeof( lp->driverInfo ));
1590 
1591  DBG_LEAVE( DbgInfo );
1592  return result;
1593 } // cfg_driver_info
1594 /*============================================================================*/
1595 
1596 
1597 
1598 
1599 /*******************************************************************************
1600  * cfg_driver_identity()
1601  *******************************************************************************
1602  *
1603  * DESCRIPTION:
1604  *
1605  * Retrieves ID information from the card.
1606  *
1607  * PARAMETERS:
1608  *
1609  * urq - a pointer to the UIL request buffer
1610  * lp - a pointer to the device's private adapter structure
1611  *
1612  * RETURNS:
1613  *
1614  * UIL_SUCCESS
1615  * UIL_ERR_xxx value otherwise
1616  *
1617  ******************************************************************************/
1618 int cfg_driver_identity( struct uilreq *urq, struct wl_private *lp )
1619 {
1620  int result = 0;
1621  /*------------------------------------------------------------------------*/
1622 
1623 
1624  DBG_FUNC( "wvlan_driver_identity" );
1625  DBG_ENTER( DbgInfo );
1626 
1627 
1628  /* Make sure that user buffer can handle the driver identity structure. */
1629  if( urq->len < sizeof( lp->driverIdentity )) {
1630  urq->len = sizeof( lp->driverIdentity );
1631  urq->result = UIL_ERR_LEN;
1632  DBG_LEAVE( DbgInfo );
1633  return result;
1634  }
1635 
1636  /* Verify the user buffer. */
1637  result = verify_area( VERIFY_WRITE, urq->data, sizeof( lp->driverIdentity ));
1638  if( result != 0 ) {
1639  urq->result = UIL_FAILURE;
1640  DBG_LEAVE( DbgInfo );
1641  return result;
1642  }
1643 
1644  /* Copy the driver identity into the user's buffer. */
1645  urq->result = UIL_SUCCESS;
1646  copy_to_user( urq->data, &( lp->driverIdentity ), sizeof( lp->driverIdentity ));
1647 
1648  DBG_LEAVE( DbgInfo );
1649  return result;
1650 } // cfg_driver_identity
1651 /*============================================================================*/
1652 
1653 
1654 #endif /* USE_UIL */
1655 
1656 
1657 /* If WIRELESS_EXT is not defined, then the functions that follow will not be
1658  included in the build. */
1659 /* NOTE: Are these still even needed? */
1660 #ifdef WIRELESS_EXT
1661 
1662 
1663 /*******************************************************************************
1664  * wvlan_set_netname()
1665  *******************************************************************************
1666  *
1667  * DESCRIPTION:
1668  *
1669  * Set the ESSID of the card.
1670  *
1671  * PARAMETERS:
1672  *
1673  * wrq - a pointer to the wireless request buffer
1674  * lp - a pointer to the device's private adapter structure
1675  *
1676  * RETURNS:
1677  *
1678  * 0 on success
1679  * errno value otherwise
1680  *
1681  ******************************************************************************/
1682 int wvlan_set_netname(struct net_device *dev,
1683  struct iw_request_info *info,
1684  union iwreq_data *wrqu,
1685  char *extra)
1686 {
1687  struct wl_private *lp = wl_priv(dev);
1688  unsigned long flags;
1689  int ret = 0;
1690  /*------------------------------------------------------------------------*/
1691 
1692 
1693  DBG_FUNC( "wvlan_set_netname" );
1694  DBG_ENTER( DbgInfo );
1695 
1696  wl_lock(lp, &flags);
1697 
1698  memset( lp->NetworkName, 0, sizeof( lp->NetworkName ));
1699  memcpy( lp->NetworkName, extra, wrqu->data.length);
1700 
1701  /* Commit the adapter parameters */
1702  wl_apply(lp);
1703  wl_unlock(lp, &flags);
1704 
1705  DBG_LEAVE( DbgInfo );
1706  return ret;
1707 } // wvlan_set_netname
1708 /*============================================================================*/
1709 
1710 
1711 
1712 
1713 /*******************************************************************************
1714  * wvlan_get_netname()
1715  *******************************************************************************
1716  *
1717  * DESCRIPTION:
1718  *
1719  * Get the ESSID of the card.
1720  *
1721  * PARAMETERS:
1722  *
1723  * wrq - a pointer to the wireless request buffer
1724  * lp - a pointer to the device's private adapter structure
1725  *
1726  * RETURNS:
1727  *
1728  * 0 on success
1729  * errno value otherwise
1730  *
1731  ******************************************************************************/
1732 int wvlan_get_netname(struct net_device *dev,
1733  struct iw_request_info *info,
1734  union iwreq_data *wrqu,
1735  char *extra)
1736 {
1737  struct wl_private *lp = wl_priv(dev);
1738  unsigned long flags;
1739  int ret = 0;
1740  int status = -1;
1741  wvName_t *pName;
1742  /*------------------------------------------------------------------------*/
1743 
1744 
1745  DBG_FUNC( "wvlan_get_netname" );
1746  DBG_ENTER( DbgInfo );
1747 
1748  wl_lock(lp, &flags);
1749 
1750  /* Get the current network name */
1751  lp->ltvRecord.len = 1 + ( sizeof( *pName ) / sizeof( hcf_16 ));
1752  lp->ltvRecord.typ = CFG_CUR_SSID;
1753 
1754  status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1755 
1756  if( status == HCF_SUCCESS ) {
1757  pName = (wvName_t *)&( lp->ltvRecord.u.u32 );
1758 
1759  memset(extra, '\0', HCF_MAX_NAME_LEN);
1760  wrqu->data.length = pName->length;
1761 
1762  memcpy(extra, pName->name, pName->length);
1763  } else {
1764  ret = -EFAULT;
1765  }
1766 
1767  wl_unlock(lp, &flags);
1768 
1769  DBG_LEAVE( DbgInfo );
1770  return ret;
1771 } // wvlan_get_netname
1772 /*============================================================================*/
1773 
1774 
1775 
1776 
1777 /*******************************************************************************
1778  * wvlan_set_station_nickname()
1779  *******************************************************************************
1780  *
1781  * DESCRIPTION:
1782  *
1783  * Set the card's station nickname.
1784  *
1785  * PARAMETERS:
1786  *
1787  * wrq - a pointer to the wireless request buffer
1788  * lp - a pointer to the device's private adapter structure
1789  *
1790  * RETURNS:
1791  *
1792  * 0 on success
1793  * errno value otherwise
1794  *
1795  ******************************************************************************/
1796 int wvlan_set_station_nickname(struct net_device *dev,
1797  struct iw_request_info *info,
1798  union iwreq_data *wrqu,
1799  char *extra)
1800 {
1801  struct wl_private *lp = wl_priv(dev);
1802  unsigned long flags;
1803  int ret = 0;
1804  /*------------------------------------------------------------------------*/
1805 
1806 
1807  DBG_FUNC( "wvlan_set_station_nickname" );
1808  DBG_ENTER( DbgInfo );
1809 
1810  wl_lock(lp, &flags);
1811 
1812  memset( lp->StationName, 0, sizeof( lp->StationName ));
1813 
1814  memcpy( lp->StationName, extra, wrqu->data.length);
1815 
1816  /* Commit the adapter parameters */
1817  wl_apply( lp );
1818  wl_unlock(lp, &flags);
1819 
1820  DBG_LEAVE( DbgInfo );
1821  return ret;
1822 } // wvlan_set_station_nickname
1823 /*============================================================================*/
1824 
1825 
1826 
1827 
1828 /*******************************************************************************
1829  * wvlan_get_station_nickname()
1830  *******************************************************************************
1831  *
1832  * DESCRIPTION:
1833  *
1834  * Get the card's station nickname.
1835  *
1836  * PARAMETERS:
1837  *
1838  * wrq - a pointer to the wireless request buffer
1839  * lp - a pointer to the device's private adapter structure
1840  *
1841  * RETURNS:
1842  *
1843  * 0 on success
1844  * errno value otherwise
1845  *
1846  ******************************************************************************/
1847 int wvlan_get_station_nickname(struct net_device *dev,
1848  struct iw_request_info *info,
1849  union iwreq_data *wrqu,
1850  char *extra)
1851 {
1852  struct wl_private *lp = wl_priv(dev);
1853  unsigned long flags;
1854  int ret = 0;
1855  int status = -1;
1856  wvName_t *pName;
1857  /*------------------------------------------------------------------------*/
1858 
1859 
1860  DBG_FUNC( "wvlan_get_station_nickname" );
1861  DBG_ENTER( DbgInfo );
1862 
1863  wl_lock( lp, &flags );
1864 
1865  /* Get the current station name */
1866  lp->ltvRecord.len = 1 + ( sizeof( *pName ) / sizeof( hcf_16 ));
1868 
1869  status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1870 
1871  if( status == HCF_SUCCESS ) {
1872  pName = (wvName_t *)&( lp->ltvRecord.u.u32 );
1873 
1874  memset(extra, '\0', HCF_MAX_NAME_LEN);
1875  wrqu->data.length = pName->length;
1876  memcpy(extra, pName->name, pName->length);
1877  } else {
1878  ret = -EFAULT;
1879  }
1880 
1881  wl_unlock(lp, &flags);
1882 
1883 //out:
1884  DBG_LEAVE( DbgInfo );
1885  return ret;
1886 } // wvlan_get_station_nickname
1887 /*============================================================================*/
1888 
1889 
1890 
1891 
1892 /*******************************************************************************
1893  * wvlan_set_porttype()
1894  *******************************************************************************
1895  *
1896  * DESCRIPTION:
1897  *
1898  * Set the card's porttype
1899  *
1900  * PARAMETERS:
1901  *
1902  * wrq - a pointer to the wireless request buffer
1903  * lp - a pointer to the device's private adapter structure
1904  *
1905  * RETURNS:
1906  *
1907  * 0 on success
1908  * errno value otherwise
1909  *
1910  ******************************************************************************/
1911 int wvlan_set_porttype(struct net_device *dev,
1912  struct iw_request_info *info,
1913  union iwreq_data *wrqu,
1914  char *extra)
1915 {
1916  struct wl_private *lp = wl_priv(dev);
1917  unsigned long flags;
1918  int ret = 0;
1919  hcf_16 portType;
1920  /*------------------------------------------------------------------------*/
1921 
1922 
1923  DBG_FUNC( "wvlan_set_porttype" );
1924  DBG_ENTER( DbgInfo );
1925 
1926  wl_lock(lp, &flags);
1927 
1928  /* Validate the new value */
1929  portType = *((__u32 *)extra);
1930 
1931  if( !(( portType == 1 ) || ( portType == 3 ))) {
1932  ret = -EINVAL;
1933  goto out_unlock;
1934  }
1935 
1936  lp->PortType = portType;
1937 
1938  /* Commit the adapter parameters */
1939  wl_apply( lp );
1940 
1941 out_unlock:
1942  wl_unlock(lp, &flags);
1943 
1944 //out:
1945  DBG_LEAVE( DbgInfo );
1946  return ret;
1947 }
1948 
1949 /*============================================================================*/
1950 
1951 
1952 /*******************************************************************************
1953  * wvlan_get_porttype()
1954  *******************************************************************************
1955  *
1956  * DESCRIPTION:
1957  *
1958  * Get the card's porttype
1959  *
1960  * PARAMETERS:
1961  *
1962  * wrq - a pointer to the wireless request buffer
1963  * lp - a pointer to the device's private adapter structure
1964  *
1965  * RETURNS:
1966  *
1967  * 0 on success
1968  * errno value otherwise
1969  *
1970  ******************************************************************************/
1971 int wvlan_get_porttype(struct net_device *dev,
1972  struct iw_request_info *info,
1973  union iwreq_data *wrqu,
1974  char *extra)
1975 {
1976  struct wl_private *lp = wl_priv(dev);
1977  unsigned long flags;
1978  int ret = 0;
1979  int status = -1;
1980  hcf_16 *pPortType;
1981  __u32 *pData = (__u32 *)extra;
1982  /*------------------------------------------------------------------------*/
1983 
1984 
1985  DBG_FUNC( "wvlan_get_porttype" );
1986  DBG_ENTER( DbgInfo );
1987 
1988  wl_lock( lp, &flags );
1989 
1990  /* Get the current port type */
1991  lp->ltvRecord.len = 1 + ( sizeof( *pPortType ) / sizeof( hcf_16 ));
1993 
1994  status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord ));
1995 
1996  if( status == HCF_SUCCESS ) {
1997  pPortType = (hcf_16 *)&( lp->ltvRecord.u.u32 );
1998 
1999  *pData = CNV_LITTLE_TO_INT( *pPortType );
2000  } else {
2001  ret = -EFAULT;
2002  }
2003 
2004  wl_unlock(lp, &flags);
2005 
2006 //out:
2007  DBG_LEAVE( DbgInfo );
2008  return ret;
2009 } // wvlan_get_porttype
2010 /*============================================================================*/
2011 
2012 #endif // WIRELESS_EXT
2013 
2014 
2015 
2016 
2017 #ifdef USE_RTS
2018 /*******************************************************************************
2019  * wvlan_rts()
2020  *******************************************************************************
2021  *
2022  * DESCRIPTION:
2023  *
2024  * IOCTL handler for RTS commands
2025  *
2026  * PARAMETERS:
2027  *
2028  * rrq - a pointer to the rts request buffer
2029  * lp - a pointer to the device's private adapter structure
2030  *
2031  * RETURNS:
2032  *
2033  * 0 on success
2034  * errno value otherwise
2035  *
2036  ******************************************************************************/
2037 int wvlan_rts( struct rtsreq *rrq, __u32 io_base )
2038 {
2039  int ioctl_ret = 0;
2040  /*------------------------------------------------------------------------*/
2041 
2042 
2043  DBG_FUNC( "wvlan_rts" );
2044  DBG_ENTER( DbgInfo );
2045 
2046 
2047  DBG_PRINT( "io_base: 0x%08x\n", io_base );
2048 
2049  switch( rrq->typ ) {
2050  case WL_IOCTL_RTS_READ:
2051  DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_READ\n");
2052  rrq->data[0] = IN_PORT_WORD( io_base + rrq->reg );
2053  DBG_TRACE( DbgInfo, " reg 0x%04x ==> 0x%04x\n", rrq->reg, CNV_LITTLE_TO_SHORT( rrq->data[0] ) );
2054  break;
2055  case WL_IOCTL_RTS_WRITE:
2056  DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_WRITE\n");
2057  OUT_PORT_WORD( io_base + rrq->reg, rrq->data[0] );
2058  DBG_TRACE( DbgInfo, " reg 0x%04x <== 0x%04x\n", rrq->reg, CNV_LITTLE_TO_SHORT( rrq->data[0] ) );
2059  break;
2061  DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_BATCH_READ\n");
2062  IN_PORT_STRING_16( io_base + rrq->reg, rrq->data, rrq->len );
2063  DBG_TRACE( DbgInfo, " reg 0x%04x ==> %d bytes\n", rrq->reg, rrq->len * sizeof (__u16 ) );
2064  break;
2066  DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_BATCH_WRITE\n");
2067  OUT_PORT_STRING_16( io_base + rrq->reg, rrq->data, rrq->len );
2068  DBG_TRACE( DbgInfo, " reg 0x%04x <== %d bytes\n", rrq->reg, rrq->len * sizeof (__u16) );
2069  break;
2070  default:
2071 
2072  DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- UNSUPPORTED RTS CODE: 0x%X", rrq->typ );
2073  ioctl_ret = -EOPNOTSUPP;
2074  break;
2075  }
2076 
2077  DBG_LEAVE( DbgInfo );
2078  return ioctl_ret;
2079 } // wvlan_rts
2080 /*============================================================================*/
2081 
2082 #endif /* USE_RTS */