但不影响WIFI的使用, 串口输出如下:
mlan0     regioncode:48 
Can not find ssid: g苅sQJ?秃F|耇?桤峷Z.c3熒?
ioctl[SIOCSIWESSID]: Bad address
udhcpc (v1.20.2) started
Setting IP address 0.0.0.0 on mlan0
Sending discover...
MMSG: Link up
Sending discover...
Sending select for 192.168.1.103...
Lease of 192.168.1.103 obtained, lease time 7200
Setting IP address 192.168.1.103 on mlan0
Deleting routers
route: SIOCDELRT: No such process
Adding router 192.168.1.1
Recreating /etc/resolv.conf
 Adding DNS server 192.168.1.1
 
 
 经查发现“Can not find ssid: g苅sQJ?秃F|耇?桤峷Z.c3熒?”是内核中w8782的输出的,
 而且是在运行wpa_supplicant -B -Dwext -imlan0 -c ./wpa2.conf 时出现。
 
 跟踪wpa_supplicant源码,发现在src/drivers/driver_wext.c中,生成一个随机的32字节长SSID,
 让w8782模块去连接,当然出现找不到SSID和出现乱码了(参考1735-1739注释)。
1701 static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
1702 {
1703     struct iwreq iwr;
1704     const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
1705     u8 ssid[32];
1706     int i;
1707
1708     /*
1709      * Only force-disconnect when the card is in infrastructure mode,
1710      * otherwise the driver might interpret the cleared BSSID and random
1711      * SSID as an attempt to create a new ad-hoc network.
1712      */
1713     os_memset(&iwr, 0, sizeof(iwr));
1714     os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
1715     if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
1716         perror("ioctl[SIOCGIWMODE]");
1717         iwr.u.mode = IW_MODE_INFRA;
1718     }
1719
1720     if (iwr.u.mode == IW_MODE_INFRA) {
1721         if (drv->cfg80211) {
1722             /*
1723              * cfg80211 supports SIOCSIWMLME commands, so there is
1724              * no need for the random SSID hack, but clear the
1725              * BSSID and SSID.
1726              */
1727             if (wpa_driver_wext_set_bssid(drv, null_bssid) < 0 ||
1728                 wpa_driver_wext_set_ssid(drv, (u8 *) "", 0) < 0) {
1729                 wpa_printf(MSG_DEBUG, "WEXT: Failed to clear "
1730                        "to disconnect");
1731             }
1732             return;
1733         }
1734         /*
1735          * Clear the BSSID selection and set a random SSID to make sure
1736          * the driver will not be trying to associate with something
1737          * even if it does not understand SIOCSIWMLME commands (or
1738          * tries to associate automatically after deauth/disassoc).
1739          */
1740         for (i = 0; i < 32; i++)
1741             ssid[i] = rand() & 0xFF;
1742         if (wpa_driver_wext_set_bssid(drv, null_bssid) < 0 ||
1743             wpa_driver_wext_set_ssid(drv, ssid, 32) < 0) {
1744             wpa_printf(MSG_DEBUG, "WEXT: Failed to set bogus "
1745                    "BSSID/SSID to disconnect");
1746         }
1747     }
1748 }

进一步看,为什么不走1722-1732这个分支呢,这样就不会让8782试较长连接随机产生的SSID了。
显然drv->cfg80211为0,查找了一下将其置位的地方是同一文件中的函数.
 697 void * wpa_driver_wext_init(void *ctx, const char *ifname)
 698 {
 699     struct wpa_driver_wext_data *drv;
 700     struct netlink_config *cfg;
 701     char path[128];
 702     struct stat buf;
 703
 ....
 ....
 709
 710     os_snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211", ifname);
 711     if (stat(path, &buf) == 0) {
 712         wpa_printf(MSG_DEBUG, "WEXT: cfg80211-based driver detected");
 713         drv->cfg80211 = 1;
 714     }
 715
 716     drv->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);
 717     if (drv->ioctl_sock < 0) {
 718         perror("socket(PF_INET,SOCK_DGRAM)");
 719         goto err1;
 720     }
 }

 原来需要/sys/class/net/mlan0/phy80211文件,但在板子上的系统上查了一下,并没有phy80211这个
 文件。应该是内核没有开启这个功能。

 折腾了一番,找到phy80211对应的是内核源码中 net/mac80211部分代码,确实没有使能。
重新配置内核,打开MAC80211:
+CONFIG_MAC80211=y
+CONFIG_MAC80211_HAS_RC=y
+# CONFIG_MAC80211_RC_PID is not set
+CONFIG_MAC80211_RC_MINSTREL=y
+# CONFIG_MAC80211_RC_DEFAULT_PID is not set
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel"
+# CONFIG_MAC80211_MESH is not set
+# CONFIG_MAC80211_LEDS is not set
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set

编译后重新跑,结果仍然没有找到phy80211。
经调试,在内核net/mac80211/main.c代码中, ieee80211_init(void)在内核启动时调用了,但
ieee80211_register_hw(struct ieee80211_hw *hw)没有调用,ieee80211_register_hw()将调用ieee80211_if_add(),
而ieee80211_if_add()将进行赋值ndev->ieee80211_ptr = &sdata->wdev; 这样在net/wireless/core.c中
的cfg80211_netdev_notifier_call()函数中就能进行网络设备的注册,从而生成phy80211文件(参考
下述代码657-661和690-694)。
652 static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
653                      unsigned long state,
654                      void *ndev)
655 {
656     struct net_device *dev = ndev;
657     struct wireless_dev *wdev = dev->ieee80211_ptr;
658     struct cfg80211_registered_device *rdev;
659
660     if (!wdev)
661         return NOTIFY_DONE;
662
663     rdev = wiphy_to_dev(wdev->wiphy);
664
665     WARN_ON(wdev->iftype == NL80211_IFTYPE_UNSPECIFIED);
666
667     switch (state) {
668     case NETDEV_POST_INIT:
669         SET_NETDEV_DEVTYPE(dev, &wiphy_type);
670         break;
671     case NETDEV_REGISTER:
672         /*
673          * NB: cannot take rdev->mtx here because this may be
674          * called within code protected by it when interfaces
675          * are added with nl80211.
676          */
677         mutex_init(&wdev->mtx);
678         INIT_WORK(&wdev->cleanup_work, wdev_cleanup_work);
679         INIT_LIST_HEAD(&wdev->event_list);
680         spin_lock_init(&wdev->event_lock);
681         INIT_LIST_HEAD(&wdev->action_registrations);
682         spin_lock_init(&wdev->action_registrations_lock);
683
684         mutex_lock(&rdev->devlist_mtx);
685         list_add_rcu(&wdev->list, &rdev->netdev_list);
686         rdev->devlist_generation++;
687         /* can only change netns with wiphy */
688         dev->features |= NETIF_F_NETNS_LOCAL;
689
690         if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj,
691                       "phy80211")) {
692             printk(KERN_ERR "wireless: failed to add phy80211 "
693                 "symlink to netdev!\n");
694         }
695         wdev->netdev = dev;
696         wdev->sme_state = CFG80211_SME_IDLE;
697         mutex_unlock(&rdev->devlist_mtx);
698 #ifdef CONFIG_CFG80211_WEXT
699         wdev->wext.default_key = -1;
700         wdev->wext.default_mgmt_key = -1;
701         wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
702 #endif
703
704         if (wdev->wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT)
705             wdev->ps = true;
706         else
707             wdev->ps = false;
......
......
}

为什么ieee80211_register_hw()没有被调用呢? 这就是w8782驱动的问题,也许是
w8782驱动设计就是如此,它不需要IEEE80211。driver/net/wireless/下面很多其它
wifi模块是会调用ieee80211_register_hw()来进行注册的。。。

Logo

更多推荐