| /******************************************************************************* |
| * Agere Systems Inc. |
| * Wireless device driver for Linux (wlags49). |
| * |
| * Copyright (c) 1998-2003 Agere Systems Inc. |
| * All rights reserved. |
| * http://www.agere.com |
| * |
| * Initially developed by TriplePoint, Inc. |
| * http://www.triplepoint.com |
| * |
| *------------------------------------------------------------------------------ |
| * |
| * This file defines handling routines for the private IOCTLs |
| * |
| *------------------------------------------------------------------------------ |
| * |
| * SOFTWARE LICENSE |
| * |
| * This software is provided subject to the following terms and conditions, |
| * which you should read carefully before using the software. Using this |
| * software indicates your acceptance of these terms and conditions. If you do |
| * not agree with these terms and conditions, do not use the software. |
| * |
| * Copyright © 2003 Agere Systems Inc. |
| * All rights reserved. |
| * |
| * Redistribution and use in source or binary forms, with or without |
| * modifications, are permitted provided that the following conditions are met: |
| * |
| * . Redistributions of source code must retain the above copyright notice, this |
| * list of conditions and the following Disclaimer as comments in the code as |
| * well as in the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * . Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following Disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * . Neither the name of Agere Systems Inc. nor the names of the contributors |
| * may be used to endorse or promote products derived from this software |
| * without specific prior written permission. |
| * |
| * Disclaimer |
| * |
| * THIS SOFTWARE IS PROVIDED AS IS AND ANY EXPRESS OR IMPLIED WARRANTIES, |
| * INCLUDING, BUT NOT LIMITED TO, INFRINGEMENT AND THE IMPLIED WARRANTIES OF |
| * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ANY |
| * USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE IS SOLELY AT THE USERS OWN |
| * RISK. IN NO EVENT SHALL AGERE SYSTEMS INC. OR CONTRIBUTORS BE LIABLE FOR ANY |
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, INCLUDING, BUT NOT LIMITED TO, CONTRACT, STRICT |
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
| * DAMAGE. |
| * |
| ******************************************************************************/ |
| |
| /******************************************************************************* |
| * include files |
| ******************************************************************************/ |
| #include <wl_version.h> |
| |
| #include <linux/if_arp.h> |
| #include <linux/ioport.h> |
| #include <linux/slab.h> |
| #include <linux/delay.h> |
| #include <asm/uaccess.h> |
| |
| #include <debug.h> |
| #include <hcf.h> |
| #include <hcfdef.h> |
| |
| #include <wl_if.h> |
| #include <wl_internal.h> |
| #include <wl_enc.h> |
| #include <wl_main.h> |
| #include <wl_priv.h> |
| #include <wl_util.h> |
| #include <wl_netdev.h> |
| |
| int wvlan_uil_connect( struct uilreq *urq, struct wl_private *lp ); |
| int wvlan_uil_disconnect( struct uilreq *urq, struct wl_private *lp ); |
| int wvlan_uil_action( struct uilreq *urq, struct wl_private *lp ); |
| int wvlan_uil_block( struct uilreq *urq, struct wl_private *lp ); |
| int wvlan_uil_unblock( struct uilreq *urq, struct wl_private *lp ); |
| int wvlan_uil_send_diag_msg( struct uilreq *urq, struct wl_private *lp ); |
| int wvlan_uil_put_info( struct uilreq *urq, struct wl_private *lp ); |
| int wvlan_uil_get_info( struct uilreq *urq, struct wl_private *lp ); |
| |
| int cfg_driver_info( struct uilreq *urq, struct wl_private *lp ); |
| int cfg_driver_identity( struct uilreq *urq, struct wl_private *lp ); |
| |
| |
| /******************************************************************************* |
| * global variables |
| ******************************************************************************/ |
| #if DBG |
| extern dbg_info_t *DbgInfo; |
| #endif // DBG |
| |
| |
| |
| |
| /* If USE_UIL is not defined, then none of the UIL Interface code below will |
| be included in the build */ |
| #ifdef USE_UIL |
| |
| /******************************************************************************* |
| * wvlan_uil() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * The handler function for the UIL interface. |
| * |
| * PARAMETERS: |
| * |
| * urq - a pointer to the UIL request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * 0 on success |
| * errno value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_uil( struct uilreq *urq, struct wl_private *lp ) |
| { |
| int ioctl_ret = 0; |
| /*------------------------------------------------------------------------*/ |
| |
| DBG_FUNC( "wvlan_uil" ); |
| DBG_ENTER( DbgInfo ); |
| |
| switch( urq->command ) { |
| case UIL_FUN_CONNECT: |
| DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_CONNECT\n"); |
| ioctl_ret = wvlan_uil_connect( urq, lp ); |
| break; |
| case UIL_FUN_DISCONNECT: |
| DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_DISCONNECT\n"); |
| ioctl_ret = wvlan_uil_disconnect( urq, lp ); |
| break; |
| case UIL_FUN_ACTION: |
| DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_ACTION\n" ); |
| ioctl_ret = wvlan_uil_action( urq, lp ); |
| break; |
| case UIL_FUN_SEND_DIAG_MSG: |
| DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_SEND_DIAG_MSG\n"); |
| ioctl_ret = wvlan_uil_send_diag_msg( urq, lp ); |
| break; |
| case UIL_FUN_GET_INFO: |
| DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_GET_INFO\n"); |
| ioctl_ret = wvlan_uil_get_info( urq, lp ); |
| break; |
| case UIL_FUN_PUT_INFO: |
| DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- WVLAN2_UIL_PUT_INFO\n"); |
| ioctl_ret = wvlan_uil_put_info( urq, lp ); |
| break; |
| default: |
| DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_UIL -- UNSUPPORTED UIL CODE: 0x%X", urq->command ); |
| ioctl_ret = -EOPNOTSUPP; |
| break; |
| } |
| DBG_LEAVE( DbgInfo ); |
| return ioctl_ret; |
| } // wvlan_uil |
| /*============================================================================*/ |
| |
| |
| |
| |
| /******************************************************************************* |
| * wvlan_uil_connect() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Connect to the UIL in order to make a request. |
| * |
| * PARAMETERS: |
| * |
| * urq - a pointer to the UIL request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * UIL_SUCCESS |
| * UIL_ERR_xxx value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_uil_connect( struct uilreq *urq, struct wl_private *lp ) |
| { |
| int result = 0; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_uil_connect" ); |
| DBG_ENTER( DbgInfo ); |
| |
| |
| if( !( lp->flags & WVLAN2_UIL_CONNECTED )) { |
| lp->flags |= WVLAN2_UIL_CONNECTED; |
| urq->hcfCtx = &( lp->hcfCtx ); |
| urq->result = UIL_SUCCESS; |
| } else { |
| DBG_WARNING( DbgInfo, "UIL_ERR_IN_USE\n" ); |
| urq->result = UIL_ERR_IN_USE; |
| } |
| |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } // wvlan_uil_connect |
| /*============================================================================*/ |
| |
| |
| |
| |
| /******************************************************************************* |
| * wvlan_uil_disconnect() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Disonnect from the UIL after a request has been completed. |
| * |
| * PARAMETERS: |
| * |
| * urq - a pointer to the UIL request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * UIL_SUCCESS |
| * UIL_ERR_xxx value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_uil_disconnect( struct uilreq *urq, struct wl_private *lp ) |
| { |
| int result = 0; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_uil_disconnect" ); |
| DBG_ENTER( DbgInfo ); |
| |
| |
| if( urq->hcfCtx == &( lp->hcfCtx )) { |
| if (lp->flags & WVLAN2_UIL_CONNECTED) { |
| lp->flags &= ~WVLAN2_UIL_CONNECTED; |
| /* |
| if (lp->flags & WVLAN2_UIL_BUSY) { |
| lp->flags &= ~WVLAN2_UIL_BUSY; |
| netif_start_queue(lp->dev); |
| } |
| */ |
| } |
| |
| urq->hcfCtx = NULL; |
| urq->result = UIL_SUCCESS; |
| } else { |
| DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" ); |
| urq->result = UIL_ERR_WRONG_IFB; |
| } |
| |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } // wvlan_uil_disconnect |
| /*============================================================================*/ |
| |
| |
| |
| |
| /******************************************************************************* |
| * wvlan_uil_action() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Handler for the UIL_ACT_xxx subcodes associated with UIL_FUN_ACTION |
| * |
| * PARAMETERS: |
| * |
| * urq - a pointer to the UIL request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * UIL_SUCCESS |
| * UIL_ERR_xxx value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_uil_action( struct uilreq *urq, struct wl_private *lp ) |
| { |
| int result = 0; |
| ltv_t *ltv; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_uil_action" ); |
| DBG_ENTER( DbgInfo ); |
| |
| |
| if( urq->hcfCtx == &( lp->hcfCtx )) { |
| /* Make sure there's an LTV in the request buffer */ |
| ltv = (ltv_t *)urq->data; |
| if( ltv != NULL ) { |
| /* Switch on the Type field of the LTV contained in the request |
| buffer */ |
| switch( ltv->typ ) { |
| case UIL_ACT_BLOCK: |
| DBG_TRACE( DbgInfo, "UIL_ACT_BLOCK\n" ); |
| result = wvlan_uil_block( urq, lp ); |
| break; |
| case UIL_ACT_UNBLOCK: |
| DBG_TRACE( DbgInfo, "UIL_ACT_UNBLOCK\n" ); |
| result = wvlan_uil_unblock( urq, lp ); |
| break; |
| case UIL_ACT_SCAN: |
| DBG_TRACE( DbgInfo, "UIL_ACT_SCAN\n" ); |
| urq->result = hcf_action( &( lp->hcfCtx ), MDD_ACT_SCAN ); |
| break; |
| case UIL_ACT_APPLY: |
| DBG_TRACE( DbgInfo, "UIL_ACT_APPLY\n" ); |
| urq->result = wl_apply( lp ); |
| break; |
| case UIL_ACT_RESET: |
| DBG_TRACE( DbgInfo, "UIL_ACT_RESET\n" ); |
| urq->result = wl_go( lp ); |
| break; |
| default: |
| DBG_WARNING( DbgInfo, "Unknown action code: 0x%x\n", ltv->typ ); |
| break; |
| } |
| } else { |
| DBG_ERROR( DbgInfo, "Bad LTV for this action\n" ); |
| urq->result = UIL_ERR_LEN; |
| } |
| } else { |
| DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" ); |
| urq->result = UIL_ERR_WRONG_IFB; |
| } |
| |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } // wvlan_uil_action |
| /*============================================================================*/ |
| |
| |
| |
| |
| /******************************************************************************* |
| * wvlan_uil_block() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Sets a block in the driver to prevent access to the card by other |
| * processes. |
| * |
| * PARAMETERS: |
| * |
| * urq - a pointer to the UIL request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * UIL_SUCCESS |
| * UIL_ERR_xxx value otherwise |
| * |
| ******************************************************************************/ |
| |
| int wvlan_uil_block( struct uilreq *urq, struct wl_private *lp ) |
| { |
| int result = 0; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_uil_block" ); |
| DBG_ENTER( DbgInfo ); |
| |
| if( urq->hcfCtx == &( lp->hcfCtx )) { |
| if( capable( CAP_NET_ADMIN )) { |
| lp->flags |= WVLAN2_UIL_BUSY; |
| netif_stop_queue(lp->dev); |
| WL_WDS_NETIF_STOP_QUEUE( lp ); |
| urq->result = UIL_SUCCESS; |
| } else { |
| DBG_ERROR( DbgInfo, "EPERM\n" ); |
| urq->result = UIL_FAILURE; |
| result = -EPERM; |
| } |
| } else { |
| DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" ); |
| urq->result = UIL_ERR_WRONG_IFB; |
| } |
| |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } // wvlan_uil_block |
| /*============================================================================*/ |
| |
| |
| |
| |
| /******************************************************************************* |
| * wvlan_uil_unblock() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Unblocks the driver to restore access to the card by other processes. |
| * |
| * PARAMETERS: |
| * |
| * urq - a pointer to the UIL request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * UIL_SUCCESS |
| * UIL_ERR_xxx value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_uil_unblock( struct uilreq *urq, struct wl_private *lp ) |
| { |
| int result = 0; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_uil_unblock" ); |
| DBG_ENTER( DbgInfo ); |
| |
| if( urq->hcfCtx == &( lp->hcfCtx )) { |
| if( capable( CAP_NET_ADMIN )) { |
| if (lp->flags & WVLAN2_UIL_BUSY) { |
| lp->flags &= ~WVLAN2_UIL_BUSY; |
| netif_wake_queue(lp->dev); |
| WL_WDS_NETIF_WAKE_QUEUE( lp ); |
| } |
| } else { |
| DBG_ERROR( DbgInfo, "EPERM\n" ); |
| urq->result = UIL_FAILURE; |
| result = -EPERM; |
| } |
| } else { |
| DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" ); |
| urq->result = UIL_ERR_WRONG_IFB; |
| } |
| |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } // wvlan_uil_unblock |
| /*============================================================================*/ |
| |
| |
| |
| |
| /******************************************************************************* |
| * wvlan_uil_send_diag_msg() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Sends a diagnostic message to the card. |
| * |
| * PARAMETERS: |
| * |
| * urq - a pointer to the UIL request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * UIL_SUCCESS |
| * UIL_ERR_xxx value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_uil_send_diag_msg( struct uilreq *urq, struct wl_private *lp ) |
| { |
| int result = 0; |
| DESC_STRCT Descp[1]; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_uil_send_diag_msg" ); |
| DBG_ENTER( DbgInfo ); |
| |
| if( urq->hcfCtx == &( lp->hcfCtx )) { |
| if( capable( CAP_NET_ADMIN )) { |
| if ((urq->data != NULL) && (urq->len != 0)) { |
| if (lp->hcfCtx.IFB_RscInd != 0) { |
| u_char *data; |
| |
| // Verify the user buffer |
| result = verify_area(VERIFY_READ, urq->data, urq->len); |
| if (result != 0) { |
| DBG_ERROR( DbgInfo, "verify_area failed, result: %d\n", result ); |
| urq->result = UIL_FAILURE; |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } |
| |
| data = kmalloc(urq->len, GFP_KERNEL); |
| if (data != NULL) { |
| memset( Descp, 0, sizeof( DESC_STRCT )); |
| memcpy( data, urq->data, urq->len ); |
| |
| Descp[0].buf_addr = (wci_bufp)data; |
| Descp[0].BUF_CNT = urq->len; |
| Descp[0].next_desc_addr = 0; // terminate list |
| |
| hcf_send_msg( &(lp->hcfCtx), &Descp[0], HCF_PORT_0 ); |
| kfree( data ); |
| } else { |
| DBG_ERROR( DbgInfo, "ENOMEM\n" ); |
| urq->result = UIL_FAILURE; |
| result = -ENOMEM; |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } |
| |
| } else { |
| urq->result = UIL_ERR_BUSY; |
| } |
| |
| } else { |
| urq->result = UIL_FAILURE; |
| } |
| } else { |
| DBG_ERROR( DbgInfo, "EPERM\n" ); |
| urq->result = UIL_FAILURE; |
| result = -EPERM; |
| } |
| } else { |
| DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" ); |
| urq->result = UIL_ERR_WRONG_IFB; |
| } |
| |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } // wvlan_uil_send_diag_msg |
| /*============================================================================*/ |
| |
| |
| /******************************************************************************* |
| * wvlan_uil_put_info() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Sends a specific RID directly to the driver to set configuration info. |
| * |
| * PARAMETERS: |
| * |
| * urq - a pointer to the UIL request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * UIL_SUCCESS |
| * UIL_ERR_xxx value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_uil_put_info( struct uilreq *urq, struct wl_private *lp ) |
| { |
| int result = 0; |
| ltv_t *pLtv; |
| bool_t ltvAllocated = FALSE; |
| ENCSTRCT sEncryption; |
| |
| #ifdef USE_WDS |
| hcf_16 hcfPort = HCF_PORT_0; |
| #endif /* USE_WDS */ |
| /*------------------------------------------------------------------------*/ |
| DBG_FUNC( "wvlan_uil_put_info" ); |
| DBG_ENTER( DbgInfo ); |
| |
| |
| if( urq->hcfCtx == &( lp->hcfCtx )) { |
| if( capable( CAP_NET_ADMIN )) { |
| if(( urq->data != NULL ) && ( urq->len != 0 )) { |
| /* Make sure that we have at least a command and length to send. */ |
| if( urq->len < ( sizeof( hcf_16 ) * 2 )) { |
| urq->len = sizeof( lp->ltvRecord ); |
| urq->result = UIL_ERR_LEN; |
| DBG_ERROR( DbgInfo, "No Length/Type in LTV!!!\n" ); |
| DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" ); |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } |
| |
| /* Verify the user buffer */ |
| result = verify_area( VERIFY_READ, urq->data, urq->len ); |
| if( result != 0 ) { |
| urq->result = UIL_FAILURE; |
| DBG_ERROR( DbgInfo, "verify_area(), VERIFY_READ FAILED\n" ); |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } |
| |
| /* Get only the command and length information. */ |
| copy_from_user( &( lp->ltvRecord ), urq->data, sizeof( hcf_16 ) * 2 ); |
| |
| /* Make sure the incoming LTV record length is within the bounds of the |
| IOCTL length */ |
| if((( lp->ltvRecord.len + 1 ) * sizeof( hcf_16 )) > urq->len ) { |
| urq->len = sizeof( lp->ltvRecord ); |
| urq->result = UIL_ERR_LEN; |
| DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" ); |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } |
| |
| /* If the requested length is greater than the size of our local |
| LTV record, try to allocate it from the kernel stack. |
| Otherwise, we just use our local LTV record. */ |
| if( urq->len > sizeof( lp->ltvRecord )) { |
| pLtv = kmalloc(urq->len, GFP_KERNEL); |
| if (pLtv != NULL) { |
| ltvAllocated = TRUE; |
| } else { |
| DBG_ERROR( DbgInfo, "Alloc FAILED\n" ); |
| urq->len = sizeof( lp->ltvRecord ); |
| urq->result = UIL_ERR_LEN; |
| result = -ENOMEM; |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } |
| } else { |
| pLtv = &( lp->ltvRecord ); |
| } |
| |
| /* Copy the data from the user's buffer into the local LTV |
| record data area. */ |
| copy_from_user( pLtv, urq->data, urq->len ); |
| |
| |
| /* We need to snoop the commands to see if there is anything we |
| need to store for the purposes of a reset or start/stop |
| sequence. Perform endian translation as needed */ |
| switch( pLtv->typ ) { |
| case CFG_CNF_PORT_TYPE: |
| lp->PortType = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_CNF_OWN_MAC_ADDR: |
| /* TODO: determine if we are going to store anything based on this */ |
| break; |
| case CFG_CNF_OWN_CHANNEL: |
| lp->Channel = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| /* CFG_CNF_OWN_SSID currently same as CNF_DESIRED_SSID. Do we |
| need separate storage for this? */ |
| //case CFG_CNF_OWN_SSID: |
| case CFG_CNF_OWN_ATIM_WINDOW: |
| lp->atimWindow = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_CNF_SYSTEM_SCALE: |
| lp->DistanceBetweenAPs = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| |
| case CFG_CNF_MAX_DATA_LEN: |
| /* TODO: determine if we are going to store anything based |
| on this */ |
| break; |
| case CFG_CNF_PM_ENABLED: |
| lp->PMEnabled = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_CNF_MCAST_RX: |
| lp->MulticastReceive = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_CNF_MAX_SLEEP_DURATION: |
| lp->MaxSleepDuration = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_CNF_HOLDOVER_DURATION: |
| lp->holdoverDuration = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_CNF_OWN_NAME: |
| memset( lp->StationName, 0, sizeof( lp->StationName )); |
| memcpy( (void *)lp->StationName, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0]); |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_CNF_LOAD_BALANCING: |
| lp->loadBalancing = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_CNF_MEDIUM_DISTRIBUTION: |
| lp->mediumDistribution = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| #ifdef WARP |
| case CFG_CNF_TX_POW_LVL: |
| lp->txPowLevel = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| //case CFG_CNF_SHORT_RETRY_LIMIT: // Short Retry Limit |
| //case 0xFC33: // Long Retry Limit |
| case CFG_SUPPORTED_RATE_SET_CNTL: // Supported Rate Set Control |
| lp->srsc[0] = pLtv->u.u16[0]; |
| lp->srsc[1] = pLtv->u.u16[1]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| pLtv->u.u16[1] = CNV_INT_TO_LITTLE( pLtv->u.u16[1] ); |
| break; |
| case CFG_BASIC_RATE_SET_CNTL: // Basic Rate Set Control |
| lp->brsc[0] = pLtv->u.u16[0]; |
| lp->brsc[1] = pLtv->u.u16[1]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| pLtv->u.u16[1] = CNV_INT_TO_LITTLE( pLtv->u.u16[1] ); |
| break; |
| case CFG_CNF_CONNECTION_CNTL: |
| lp->connectionControl = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| //case CFG_PROBE_DATA_RATE: |
| #endif // HERMES25 |
| |
| #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP |
| //;?should we restore this to allow smaller memory footprint |
| |
| case CFG_CNF_OWN_DTIM_PERIOD: |
| lp->DTIMPeriod = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| #ifdef WARP |
| case CFG_CNF_OWN_BEACON_INTERVAL: // Own Beacon Interval |
| lp->ownBeaconInterval = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| #endif // WARP |
| case CFG_COEXISTENSE_BEHAVIOUR: // Coexistence behavior |
| lp->coexistence = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| #ifdef USE_WDS |
| case CFG_CNF_WDS_ADDR1: |
| memcpy( &lp->wds_port[0].wdsAddress, &pLtv->u.u8[0], ETH_ALEN ); |
| hcfPort = HCF_PORT_1; |
| break; |
| case CFG_CNF_WDS_ADDR2: |
| memcpy( &lp->wds_port[1].wdsAddress, &pLtv->u.u8[0], ETH_ALEN ); |
| hcfPort = HCF_PORT_2; |
| break; |
| case CFG_CNF_WDS_ADDR3: |
| memcpy( &lp->wds_port[2].wdsAddress, &pLtv->u.u8[0], ETH_ALEN ); |
| hcfPort = HCF_PORT_3; |
| break; |
| case CFG_CNF_WDS_ADDR4: |
| memcpy( &lp->wds_port[3].wdsAddress, &pLtv->u.u8[0], ETH_ALEN ); |
| hcfPort = HCF_PORT_4; |
| break; |
| case CFG_CNF_WDS_ADDR5: |
| memcpy( &lp->wds_port[4].wdsAddress, &pLtv->u.u8[0], ETH_ALEN ); |
| hcfPort = HCF_PORT_5; |
| break; |
| case CFG_CNF_WDS_ADDR6: |
| memcpy( &lp->wds_port[5].wdsAddress, &pLtv->u.u8[0], ETH_ALEN ); |
| hcfPort = HCF_PORT_6; |
| break; |
| #endif /* USE_WDS */ |
| |
| case CFG_CNF_MCAST_PM_BUF: |
| lp->multicastPMBuffering = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_CNF_REJECT_ANY: |
| lp->RejectAny = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| #endif |
| |
| case CFG_CNF_ENCRYPTION: |
| lp->EnableEncryption = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_CNF_AUTHENTICATION: |
| lp->authentication = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP |
| //;?should we restore this to allow smaller memory footprint |
| |
| //case CFG_CNF_EXCL_UNENCRYPTED: |
| //lp->ExcludeUnencrypted = pLtv->u.u16[0]; |
| //pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| //break; |
| case CFG_CNF_MCAST_RATE: |
| /* TODO: determine if we are going to store anything based on this */ |
| break; |
| case CFG_CNF_INTRA_BSS_RELAY: |
| lp->intraBSSRelay = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| #endif |
| |
| case CFG_CNF_MICRO_WAVE: |
| /* TODO: determine if we are going to store anything based on this */ |
| break; |
| //case CFG_CNF_LOAD_BALANCING: |
| /* TODO: determine if we are going to store anything based on this */ |
| //break; |
| //case CFG_CNF_MEDIUM_DISTRIBUTION: |
| /* TODO: determine if we are going to store anything based on this */ |
| //break; |
| //case CFG_CNF_RX_ALL_GROUP_ADDRESS: |
| // TODO: determine if we are going to store anything based on this |
| //break; |
| //case CFG_CNF_COUNTRY_INFO: |
| /* TODO: determine if we are going to store anything based on this */ |
| //break; |
| case CFG_CNF_OWN_SSID: |
| //case CNF_DESIRED_SSID: |
| case CFG_DESIRED_SSID: |
| memset( lp->NetworkName, 0, sizeof( lp->NetworkName )); |
| memcpy( (void *)lp->NetworkName, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0] ); |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| |
| /* take care of the special network name "ANY" case */ |
| if(( strlen( &pLtv->u.u8[2] ) == 0 ) || |
| ( strcmp( &pLtv->u.u8[2], "ANY" ) == 0 ) || |
| ( strcmp( &pLtv->u.u8[2], "any" ) == 0 )) { |
| /* set the SSID_STRCT llen field (u16[0]) to zero, and the |
| effectually null the string u8[2] */ |
| pLtv->u.u16[0] = 0; |
| pLtv->u.u8[2] = 0; |
| } |
| break; |
| case CFG_GROUP_ADDR: |
| /* TODO: determine if we are going to store anything based on this */ |
| break; |
| case CFG_CREATE_IBSS: |
| lp->CreateIBSS = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_RTS_THRH: |
| lp->RTSThreshold = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_TX_RATE_CNTL: |
| lp->TxRateControl[0] = pLtv->u.u16[0]; |
| lp->TxRateControl[1] = pLtv->u.u16[1]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| pLtv->u.u16[1] = CNV_INT_TO_LITTLE( pLtv->u.u16[1] ); |
| break; |
| case CFG_PROMISCUOUS_MODE: |
| /* TODO: determine if we are going to store anything based on this */ |
| break; |
| //case CFG_WAKE_ON_LAN: |
| /* TODO: determine if we are going to store anything based on this */ |
| //break; |
| #if 1 //;? #if (HCF_TYPE) & HCF_TYPE_AP |
| //;?should we restore this to allow smaller memory footprint |
| case CFG_RTS_THRH0: |
| lp->RTSThreshold = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_TX_RATE_CNTL0: |
| //;?no idea what this should be, get going so comment it out lp->TxRateControl = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| #ifdef USE_WDS |
| case CFG_RTS_THRH1: |
| lp->wds_port[0].rtsThreshold = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| hcfPort = HCF_PORT_1; |
| break; |
| case CFG_RTS_THRH2: |
| lp->wds_port[1].rtsThreshold = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| hcfPort = HCF_PORT_2; |
| break; |
| case CFG_RTS_THRH3: |
| lp->wds_port[2].rtsThreshold = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| hcfPort = HCF_PORT_3; |
| break; |
| case CFG_RTS_THRH4: |
| lp->wds_port[3].rtsThreshold = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| hcfPort = HCF_PORT_4; |
| break; |
| case CFG_RTS_THRH5: |
| lp->wds_port[4].rtsThreshold = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| hcfPort = HCF_PORT_5; |
| break; |
| case CFG_RTS_THRH6: |
| lp->wds_port[5].rtsThreshold = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| hcfPort = HCF_PORT_6; |
| break; |
| case CFG_TX_RATE_CNTL1: |
| lp->wds_port[0].txRateCntl = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| hcfPort = HCF_PORT_1; |
| break; |
| case CFG_TX_RATE_CNTL2: |
| lp->wds_port[1].txRateCntl = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| hcfPort = HCF_PORT_2; |
| break; |
| case CFG_TX_RATE_CNTL3: |
| lp->wds_port[2].txRateCntl = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| hcfPort = HCF_PORT_3; |
| break; |
| case CFG_TX_RATE_CNTL4: |
| lp->wds_port[3].txRateCntl = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| hcfPort = HCF_PORT_4; |
| break; |
| case CFG_TX_RATE_CNTL5: |
| lp->wds_port[4].txRateCntl = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| hcfPort = HCF_PORT_5; |
| break; |
| case CFG_TX_RATE_CNTL6: |
| lp->wds_port[5].txRateCntl = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| hcfPort = HCF_PORT_6; |
| break; |
| #endif /* USE_WDS */ |
| #endif /* (HCF_TYPE) & HCF_TYPE_AP */ |
| |
| case CFG_DEFAULT_KEYS: |
| { |
| CFG_DEFAULT_KEYS_STRCT *pKeys = (CFG_DEFAULT_KEYS_STRCT *)pLtv; |
| |
| pKeys->key[0].len = CNV_INT_TO_LITTLE( pKeys->key[0].len ); |
| pKeys->key[1].len = CNV_INT_TO_LITTLE( pKeys->key[1].len ); |
| pKeys->key[2].len = CNV_INT_TO_LITTLE( pKeys->key[2].len ); |
| pKeys->key[3].len = CNV_INT_TO_LITTLE( pKeys->key[3].len ); |
| |
| memcpy( (void *)&(lp->DefaultKeys), (void *)pKeys, |
| sizeof( CFG_DEFAULT_KEYS_STRCT )); |
| } |
| break; |
| case CFG_TX_KEY_ID: |
| lp->TransmitKeyID = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_SCAN_SSID: |
| /* TODO: determine if we are going to store anything based on this */ |
| break; |
| case CFG_TICK_TIME: |
| /* TODO: determine if we are going to store anything based on this */ |
| break; |
| /* these RIDS are Info RIDs, and should they be allowed for puts??? */ |
| case CFG_MAX_LOAD_TIME: |
| case CFG_DL_BUF: |
| //case CFG_HSI_SUP_RANGE: |
| case CFG_NIC_SERIAL_NUMBER: |
| case CFG_NIC_IDENTITY: |
| case CFG_NIC_MFI_SUP_RANGE: |
| case CFG_NIC_CFI_SUP_RANGE: |
| case CFG_NIC_TEMP_TYPE: |
| case CFG_NIC_PROFILE: |
| case CFG_FW_IDENTITY: |
| case CFG_FW_SUP_RANGE: |
| case CFG_MFI_ACT_RANGES_STA: |
| case CFG_CFI_ACT_RANGES_STA: |
| case CFG_PORT_STAT: |
| case CFG_CUR_SSID: |
| case CFG_CUR_BSSID: |
| case CFG_COMMS_QUALITY: |
| case CFG_CUR_TX_RATE: |
| case CFG_CUR_BEACON_INTERVAL: |
| case CFG_CUR_SCALE_THRH: |
| case CFG_PROTOCOL_RSP_TIME: |
| case CFG_CUR_SHORT_RETRY_LIMIT: |
| case CFG_CUR_LONG_RETRY_LIMIT: |
| case CFG_MAX_TX_LIFETIME: |
| case CFG_MAX_RX_LIFETIME: |
| case CFG_CF_POLLABLE: |
| case CFG_AUTHENTICATION_ALGORITHMS: |
| case CFG_PRIVACY_OPT_IMPLEMENTED: |
| //case CFG_CURRENT_REMOTE_RATES: |
| //case CFG_CURRENT_USED_RATES: |
| //case CFG_CURRENT_SYSTEM_SCALE: |
| //case CFG_CURRENT_TX_RATE1: |
| //case CFG_CURRENT_TX_RATE2: |
| //case CFG_CURRENT_TX_RATE3: |
| //case CFG_CURRENT_TX_RATE4: |
| //case CFG_CURRENT_TX_RATE5: |
| //case CFG_CURRENT_TX_RATE6: |
| case CFG_NIC_MAC_ADDR: |
| case CFG_PCF_INFO: |
| //case CFG_CURRENT_COUNTRY_INFO: |
| case CFG_PHY_TYPE: |
| case CFG_CUR_CHANNEL: |
| //case CFG_CURRENT_POWER_STATE: |
| //case CFG_CCAMODE: |
| case CFG_SUPPORTED_DATA_RATES: |
| break; |
| case CFG_AP_MODE: |
| //;? lp->DownloadFirmware = ( pLtv->u.u16[0] ) + 1; |
| DBG_ERROR( DbgInfo, "set CFG_AP_MODE no longer supported\n" ); |
| break; |
| case CFG_ENCRYPT_STRING: |
| /* TODO: ENDIAN TRANSLATION HERE??? */ |
| memset( lp->szEncryption, 0, sizeof( lp->szEncryption )); |
| memcpy( (void *)lp->szEncryption, (void *)&pLtv->u.u8[0], |
| ( pLtv->len * sizeof( hcf_16 )) ); |
| wl_wep_decode( CRYPT_CODE, &sEncryption, |
| lp->szEncryption ); |
| |
| /* the Linux driver likes to use 1-4 for the key IDs, and then |
| convert to 0-3 when sending to the card. The Windows code |
| base used 0-3 in the API DLL, which was ported to Linux. For |
| the sake of the user experience, we decided to keep 0-3 as the |
| numbers used in the DLL; and will perform the +1 conversion here. |
| We could have converted the entire Linux driver, but this is |
| less obtrusive. This may be a "todo" to convert the whole driver */ |
| lp->TransmitKeyID = sEncryption.wTxKeyID + 1; |
| lp->EnableEncryption = sEncryption.wEnabled; |
| |
| memcpy( &lp->DefaultKeys, &sEncryption.EncStr, |
| sizeof( CFG_DEFAULT_KEYS_STRCT )); |
| break; |
| /*case CFG_COUNTRY_STRING: |
| memset( lp->countryString, 0, sizeof( lp->countryString )); |
| memcpy( (void *)lp->countryString, (void *)&pLtv->u.u8[2], (size_t)pLtv->u.u16[0]); |
| break; |
| */ |
| |
| case CFG_DRIVER_ENABLE: |
| lp->driverEnable = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_WOLAS_ENABLE: |
| lp->wolasEnable = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_SET_WPA_AUTH_KEY_MGMT_SUITE: |
| lp->AuthKeyMgmtSuite = pLtv->u.u16[0]; |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_DISASSOCIATE_ADDR: |
| pLtv->u.u16[ETH_ALEN / 2] = CNV_INT_TO_LITTLE( pLtv->u.u16[ETH_ALEN / 2] ); |
| break; |
| case CFG_ADD_TKIP_DEFAULT_KEY: |
| case CFG_REMOVE_TKIP_DEFAULT_KEY: |
| /* Endian convert the Tx Key Information */ |
| pLtv->u.u16[0] = CNV_INT_TO_LITTLE( pLtv->u.u16[0] ); |
| break; |
| case CFG_ADD_TKIP_MAPPED_KEY: |
| break; |
| case CFG_REMOVE_TKIP_MAPPED_KEY: |
| break; |
| /* some RIDs just can't be put */ |
| case CFG_MB_INFO: |
| case CFG_IFB: |
| default: |
| break; |
| } |
| |
| /* This code will prevent Static Configuration Entities from |
| being sent to the card, as they require a call to |
| UIL_ACT_APPLY to take effect. Dynamic Entities will be sent |
| immediately */ |
| switch( pLtv->typ ) { |
| case CFG_CNF_PORT_TYPE: |
| case CFG_CNF_OWN_MAC_ADDR: |
| case CFG_CNF_OWN_CHANNEL: |
| case CFG_CNF_OWN_SSID: |
| case CFG_CNF_OWN_ATIM_WINDOW: |
| case CFG_CNF_SYSTEM_SCALE: |
| case CFG_CNF_MAX_DATA_LEN: |
| case CFG_CNF_PM_ENABLED: |
| case CFG_CNF_MCAST_RX: |
| case CFG_CNF_MAX_SLEEP_DURATION: |
| case CFG_CNF_HOLDOVER_DURATION: |
| case CFG_CNF_OWN_NAME: |
| case CFG_CNF_LOAD_BALANCING: |
| case CFG_CNF_MEDIUM_DISTRIBUTION: |
| #ifdef WARP |
| case CFG_CNF_TX_POW_LVL: |
| case CFG_CNF_CONNECTION_CNTL: |
| //case CFG_PROBE_DATA_RATE: |
| #endif // HERMES25 |
| #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP |
| //;?should we restore this to allow smaller memory footprint |
| case CFG_CNF_OWN_DTIM_PERIOD: |
| #ifdef WARP |
| case CFG_CNF_OWN_BEACON_INTERVAL: // Own Beacon Interval |
| #endif // WARP |
| #ifdef USE_WDS |
| case CFG_CNF_WDS_ADDR1: |
| case CFG_CNF_WDS_ADDR2: |
| case CFG_CNF_WDS_ADDR3: |
| case CFG_CNF_WDS_ADDR4: |
| case CFG_CNF_WDS_ADDR5: |
| case CFG_CNF_WDS_ADDR6: |
| #endif |
| case CFG_CNF_MCAST_PM_BUF: |
| case CFG_CNF_REJECT_ANY: |
| #endif |
| |
| case CFG_CNF_ENCRYPTION: |
| case CFG_CNF_AUTHENTICATION: |
| #if 1 //;? (HCF_TYPE) & HCF_TYPE_AP |
| //;?should we restore this to allow smaller memory footprint |
| |
| case CFG_CNF_EXCL_UNENCRYPTED: |
| case CFG_CNF_MCAST_RATE: |
| case CFG_CNF_INTRA_BSS_RELAY: |
| #endif |
| |
| case CFG_CNF_MICRO_WAVE: |
| //case CFG_CNF_LOAD_BALANCING: |
| //case CFG_CNF_MEDIUM_DISTRIBUTION: |
| //case CFG_CNF_RX_ALL_GROUP_ADDRESS: |
| //case CFG_CNF_COUNTRY_INFO: |
| //case CFG_COUNTRY_STRING: |
| case CFG_AP_MODE: |
| case CFG_ENCRYPT_STRING: |
| //case CFG_DRIVER_ENABLE: |
| case CFG_WOLAS_ENABLE: |
| case CFG_MB_INFO: |
| case CFG_IFB: |
| break; |
| /* Deal with this dynamic MSF RID, as it's required for WPA */ |
| case CFG_DRIVER_ENABLE: |
| if( lp->driverEnable ) { |
| //hcf_cntl_port( &( lp->hcfCtx ), |
| // HCF_PORT_ENABLE | HCF_PORT_0 ); |
| // //hcf_cntl( &( lp->hcfCtx ), |
| // // HCF_PORT_ENABLE | HCF_PORT_0 ); |
| //hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_ENABLE ); |
| // //hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_CONNECT ); |
| |
| hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_ENABLE | HCF_PORT_0 ); |
| hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_CONNECT ); |
| } else { |
| //hcf_cntl_port( &( lp->hcfCtx ), |
| // HCF_PORT_DISABLE | HCF_PORT_0 ); |
| // //hcf_cntl( &( lp->hcfCtx ), |
| // // HCF_PORT_DISABLE | HCF_PORT_0 ); |
| //hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISABLE ); |
| // //hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISCONNECT ); |
| |
| hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISABLE | HCF_PORT_0 ); |
| hcf_cntl( &( lp->hcfCtx ), HCF_CNTL_DISCONNECT ); |
| } |
| break; |
| default: |
| wl_act_int_off( lp ); |
| urq->result = hcf_put_info(&(lp->hcfCtx), (LTVP) pLtv); |
| wl_act_int_on( lp ); |
| break; |
| } |
| |
| if( ltvAllocated ) { |
| kfree( pLtv ); |
| } |
| } else { |
| urq->result = UIL_FAILURE; |
| } |
| } else { |
| DBG_ERROR( DbgInfo, "EPERM\n" ); |
| urq->result = UIL_FAILURE; |
| result = -EPERM; |
| } |
| } else { |
| DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" ); |
| urq->result = UIL_ERR_WRONG_IFB; |
| } |
| |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } // wvlan_uil_put_info |
| /*============================================================================*/ |
| |
| /******************************************************************************* |
| * wvlan_uil_get_info() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Sends a specific RID directly to the driver to retrieve configuration |
| * info. |
| * |
| * PARAMETERS: |
| * |
| * urq - a pointer to the UIL request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * UIL_SUCCESS |
| * UIL_ERR_xxx value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_uil_get_info( struct uilreq *urq, struct wl_private *lp ) |
| { |
| int result = 0; |
| int i; |
| /*------------------------------------------------------------------------*/ |
| |
| DBG_FUNC( "wvlan_uil_get_info" ); |
| DBG_ENTER( DbgInfo ); |
| |
| if( urq->hcfCtx == &( lp->hcfCtx )) { |
| if(( urq->data != NULL ) && ( urq->len != 0 )) { |
| ltv_t *pLtv; |
| bool_t ltvAllocated = FALSE; |
| |
| /* Make sure that we have at least a command and length */ |
| if( urq->len < ( sizeof( hcf_16 ) * 2 )) { |
| urq->len = sizeof( lp->ltvRecord ); |
| DBG_ERROR( DbgInfo, "No Length/Type in LTV!!!\n" ); |
| DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" ); |
| urq->result = UIL_ERR_LEN; |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } |
| |
| /* Verify the user's LTV record header. */ |
| result = verify_area( VERIFY_READ, urq->data, sizeof( hcf_16 ) * 2 ); |
| if( result != 0 ) { |
| DBG_ERROR( DbgInfo, "verify_area(), VERIFY_READ FAILED\n" ); |
| urq->result = UIL_FAILURE; |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } |
| |
| /* Get only the command and length information. */ |
| result = copy_from_user( &( lp->ltvRecord ), urq->data, sizeof( hcf_16 ) * 2 ); |
| |
| /* Make sure the incoming LTV record length is within the bounds of |
| the IOCTL length. */ |
| if((( lp->ltvRecord.len + 1 ) * sizeof( hcf_16 )) > urq->len ) { |
| DBG_ERROR( DbgInfo, "Incoming LTV too big\n" ); |
| urq->len = sizeof( lp->ltvRecord ); |
| urq->result = UIL_ERR_LEN; |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } |
| |
| /* Determine if hcf_get_info() is needed or not */ |
| switch ( lp->ltvRecord.typ ) { |
| case CFG_NIC_IDENTITY: |
| memcpy( &lp->ltvRecord.u.u8[0], &lp->NICIdentity, sizeof( lp->NICIdentity )); |
| break; |
| case CFG_PRI_IDENTITY: |
| memcpy( &lp->ltvRecord.u.u8[0], &lp->PrimaryIdentity, sizeof( lp->PrimaryIdentity )); |
| break; |
| case CFG_AP_MODE: |
| DBG_ERROR( DbgInfo, "set CFG_AP_MODE no longer supported, so is get useful ????\n" ); |
| lp->ltvRecord.u.u16[0] = |
| CNV_INT_TO_LITTLE( lp->hcfCtx.IFB_FWIdentity.comp_id ) == COMP_ID_FW_AP; |
| break; |
| //case CFG_DRV_INFO: |
| case CFG_ENCRYPT_STRING: |
| case CFG_COUNTRY_STRING: |
| case CFG_DRIVER_ENABLE: |
| case CFG_WOLAS_ENABLE: |
| // TODO: determine if we're going to support these |
| urq->result = UIL_FAILURE; |
| break; |
| case CFG_DRV_INFO: |
| DBG_TRACE( DbgInfo, "Intercept CFG_DRV_INFO\n" ); |
| result = cfg_driver_info( urq, lp ); |
| break; |
| case CFG_DRV_IDENTITY: |
| DBG_TRACE( DbgInfo, "Intercept CFG_DRV_IDENTITY\n" ); |
| result = cfg_driver_identity( urq, lp ); |
| break; |
| case CFG_IFB: |
| /* IFB can be a security hole */ |
| if( !capable( CAP_NET_ADMIN )) { |
| result = -EPERM; |
| break; |
| } |
| |
| /* Else fall through to the default */ |
| |
| case CFG_FW_IDENTITY: // For Hermes-1, this is cached |
| default: |
| |
| /* Verify the user buffer */ |
| result = verify_area( VERIFY_WRITE, urq->data, urq->len ); |
| if( result != 0 ) { |
| DBG_ERROR( DbgInfo, "verify_area(), VERIFY_WRITE FAILED\n" ); |
| urq->result = UIL_FAILURE; |
| break; |
| } |
| |
| /* If the requested length is greater than the size of our local |
| LTV record, try to allocate it from the kernel stack. |
| Otherwise, we just use our local LTV record. */ |
| if( urq->len > sizeof( lp->ltvRecord )) { |
| pLtv = kmalloc(urq->len, GFP_KERNEL); |
| if (pLtv != NULL) { |
| ltvAllocated = TRUE; |
| |
| /* Copy the command/length information into the new buffer. */ |
| memcpy( pLtv, &( lp->ltvRecord ), sizeof( hcf_16 ) * 2 ); |
| } else { |
| urq->len = sizeof( lp->ltvRecord ); |
| urq->result = UIL_ERR_LEN; |
| DBG_ERROR( DbgInfo, "kmalloc FAILED\n" ); |
| DBG_ERROR( DbgInfo, "UIL_ERR_LEN\n" ); |
| result = -ENOMEM; |
| break; |
| } |
| } else { |
| pLtv = &( lp->ltvRecord ); |
| } |
| |
| wl_act_int_off( lp ); |
| urq->result = hcf_get_info( &( lp->hcfCtx ), (LTVP) pLtv ); |
| wl_act_int_on( lp ); |
| |
| // Copy the LTV into the user's buffer. |
| //copy_to_user( urq->data, pLtv, urq->len ); |
| |
| //if( ltvAllocated ) |
| //{ |
| // kfree( pLtv ); |
| //} |
| |
| //urq->result = UIL_SUCCESS; |
| break; |
| } |
| |
| /* Handle endian conversion of special fields */ |
| switch( lp->ltvRecord.typ ) { |
| /* simple int gets just need the first hcf_16 byte flipped */ |
| case CFG_CNF_PORT_TYPE: |
| case CFG_CNF_OWN_CHANNEL: |
| case CFG_CNF_OWN_ATIM_WINDOW: |
| case CFG_CNF_SYSTEM_SCALE: |
| case CFG_CNF_MAX_DATA_LEN: |
| case CFG_CNF_PM_ENABLED: |
| case CFG_CNF_MCAST_RX: |
| case CFG_CNF_MAX_SLEEP_DURATION: |
| case CFG_CNF_HOLDOVER_DURATION: |
| case CFG_CNF_OWN_DTIM_PERIOD: |
| case CFG_CNF_MCAST_PM_BUF: |
| case CFG_CNF_REJECT_ANY: |
| case CFG_CNF_ENCRYPTION: |
| case CFG_CNF_AUTHENTICATION: |
| case CFG_CNF_EXCL_UNENCRYPTED: |
| case CFG_CNF_INTRA_BSS_RELAY: |
| case CFG_CNF_MICRO_WAVE: |
| case CFG_CNF_LOAD_BALANCING: |
| case CFG_CNF_MEDIUM_DISTRIBUTION: |
| #ifdef WARP |
| case CFG_CNF_TX_POW_LVL: |
| case CFG_CNF_CONNECTION_CNTL: |
| case CFG_CNF_OWN_BEACON_INTERVAL: // Own Beacon Interval |
| case CFG_COEXISTENSE_BEHAVIOUR: // Coexistence Behavior |
| //case CFG_CNF_RX_ALL_GROUP_ADDRESS: |
| #endif // HERMES25 |
| case CFG_CREATE_IBSS: |
| case CFG_RTS_THRH: |
| case CFG_PROMISCUOUS_MODE: |
| //case CFG_WAKE_ON_LAN: |
| case CFG_RTS_THRH0: |
| case CFG_RTS_THRH1: |
| case CFG_RTS_THRH2: |
| case CFG_RTS_THRH3: |
| case CFG_RTS_THRH4: |
| case CFG_RTS_THRH5: |
| case CFG_RTS_THRH6: |
| case CFG_TX_RATE_CNTL0: |
| case CFG_TX_RATE_CNTL1: |
| case CFG_TX_RATE_CNTL2: |
| case CFG_TX_RATE_CNTL3: |
| case CFG_TX_RATE_CNTL4: |
| case CFG_TX_RATE_CNTL5: |
| case CFG_TX_RATE_CNTL6: |
| case CFG_TX_KEY_ID: |
| case CFG_TICK_TIME: |
| case CFG_MAX_LOAD_TIME: |
| case CFG_NIC_TEMP_TYPE: |
| case CFG_PORT_STAT: |
| case CFG_CUR_TX_RATE: |
| case CFG_CUR_BEACON_INTERVAL: |
| case CFG_PROTOCOL_RSP_TIME: |
| case CFG_CUR_SHORT_RETRY_LIMIT: |
| case CFG_CUR_LONG_RETRY_LIMIT: |
| case CFG_MAX_TX_LIFETIME: |
| case CFG_MAX_RX_LIFETIME: |
| case CFG_CF_POLLABLE: |
| case CFG_PRIVACY_OPT_IMPLEMENTED: |
| //case CFG_CURRENT_REMOTE_RATES: |
| //case CFG_CURRENT_USED_RATES: |
| //case CFG_CURRENT_SYSTEM_SCALE: |
| //case CFG_CURRENT_TX_RATE1: |
| //case CFG_CURRENT_TX_RATE2: |
| //case CFG_CURRENT_TX_RATE3: |
| //case CFG_CURRENT_TX_RATE4: |
| //case CFG_CURRENT_TX_RATE5: |
| //case CFG_CURRENT_TX_RATE6: |
| case CFG_PHY_TYPE: |
| case CFG_CUR_CHANNEL: |
| //case CFG_CURRENT_POWER_STATE: |
| //case CFG_CCAMODE: |
| // lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] ); |
| // break; |
| /* name string gets just need the first hcf_16 byte flipped (length of string) */ |
| case CFG_CNF_OWN_SSID: |
| case CFG_CNF_OWN_NAME: |
| //case CNF_DESIRED_SSID: |
| case CFG_DESIRED_SSID: |
| case CFG_SCAN_SSID: |
| case CFG_CUR_SSID: |
| lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] ); |
| break; |
| /* non-length counted strings need no byte flipping */ |
| case CFG_CNF_OWN_MAC_ADDR: |
| /* this case is no longer valid: CFG_CNF_WDS_ADDR */ |
| case CFG_CNF_WDS_ADDR1: |
| case CFG_CNF_WDS_ADDR2: |
| case CFG_CNF_WDS_ADDR3: |
| case CFG_CNF_WDS_ADDR4: |
| case CFG_CNF_WDS_ADDR5: |
| case CFG_CNF_WDS_ADDR6: |
| case CFG_GROUP_ADDR: |
| case CFG_NIC_SERIAL_NUMBER: |
| case CFG_CUR_BSSID: |
| case CFG_NIC_MAC_ADDR: |
| case CFG_SUPPORTED_DATA_RATES: /* need to ensure we can treat this as a string */ |
| break; |
| //case CFG_CNF_COUNTRY_INFO: /* special case, see page 75 of 022486, Rev C. */ |
| //case CFG_CURRENT_COUNTRY_INFO: /* special case, see page 101 of 022486, Rev C. */ |
| /* |
| lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] ); |
| lp->ltvRecord.u.u16[3] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[3] ); |
| |
| for( i = 4; i < lp->ltvRecord.len; i++ ) { |
| lp->ltvRecord.u.u16[i] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[i] ); |
| } |
| break; |
| */ |
| |
| case CFG_DEFAULT_KEYS: |
| { |
| CFG_DEFAULT_KEYS_STRCT *pKeys = (CFG_DEFAULT_KEYS_STRCT *)&lp->ltvRecord.u.u8[0]; |
| |
| pKeys[0].len = CNV_INT_TO_LITTLE( pKeys[0].len ); |
| pKeys[1].len = CNV_INT_TO_LITTLE( pKeys[1].len ); |
| pKeys[2].len = CNV_INT_TO_LITTLE( pKeys[2].len ); |
| pKeys[3].len = CNV_INT_TO_LITTLE( pKeys[3].len ); |
| } |
| break; |
| case CFG_CNF_MCAST_RATE: |
| case CFG_TX_RATE_CNTL: |
| case CFG_SUPPORTED_RATE_SET_CNTL: // Supported Rate Set Control |
| case CFG_BASIC_RATE_SET_CNTL: // Basic Rate Set Control |
| lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] ); |
| lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] ); |
| break; |
| case CFG_DL_BUF: |
| case CFG_NIC_IDENTITY: |
| case CFG_COMMS_QUALITY: |
| case CFG_PCF_INFO: |
| lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] ); |
| lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] ); |
| lp->ltvRecord.u.u16[2] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[2] ); |
| break; |
| case CFG_FW_IDENTITY: |
| lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] ); |
| lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] ); |
| lp->ltvRecord.u.u16[2] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[2] ); |
| lp->ltvRecord.u.u16[3] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[3] ); |
| break; |
| //case CFG_HSI_SUP_RANGE: |
| case CFG_NIC_MFI_SUP_RANGE: |
| case CFG_NIC_CFI_SUP_RANGE: |
| case CFG_NIC_PROFILE: |
| case CFG_FW_SUP_RANGE: |
| lp->ltvRecord.u.u16[0] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[0] ); |
| lp->ltvRecord.u.u16[1] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[1] ); |
| lp->ltvRecord.u.u16[2] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[2] ); |
| lp->ltvRecord.u.u16[3] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[3] ); |
| lp->ltvRecord.u.u16[4] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[4] ); |
| break; |
| case CFG_MFI_ACT_RANGES_STA: |
| case CFG_CFI_ACT_RANGES_STA: |
| case CFG_CUR_SCALE_THRH: |
| case CFG_AUTHENTICATION_ALGORITHMS: |
| for( i = 0; i < ( lp->ltvRecord.len - 1 ); i++ ) { |
| lp->ltvRecord.u.u16[i] = CNV_INT_TO_LITTLE( lp->ltvRecord.u.u16[i] ); |
| } |
| break; |
| /* done at init time, and endian handled then */ |
| case CFG_PRI_IDENTITY: |
| break; |
| case CFG_MB_INFO: |
| //wvlanEndianTranslateMailbox( pLtv ); |
| break; |
| /* MSF and HCF RIDS */ |
| case CFG_IFB: |
| case CFG_DRV_INFO: |
| case CFG_AP_MODE: |
| case CFG_ENCRYPT_STRING: |
| case CFG_COUNTRY_STRING: |
| case CFG_DRIVER_ENABLE: |
| case CFG_WOLAS_ENABLE: |
| default: |
| break; |
| } |
| |
| // Copy the LTV into the user's buffer. |
| copy_to_user( urq->data, &( lp->ltvRecord ), urq->len ); |
| |
| if( ltvAllocated ) { |
| kfree( &( lp->ltvRecord )); |
| } |
| |
| urq->result = UIL_SUCCESS; |
| } else { |
| urq->result = UIL_FAILURE; |
| } |
| } else { |
| DBG_ERROR( DbgInfo, "UIL_ERR_WRONG_IFB\n" ); |
| urq->result = UIL_ERR_WRONG_IFB; |
| } |
| |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } // wvlan_uil_get_info |
| /*============================================================================*/ |
| |
| |
| |
| |
| |
| /******************************************************************************* |
| * cfg_driver_info() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Retrieves driver information. |
| * |
| * PARAMETERS: |
| * |
| * urq - a pointer to the UIL request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * UIL_SUCCESS |
| * UIL_ERR_xxx value otherwise |
| * |
| ******************************************************************************/ |
| int cfg_driver_info( struct uilreq *urq, struct wl_private *lp ) |
| { |
| int result = 0; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "cfg_driver_info" ); |
| DBG_ENTER( DbgInfo ); |
| |
| |
| /* Make sure that user buffer can handle the driver information buffer */ |
| if( urq->len < sizeof( lp->driverInfo )) { |
| urq->len = sizeof( lp->driverInfo ); |
| urq->result = UIL_ERR_LEN; |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } |
| |
| /* Verify the user buffer. */ |
| result = verify_area( VERIFY_WRITE, urq->data, sizeof( lp->driverInfo )); |
| if( result != 0 ) { |
| urq->result = UIL_FAILURE; |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } |
| |
| lp->driverInfo.card_stat = lp->hcfCtx.IFB_CardStat; |
| |
| // Copy the driver information into the user's buffer. |
| urq->result = UIL_SUCCESS; |
| copy_to_user( urq->data, &( lp->driverInfo ), sizeof( lp->driverInfo )); |
| |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } // cfg_driver_info |
| /*============================================================================*/ |
| |
| |
| |
| |
| /******************************************************************************* |
| * cfg_driver_identity() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Retrieves ID information from the card. |
| * |
| * PARAMETERS: |
| * |
| * urq - a pointer to the UIL request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * UIL_SUCCESS |
| * UIL_ERR_xxx value otherwise |
| * |
| ******************************************************************************/ |
| int cfg_driver_identity( struct uilreq *urq, struct wl_private *lp ) |
| { |
| int result = 0; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_driver_identity" ); |
| DBG_ENTER( DbgInfo ); |
| |
| |
| /* Make sure that user buffer can handle the driver identity structure. */ |
| if( urq->len < sizeof( lp->driverIdentity )) { |
| urq->len = sizeof( lp->driverIdentity ); |
| urq->result = UIL_ERR_LEN; |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } |
| |
| /* Verify the user buffer. */ |
| result = verify_area( VERIFY_WRITE, urq->data, sizeof( lp->driverIdentity )); |
| if( result != 0 ) { |
| urq->result = UIL_FAILURE; |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } |
| |
| /* Copy the driver identity into the user's buffer. */ |
| urq->result = UIL_SUCCESS; |
| copy_to_user( urq->data, &( lp->driverIdentity ), sizeof( lp->driverIdentity )); |
| |
| DBG_LEAVE( DbgInfo ); |
| return result; |
| } // cfg_driver_identity |
| /*============================================================================*/ |
| |
| |
| #endif /* USE_UIL */ |
| |
| |
| /* If WIRELESS_EXT is not defined, then the functions that follow will not be |
| included in the build. */ |
| /* NOTE: Are these still even needed? */ |
| #ifdef WIRELESS_EXT |
| |
| |
| /******************************************************************************* |
| * wvlan_set_netname() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Set the ESSID of the card. |
| * |
| * PARAMETERS: |
| * |
| * wrq - a pointer to the wireless request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * 0 on success |
| * errno value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_set_netname(struct net_device *dev, |
| struct iw_request_info *info, |
| union iwreq_data *wrqu, |
| char *extra) |
| { |
| struct wl_private *lp = wl_priv(dev); |
| unsigned long flags; |
| int ret = 0; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_set_netname" ); |
| DBG_ENTER( DbgInfo ); |
| |
| wl_lock(lp, &flags); |
| |
| memset( lp->NetworkName, 0, sizeof( lp->NetworkName )); |
| memcpy( lp->NetworkName, extra, wrqu->data.length); |
| |
| /* Commit the adapter parameters */ |
| wl_apply(lp); |
| wl_unlock(lp, &flags); |
| |
| DBG_LEAVE( DbgInfo ); |
| return ret; |
| } // wvlan_set_netname |
| /*============================================================================*/ |
| |
| |
| |
| |
| /******************************************************************************* |
| * wvlan_get_netname() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Get the ESSID of the card. |
| * |
| * PARAMETERS: |
| * |
| * wrq - a pointer to the wireless request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * 0 on success |
| * errno value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_get_netname(struct net_device *dev, |
| struct iw_request_info *info, |
| union iwreq_data *wrqu, |
| char *extra) |
| { |
| struct wl_private *lp = wl_priv(dev); |
| unsigned long flags; |
| int ret = 0; |
| int status = -1; |
| wvName_t *pName; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_get_netname" ); |
| DBG_ENTER( DbgInfo ); |
| |
| wl_lock(lp, &flags); |
| |
| /* Get the current network name */ |
| lp->ltvRecord.len = 1 + ( sizeof( *pName ) / sizeof( hcf_16 )); |
| lp->ltvRecord.typ = CFG_CUR_SSID; |
| |
| status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord )); |
| |
| if( status == HCF_SUCCESS ) { |
| pName = (wvName_t *)&( lp->ltvRecord.u.u32 ); |
| |
| memset(extra, '\0', HCF_MAX_NAME_LEN); |
| wrqu->data.length = pName->length; |
| |
| memcpy(extra, pName->name, pName->length); |
| } else { |
| ret = -EFAULT; |
| } |
| |
| wl_unlock(lp, &flags); |
| |
| DBG_LEAVE( DbgInfo ); |
| return ret; |
| } // wvlan_get_netname |
| /*============================================================================*/ |
| |
| |
| |
| |
| /******************************************************************************* |
| * wvlan_set_station_nickname() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Set the card's station nickname. |
| * |
| * PARAMETERS: |
| * |
| * wrq - a pointer to the wireless request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * 0 on success |
| * errno value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_set_station_nickname(struct net_device *dev, |
| struct iw_request_info *info, |
| union iwreq_data *wrqu, |
| char *extra) |
| { |
| struct wl_private *lp = wl_priv(dev); |
| unsigned long flags; |
| int ret = 0; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_set_station_nickname" ); |
| DBG_ENTER( DbgInfo ); |
| |
| wl_lock(lp, &flags); |
| |
| memset( lp->StationName, 0, sizeof( lp->StationName )); |
| |
| memcpy( lp->StationName, extra, wrqu->data.length); |
| |
| /* Commit the adapter parameters */ |
| wl_apply( lp ); |
| wl_unlock(lp, &flags); |
| |
| DBG_LEAVE( DbgInfo ); |
| return ret; |
| } // wvlan_set_station_nickname |
| /*============================================================================*/ |
| |
| |
| |
| |
| /******************************************************************************* |
| * wvlan_get_station_nickname() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Get the card's station nickname. |
| * |
| * PARAMETERS: |
| * |
| * wrq - a pointer to the wireless request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * 0 on success |
| * errno value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_get_station_nickname(struct net_device *dev, |
| struct iw_request_info *info, |
| union iwreq_data *wrqu, |
| char *extra) |
| { |
| struct wl_private *lp = wl_priv(dev); |
| unsigned long flags; |
| int ret = 0; |
| int status = -1; |
| wvName_t *pName; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_get_station_nickname" ); |
| DBG_ENTER( DbgInfo ); |
| |
| wl_lock( lp, &flags ); |
| |
| /* Get the current station name */ |
| lp->ltvRecord.len = 1 + ( sizeof( *pName ) / sizeof( hcf_16 )); |
| lp->ltvRecord.typ = CFG_CNF_OWN_NAME; |
| |
| status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord )); |
| |
| if( status == HCF_SUCCESS ) { |
| pName = (wvName_t *)&( lp->ltvRecord.u.u32 ); |
| |
| memset(extra, '\0', HCF_MAX_NAME_LEN); |
| wrqu->data.length = pName->length; |
| memcpy(extra, pName->name, pName->length); |
| } else { |
| ret = -EFAULT; |
| } |
| |
| wl_unlock(lp, &flags); |
| |
| //out: |
| DBG_LEAVE( DbgInfo ); |
| return ret; |
| } // wvlan_get_station_nickname |
| /*============================================================================*/ |
| |
| |
| |
| |
| /******************************************************************************* |
| * wvlan_set_porttype() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Set the card's porttype |
| * |
| * PARAMETERS: |
| * |
| * wrq - a pointer to the wireless request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * 0 on success |
| * errno value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_set_porttype(struct net_device *dev, |
| struct iw_request_info *info, |
| union iwreq_data *wrqu, |
| char *extra) |
| { |
| struct wl_private *lp = wl_priv(dev); |
| unsigned long flags; |
| int ret = 0; |
| hcf_16 portType; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_set_porttype" ); |
| DBG_ENTER( DbgInfo ); |
| |
| wl_lock(lp, &flags); |
| |
| /* Validate the new value */ |
| portType = *((__u32 *)extra); |
| |
| if( !(( portType == 1 ) || ( portType == 3 ))) { |
| ret = -EINVAL; |
| goto out_unlock; |
| } |
| |
| lp->PortType = portType; |
| |
| /* Commit the adapter parameters */ |
| wl_apply( lp ); |
| |
| out_unlock: |
| wl_unlock(lp, &flags); |
| |
| //out: |
| DBG_LEAVE( DbgInfo ); |
| return ret; |
| } |
| |
| /*============================================================================*/ |
| |
| |
| /******************************************************************************* |
| * wvlan_get_porttype() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * Get the card's porttype |
| * |
| * PARAMETERS: |
| * |
| * wrq - a pointer to the wireless request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * 0 on success |
| * errno value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_get_porttype(struct net_device *dev, |
| struct iw_request_info *info, |
| union iwreq_data *wrqu, |
| char *extra) |
| { |
| struct wl_private *lp = wl_priv(dev); |
| unsigned long flags; |
| int ret = 0; |
| int status = -1; |
| hcf_16 *pPortType; |
| __u32 *pData = (__u32 *)extra; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_get_porttype" ); |
| DBG_ENTER( DbgInfo ); |
| |
| wl_lock( lp, &flags ); |
| |
| /* Get the current port type */ |
| lp->ltvRecord.len = 1 + ( sizeof( *pPortType ) / sizeof( hcf_16 )); |
| lp->ltvRecord.typ = CFG_CNF_PORT_TYPE; |
| |
| status = hcf_get_info( &( lp->hcfCtx ), (LTVP)&( lp->ltvRecord )); |
| |
| if( status == HCF_SUCCESS ) { |
| pPortType = (hcf_16 *)&( lp->ltvRecord.u.u32 ); |
| |
| *pData = CNV_LITTLE_TO_INT( *pPortType ); |
| } else { |
| ret = -EFAULT; |
| } |
| |
| wl_unlock(lp, &flags); |
| |
| //out: |
| DBG_LEAVE( DbgInfo ); |
| return ret; |
| } // wvlan_get_porttype |
| /*============================================================================*/ |
| |
| #endif // WIRELESS_EXT |
| |
| |
| |
| |
| #ifdef USE_RTS |
| /******************************************************************************* |
| * wvlan_rts() |
| ******************************************************************************* |
| * |
| * DESCRIPTION: |
| * |
| * IOCTL handler for RTS commands |
| * |
| * PARAMETERS: |
| * |
| * rrq - a pointer to the rts request buffer |
| * lp - a pointer to the device's private adapter structure |
| * |
| * RETURNS: |
| * |
| * 0 on success |
| * errno value otherwise |
| * |
| ******************************************************************************/ |
| int wvlan_rts( struct rtsreq *rrq, __u32 io_base ) |
| { |
| int ioctl_ret = 0; |
| /*------------------------------------------------------------------------*/ |
| |
| |
| DBG_FUNC( "wvlan_rts" ); |
| DBG_ENTER( DbgInfo ); |
| |
| |
| DBG_PRINT( "io_base: 0x%08x\n", io_base ); |
| |
| switch( rrq->typ ) { |
| case WL_IOCTL_RTS_READ: |
| DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_READ\n"); |
| rrq->data[0] = IN_PORT_WORD( io_base + rrq->reg ); |
| DBG_TRACE( DbgInfo, " reg 0x%04x ==> 0x%04x\n", rrq->reg, CNV_LITTLE_TO_SHORT( rrq->data[0] ) ); |
| break; |
| case WL_IOCTL_RTS_WRITE: |
| DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_WRITE\n"); |
| OUT_PORT_WORD( io_base + rrq->reg, rrq->data[0] ); |
| DBG_TRACE( DbgInfo, " reg 0x%04x <== 0x%04x\n", rrq->reg, CNV_LITTLE_TO_SHORT( rrq->data[0] ) ); |
| break; |
| case WL_IOCTL_RTS_BATCH_READ: |
| DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_BATCH_READ\n"); |
| IN_PORT_STRING_16( io_base + rrq->reg, rrq->data, rrq->len ); |
| DBG_TRACE( DbgInfo, " reg 0x%04x ==> %d bytes\n", rrq->reg, rrq->len * sizeof (__u16 ) ); |
| break; |
| case WL_IOCTL_RTS_BATCH_WRITE: |
| DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- WL_IOCTL_RTS_BATCH_WRITE\n"); |
| OUT_PORT_STRING_16( io_base + rrq->reg, rrq->data, rrq->len ); |
| DBG_TRACE( DbgInfo, " reg 0x%04x <== %d bytes\n", rrq->reg, rrq->len * sizeof (__u16) ); |
| break; |
| default: |
| |
| DBG_TRACE(DbgInfo, "IOCTL: WVLAN2_IOCTL_RTS -- UNSUPPORTED RTS CODE: 0x%X", rrq->typ ); |
| ioctl_ret = -EOPNOTSUPP; |
| break; |
| } |
| |
| DBG_LEAVE( DbgInfo ); |
| return ioctl_ret; |
| } // wvlan_rts |
| /*============================================================================*/ |
| |
| #endif /* USE_RTS */ |