iwpriv解析

28091 ワード

原文の住所:http://blog.csdn.net/wanggongzhen1983/article/details/5330211
iwprivは次のwlan_を処理します。prvate_argsのすべての拡張コマンドは、iwprivの実装上、このようになります。=>main
=>set_private
=>iw_get_priv_info wireless wlan_private_args .

dev_ioctl
=>wext_handle_ioctl
=>wireless_process_ioctl
    if (cmd == SIOCGIWPRIV && dev->wireless_handlers)
        return ioctl_standard_call(dev, ifr, cmd,
                     &iw_handler_get_private);
static int ioctl_standard_call(struct net_device *    dev,
             struct ifreq *        ifr,
             unsigned int        cmd,
             iw_handler        handler)
{
    ...
        /* Call the handler */
        ret = handler(dev, &info, &(iwr->u), extra);
            if (user_length < iwr->u.data.length) {
                kfree(extra);
                return -E2BIG;
// iwpriv, wifi private , , iwpriv
//maxpriv 16, 16 , wifi private_args
//newpriv = realloc(priv, maxpriv * sizeof(priv[0])); , , wifi wlan_private_args
// iwpriv .
            }
    ...
}
    /* New driver API : try to find the handler */
    handler = get_handler(dev, cmd);//

    if (handler) {
        /* Standard and private are not the same */
        if (cmd < SIOCIWFIRSTPRIV)
            return ioctl_standard_call(dev, ifr, cmd, handler);
        else
// handler, iwpriv , iwpriv dev->do_ioctl .
            return ioctl_private_call(dev, ifr, cmd, handler);
    }
    /* Old driver API : call driver ioctl handler */
    if (dev->do_ioctl)
// dev->wireless_handlers->standard dev->wireless_handlers->private[index cmd ,
//dev->do_ioctl = wlan_do_ioctl; wlan_do_ioctl .
        return dev->do_ioctl(dev, ifr, cmd);

static iw_handler get_handler(struct net_device *dev, unsigned int cmd)
{
    /* Don't "optimise" the following variable, it will crash */
    unsigned int    index;        /* *MUST* be unsigned */

    /* Check if we have some wireless handlers defined */
    if (dev->wireless_handlers == NULL)
        return NULL;

    /* Try as a standard command */
    index = cmd - SIOCIWFIRST;
    if (index < dev->wireless_handlers->num_standard)
        return dev->wireless_handlers->standard[index];

    /* Try as a private command */
    index = cmd - SIOCIWFIRSTPRIV;//

    if (index < dev->wireless_handlers->num_private)
        return dev->wireless_handlers->private[index];// private handler.
    /* Not found */
    return NULL;
}
wlan_private_args wifi , iwpriv struct iw_handler_def wlan_handler_def = {
  num_standard:sizeof(wlan_handler) / sizeof(iw_handler),
  num_private:sizeof(wlan_private_handler) / sizeof(iw_handler),
  num_private_args:sizeof(wlan_private_args) / sizeof(struct iw_priv_args),
  standard:(iw_handler *) wlan_handler,
  private:(iw_handler *) wlan_private_handler,
  private_args:(struct iw_priv_args *) wlan_private_args,
#if WIRELESS_EXT > 20
  get_wireless_stats:wlan_get_wireless_stats,
#endif
};
, wifi iwpriv .
static const struct iw_prvアークス?ランタンprvate_アークス[]={     「extscan」     「ホットcmd」     「arpfilter」     「regrdwr」     「sdcmd 52 rw」     「sdcmd 53 rw」     「setgetconf」     「getscis」     「scantype」     「deauth」     「getNF」     「get RSSI」     「bgscan」     「enabole 11 d」     「adhocgrate」     「sdioclock」     「wmm」     「updnullgen」     「set coalescing」     「adhocgprot」     「set powercons」     「wmmuqosinfo」     「lolisteninter」     「fwwake umethod」     「pspnullinterval」     「bcnmisto」     「adhocawakepd」     「module type」     「autdeepsleep」     「enhancps」     「wakeumt」     「setrxant」     「settxant」     「authalgs」     「encryptionmode」     「setre gioncode」     「set listeninter」     「setmultiledtim」     「setbcnavg」     「setsdataavg」     "assicate"     「getre gioncode」     「get listeninter」     「getmultiledtim」     「gettxrate」     「getbcnavg」     「ゲットdataavg」     「getrxant」     「gettxant」     「getts」     「wpspsession」     「deepsleep」     「adhocstop」     「ラジオ」     「ラジォフ」     「rmaeskey」     「crypt Teutest」     「リアルオン」     「リアルオフィス」     「wlandle-on」     「wlandle-off」     「slepparams」     「requesttpc」     「パワフル」     「measreq」     「bca-ts」     「scanmode」     「ゲッタードホーク」     「set genie」     「get genie」     「qstatus」     「tsustatus」     「setaeskey」     「ゲテーゼ」     「version」     「verext」     「setwpaie」     「setband」     「setadhoch」     「chanswann」     「get band」     「getadhocch」     「getlog」     「tpcfg」     「scanprobes」     「ledgpio」     「sleppd」     「rateadapt」     「getsSNR」     「getrate」     「getrxinfo」     「atimwindow」     「bcninterval」     「sdiopull ctrl」     「scantime」     「syssclock」     「txcontrol」     「hscfg」     「hssetpara」     「inactoext」     「dbgscfg」     「drvdbg」     「drvdelaymax」     「intfctrl」     「set quietie」     「」     「setuserscan」     「getscantable」     「setmrvltlv」     「getassocrsp」     addts     「デルタ」     「qconfig」     「qstats」     「txpktstats」     「getcfptable」     「mefcfg」     「getmem」}
 
 
  ethx ioctl ====================
1. iwpriv
wireless tools iwpriv :
iwpriv ethX private-command [parameters]
iwpriv :
int main(int argc, char *argv[])
{
    ...
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    ...
    ioctl(sockfd, ioctl_val, &iwr);// ioctl
    ...
}
====================
2. sys_ioctl
ioctl(sockfd, ioctl_val, &iwr); sys_ioctl , :
sys_ioctl=>vfs_ioctl=>do_ioctl=
filp->f_op->unlocked_ioctl ioctl , sock_ioctl, sock_ioctl,
sock_ioctl=>
{
    ...
    #ifdef CONFIG_WIRELESS_EXT
        if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) {
            err = dev_ioctl(net, cmd, argp);//
        } else
    #endif
    ...
}
dev_ioctl=>wext_handle_ioctl
{
    ...
/* Take care of Wireless Extensions */
    if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
        return wext_handle_ioctl(net, &ifr, cmd, arg);
    ...
}
wext_handle_ioctl=>wireless_process_ioctl=>
if ((dev = __dev_get_by_name(net, ifr->ifr_name)) == NULL) ,
net , ioctl ethX struct net_device ,
ioctl_private_call(handler) dev->do_ioctl(dev, ifr, cmd) ioctl,
wlan_handler_def wlan_do_ioctl
====================
3.wifi kernel
wlan_probe()=>wlan_add_card()=>alloc_etherdev()=>
struct net_device *dev=alloc_etherdev() dev , :
    ...
    /* Setup the OS Interface to our functions */
    dev->open = wlan_open;
    dev->hard_start_xmit = wlan_hard_start_xmit;
    dev->stop = wlan_close;
    dev->do_ioctl = wlan_do_ioctl;
    dev->set_mac_address = wlan_set_mac_address;
    dev->tx_timeout = wlan_tx_timeout;
    dev->get_stats = wlan_get_stats;
    dev->watchdog_timeo = MRVDRV_DEFAULT_WATCHDOG_TIMEOUT;
    dev->wireless_handlers = (struct iw_handler_def *) &wlan_handler_def;
    dev->set_multicast_list = wlan_set_multicast_list;
    ...
4.socket ioctl ethX
asmlinkage long sys_socket(int family, int type, int protocol);sys_socket=>sock_create=>__sock_create=>sock = sock_alloc(); sock_mnt->mnt_sb socket inode , inode sock , sokcet dentry ,
net_families family ops ,
net_proto_family *pf=net_families[family];
pf->create(net, sock, protocol);// , ipv4, inet_create
ipv4
static struct net_proto_family inet_family_ops = {
    .family = PF_INET,
    .create = inet_create,
    .owner    = THIS_MODULE,
};
sokcet ,
sockfd = socket(AF_INET, SOCK_STREAM, 0);//AF_INET PF_INET, PF_INET
family AF_INET,type SOCK_STREAM, protocol 0, IP ,
inet_create=>inetsw[sock->type] inetsw[SOCK_STREAM],
inetsw[sock->type] protocol ,
inetsw[] ?inet_init()=>inet_register_protosw(inetsw_array)=> inetsw_array protocol inetsw ,
static struct inet_protosw inetsw_array[] =
{
    {
        .type = SOCK_STREAM,
        .protocol = IPPROTO_TCP,
        .prot = &tcp_prot,
        .ops = &inet_stream_ops,
        .capability = -1,
        .no_check = 0,
        .flags = INET_PROTOSW_PERMANENT | INET_PROTOSW_ICSK,
    },
    {
        .type = SOCK_DGRAM,
        .protocol = IPPROTO_UDP,
        .prot = &udp_prot,
        .ops = &inet_dgram_ops,
        .capability = -1,
        .no_check = UDP_CSUM_DEFAULT,
        .flags = INET_PROTOSW_PERMANENT,
    },

    {
        .type = SOCK_RAW,
        .protocol = IPPROTO_IP,    /* wild card */
        .prot = &raw_prot,
        .ops = &inet_sockraw_ops,
        .capability = CAP_NET_RAW,
        .no_check = UDP_CSUM_DEFAULT,
        .flags = INET_PROTOSW_REUSE,
    }
};
inet_init, fs_initcall(inet_init) , 5 build in , kernel start_kernel=>rest_init=>kernel_init=>do_basic_setup=>do_initcalls module .
sock->ops = answer->ops; ipv4 inet_stream_ops,
ops file ,
sys_socket=>sock_map_fd=>sock_attach_fd=>
dentry->d_op = &sockfs_dentry_operations;
init_file(file, sock_mnt, dentry, FMODE_READ | FMODE_WRITE, &socket_file_ops);
file->private_data = sock;
init_file=>file->f_op = fop; file->f_op = socket_file_ops;
read(),wirte(),poll() ioctl() file->f_op socket_file_ops ,
:
read() sock_aio_read
write() sock_aio_write
ioctl() sock_ioctl
socket_file_ops :
static const struct file_operations socket_file_ops = {
    .owner =    THIS_MODULE,
    .llseek =    no_llseek,
    .aio_read =    sock_aio_read,
    .aio_write =    sock_aio_write,
    .poll =        sock_poll,
    .unlocked_ioctl = sock_ioctl,
#ifdef CONFIG_COMPAT
    .compat_ioctl = compat_sock_ioctl,
#endif
    .mmap =        sock_mmap,
    .open =        sock_no_open,    /* special open code to disallow open via /proc */
    .release =    sock_close,
    .fasync =    sock_fasync,
    .sendpage =    sock_sendpage,
    .splice_write = generic_splice_sendpage,
};
, , , , , 【gliethttp.Leith】
wireless extention Blog :
wlan_add_card=>
wlan_create_thread(wlan_service_main_thread, &priv->MainThread, "wlan_main_service");
=>wlan_service_main_thread=>wlan_exec_next_cmd=>
wlan_enter_ps wlan_exit_ps

sbi_interrupt=> sdio ,sdio_irq_thread=>process_sdio_pending_irqs=> func->irq_handler(func); .
mmc_signal_sdio_irq=> wake_up_process(host->sdio_irq_thread); irq , wlan_exec_next_cmd
pxamci_irq mmc irq ,pxamci_irq=>mmc_signal_sdio_irq(host->mmc);
wlan_exec_next_cmd=> cmd CmdNode ,
wlan_dnld_cmd_to_fw(wlan_private * priv, CmdCtrlNode * CmdNode) CmdNode ,
wlan_mod_timer(&Adapter->MrvDrvCommandTimer, MRVDRV_TIMER_5S);
wlan_cmd_timeout_func ,
cmd , wlan_process_cmdresp, wlan_cancel_timer(&Adapter->MrvDrvCommandTimer);
wlan_service_main_thread=>
====
    /* Execute the next command */
    if (!priv->wlan_dev.cmd_sent && !Adapter->CurCmd)
        wlan_exec_next_cmd(priv);
====

wlan_prepare_cmd=>
wlan_hostcmd_ioctl=>
CmdNode wlan_get_cmd_node, , , CmdNode :
wlan_insert_cmd_to_pending_q(Adapter, CmdNode, TRUE);
wake_up_interruptible(&priv->MainThread.waitQ);

/*
 * iwconfig settable callbacks 
 */
static const iw_handler wlan_handler[] ,
/** wlan_handler_def */
struct iw_handler_def wlan_handler_def = {
  num_standard:sizeof(wlan_handler) / sizeof(iw_handler),
  num_private:sizeof(wlan_private_handler) / sizeof(iw_handler),
  num_private_args:sizeof(wlan_private_args) / sizeof(struct iw_priv_args),
  standard:(iw_handler *) wlan_handler,
  private:(iw_handler *) wlan_private_handler,
  private_args:(struct iw_priv_args *) wlan_private_args,
#if WIRELESS_EXT > 20
  get_wireless_stats:wlan_get_wireless_stats,
#endif
};
wlan_add_card
dev->wireless_handlers = (struct iw_handler_def *) &wlan_handler_def;
=============== kernel net wireless extention static iw_handler get_handler(struct net_device *dev, unsigned int cmd)
{
    /* Don't "optimise" the following variable, it will crash */
    unsigned int    index;        /* *MUST* be unsigned */
    /* Check if we have some wireless handlers defined */
    if (dev->wireless_handlers == NULL)
        return NULL;
    /* Try as a standard command */
    index = cmd - SIOCIWFIRST;
    if (index < dev->wireless_handlers->num_standard)
        return dev->wireless_handlers->standard[index];
    /* Try as a private command */
    index = cmd - SIOCIWFIRSTPRIV;
    if (index < dev->wireless_handlers->num_private)
        return dev->wireless_handlers->private[index];
    /* Not found */
    return NULL;
}

=>sock_ioctl
=>dev_ioctl
+++/* Take care of Wireless Extensions */
+++if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)
+++return wext_handle_ioctl(net, &ifr, cmd, arg);
=>wext_handle_ioctl
=>wireless_process_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd)
=>get_handler(dev, cmd); cmd, dev->do_ioctl ,

wlan_reassoc_timer_func=>
wmm_start_queue=>
wlan_tx_packet=>
wlan_tx_timeout=>
wlan_remove_card=>
wlan_hostcmd_ioctl=>
wlan_auto_deep_sleep=>
wlan_set_deep_sleep=>
wlan_prepare_cmd=>
wlan_cmd_timeout_func=>
wake_up_interruptible(&priv->MainThread.waitQ); wlan_service_main_thread .
wlan_hard_start_xmit=>wlan_tx_packet
dev->tx_timeout = wlan_tx_timeout;
wlan_initialize_timer(&Adapter->MrvDrvCommandTimer, wlan_cmd_timeout_func, priv);
int wlan_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
{
    ...
        case WLAN_WAKEUP_MT:
            if (wrq->u.data.length > 0)
                Adapter->IntCounter++;
            wake_up_interruptible(&priv->MainThread.waitQ);
            break;
    ...
}

wlan_process_cmdresp() cmd ,
wlan_insert_cmd_to_free_q=>wlan_clean_cmd_noder, cmd_node,
wlan_clean_cmd_noder pTempNode->CmdWaitQWoken = TRUE; cmd_node , .
wake_up_interruptible(&pTempNode->cmdwait_q);