Samsung VZW MB1 update
/drivers/net/wireless/bcmdhd/wl_cfgp2p.c
blob:969da37ae209d51b78e1f388d0fd966ab1bb4cae -> blob:64eb5f024ecd2b28cdc0d456e542037ca223bc6c
--- drivers/net/wireless/bcmdhd/wl_cfgp2p.c
+++ drivers/net/wireless/bcmdhd/wl_cfgp2p.c
@@ -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 <typedefs.h>
@@ -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);
+}