--- 969da37ae209d51b78e1f388d0fd966ab1bb4cae +++ 64eb5f024ecd2b28cdc0d456e542037ca223bc6c @@ -21,7 +21,7 @@ * software in any way with any other Broadcom software provided under a license * other than the GPL, without Broadcom's express prior written consent. * - * $Id: wl_cfgp2p.c 357864 2012-09-20 06:41:42Z $ + * $Id: wl_cfgp2p.c 371797 2012-11-29 11:19:45Z $ * */ #include @@ -409,7 +409,7 @@ wl_cfgp2p_ifadd(struct wl_priv *wl, stru memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet)); CFGP2P_DBG(("---wl p2p_ifadd "MACDBG" %s %u\n", - STR_TO_MACD(ifreq.addr.octet), + MAC2STRDBG(ifreq.addr.octet), (if_type == WL_P2P_IF_GO) ? "go" : "client", (chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT)); @@ -438,7 +438,7 @@ wl_cfgp2p_ifdisable(struct wl_priv *wl, struct net_device *netdev = wl_to_prmry_ndev(wl); CFGP2P_INFO(("------primary idx %d : wl p2p_ifdis "MACDBG"\n", - netdev->ifindex, STR_TO_MACD(mac->octet))); + netdev->ifindex, MAC2STRDBG(mac->octet))); ret = wldev_iovar_setbuf(netdev, "p2p_ifdis", mac, sizeof(*mac), wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); if (unlikely(ret < 0)) { @@ -459,7 +459,7 @@ wl_cfgp2p_ifdel(struct wl_priv *wl, stru struct net_device *netdev = wl_to_prmry_ndev(wl); CFGP2P_INFO(("------primary idx %d : wl p2p_ifdel "MACDBG"\n", - netdev->ifindex, STR_TO_MACD(mac->octet))); + netdev->ifindex, MAC2STRDBG(mac->octet))); ret = wldev_iovar_setbuf(netdev, "p2p_ifdel", mac, sizeof(*mac), wl->ioctl_buf, WLC_IOCTL_MAXLEN, &wl->ioctl_buf_sync); if (unlikely(ret < 0)) { @@ -488,7 +488,7 @@ wl_cfgp2p_ifchange(struct wl_priv *wl, s memcpy(ifreq.addr.octet, mac->octet, sizeof(ifreq.addr.octet)); CFGP2P_INFO(("---wl p2p_ifchange "MACDBG" %s %u" - " chanspec 0x%04x\n", STR_TO_MACD(ifreq.addr.octet), + " chanspec 0x%04x\n", MAC2STRDBG(ifreq.addr.octet), (if_type == WL_P2P_IF_GO) ? "go" : "client", (chspec & WL_CHANSPEC_CHAN_MASK) >> WL_CHANSPEC_CHAN_SHIFT, ifreq.chspec)); @@ -520,7 +520,7 @@ wl_cfgp2p_ifidx(struct wl_priv *wl, stru u8 getbuf[64]; struct net_device *dev = wl_to_prmry_ndev(wl); - CFGP2P_INFO(("---wl p2p_if "MACDBG"\n", STR_TO_MACD(mac->octet))); + CFGP2P_INFO(("---wl p2p_if "MACDBG"\n", MAC2STRDBG(mac->octet))); ret = wldev_iovar_getbuf_bsscfg(dev, "p2p_if", mac, sizeof(*mac), getbuf, sizeof(getbuf), wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_PRIMARY), NULL); @@ -677,7 +677,7 @@ wl_cfgp2p_deinit_discovery(struct wl_pri /* Clear the saved bsscfg index of the discovery BSSCFG to indicate we * have no discovery BSS. */ - wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = 0; + wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) = WL_INVALID; wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE) = NULL; return ret; @@ -1262,16 +1262,26 @@ exit: s32 wl_cfgp2p_clear_management_ie(struct wl_priv *wl, s32 bssidx) { + + s32 vndrie_flag[] = {VNDR_IE_BEACON_FLAG, VNDR_IE_PRBRSP_FLAG, VNDR_IE_ASSOCRSP_FLAG, + VNDR_IE_PRBREQ_FLAG, VNDR_IE_ASSOCREQ_FLAG}; + s32 index = -1; + struct net_device *ndev = wl_cfgp2p_find_ndev(wl, bssidx); #define INIT_IE(IE_TYPE, BSS_TYPE) \ do { \ memset(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie, 0, \ sizeof(wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie)); \ wl_to_p2p_bss_saved_ie(wl, BSS_TYPE).p2p_ ## IE_TYPE ## _ie_len = 0; \ } while (0); - if (bssidx < 0) { - CFGP2P_ERR(("invalid bssidx\n")); + + if (bssidx < 0 || ndev == NULL) { + CFGP2P_ERR(("invalid %s\n", (bssidx < 0) ? "bssidx" : "ndev")); return BCME_BADARG; } + for (index = 0; index < ARRAYSIZE(vndrie_flag); index++) { + /* clean up vndr ies in dongle */ + wl_cfgp2p_set_management_ie(wl, ndev, bssidx, vndrie_flag[index], NULL, 0); + } INIT_IE(probe_req, bssidx); INIT_IE(probe_res, bssidx); INIT_IE(assoc_req, bssidx); @@ -1441,6 +1451,27 @@ wl_cfgp2p_find_idx(struct wl_priv *wl, s exit: return index; } +struct net_device * +wl_cfgp2p_find_ndev(struct wl_priv *wl, s32 bssidx) +{ + u32 i; + struct net_device *ndev = NULL; + if (bssidx < 0) { + CFGP2P_ERR((" bsscfg idx is invalid\n")); + goto exit; + } + + for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) { + if (bssidx == wl_to_p2p_bss_bssidx(wl, i)) { + ndev = wl_to_p2p_bss_ndev(wl, i); + break; + } + } + +exit: + return ndev; +} + /* * Callback function for WLC_E_P2P_DISC_LISTEN_COMPLETE */ @@ -1893,10 +1924,14 @@ wl_cfgp2p_supported(struct wl_priv *wl, s32 wl_cfgp2p_down(struct wl_priv *wl) { - + s32 i = 0, index = -1; wl_cfgp2p_cancel_listen(wl, wl->p2p_net ? wl->p2p_net : wl_to_prmry_ndev(wl), TRUE); - + for (i = 0; i < P2PAPI_BSSCFG_MAX; i++) { + index = wl_to_p2p_bss_bssidx(wl, i); + if (index != WL_INVALID) + wl_cfgp2p_clear_management_ie(wl, index); + } wl_cfgp2p_deinit_priv(wl); return 0; } @@ -2042,10 +2077,17 @@ wl_cfgp2p_set_p2p_ps(struct wl_priv *wl, } if ((legacy_ps != -1) && ((legacy_ps == PM_MAX) || (legacy_ps == PM_OFF))) { +#if !defined(SUPPORT_PM2_ONLY) + if (legacy_ps == PM_MAX) + legacy_ps = PM_FAST; +#endif /* SUPPORT_PM2_ONLY */ + ret = wldev_ioctl(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION), WLC_SET_PM, &legacy_ps, sizeof(legacy_ps), true); if (unlikely(ret)) { CFGP2P_ERR(("error (%d)\n", ret)); + } else { + wl_cfg80211_update_power_mode(ndev); } } else @@ -2166,13 +2208,25 @@ wl_cfgp2p_register_ndev(struct wl_priv * { int ret = 0; struct net_device* net = NULL; - struct wireless_dev *wdev; + struct wireless_dev *wdev = NULL; uint8 temp_addr[ETHER_ADDR_LEN] = { 0x00, 0x90, 0x4c, 0x33, 0x22, 0x11 }; + if (wl->p2p_net) { + CFGP2P_ERR(("p2p_net defined already.\n")); + return -EINVAL; + } + /* Allocate etherdev, including space for private structure */ if (!(net = alloc_etherdev(sizeof(struct wl_priv *)))) { CFGP2P_ERR(("%s: OOM - alloc_etherdev\n", __FUNCTION__)); - goto fail; + return -ENODEV; + } + + wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); + if (unlikely(!wdev)) { + WL_ERR(("Could not allocate wireless device\n")); + free_netdev(net); + return -ENOMEM; } strncpy(net->name, "p2p%d", sizeof(net->name) - 1); @@ -2195,12 +2249,6 @@ wl_cfgp2p_register_ndev(struct wl_priv * /* Register with a dummy MAC addr */ memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN); - wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); - if (unlikely(!wdev)) { - WL_ERR(("Could not allocate wireless device\n")); - return -ENOMEM; - } - wdev->wiphy = wl->wdev->wiphy; wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS); @@ -2216,40 +2264,23 @@ wl_cfgp2p_register_ndev(struct wl_priv * /* Associate p2p0 network interface with new wdev */ wdev->netdev = net; + ret = register_netdev(net); + if (ret) { + CFGP2P_ERR((" register_netdevice failed (%d)\n", ret)); + free_netdev(net); + kfree(wdev); + return -ENODEV; + } + /* store p2p net ptr for further reference. Note that iflist won't have this * entry as there corresponding firmware interface is a "Hidden" interface. */ - if (wl->p2p_net) { - CFGP2P_ERR(("p2p_net defined already.\n")); - return -EINVAL; - } else { wl->p2p_wdev = wdev; wl->p2p_net = net; - } - - ret = register_netdev(net); - if (ret) { - CFGP2P_ERR((" register_netdevice failed (%d)\n", ret)); - goto fail; - } printk("%s: P2P Interface Registered\n", net->name); return ret; -fail: - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 31) - net->open = NULL; -#else - net->netdev_ops = NULL; -#endif - - if (net) { - unregister_netdev(net); - free_netdev(net); - } - - return -ENODEV; } s32 @@ -2268,7 +2299,13 @@ wl_cfgp2p_unregister_ndev(struct wl_priv } static int wl_cfgp2p_start_xmit(struct sk_buff *skb, struct net_device *ndev) { - CFGP2P_DBG(("(%s) is not used for data operations. Droping the packet. \n", ndev->name)); + if(skb) + { + CFGP2P_DBG(("(%s) is not used for data operations.Droping the packet.\n", + ndev->name)); + dev_kfree_skb_any(skb); + } + return 0; } @@ -2296,21 +2333,22 @@ static int wl_cfgp2p_do_ioctl(struct net static int wl_cfgp2p_if_open(struct net_device *net) { + extern struct wl_priv *wlcfg_drv_priv; struct wireless_dev *wdev = net->ieee80211_ptr; - - if (!wdev) + struct wl_priv *wl = NULL; + wl = wlcfg_drv_priv; + if (!wdev || !wl || !wl->p2p) return -EINVAL; - + WL_TRACE(("Enter\n")); /* If suppose F/W download (ifconfig wlan0 up) hasn't been done by now, * do it here. This will make sure that in concurrent mode, supplicant * is not dependent on a particular order of interface initialization. * i.e you may give wpa_supp -iwlan0 -N -ip2p0 or wpa_supp -ip2p0 -N * -iwlan0. */ - wl_cfg80211_do_driver_init(net); - wdev->wiphy->interface_modes |= (BIT(NL80211_IFTYPE_P2P_CLIENT) | BIT(NL80211_IFTYPE_P2P_GO)); + wl_cfg80211_do_driver_init(net); return 0; } @@ -2341,10 +2379,10 @@ static int wl_cfgp2p_if_stop(struct net_ wdev->wiphy->interface_modes = (wdev->wiphy->interface_modes) & (~(BIT(NL80211_IFTYPE_P2P_CLIENT)| BIT(NL80211_IFTYPE_P2P_GO))); -#if defined(CUSTOMER_HW4) - if (net->flags & IFF_UP) - net->flags &= ~IFF_UP; -#endif - return 0; } + +bool wl_cfgp2p_is_ifops(const struct net_device_ops *if_ops) +{ + return (if_ops == &wl_cfgp2p_if_ops); +}