Fix p2p group add issue.
Change-Id: Ieb8fba54e04912b4002837243c00ba90fd150e5d
Signed-off-by: Howard M. Harte <hharte@broadcom.com>
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
bool ap_fw_loaded = FALSE;
#if defined(KEEP_ALIVE)
-int dhd_keep_alive_onoff(dhd_pub_t *dhd, int ka_on);
+int dhd_keep_alive_onoff(dhd_pub_t *dhd);
#endif /* KEEP_ALIVE */
/* Packet alignment for most efficient SDIO (can change based on platform) */
#if defined(SOFTAP)
if (ap_fw_loaded == FALSE)
#endif
- if ((res = dhd_keep_alive_onoff(dhd, 1)) < 0)
+ if ((res = dhd_keep_alive_onoff(dhd)) < 0)
DHD_ERROR(("%s set keeplive failed %d\n",
__FUNCTION__, res));
}
#endif /* PNO_SUPPORT */
#if defined(KEEP_ALIVE)
-int dhd_keep_alive_onoff(dhd_pub_t *dhd, int ka_on)
+int dhd_keep_alive_onoff(dhd_pub_t *dhd)
{
- char buf[256];
- char *buf_ptr = buf;
- wl_keep_alive_pkt_t keep_alive_pkt;
- char * str;
- int str_len, buf_len;
- int res = -1;
- int keep_alive_period = KEEP_ALIVE_PERIOD; /* in ms */
+ char buf[256];
+ const char *str;
+ wl_mkeep_alive_pkt_t mkeep_alive_pkt;
+ wl_mkeep_alive_pkt_t *mkeep_alive_pktp;
+ int buf_len;
+ int str_len;
+ int res = -1;
- DHD_TRACE(("%s: param=%d\n", __FUNCTION__, ka_on));
+ DHD_ERROR(("%s Enter\n", __FUNCTION__));
- if (ka_on) { /* on suspend */
- keep_alive_pkt.period_msec = keep_alive_period;
-
- } else {
- /* on resume, turn off keep_alive packets */
- keep_alive_pkt.period_msec = 0;
- }
-
- /* IOC var name */
- str = "keep_alive";
+ str = "mkeep_alive";
str_len = strlen(str);
strncpy(buf, str, str_len);
- buf[str_len] = '\0';
+ buf[ str_len ] = '\0';
+ mkeep_alive_pktp = (wl_mkeep_alive_pkt_t *) (buf + str_len + 1);
+ mkeep_alive_pkt.period_msec = KEEP_ALIVE_PERIOD;
buf_len = str_len + 1;
+ mkeep_alive_pkt.version = htod16(WL_MKEEP_ALIVE_VERSION);
+ mkeep_alive_pkt.length = htod16(WL_MKEEP_ALIVE_FIXED_LEN);
+ /* Setup keep alive zero for null packet generation */
+ mkeep_alive_pkt.keep_alive_id = 0;
+ mkeep_alive_pkt.len_bytes = 0;
+ buf_len += WL_MKEEP_ALIVE_FIXED_LEN;
+ /* Keep-alive attributes are set in local variable (mkeep_alive_pkt), and
+ * then memcpy'ed into buffer (mkeep_alive_pktp) since there is no
+ * guarantee that the buffer is properly aligned.
+ */
+ memcpy((char *)mkeep_alive_pktp, &mkeep_alive_pkt, WL_MKEEP_ALIVE_FIXED_LEN);
- /* set ptr to IOCTL payload after the var name */
- buf_ptr += buf_len; /* include term Z */
-
- /* copy Keep-alive attributes from local var keep_alive_pkt */
- str = NULL_PKT_STR;
- keep_alive_pkt.len_bytes = strlen(str);
-
- memcpy(buf_ptr, &keep_alive_pkt, WL_KEEP_ALIVE_FIXED_LEN);
- buf_ptr += WL_KEEP_ALIVE_FIXED_LEN;
-
- /* copy packet data */
- memcpy(buf_ptr, str, keep_alive_pkt.len_bytes);
- buf_len += (WL_KEEP_ALIVE_FIXED_LEN + keep_alive_pkt.len_bytes);
-/*
res = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, buf_len, TRUE, 0);
-*/
+
return res;
}
#endif /* defined(KEEP_ALIVE) */
}
if (ret == 0) {
strncpy(ifp->net->name, ifp->name, IFNAMSIZ);
+ ifp->net->name[IFNAMSIZ - 1] = '\0';
+ memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd));
#ifdef WL_CFG80211
if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
- wl_cfg80211_notify_ifadd(ifp->net);
+ if (!wl_cfg80211_notify_ifadd(ifp->net, ifp->idx, dhd_net_attach)) {
+ ifp->state = 0;
+ return;
+ }
+
#endif
- ifp->net->name[IFNAMSIZ - 1] = '\0';
- memcpy(netdev_priv(ifp->net), &dhd, sizeof(dhd));
if ((err = dhd_net_attach(&dhd->pub, ifp->idx)) != 0) {
DHD_ERROR(("%s: dhd_net_attach failed, err %d\n",
__FUNCTION__, err));
uint32 high;
};
-
+typedef struct wl_mkeep_alive_pkt {
+ uint16 version;
+ uint16 length;
+ uint32 period_msec;
+ uint16 len_bytes;
+ uint8 keep_alive_id;
+ uint8 data[1];
+} wl_mkeep_alive_pkt_t;
+
+#define WL_MKEEP_ALIVE_VERSION 1
+#define WL_MKEEP_ALIVE_FIXED_LEN OFFSETOF(wl_mkeep_alive_pkt_t, data)
+#define WL_MKEEP_ALIVE_PRECISION 500
#define WLC_ROAM_TRIGGER_DEFAULT 0
#define WLC_ROAM_TRIGGER_BANDWIDTH 1
static s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
struct net_device *dev, bool enabled,
s32 timeout);
-static s32 wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy,
- struct net_device *dev,
- const u8 *addr,
- const struct cfg80211_bitrate_mask *mask);
static int wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme);
static s32 wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
struct wl_priv *wl = WL_PRIV_GET();
struct net_device *_ndev;
dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
+ int (*net_attach)(dhd_pub_t *dhdp, int ifidx);
WL_DBG(("if name: %s, type: %d\n", name, type));
switch (type) {
wl->p2p->vif_created = true;
set_mode_by_netdev(wl, _ndev, mode);
wl = wdev_to_wl(vwdev);
+ net_attach = wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION);
+ rtnl_unlock();
+ if (net_attach && !net_attach(dhd, _ndev->ifindex))
+ WL_DBG((" virtual interface(%s) is "
+ "created\n", wl->p2p->vir_ifname));
+ else {
+ rtnl_lock();
+ goto fail;
+ }
+ rtnl_lock();
return _ndev;
} else {
wl->p2p->vif_created = false;
}
}
+fail:
return ERR_PTR(-ENODEV);
}
}
s32
-wl_cfg80211_notify_ifadd(struct net_device *net)
+wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx,
+int (*_net_attach)(dhd_pub_t *dhdp, int ifidx))
{
struct wl_priv *wl = WL_PRIV_GET();
s32 ret = BCME_OK;
- if (!net || !net->name) {
+ if (!net) {
WL_ERR(("net is NULL\n"));
return 0;
}
wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = net;
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) =
P2PAPI_BSSCFG_CONNECTION;
+ wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION) = _net_attach;
wl_clr_p2p_status(wl, IF_ADD);
+ net->ifindex = idx;
wake_up_interruptible(&wl->dongle_event_wait);
}
return ret;
return ret;
}
-static s32
-wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
- const u8 *addr,
- const struct cfg80211_bitrate_mask *mask)
-{
- struct wl_rateset rateset;
- s32 rate;
- s32 val;
- s32 err_bg;
- s32 err_a;
- u32 legacy;
- s32 err = 0;
-
- CHECK_SYS_UP();
- /* addr param is always NULL. ignore it */
- /* Get current rateset */
- err = wldev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset,
- sizeof(rateset), false);
- if (unlikely(err)) {
- WL_ERR(("could not get current rateset (%d)\n", err));
- return err;
- }
-
- rateset.count = dtoh32(rateset.count);
-
- legacy = wl_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy);
- if (!legacy)
- legacy = wl_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy);
-
- val = wl_g_rates[legacy - 1].bitrate * 100000;
-
- if (val < rateset.count) {
- /* Select rate by rateset index */
- rate = rateset.rates[val] & 0x7f;
- } else {
- /* Specified rate in bps */
- rate = val / 500000;
- }
-
- WL_DBG(("rate %d mbps\n", (rate / 2)));
-
- /*
- *
- * Set rate override,
- * Since the is a/b/g-blind, both a/bg_rate are enforced.
- */
- err_bg = wl_dev_intvar_set(dev, "bg_rate", rate);
- err_a = wl_dev_intvar_set(dev, "a_rate", rate);
- if (unlikely(err_bg && err_a)) {
- WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a));
- return err_bg | err_a;
- }
-
- return err;
-}
-
static s32 wl_cfg80211_resume(struct wiphy *wiphy)
{
struct wl_priv *wl = WL_PRIV_GET();
.set_default_key = wl_cfg80211_config_default_key,
.set_default_mgmt_key = wl_cfg80211_config_default_mgmt_key,
.set_power_mgmt = wl_cfg80211_set_power_mgmt,
- .set_bitrate_mask = wl_cfg80211_set_bitrate_mask,
.connect = wl_cfg80211_connect,
.disconnect = wl_cfg80211_disconnect,
.suspend = wl_cfg80211_suspend,
extern struct sdio_func *wl_cfg80211_get_sdio_func(void); /* set sdio function info */
extern s32 wl_cfg80211_up(void); /* dongle up */
extern s32 wl_cfg80211_down(void); /* dongle down */
-extern s32 wl_cfg80211_notify_ifadd(struct net_device *net);
+extern s32 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx,
+int (*_net_attach)(dhd_pub_t *dhdp, int ifidx));
extern s32 wl_cfg80211_ifdel_ops(struct net_device *net);
extern s32 wl_cfg80211_notify_ifdel(struct net_device *net);
extern s32 wl_cfg80211_is_progress_ifadd(void);
u32 bssidx;
struct net_device *dev;
struct p2p_saved_ie saved_ie;
+ void *private_data;
};
struct p2p_info {
#define wl_to_p2p_bss_ndev(w, type) ((wl)->p2p->bss_idx[type].dev)
#define wl_to_p2p_bss_bssidx(w, type) ((wl)->p2p->bss_idx[type].bssidx)
#define wl_to_p2p_bss_saved_ie(w, type) ((wl)->p2p->bss_idx[type].saved_ie)
+#define wl_to_p2p_bss_private(w, type) ((wl)->p2p->bss_idx[type].private_data)
#define wl_to_p2p_bss(wl, type) ((wl)->p2p->bss_idx[type])
#define wl_get_p2p_status(wl, stat) ((!(wl)->p2p_supported) ? 0 : test_bit(WLP2P_STATUS_ ## stat, \
&(wl)->p2p->status))