Exemple #1
0
/*
 * Wrapper functions for all standard and private IOCTL functions
 */
static int ath_iw_wrapper_handler(struct net_device *dev,
                                  struct iw_request_info *info,
                                  union iwreq_data *wrqu, char *extra)
{
    struct ath_softc_net80211 *scn = ath_netdev_priv(dev);
    int cmd_id;
    iw_handler handler;

    /* reject ioctls */
    if ((!scn) ||
        (scn && scn->sc_htc_delete_in_progress)){
        printk("%s : #### delete is in progress, scn %p \n", __func__, scn);
        return -EINVAL;
    }
    
    /* private ioctls */
    if (info->cmd >= SIOCIWFIRSTPRIV) {
        cmd_id = (info->cmd - SIOCIWFIRSTPRIV);
        if (cmd_id < 0 || cmd_id >= TABLE_SIZE(ath_iw_priv_handlers)) {
            printk("%s : #### wrong private ioctl 0x%x\n", __func__, info->cmd);
            return -EINVAL;
        }
        
        handler = ath_iw_priv_handlers[cmd_id];
        if (handler)
            return handler(dev, info, wrqu, extra);
        
        printk("%s : #### no registered private ioctl function for cmd 0x%x\n", __func__, info->cmd);
    }
   
    printk("%s : #### unknown command 0x%x\n", __func__, info->cmd);
    
    return -EINVAL;
}
Exemple #2
0
static void
#else
static int
#endif
ospriv_vlan_kill_vid(struct net_device *dev, unsigned short vid)
{
    osif_dev  *osifp = ath_netdev_priv(dev);

	if (osifp->vlgrp != NULL)
	{
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,20)
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,3,0)
	vlan_group_set_device(osifp->vlgrp, vid, NULL);
#else
	osifp->vlgrp = NULL;
	osifp->vlanID = 0;
#endif
#else
        osifp->vlgrp->vlan_devices[vid] = NULL;
#endif
	}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)
	osifp->vlanID = 0;
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
	return 0;
#endif
}
Exemple #3
0
static void
ieee80211_wow_set_gpio(wlan_if_t vap)
{
    osdev_t                     os_handle = vap->iv_ic->ic_osdev;
    struct net_device           *dev = os_handle->netdev;
    struct ath_softc_net80211   *scn = ath_netdev_priv(dev);
    struct ath_softc            *sc = ATH_DEV_TO_SC(scn->sc_dev);
    struct ath_hal              *ah = sc->sc_ah;

    ah_wow_set_gpio_hi(ah);
}
Exemple #4
0
static void
#else
static int
#endif
ospriv_vlan_register(struct net_device *dev, struct vlan_group *grp)
{
    osif_dev  *osifp = ath_netdev_priv(dev);

	osifp->vlgrp = grp;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
    return 0;
#endif
}
Exemple #5
0
static int ath_iw_getparam(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
{
    struct ath_softc_net80211 *scn  = ath_netdev_priv(dev);
    struct ath_softc          *sc   = ATH_DEV_TO_SC(scn->sc_dev);
    struct ath_hal            *ah   = sc->sc_ah;
    int                     param   = *(int *)extra;
    int                      *val   = (int *)extra; 
    int                    retval   = 0;
    
    /*
    ** Code Begins
    ** Since the parameter passed is the value of the parameter ID, we can call directly
    */
    if (ath_ioctl_debug)
        printk("***%s: dev=%s ioctl=0x%04x  name=%s \n", __func__, dev->name, param, find_ath_ioctl_name(param, 0));

    if ( param & ATH_PARAM_SHIFT )
    {
        /*
        ** It's an ATH value.  Call the  ATH configuration interface
        */
        
        param -= ATH_PARAM_SHIFT;
        if ( scn->sc_ops->ath_get_config_param(scn->sc_dev,(ath_param_ID_t)param,extra) )
        {
            retval = -EOPNOTSUPP;
        }
    }
    else if ( param & SPECIAL_PARAM_SHIFT )
    {
        if ( param == (SPECIAL_PARAM_SHIFT | SPECIAL_PARAM_COUNTRY_ID) ) {
            HAL_COUNTRY_ENTRY         cval;
    
            scn->sc_ops->get_current_country(scn->sc_dev, &cval);
            val[0] = cval.countryCode;
        } else {
            retval = -EOPNOTSUPP;
        }
    }
    else
    {
        if ( !ath_hal_get_config_param(ah, (HAL_CONFIG_OPS_PARAMS_TYPE)param, extra) )
        {
            retval = -EOPNOTSUPP;
        }
    }

    return (retval);
}
Exemple #6
0
static void
#else
static int
#endif
ospriv_vlan_add_vid(struct net_device *dev, unsigned short vid)
{
    osif_dev  *osifp = ath_netdev_priv(dev);
	if (osifp->vlgrp != NULL)
		osifp->vlanID = vid;
	else
		osifp->vlanID = 0;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)
	return 0;
#endif
}
Exemple #7
0
/* AUTELAN-Added-End : [email protected] */
static int ath_iw_sethwaddr(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
{
    int retval;
    unsigned char addr[IEEE80211_ADDR_LEN];
    struct sockaddr sa;
    int i = 0;
    char *buf = extra;
    struct ath_softc_net80211 *scn = ath_netdev_priv(dev);
    struct ieee80211com *ic = &scn->sc_ic;

    do {
        retval = char_to_num(*buf++);
        if ( retval < 0 )
            break;

        addr[i] = retval << 4;

        retval = char_to_num(*buf++);
        if ( retval < 0 )
            break;

        addr[i++] += retval;

        if ( i < IEEE80211_ADDR_LEN && *buf++ != ':' ) {
            retval = -EINVAL;
            break;
        }
        retval = 0;
    } while ( i < IEEE80211_ADDR_LEN );

    if ( !retval ) {
        if ( !TAILQ_EMPTY(&ic->ic_vaps) ) {
            retval = -EBUSY; //We do not set the MAC address if there are VAPs present
        } else {
            IEEE80211_ADDR_COPY(&sa.sa_data, addr);
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,30)
            retval = dev->netdev_ops->ndo_set_mac_address(dev, &sa);
#else
            retval = dev->set_mac_address(dev, &sa);
#endif
        }
    }

    return retval;
}
Exemple #8
0
static int ath_iw_setcountry(struct net_device *dev,
                           struct iw_request_info *info,
                           void *w,
                           char *extra)
{

    struct ath_softc_net80211 *scn =  ath_netdev_priv(dev);
    struct ath_softc          *sc  = ATH_DEV_TO_SC(scn->sc_dev);
    char *p = (char *) extra;
    int retval;

    if (sc->sc_ieee_ops->set_countrycode) {
        retval = sc->sc_ieee_ops->set_countrycode(sc->sc_ieee, p, 0, CLIST_NEW_COUNTRY);
    } else {
        retval = -EOPNOTSUPP;
    }

    return retval;
}
Exemple #9
0
static int ath_iw_getcountry(struct net_device *dev, struct iw_request_info *info, void *w, char *extra)
{
    struct ath_softc_net80211 *scn  = ath_netdev_priv(dev);
    struct iw_point           *wri  = (struct iw_point *)w;
    HAL_COUNTRY_ENTRY         cval;
    char                      *str  = (char *)extra;
    
    /*
    ** Code Begins
    */

    scn->sc_ops->get_current_country(scn->sc_dev, &cval);
    str[0] = cval.iso[0];
    str[1] = cval.iso[1];
    str[2] = cval.iso[2];
    str[3] = 0;
    wri->length = 3;
    
    return (0);
}
Exemple #10
0
static int ath_iw_setparam(struct net_device *dev,
                           struct iw_request_info *info,
                           void *w,
                           char *extra)
{

    struct ath_softc_net80211 *scn =  ath_netdev_priv(dev);
    struct ath_softc          *sc  =  ATH_DEV_TO_SC(scn->sc_dev);
    struct ath_hal            *ah =   sc->sc_ah;
    int *i = (int *) extra;
    int param = i[0];       /* parameter id is 1st */
    int value = i[1];       /* NB: most values are TYPE_INT */
    int retval = 0;
    
    /*
    ** Code Begins
    ** Since the parameter passed is the value of the parameter ID, we can call directly
    */
    if (ath_ioctl_debug)
        printk("***%s: dev=%s ioctl=0x%04x  name=%s\n", __func__, dev->name, param, find_ath_ioctl_name(param, 1));


    if ( param & ATH_PARAM_SHIFT )
    {
        /*
        ** It's an ATH value.  Call the  ATH configuration interface
        */
        
        param -= ATH_PARAM_SHIFT;
        retval = scn->sc_ops->ath_set_config_param(scn->sc_dev,
                                                   (ath_param_ID_t)param,
                                                   &value);
    }
    else if ( param & SPECIAL_PARAM_SHIFT )
    {
        if ( param == (SPECIAL_PARAM_SHIFT | SPECIAL_PARAM_COUNTRY_ID) ) {
            int j; 
            for(j=0; j < sizeof(staOnlyCountryCodes)/sizeof(staOnlyCountryCodes[0]); j++) {
                if(staOnlyCountryCodes[j] == value) {
                    printk("***%s: dev=%s ioctl=0x%04x  name=%s The country code %d is a STA only country code\n", __func__, dev->name, param, find_ath_ioctl_name(param, 1),value);
                    retval = -EOPNOTSUPP;
                    return (retval);
                }
            }
            if (sc->sc_ieee_ops->set_countrycode) {
                retval = sc->sc_ieee_ops->set_countrycode(
                    sc->sc_ieee, NULL, value, CLIST_NEW_COUNTRY);
            }
        } else if ( param  == (SPECIAL_PARAM_SHIFT | SPECIAL_PARAM_ASF_AMEM_PRINT) ) {
            asf_amem_status_print();
            if ( value ) {
                asf_amem_allocs_print(asf_amem_alloc_all, value == 1);
            }
        } else if (param  == (SPECIAL_PARAM_SHIFT | SPECIAL_PARAM_DISP_TPC) ) {
            ath_hal_display_tpctables(ah);
        } else {
            retval = -EOPNOTSUPP;
        }
    }
    else
    {
        retval = (int) ath_hal_set_config_param(
            ah, (HAL_CONFIG_OPS_PARAMS_TYPE)param, &value);
    }

    return (retval);    
}
Exemple #11
0
int
ieee80211_ioctl_wireless_qos(struct net_device *dev,struct han_ioctl_priv_args *a,struct iwreq *iwr)
{
	int retv = 0;
	osif_dev *osifp = ath_netdev_priv(dev);
    wlan_if_t vap = osifp->os_if;
	int i;
	
	switch (a->u.wmm.subtype) {
		case HAN_IOCTL_WMM_ENABLE:
			if(OP_SET == a->u.wmm.op){
				vap->priv_wmm.wmm_flag = a->u.wmm.wmm_args.wmm_enable;
				
				retv = wlan_set_param(vap, IEEE80211_FEATURE_WMM, vap->priv_wmm.wmm_flag);
	            if(osifp->osif_is_mode_offload) {
		            /* For offload interface the AMPDU parameter corresponds to
		             * number of subframes in AMPDU
		             */
		            if (vap->priv_wmm.wmm_flag) {
		                /* WMM is enabled - reset number of subframes in AMPDU
		                 * to 64
		                 */
		                wlan_set_param(vap, IEEE80211_FEATURE_AMPDU, 64);
		            }
		            else {
		                wlan_set_param(vap, IEEE80211_FEATURE_AMPDU, 0);
		            }
		        } else {
		            wlan_set_param(vap, IEEE80211_FEATURE_AMPDU, vap->priv_wmm.wmm_flag);
		        }
		        if (retv == EOK) {
		            retv = ENETRESET;
		        }
			}else if(OP_GET == a->u.wmm.op){
				a->u.wmm.wmm_args.wmm_enable = vap->priv_wmm.wmm_flag;
			}else {
				retv = ENETRESET;
			}
			break;
			
		case HAN_IOCTL_WMM_DSCP_ENABLE:
			if(OP_SET == a->u.wmm.op){
				vap->priv_wmm.dscp_flag= a->u.wmm.wmm_args.dscp_enable;
				if(osifp->osif_is_mode_offload) {
					vap->iv_override_dscp = vap->priv_wmm.dscp_flag;
				}
			}else if(OP_GET == a->u.wmm.op){
				a->u.wmm.wmm_args.dscp_enable = vap->priv_wmm.dscp_flag;
			}else {
				retv = ENETRESET;
			}
			break;
			
		case HAN_IOCTL_WMM_8021P_ENABLE:
			if(OP_SET == a->u.wmm.op){
				vap->priv_wmm.vlan_flag = a->u.wmm.wmm_args.vlan_enable;
				
			}else if(OP_GET == a->u.wmm.op){
				a->u.wmm.wmm_args.vlan_enable = vap->priv_wmm.vlan_flag;
			}else {
				retv = ENETRESET;
			}
			break;
		case HAN_IOCTL_WMM_DEBUG:
			if(OP_SET == a->u.wmm.op){
				vap->priv_wmm.debug= a->u.wmm.wmm_args.debug;
				if(vap->priv_wmm.debug == 3){
					print_dscp_to_wmm_map(vap);
				}else if(vap->priv_wmm.debug == 4){
					print_8021p_to_wmm_map(vap);
				}
			}else if(OP_GET == a->u.wmm.op){
				a->u.wmm.wmm_args.debug= vap->priv_wmm.debug;
			}else {
				retv = ENETRESET;
			}
				break;
		case HAN_IOCTL_WMM_DSCP_TO_BK:
			if(OP_SET == a->u.wmm.op){
				WMM_STORE_INFO_USER_TO_DRIVER(vap,a,dscp_to_bk);
				SET_DSCP_TO_WMM_AMP(vap,dscp_to_bk,WME_AC_BK);
				if(osifp->osif_is_mode_offload) {
					ol_set_dscp_to_wmm(vap);
				}
		    }else if(OP_GET == a->u.wmm.op){
				WMM_STORE_INFO_DRIVER_TO_USER(vap,a,dscp_to_bk);
			}else {
				retv = ENETRESET;
			}
			break;
		case HAN_IOCTL_WMM_DSCP_TO_BE:
			if(OP_SET == a->u.wmm.op){
				WMM_STORE_INFO_USER_TO_DRIVER(vap,a,dscp_to_be);
				SET_DSCP_TO_WMM_AMP(vap,dscp_to_be,WME_AC_BE);
				if(osifp->osif_is_mode_offload) {
					ol_set_dscp_to_wmm(vap);
				}
		    }else if(OP_GET == a->u.wmm.op){
				WMM_STORE_INFO_DRIVER_TO_USER(vap,a,dscp_to_be);
			}else {
				retv = ENETRESET;
			}
			break;
		case HAN_IOCTL_WMM_DSCP_TO_VI:
			if(OP_SET == a->u.wmm.op){
				WMM_STORE_INFO_USER_TO_DRIVER(vap,a,dscp_to_vi);
				SET_DSCP_TO_WMM_AMP(vap,dscp_to_vi,WME_AC_VI);
				if(osifp->osif_is_mode_offload) {
					ol_set_dscp_to_wmm(vap);
				}
		    }else if(OP_GET == a->u.wmm.op){
				WMM_STORE_INFO_DRIVER_TO_USER(vap,a,dscp_to_vi);
			}else {
				retv = ENETRESET;
			}
			break;
		case HAN_IOCTL_WMM_DSCP_TO_VO:
			if(OP_SET == a->u.wmm.op){
				WMM_STORE_INFO_USER_TO_DRIVER(vap,a,dscp_to_vo);
				SET_DSCP_TO_WMM_AMP(vap,dscp_to_vo,WME_AC_VO);
				if(osifp->osif_is_mode_offload) {
					ol_set_dscp_to_wmm(vap);
				}
		    }else if(OP_GET == a->u.wmm.op){
				WMM_STORE_INFO_DRIVER_TO_USER(vap,a,dscp_to_vo);
			}else {
				retv = ENETRESET;
			}
			break;
		case HAN_IOCTL_WMM_BK_TO_DSCP:
			if(OP_SET == a->u.wmm.op){
				vap->priv_wmm.wmm_to_dscp_map[WME_AC_BK] = a->u.wmm.wmm_args.bk_to_dscp;
			}else if(OP_GET == a->u.wmm.op){
				a->u.wmm.wmm_args.bk_to_dscp = vap->priv_wmm.wmm_to_dscp_map[WME_AC_BK];
			}else {
				retv = ENETRESET;
			} 
			break;
		case HAN_IOCTL_WMM_BE_TO_DSCP:
			if(OP_SET == a->u.wmm.op){
				vap->priv_wmm.wmm_to_dscp_map[WME_AC_BE] = a->u.wmm.wmm_args.be_to_dscp;
			}else if(OP_GET == a->u.wmm.op){
				a->u.wmm.wmm_args.be_to_dscp = vap->priv_wmm.wmm_to_dscp_map[WME_AC_BE];
			}else {
				retv = ENETRESET;
			} 
			
			break;
		case HAN_IOCTL_WMM_VI_TO_DSCP:
			if(OP_SET == a->u.wmm.op){
				vap->priv_wmm.wmm_to_dscp_map[WME_AC_VI] = a->u.wmm.wmm_args.vi_to_dscp;
			}else if(OP_GET == a->u.wmm.op){
				a->u.wmm.wmm_args.vi_to_dscp = vap->priv_wmm.wmm_to_dscp_map[WME_AC_VI];
			}else {
				retv = ENETRESET;
			} 
			break;
		case HAN_IOCTL_WMM_VO_TO_DSCP:
			if(OP_SET == a->u.wmm.op){
			vap->priv_wmm.wmm_to_dscp_map[WME_AC_VO] = a->u.wmm.wmm_args.vo_to_dscp;
			
			}else if(OP_GET == a->u.wmm.op){
			a->u.wmm.wmm_args.vo_to_dscp = vap->priv_wmm.wmm_to_dscp_map[WME_AC_VO];
			}else {
				retv = ENETRESET;
			} 
			break;
		case HAN_IOCTL_WMM_8021P_TO_BK:
			if(OP_SET == a->u.wmm.op){
				WMM_STORE_INFO_USER_TO_DRIVER(vap,a,vlan_to_bk);
				SET_VLAN_TO_WMM_AMP(vap,vlan_to_bk,WME_AC_BK);
				
		    }else if(OP_GET == a->u.wmm.op){
				WMM_STORE_INFO_DRIVER_TO_USER(vap,a,vlan_to_bk);
			}else {
				retv = ENETRESET;
			}
			break;
		case HAN_IOCTL_WMM_8021P_TO_BE:
			if(OP_SET == a->u.wmm.op){
				WMM_STORE_INFO_USER_TO_DRIVER(vap,a,vlan_to_be);
				SET_VLAN_TO_WMM_AMP(vap,vlan_to_be,WME_AC_BE);
		    }else if(OP_GET == a->u.wmm.op){
				WMM_STORE_INFO_DRIVER_TO_USER(vap,a,vlan_to_be);
			}else {
				retv = ENETRESET;
			}
			break;
		case HAN_IOCTL_WMM_8021P_TO_VI:
			if(OP_SET == a->u.wmm.op){
				WMM_STORE_INFO_USER_TO_DRIVER(vap,a,vlan_to_vi);
				SET_VLAN_TO_WMM_AMP(vap,vlan_to_vi,WME_AC_VI);
		    }else if(OP_GET == a->u.wmm.op){
				WMM_STORE_INFO_DRIVER_TO_USER(vap,a,vlan_to_vi);
			}else {
				retv = ENETRESET;
			}
			break;
		case HAN_IOCTL_WMM_8021P_TO_VO:
			if(OP_SET == a->u.wmm.op){
				WMM_STORE_INFO_USER_TO_DRIVER(vap,a,vlan_to_vo);
				SET_VLAN_TO_WMM_AMP(vap,vlan_to_vo,WME_AC_VO);
		    }else if(OP_GET == a->u.wmm.op){
				WMM_STORE_INFO_DRIVER_TO_USER(vap,a,vlan_to_vo);
			}else {
				retv = ENETRESET;
			}
			break;
		case HAN_IOCTL_WMM_BK_TO_8021P:
			if(OP_SET == a->u.wmm.op){
				vap->priv_wmm.wmm_to_vlan_map[WME_AC_BK] = a->u.wmm.wmm_args.bk_to_vlan;
			}else if(OP_GET == a->u.wmm.op){
				a->u.wmm.wmm_args.bk_to_vlan = vap->priv_wmm.wmm_to_vlan_map[WME_AC_BK];
			}else {
				retv = ENETRESET;
			}
			break;
		case HAN_IOCTL_WMM_BE_TO_8021P:
			if(OP_SET == a->u.wmm.op){
				vap->priv_wmm.wmm_to_vlan_map[WME_AC_BE] = a->u.wmm.wmm_args.be_to_vlan;
			}else if(OP_GET == a->u.wmm.op){
				a->u.wmm.wmm_args.be_to_vlan = vap->priv_wmm.wmm_to_vlan_map[WME_AC_BE] ;
			}else {
				retv = ENETRESET;
			}
			break;
		case HAN_IOCTL_WMM_VI_TO_8021P:
			if(OP_SET == a->u.wmm.op){
				vap->priv_wmm.wmm_to_vlan_map[WME_AC_VI] = a->u.wmm.wmm_args.vi_to_vlan;
			}else if(OP_GET == a->u.wmm.op){
			   a->u.wmm.wmm_args.vi_to_vlan = vap->priv_wmm.wmm_to_vlan_map[WME_AC_VI];
			}else {
				retv = ENETRESET;
			}
			break;
		case HAN_IOCTL_WMM_VO_TO_8021P:
			if(OP_SET == a->u.wmm.op){
				vap->priv_wmm.wmm_to_vlan_map[WME_AC_VO] = a->u.wmm.wmm_args.vo_to_vlan;
			}else if(OP_GET == a->u.wmm.op){
				a->u.wmm.wmm_args.vo_to_vlan = vap->priv_wmm.wmm_to_vlan_map[WME_AC_VO];
			}else {
				retv = ENETRESET;
			}
			break;
		case HAN_IOCTL_WMM_STATISTICS:
			a->u.wmm.wmm_stat.wmm_enable = vap->priv_wmm.wmm_flag;
			a->u.wmm.wmm_stat.dscp_enable = vap->priv_wmm.dscp_flag;
			a->u.wmm.wmm_stat.vlan_enable = vap->priv_wmm.vlan_flag;
			a->u.wmm.wmm_stat.dscp_to_wmm_packets_ok = vap->priv_wmm.dscp_to_wmm_ok;
			a->u.wmm.wmm_stat.dscp_to_wmm_packets_error = vap->priv_wmm.dscp_to_wmm_error;
			a->u.wmm.wmm_stat.wmm_to_dscp_packets_ok = vap->priv_wmm.wmm_to_dscp_ok;
			a->u.wmm.wmm_stat.wmm_to_dscp_packets_error = vap->priv_wmm.wmm_to_dscp_error;
			a->u.wmm.wmm_stat.vlan_to_wmm_packets_ok = vap->priv_wmm.vlan_to_wmm_ok;
			a->u.wmm.wmm_stat.vlan_to_wmm_packets_error = vap->priv_wmm.vlan_to_wmm_error;
			a->u.wmm.wmm_stat.wmm_to_vlan_packets_ok = vap->priv_wmm.wmm_to_vlan_ok;
			a->u.wmm.wmm_stat.wmm_to_vlan_packets_error = vap->priv_wmm.wmm_to_vlan_error;
			break;
		default:
			return -EFAULT;		
	}

	if(OP_GET == a->u.wmm.op){
		copy_to_user(iwr->u.data.pointer, a, sizeof(struct han_ioctl_priv_args));
	}
	
	return retv;
}
Exemple #12
0
int ath_statistic_read(char *buf, char **start, off_t off, int count, int *eof, void *data)
{
    struct net_device *dev0;
    struct ath_softc *sc0, *sc1;
    static unsigned long long crc_err_cnt0=0;
    static unsigned long long crc_err_cnt1=0;
    static unsigned int retry0=0;
    static unsigned int retry1=0;
    static unsigned int rxpkts0=0;
    static unsigned int rxpkts1=0;
    static unsigned int txpkts0=0;
    static unsigned int txpkts1=0;
    unsigned int retry0_inc=0, retry1_inc=0,rxpkts0_inc=0,rxpkts1_inc=0,txpkts0_inc=0,txpkts1_inc=0,crc_err_cnt0_inc=0, crc_err_cnt1_inc=0;
    unsigned long flags;

    dev0 = dev_get_by_name(&init_net, "wifi0");

    local_irq_save(flags);

    if(dev0)
    {
    
    sc0 = ATH_DEV_TO_SC(((struct ath_softc_net80211 *)(ath_netdev_priv(dev0)))->sc_dev);

    if(sc0->sc_stats.ast_11n_stats.tx_sf_hw_xretries >= retry0)
        retry0_inc = sc0->sc_stats.ast_11n_stats.tx_sf_hw_xretries - retry0;
    else
        retry0_inc = 0xffffffff - retry0 + sc0->sc_stats.ast_11n_stats.tx_sf_hw_xretries;
    retry0 = sc0->sc_stats.ast_11n_stats.tx_sf_hw_xretries;

    if(sc0->sc_phy_stats[sc0->sc_curmode].ast_rx_crcerr >= crc_err_cnt0)
        crc_err_cnt0_inc = (unsigned int)(sc0->sc_phy_stats[sc0->sc_curmode].ast_rx_crcerr - crc_err_cnt0);
    else
        crc_err_cnt0_inc = (unsigned int)(0xffffffffffffffffLL - crc_err_cnt0 + sc0->sc_phy_stats[sc0->sc_curmode].ast_rx_crcerr);
    crc_err_cnt0 = sc0->sc_phy_stats[sc0->sc_curmode].ast_rx_crcerr;

    if(sc0->sc_stats.ast_11n_stats.rx_pkts > rxpkts0)
        rxpkts0_inc = sc0->sc_stats.ast_11n_stats.rx_pkts - rxpkts0;
    else
        rxpkts0_inc = 0xffffffff - rxpkts0 + sc0->sc_stats.ast_11n_stats.rx_pkts;
    rxpkts0 = sc0->sc_stats.ast_11n_stats.rx_pkts;

    if(sc0->sc_stats.ast_11n_stats.tx_pkts > txpkts0)
        txpkts0_inc = sc0->sc_stats.ast_11n_stats.tx_pkts - txpkts0;
    else
        txpkts0_inc = 0xffffffff - txpkts0 + sc0->sc_stats.ast_11n_stats.tx_pkts;
    txpkts0 = sc0->sc_stats.ast_11n_stats.tx_pkts;

    dev_put(dev0);
    }
#if 0    
    if(dev1)
    {
    
    sc1 = ATH_DEV_TO_SC(((struct ath_softc_net80211 *)(ath_netdev_priv(dev1)))->sc_dev);

    if(sc1->sc_stats.ast_11n_stats.tx_sf_hw_xretries >= retry1)
        retry1_inc = sc1->sc_stats.ast_11n_stats.tx_sf_hw_xretries - retry1;
    else
        retry1_inc = 0xffffffff - retry1 + sc1->sc_stats.ast_11n_stats.tx_sf_hw_xretries;
    retry1 = sc1->sc_stats.ast_11n_stats.tx_sf_hw_xretries;


    if(sc1->sc_phy_stats[sc1->sc_curmode].ast_rx_crcerr >= crc_err_cnt1)
        crc_err_cnt1_inc = (unsigned int)(sc1->sc_phy_stats[sc1->sc_curmode].ast_rx_crcerr - crc_err_cnt1);
    else
        crc_err_cnt1_inc = (unsigned int)(0xffffffffffffffffLL - crc_err_cnt1 + sc1->sc_phy_stats[sc1->sc_curmode].ast_rx_crcerr);
    crc_err_cnt1 = sc1->sc_phy_stats[sc1->sc_curmode].ast_rx_crcerr;


    if(sc1->sc_stats.ast_11n_stats.rx_pkts > rxpkts1)
        rxpkts1_inc = sc1->sc_stats.ast_11n_stats.rx_pkts - rxpkts1;
    else
        rxpkts1_inc = 0xffffffff - rxpkts1 + sc1->sc_stats.ast_11n_stats.rx_pkts;
    rxpkts1 = sc1->sc_stats.ast_11n_stats.rx_pkts;

    
    if(sc1->sc_stats.ast_11n_stats.tx_pkts > txpkts1)
        txpkts1_inc = sc1->sc_stats.ast_11n_stats.tx_pkts - txpkts1;
    else
        txpkts1_inc = 0xffffffff - txpkts1 + sc1->sc_stats.ast_11n_stats.tx_pkts;
    txpkts1 = sc1->sc_stats.ast_11n_stats.tx_pkts;

    }
#endif
    local_irq_restore(flags);

    return (snprintf(buf, count, "wifi0\nrx pkts %d(crc error: %d ratio:1/%d)\ntx pkts %d(retries: %d ratio:1/%d)\n", 
    rxpkts0_inc, crc_err_cnt0_inc, crc_err_cnt0_inc?(rxpkts0_inc/crc_err_cnt0_inc):-1,
    txpkts0_inc, retry0_inc, retry0_inc?(txpkts0_inc/retry0_inc):-1));
}