w8782连WIFI出现Can not find ssid并且出现乱码问题
但不影响WIFI的使用, 串口输出如下:arm-linux#> ./w8782sta_enc.sh [Jmlan0 regioncode:48 Can not find ssid: g苅sQJ?秃F|耇?桤峷Z.c3熒?ioctl[SIOCSIWESSID]: Bad addressudhcpc (v1.20.2) startedSetting IP ad
但不影响WIFI的使用, 串口输出如下:
mlan0 regioncode:48
Can not find ssid: g苅sQJ?秃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苅sQJ?秃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()来进行注册的。。。
更多推荐
所有评论(0)