return ret;
}
-int
+static int
dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
{
dhd_prot_t *prot = dhd->prot;
return ret;
}
-int
+static int
dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len, uint8 action)
{
dhd_prot_t *prot = dhd->prot;
#ifdef CONFIG_BCMDHD_FW_PATH
bcm_strncpy_s(fw_path, sizeof(fw_path), CONFIG_BCMDHD_FW_PATH, MOD_PARAM_PATHLEN-1);
-#else
+#else /* CONFIG_BCMDHD_FW_PATH */
fw_path[0] = '\0';
#endif /* CONFIG_BCMDHD_FW_PATH */
#ifdef CONFIG_BCMDHD_NVRAM_PATH
bcm_strncpy_s(nv_path, sizeof(nv_path), CONFIG_BCMDHD_NVRAM_PATH, MOD_PARAM_PATHLEN-1);
-#else
+#else /* CONFIG_BCMDHD_NVRAM_PATH */
nv_path[0] = '\0';
#endif /* CONFIG_BCMDHD_NVRAM_PATH */
#ifdef SOFTAP
else if (pktq_full(q)) {
p = pktq_peek_tail(q, &eprec);
ASSERT(p);
- if (eprec > prec)
+ if (eprec > prec || eprec < 0)
return FALSE;
}
int str_len;
uint32 mask_size;
uint32 pattern_size;
- char buf[256];
+ char buf[WLC_IOCTL_SMLEN];
char *ptr;
uint filter_mode = 1;
uint32 listen_interval = LISTEN_INTERVAL; /* Default Listen Interval in Beacons */
memset(buf, 0, sizeof(buf));
ptr = buf;
bcm_mkiovar("ver", (char *)&buf, 4, buf, sizeof(buf));
- dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), TRUE, 0);
- bcmstrtok(&ptr, "\n", 0);
- /* Print fw version info */
- DHD_ERROR(("Firmware version = %s\n", buf));
-
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, sizeof(buf), FALSE, 0)) < 0)
+ DHD_ERROR(("%s failed %d\n", __FUNCTION__, ret));
+ else {
+ bcmstrtok(&ptr, "\n", 0);
+ /* Print fw version info */
+ DHD_ERROR(("Firmware version = %s\n", buf));
+ }
/* Set PowerSave mode */
dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)&power_mode, sizeof(power_mode), TRUE, 0);
dhd_get_dtim_skip(dhd_pub_t *dhd)
{
int bcn_li_dtim;
- char buf[128];
int ret;
+ uint8 bssid[6];
int dtim_assoc = 0;
if ((dhd->dtim_skip == 0) || (dhd->dtim_skip == 1))
else
bcn_li_dtim = dhd->dtim_skip;
- /* Read DTIM value if associated */
- memset(buf, 0, sizeof(buf));
- bcm_mkiovar("dtim_assoc", 0, 0, buf, sizeof(buf));
- if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, buf, sizeof(buf), TRUE, 0)) < 0) {
+ /* Check if associated */
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_BSSID,
+ (char *)&bssid, ETHER_ADDR_LEN, FALSE, 0)) == BCME_NOTASSOCIATED) {
+ DHD_TRACE(("%s NOT assoc ret %d\n", __FUNCTION__, ret));
+ goto exit;
+ }
+
+ /* if assoc grab ap's dtim value */
+ if ((ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_DTIMPRD,
+ &dtim_assoc, sizeof(dtim_assoc), FALSE, 0)) < 0) {
DHD_ERROR(("%s failed code %d\n", __FUNCTION__, ret));
- bcn_li_dtim = 1;
goto exit;
}
- else
- dtim_assoc = dtoh32(*(int *)buf);
DHD_ERROR(("%s bcn_li_dtim=%d DTIM=%d Listen=%d\n",
__FUNCTION__, bcn_li_dtim, dtim_assoc, LISTEN_INTERVAL));
#define DHD_EVENT(args) do {if (dhd_msg_level & DHD_EVENT_VAL) printf args;} while (0)
#define DHD_BTA(args) do {if (dhd_msg_level & DHD_BTA_VAL) printf args;} while (0)
#define DHD_ISCAN(args) do {if (dhd_msg_level & DHD_ISCAN_VAL) printf args;} while (0)
+#define DHD_ARPOE(args) do {if (dhd_msg_level & DHD_ARPOE_VAL) printf args;} while (0)
#define DHD_ERROR_ON() (dhd_msg_level & DHD_ERROR_VAL)
#define DHD_TRACE_ON() (dhd_msg_level & DHD_TRACE_VAL)
#define DHD_EVENT_ON() (dhd_msg_level & DHD_EVENT_VAL)
#define DHD_BTA_ON() (dhd_msg_level & DHD_BTA_VAL)
#define DHD_ISCAN_ON() (dhd_msg_level & DHD_ISCAN_VAL)
+#define DHD_ARPOE_ON() (dhd_msg_level & DHD_ARPOE_VAL)
#else /* defined(BCMDBG) || defined(DHD_DEBUG) */
#define DHD_EVENT(args)
#define DHD_BTA(args)
#define DHD_ISCAN(args)
+#define DHD_ARPOE(args)
#define DHD_ERROR_ON() 0
#define DHD_TRACE_ON() 0
#define DHD_EVENT_ON() 0
#define DHD_BTA_ON() 0
#define DHD_ISCAN_ON() 0
+#define DHD_ARPOE_ON() 0
#endif
#define DHD_LOG(args)
*
* $Id: dhd_linux.c,v 1.131.2.55 2011-02-09 05:31:56 Exp $
*/
+
+#ifdef CONFIG_WIFI_CONTROL_FUNC
+#include <linux/platform_device.h>
+#endif
#include <typedefs.h>
#include <linuxver.h>
#include <osl.h>
#include <linux/slab.h>
#include <linux/skbuff.h>
#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/rtnetlink.h>
#include <linux/etherdevice.h>
#include <linux/random.h>
#include <linux/spinlock.h>
static uint32 tsidx = 0;
static uint32 htsf_seqnum = 0;
-
uint32 tsfsync;
struct timeval tsync;
static uint32 tsport = 5010;
static histo_t vi_d1, vi_d2, vi_d3, vi_d4;
#endif /* WLMEDIA_HTSF */
+#if defined(ANDROID) && defined(SOFTAP)
+extern bool ap_cfg_running;
+#endif
+
+/* enable HOSTIP cache update from the host side when an eth0:N is up */
+#define AOE_IP_ALIAS_SUPPORT 1
+
#ifdef PROP_TXSTATUS
#include <wlfc_proto.h>
#include <dhd_wlfc.h>
#endif
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+
-#ifdef CONFIG_WIFI_CONTROL_FUNC
-#include <linux/platform_device.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
#include <linux/wlan_plat.h>
#else
#endif
struct semaphore wifi_control_sem;
+struct dhd_bus *g_bus;
static struct wifi_platform_data *wifi_control_data = NULL;
static struct resource *wifi_irqres = NULL;
DHD_ERROR(("## %s\n", __FUNCTION__));
wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "bcmdhd_wlan_irq");
+ if (wifi_irqres == NULL)
+ wifi_irqres = platform_get_resource_byname(pdev,
+ IORESOURCE_IRQ, "bcm4329_wlan_irq");
wifi_control_data = wifi_ctrl;
wifi_set_power(1, 0); /* Power On */
DHD_TRACE(("##> %s\n", __FUNCTION__));
return 0;
}
-
static struct platform_driver wifi_device = {
.probe = wifi_probe,
.remove = wifi_remove,
}
};
+static struct platform_driver wifi_device_legacy = {
+ .probe = wifi_probe,
+ .remove = wifi_remove,
+ .suspend = wifi_suspend,
+ .resume = wifi_resume,
+ .driver = {
+ .name = "bcm4329_wlan",
+ }
+};
+
int wifi_add_dev(void)
{
DHD_TRACE(("## Calling platform_driver_register\n"));
- return platform_driver_register(&wifi_device);
+ platform_driver_register(&wifi_device);
+ platform_driver_register(&wifi_device_legacy);
+ return 0;
}
void wifi_del_dev(void)
{
DHD_TRACE(("## Unregister platform_driver_register\n"));
platform_driver_unregister(&wifi_device);
+ platform_driver_unregister(&wifi_device_legacy);
}
#endif
+#ifdef ARP_OFFLOAD_SUPPORT
+static int dhd_device_event(struct notifier_block *this,
+ unsigned long event,
+ void *ptr);
+
+static struct notifier_block dhd_notifier = {
+ .notifier_call = dhd_device_event
+};
+#endif /* ARP_OFFLOAD_SUPPORT */
+
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
#include <linux/suspend.h>
volatile bool dhd_mmc_suspend = FALSE;
#define DHD_COMPILED "\nCompiled in " SRCBASE
#else
#define DHD_COMPILED
-#endif
+#endif /* DHD_DEBUG */
static char dhd_version[] = "Dongle Host Driver, version " EPI_VERSION_STR
#ifdef DHD_DEBUG
}
#if defined(CONFIG_HAS_EARLYSUSPEND)
-extern int dhd_get_dtim_skip(dhd_pub_t *dhd);
static int dhd_set_suspend(int value, dhd_pub_t *dhd)
{
int power_mode = PM_MAX;
DHD_TRACE(("%s: idx %d, state %d\n", __FUNCTION__, ifp->idx, ifp->state));
+#ifdef WL_CFG80211
+ if (wl_cfg80211_is_progress_ifchange())
+ return;
+
+#endif
switch (ifp->state) {
case WLC_E_IF_ADD:
/*
}
if (ret == 0) {
strncpy(ifp->net->name, ifp->name, IFNAMSIZ);
+#ifdef WL_CFG80211
+ if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
+ wl_cfg80211_notify_ifadd(ifp->net);
+#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) {
__FUNCTION__, err));
ret = -EOPNOTSUPP;
} else {
-#ifdef SOFTAP
+#if defined(ANDROID) && defined(SOFTAP)
+ if (ap_cfg_running && !(dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)) {
/* semaphore that the soft AP CODE waits on */
flags = dhd_os_spin_lock(&dhd->pub);
/* signal to the SOFTAP 'sleeper' thread, wl0.1 is ready */
up(&ap_eth_ctl.sema);
dhd_os_spin_unlock(&dhd->pub, flags);
+ }
#endif
DHD_TRACE(("\n ==== pid:%x, net_device for if:%s created ===\n\n",
current->pid, ifp->net->name));
}
dhd->iflist[ifp->idx] = NULL;
MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
+#ifdef WL_CFG80211
+ if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
+ wl_cfg80211_notify_ifdel(ifp->net);
+#endif
#ifdef SOFTAP
flags = dhd_os_spin_lock(&dhd->pub);
if (ifp->net == ap_net_dev)
break;
}
+
for (i = 0; i < DHD_MAX_IFS; i++) {
if (dhd->iflist[i]) {
DHD_TRACE(("%s: interface %d\n", __FUNCTION__, i));
}
}
}
+
DHD_OS_WAKE_UNLOCK(&dhd->pub);
}
DHD_TRACE(("%s: stopped\n", __FUNCTION__));
skb_pull(skb, ETH_HLEN);
/* Process special event packets and then discard them */
- if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM)
+ if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) {
dhd_wl_host_event(dhd, &ifidx,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
skb->mac_header,
if (event.event_type == WLC_E_BTA_HCI_EVENT) {
dhd_bta_doevt(dhdp, data, event.datalen);
}
+ }
ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]);
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(net);
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
-#ifdef WL_CFG80211
- wl_cfg80211_down();
-#endif
if (dhd->pub.up == 0) {
return 0;
}
+#ifdef WL_CFG80211
+ wl_cfg80211_down();
+#endif
#ifdef PROP_TXSTATUS
dhd_wlfc_cleanup(&dhd->pub);
int ifidx;
int32 ret = 0;
-#if defined(OEM_ANDROID) && !defined(WL_CFG80211)
+#if !defined(WL_CFG80211)
/* Force start if ifconfig_up gets called before START command */
wl_control_wl_start(net);
-#endif /* defined(OEM_ANDROID) && !defined(WL_CFG80211) */
+#endif
ifidx = dhd_net2idx(dhd, net);
DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx));
dhd_attach_states_t dhd_state = DHD_ATTACH_STATE_INIT;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
+
/* updates firmware nvram path if it was provided as module parameters */
if ((firmware_path != NULL) && (firmware_path[0] != '\0'))
strcpy(fw_path, firmware_path);
}
dhd_state |= DHD_ATTACH_STATE_PROT_ATTACH;
-#if defined(CONFIG_WIRELESS_EXT)
- /* Attach and link in the iw */
- if (wl_iw_attach(net, (void *)&dhd->pub) != 0) {
- DHD_ERROR(("wl_iw_attach failed\n"));
- goto fail;
- }
- dhd_state |= DHD_ATTACH_STATE_WL_ATTACH;
-#endif /* defined(CONFIG_WIRELESS_EXT) */
-
#ifdef WL_CFG80211
/* Attach and link in the cfg80211 */
if (unlikely(wl_cfg80211_attach(net, &dhd->pub))) {
}
dhd_state |= DHD_ATTACH_STATE_CFG80211;
#endif
+#if defined(CONFIG_WIRELESS_EXT)
+ /* Attach and link in the iw */
+ if (!(dhd_state & DHD_ATTACH_STATE_CFG80211)) {
+ if (wl_iw_attach(net, (void *)&dhd->pub) != 0) {
+ DHD_ERROR(("wl_iw_attach failed\n"));
+ goto fail;
+ }
+ dhd_state |= DHD_ATTACH_STATE_WL_ATTACH;
+ }
+#endif /* defined(CONFIG_WIRELESS_EXT) */
+
+
/* Set up the watchdog timer */
init_timer(&dhd->timer);
dhd->timer.data = (ulong)dhd;
*/
memcpy(netdev_priv(net), &dhd, sizeof(dhd));
+#if defined(CONFIG_WIFI_CONTROL_FUNC)
+ g_bus = bus;
+#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) && 1
register_pm_notifier(&dhd_sleep_pm_notifier);
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP) */
register_early_suspend(&dhd->early_suspend);
dhd_state |= DHD_ATTACH_STATE_EARLYSUSPEND_DONE;
#endif
+
+#ifdef ARP_OFFLOAD_SUPPORT
+ register_inetaddr_notifier(&dhd_notifier);
+#endif /* ARP_OFFLOAD_SUPPORT */
+
dhd_state |= DHD_ATTACH_STATE_DONE;
dhd->dhd_state = dhd_state;
return &dhd->pub;
dhd_free(&dhd->pub);
}
+
return NULL;
}
setbit(dhdp->eventmask, WLC_E_TXFAIL);
setbit(dhdp->eventmask, WLC_E_JOIN_START);
setbit(dhdp->eventmask, WLC_E_SCAN_COMPLETE);
- setbit(dhdp->eventmask, WLC_E_RELOAD);
+
#ifdef PNO_SUPPORT
setbit(dhdp->eventmask, WLC_E_PFN_NET_FOUND);
#endif /* PNO_SUPPORT */
return ret;
#ifdef WRITE_MACADDR
- /* it could be used even when WIFI is not Enabled [ON] */
dhd_write_macaddr(dhd->pub.mac.octet);
#endif
+#if defined(CONFIG_SYSCTL) && defined(WL_CFG80211)
+ wl_cfg80211_sysctl_export_devaddr(&dhd->pub);
+#endif
+
return 0;
}
return 0;
}
+#ifdef ARP_OFFLOAD_SUPPORT
+/* add or remove AOE host ip(s) (up to 8 IPs on the interface) */
+void aoe_update_host_ipv4_table(dhd_pub_t *dhd_pub, u32 ipa, bool add)
+{
+ u32 ipv4_buf[8]; /* temp save for AOE host_ip table */
+ int i;
+
+ bzero(ipv4_buf, sizeof(ipv4_buf));
+
+ /* display what we've got */
+ dhd_arp_get_arp_hostip_table(dhd_pub, ipv4_buf, sizeof(ipv4_buf));
+ DHD_ARPOE(("%s: hostip table read from Dongle:\n", __FUNCTION__));
+ dhd_print_buf(ipv4_buf, 32, 4); /* max 8 IPs 4b each */
+
+ /* now we saved hoste_ip table, clr it in the dongle AOE */
+ dhd_aoe_hostip_clr(dhd_pub);
+
+ for (i = 0; i < 8; i++) {
+
+ if (add && (ipv4_buf[i] == 0)) {
+
+ ipv4_buf[i] = ipa;
+ add = FALSE; /* added ipa to local table */
+ DHD_ARPOE(("%s: Saved new IP in temp arp_hostip[%d]\n",
+ __FUNCTION__, i));
+
+ } else if (ipv4_buf[i] == ipa) {
+ ipv4_buf[i] = 0;
+ DHD_ARPOE(("%s: removed IP:%x from temp table %d\n",
+ __FUNCTION__, ipa, i));
+ }
+
+ if (ipv4_buf[i] != 0) {
+ /* add back host_ip entries from our local cache */
+ dhd_arp_offload_add_ip(dhd_pub, ipv4_buf[i]);
+ DHD_ARPOE(("%s: added IP:%x to dongle arp_hostip[%d]\n\n",
+ __FUNCTION__, ipv4_buf[i], i));
+ }
+ }
+#ifdef AOE_DBG
+ /* see the resulting hostip table */
+ dhd_arp_get_arp_hostip_table(dhd_pub, ipv4_buf, sizeof(ipv4_buf));
+ DHD_ARPOE(("%s: read back arp_hostip table:\n", __FUNCTION__));
+ dhd_print_buf(ipv4_buf, 32, 4); /* max 8 IPs 4b each */
+#endif
+}
+
+static int dhd_device_event(struct notifier_block *this,
+ unsigned long event,
+ void *ptr)
+{
+ struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
+
+ dhd_info_t *dhd;
+ dhd_pub_t *dhd_pub;
+
+ if (!ifa)
+ return NOTIFY_DONE;
+
+ dhd = *(dhd_info_t **)netdev_priv(ifa->ifa_dev->dev);
+ dhd_pub = &dhd->pub;
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
+ if (ifa->ifa_dev->dev->netdev_ops == &dhd_ops_pri) {
+#else
+ if (ifa->ifa_dev->dev) {
+#endif
+ switch (event) {
+ case NETDEV_UP:
+ DHD_ARPOE(("%s: [%s] Up IP: 0x%x\n",
+ __FUNCTION__, ifa->ifa_label, ifa->ifa_address));
+
+#ifdef AOE_IP_ALIAS_SUPPORT
+ if (ifa->ifa_label[strlen(ifa->ifa_label)-2] == 0x3a) {
+ DHD_ARPOE(("%s:add aliased IP to AOE hostip cache\n",
+ __FUNCTION__));
+ aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, TRUE);
+ }
+#endif
+ break;
+
+ case NETDEV_DOWN:
+ DHD_ARPOE(("%s: [%s] Down IP: 0x%x\n",
+ __FUNCTION__, ifa->ifa_label, ifa->ifa_address));
+
+#ifdef AOE_IP_ALIAS_SUPPORT
+ if (!(ifa->ifa_label[strlen(ifa->ifa_label)-2] == 0x3a)) {
+ DHD_ARPOE(("%s: primary interface is down, AOE clr all\n",
+ __FUNCTION__));
+ dhd_aoe_hostip_clr(&dhd->pub);
+ dhd_aoe_arp_clr(&dhd->pub);
+ } else
+ aoe_update_host_ipv4_table(dhd_pub, ifa->ifa_address, FALSE);
+#else
+ dhd_aoe_hostip_clr(&dhd->pub);
+ dhd_aoe_arp_clr(&dhd->pub);
+#endif
+ break;
+
+ default:
+ DHD_ARPOE(("%s: do noting for [%s] Event: %lu\n",
+ __func__, ifa->ifa_label, event));
+ break;
+ }
+ }
+ return NOTIFY_DONE;
+}
+#endif /* ARP_OFFLOAD_SUPPORT */
+
int
dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
{
DHD_ERROR(("couldn't register the net device, err %d\n", err));
goto fail;
}
+#if defined(WL_CFG80211)
+ if (ifidx == 0)
+ wl_cfg80211_attach_post(net);
+#endif
printf("%s: Broadcom Dongle Host Driver mac=%.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", net->name,
dhd->pub.mac.octet[0], dhd->pub.mac.octet[1], dhd->pub.mac.octet[2],
dhd->pub.mac.octet[3], dhd->pub.mac.octet[4], dhd->pub.mac.octet[5]);
-#if defined(CONFIG_WIRELESS_EXT)
-#ifdef SOFTAP
- if (ifidx == 0)
- /* Don't call for SOFTAP Interface in SOFTAP MODE */
- wl_iw_iscan_set_scan_broadcast_prep(net, 1);
-#else
+#if defined(SOFTAP) && defined(CONFIG_WIRELESS_EXT) && !defined(WL_CFG80211)
wl_iw_iscan_set_scan_broadcast_prep(net, 1);
-#endif /* SOFTAP */
-#endif /* CONFIG_WIRELESS_EXT */
+#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
- up(&dhd_registration_sem);
+ if (ifidx == 0) {
+ up(&dhd_registration_sem);
+ }
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
return 0;
osl_delay(1000*100);
}
+#ifdef ARP_OFFLOAD_SUPPORT
+ unregister_inetaddr_notifier(&dhd_notifier);
+#endif /* ARP_OFFLOAD_SUPPORT */
+
#if defined(CONFIG_HAS_EARLYSUSPEND)
if (dhd->dhd_state & DHD_ATTACH_STATE_EARLYSUSPEND_DONE) {
if (dhd->early_suspend.suspend)
}
#endif /* defined(CONFIG_WIRELESS_EXT) */
-#ifdef WL_CFG80211
- if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
- wl_cfg80211_detach();
-#endif
-
if (&dhd->thr_sysioc_ctl.thr_pid >= 0) {
PROC_STOP(&dhd->thr_sysioc_ctl);
}
unregister_netdev(ifp->net);
MFREE(dhd->pub.osh, ifp, sizeof(*ifp));
- }
+ }
}
/* Clear the watchdog timer */
if (dhdp->prot)
dhd_prot_detach(dhdp);
}
-
+#ifdef WL_CFG80211
+ if (dhd->dhd_state & DHD_ATTACH_STATE_CFG80211)
+ wl_cfg80211_detach();
+#endif
if (dhd->dhd_state & DHD_ATTACH_STATE_WAKELOCKS_INIT) {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && defined(CONFIG_PM_SLEEP)
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) */
error = dhd_bus_register();
+
if (!error)
printf("\n%s\n", dhd_version);
else {
return (bcmerror);
#if defined(CONFIG_WIRELESS_EXT)
- ASSERT(dhd->iflist[*ifidx] != NULL);
+ if (event->bsscfgidx == 0) {
+ /*
+ * Wireless ext is on primary interface only
+ */
- /*
- * Wireless ext is on primary interface only
- */
- if (dhd->iflist[*ifidx]->net && (event->bsscfgidx == 0))
- wl_iw_event(dhd->iflist[*ifidx]->net, event, *data);
+ ASSERT(dhd->iflist[*ifidx] != NULL);
+ ASSERT(dhd->iflist[*ifidx]->net != NULL);
+ if (dhd->iflist[*ifidx]->net) {
+ wl_iw_event(dhd->iflist[*ifidx]->net, event, *data);
+ }
+ }
#endif /* defined(CONFIG_WIRELESS_EXT) */
#ifdef WL_CFG80211
+
+ if ((wl_cfg80211_is_progress_ifchange() ||
+ wl_cfg80211_is_progress_ifadd()) && (*ifidx != 0)) {
+ /*
+ * If IF_ADD/CHANGE operation is going on,
+ * discard any event received on the virtual I/F
+ */
+ return (BCME_OK);
+ }
+
ASSERT(dhd->iflist[*ifidx] != NULL);
ASSERT(dhd->iflist[*ifidx]->net != NULL);
- if (dhd->iflist[*ifidx]->net)
- wl_cfg80211_event(dhd->iflist[*ifidx]->net, event, *data, GFP_ATOMIC);
-#endif
+ if (dhd->iflist[*ifidx]->net) {
+ wl_cfg80211_event(dhd->iflist[*ifidx]->net, event, *data);
+ }
+#endif /* defined(WL_CFG80211) */
return (bcmerror);
}
int
dhd_dev_reset(struct net_device *dev, uint8 flag)
{
+ int ret;
+
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
/* Turning off watchdog */
if (flag)
dhd_os_wd_timer(&dhd->pub, 0);
- dhd_bus_devreset(&dhd->pub, flag);
-
+ ret = dhd_bus_devreset(&dhd->pub, flag);
+ if (ret) {
+ DHD_ERROR(("%s: dhd_bus_devreset: %d\n", __FUNCTION__, ret));
+ return ret;
+ }
/* Turning on watchdog back */
if (!flag)
dhd_os_wd_timer(&dhd->pub, dhd_watchdog_ms);
DHD_ERROR(("%s: WLAN OFF DONE\n", __FUNCTION__));
- return 1;
+ return ret;
}
int net_os_set_suspend_disable(struct net_device *dev, int val)
dhd_info_t *dhd = *(dhd_info_t **)netdev_priv(dev);
if (dhd && dhd->pub.up)
- memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t));
+ memcpy(&dhd->pub.dhd_cspec, cspec, sizeof(wl_country_t));
}
bool
dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh,
- char *fw_path, char *nv_path)
+ char *pfw_path, char *pnv_path)
{
bool ret;
- bus->fw_path = fw_path;
- bus->nv_path = nv_path;
+ bus->fw_path = pfw_path;
+ bus->nv_path = pnv_path;
ret = dhdsdio_download_firmware(bus, osh, bus->sdh);
#endif /* BCMEMBEDIMAGE */
static int
-dhdsdio_download_code_file(struct dhd_bus *bus, char *fw_path)
+dhdsdio_download_code_file(struct dhd_bus *bus, char *pfw_path)
{
int bcmerror = -1;
int offset = 0;
void *image = NULL;
uint8 *memblock = NULL, *memptr;
- DHD_INFO(("%s: download firmware %s\n", __FUNCTION__, fw_path));
+ DHD_INFO(("%s: download firmware %s\n", __FUNCTION__, pfw_path));
- image = dhd_os_open_image(fw_path);
+ image = dhd_os_open_image(pfw_path);
if (image == NULL)
goto err;
void * image = NULL;
char * memblock = NULL;
char *bufp;
- char *nv_path;
+ char *pnv_path;
bool nvram_file_exists;
- nv_path = bus->nv_path;
+ pnv_path = bus->nv_path;
- nvram_file_exists = ((nv_path != NULL) && (nv_path[0] != '\0'));
+ nvram_file_exists = ((pnv_path != NULL) && (pnv_path[0] != '\0'));
if (!nvram_file_exists && (bus->nvram_params == NULL))
return (0);
if (nvram_file_exists) {
- image = dhd_os_open_image(nv_path);
+ image = dhd_os_open_image(pnv_path);
if (image == NULL)
goto err;
}
#if defined(BCM_RPC_NOCOPY) || defined(BCM_RCP_TXNOCOPY)
#define BCMEXTRAHDROOM 220
-#elif defined(BCM43237) && defined(BCMPKTPOOL) && defined(DMATXRC)
-#define BCMEXTRAHDROOM 0
#else
#define BCMEXTRAHDROOM 172
#endif
#define DHD_EVENT_VAL 0x0800
#define DHD_BTA_VAL 0x1000
#define DHD_ISCAN_VAL 0x2000
+#define DHD_ARPOE_VAL 0x4000
#ifdef SDTEST
/* For pktgen iovar */
#define EPI_RC_NUMBER 125
-#define EPI_INCREMENTAL_NUMBER 22
+#define EPI_INCREMENTAL_NUMBER 27
#define EPI_BUILD_NUMBER 0
-#define EPI_VERSION 5, 90, 125, 22
+#define EPI_VERSION 5, 90, 125, 27
-#define EPI_VERSION_NUM 0x055a7d16
+#define EPI_VERSION_NUM 0x055a7d1b
#define EPI_VERSION_DEV 5.90.125
-#define EPI_VERSION_STR "5.90.125.22"
+#define EPI_VERSION_STR "5.90.125.27"
#endif
#define WL_WIFI_ACTION_FRAME_SIZE sizeof(struct wl_action_frame)
+typedef struct ssid_info
+{
+ uint8 ssid_len;
+ uint8 ssid[32];
+} ssid_info_t;
+
typedef struct wl_af_params {
uint32 channel;
int32 dwell_time;
uint32 resp_len;
uint32 flags;
struct dot11_assoc_req req;
- struct ether_addr reassoc_bssid; /* used in reassoc's */
+ struct ether_addr reassoc_bssid;
struct dot11_assoc_resp resp;
} wl_assoc_info_t;
-/* flags */
-#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */
+
+#define WLC_ASSOC_REQ_IS_REASSOC 0x01
+
+
#define WLC_TXFILTER_OVERRIDE_DISABLED 0
#define WLC_TXFILTER_OVERRIDE_ENABLED 1
static void wl_init_event_handler(struct wl_priv *wl);
static struct wl_event_q *wl_deq_event(struct wl_priv *wl);
static s32 wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 type,
- const wl_event_msg_t *msg, void *data, gfp_t gfp);
+ const wl_event_msg_t *msg, void *data);
static void wl_put_event(struct wl_event_q *e);
static void wl_wakeup_event(struct wl_priv *wl);
static s32 wl_notify_connect_status(struct wl_priv *wl,
static __used s32 wl_update_pmklist(struct net_device *dev,
struct wl_pmk_list *pmk_list, s32 err);
-static void wl_set_mpc(struct net_device *ndev, s32 mpc);
-
/*
* debufs support
*/
return NULL;
}
- if (test_bit(WLP2P_STATUS_IF_DELETING, &wl->p2p_status) == 1) {
+ if (wl_get_p2p_status(wl, IF_DELETING) == 1) {
/* wait till IF_DEL is complete
* release the lock for the unregister to proceed
*/
rtnl_unlock();
WL_INFO(("%s: Released the lock and wait till IF_DEL is complete\n", __func__));
timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
- (test_bit(WLP2P_STATUS_IF_DELETING, &wl->p2p_status) == FALSE),
+ (wl_get_p2p_status(wl, IF_DELETING) == FALSE),
msecs_to_jiffies(MAX_WAIT_TIME));
/* put back the rtnl_lock again */
return ERR_PTR(-EAGAIN);
}
}
- if (!wl->p2p_on && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
- wl->p2p_on = true;
+ if (!p2p_on(wl) && strstr(name, WL_P2P_INTERFACE_PREFIX)) {
+ p2p_on(wl) = true;
wl_cfgp2p_init_discovery(wl);
}
- memset(wl->p2p_vir_ifname, 0, IFNAMSIZ);
- strncpy(wl->p2p_vir_ifname, name, IFNAMSIZ - 1);
- wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p_dev_addr, &wl->p2p_int_addr);
+ memset(wl->p2p.vir_ifname, 0, IFNAMSIZ);
+ strncpy(wl->p2p.vir_ifname, name, IFNAMSIZ - 1);
+ wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p.dev_addr, &wl->p2p.int_addr);
/* Temporary use channel 11, in case GO will be changed with set_channel API */
chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
/* For P2P mode, use P2P-specific driver features to create the
* bss: "wl p2p_ifadd"
*/
- set_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status);
- err = wl_cfgp2p_ifadd(wl, &wl->p2p_int_addr, htod32(wlif_type), chspec);
+ wl_set_p2p_status(wl, IF_ADD);
+ err = wl_cfgp2p_ifadd(wl, &wl->p2p.int_addr, htod32(wlif_type), chspec);
if (unlikely(err))
return ERR_PTR(-ENOMEM);
timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
- (test_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status) == FALSE),
+ (wl_get_p2p_status(wl, IF_ADD) == FALSE),
msecs_to_jiffies(MAX_WAIT_TIME));
- if (timeout > 0 && (!test_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status))) {
+ if (timeout > 0 && (!wl_get_p2p_status(wl, IF_ADD))) {
struct wireless_dev *vwdev;
vwdev = kzalloc(sizeof(*vwdev), GFP_KERNEL);
return ERR_PTR(-ENOMEM);
}
vwdev->wiphy = wl->wdev->wiphy;
- WL_INFO((" virtual interface(%s) is created \n", wl->p2p_vir_ifname));
+ WL_INFO((" virtual interface(%s) is created \n", wl->p2p.vir_ifname));
index = alloc_idx_vwdev(wl);
wl->vwdev[index] = vwdev;
vwdev->iftype =
SET_NETDEV_DEV(_ndev, wiphy_dev(vwdev->wiphy));
vwdev->netdev = _ndev;
set_bit(WL_STATUS_READY, &wl->status);
- wl->p2p_vif_created = TRUE;
+ wl->p2p.vif_created = TRUE;
set_mode_by_netdev(wl, _ndev, mode);
wl = wdev_to_wl(vwdev);
return _ndev;
} else {
- clear_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status);
- WL_ERR((" virtual interface(%s) is not created \n", wl->p2p_vir_ifname));
- memset(wl->p2p_vir_ifname, '\0', IFNAMSIZ);
- wl->p2p_vif_created = FALSE;
+ wl_clr_p2p_status(wl, IF_ADD);
+ WL_ERR((" virtual interface(%s) is not created \n", wl->p2p.vir_ifname));
+ memset(wl->p2p.vir_ifname, '\0', IFNAMSIZ);
+ wl->p2p.vif_created = FALSE;
}
return ERR_PTR(-ENODEV);
{
struct ether_addr p2p_mac;
struct wl_priv *wl = WL_PRIV_GET();
- memcpy(p2p_mac.octet, wl->p2p_int_addr.octet, ETHER_ADDR_LEN);
- if (wl->p2p_vif_created) {
+ memcpy(p2p_mac.octet, wl->p2p.int_addr.octet, ETHER_ADDR_LEN);
+ if (wl->p2p.vif_created) {
if (test_bit(WL_STATUS_SCANNING, &wl->status)) {
wl_cfg80211_scan_abort(wl, dev);
}
wl_cfgp2p_ifdel(wl, &p2p_mac);
WL_ERR(("ifdel command sent to Firmware.. "
"and we just come out without waiting.."));
- set_bit(WLP2P_STATUS_IF_DELETING, &wl->p2p_status);
+ wl_set_p2p_status(wl, IF_DELETING);
}
}
- if (ap && wl->p2p_vif_created) {
- WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p_vif_created,
- wl->p2p_on));
+ if (ap && wl->p2p.vif_created) {
+ WL_DBG(("p2p_vif_created (%d) p2p_on (%d)\n", wl->p2p.vif_created,
+ p2p_on(wl)));
chspec = wf_chspec_aton(WL_P2P_TEMP_CHAN);
wlif_type = ap ? WL_P2P_IF_GO : WL_P2P_IF_CLIENT;
WL_ERR(("%s : ap (%d), infra (%d), iftype: (%d)\n", ndev->name, ap, infra, type));
- set_bit(WLP2P_STATUS_IF_CHANGING, &wl->p2p_status);
- clear_bit(WLP2P_STATUS_IF_CHANGED, &wl->p2p_status);
- err = wl_cfgp2p_ifchange(wl, &wl->p2p_int_addr, htod32(wlif_type), chspec);
+ wl_set_p2p_status(wl, IF_CHANGING);
+ wl_clr_p2p_status(wl, IF_CHANGED);
+ err = wl_cfgp2p_ifchange(wl, &wl->p2p.int_addr, htod32(wlif_type), chspec);
timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
- (test_bit(WLP2P_STATUS_IF_CHANGED, &wl->p2p_status) == TRUE),
+ (wl_get_p2p_status(wl, IF_CHANGED) == TRUE),
msecs_to_jiffies(MAX_WAIT_TIME));
set_mode_by_netdev(wl, ndev, mode);
- clear_bit(WLP2P_STATUS_IF_CHANGING, &wl->p2p_status);
- clear_bit(WLP2P_STATUS_IF_CHANGED, &wl->p2p_status);
+ wl_clr_p2p_status(wl, IF_CHANGING);
+ wl_clr_p2p_status(wl, IF_CHANGED);
}
ndev->ieee80211_ptr->iftype = type;
}
WL_DBG(("IF_ADD event called from dongle, old interface name: %s, new name: %s\n",
- net->name, wl->p2p_vir_ifname));
+ net->name, wl->p2p.vir_ifname));
/* Assign the net device to CONNECT BSSCFG */
- strncpy(net->name, wl->p2p_vir_ifname, IFNAMSIZ - 1);
+ strncpy(net->name, wl->p2p.vir_ifname, IFNAMSIZ - 1);
wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_CONNECTION) = net;
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_CONNECTION) = P2PAPI_BSSCFG_CONNECTION;
- clear_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status);
+ wl_clr_p2p_status(wl, IF_ADD);
wake_up_interruptible(&wl->dongle_event_wait);
return ret;
}
}
WL_DBG(("IF_DEL event called from dongle, _net name: %s, vif name: %s\n",
- net->name, wl->p2p_vir_ifname));
- if (wl->p2p_vif_created) {
+ net->name, wl->p2p.vir_ifname));
+ if (wl->p2p.vif_created) {
s32 index = 0;
- memset(wl->p2p_vir_ifname, '\0', IFNAMSIZ);
+ memset(wl->p2p.vir_ifname, '\0', IFNAMSIZ);
index = wl_cfgp2p_find_idx(wl, net);
wl_to_p2p_bss_ndev(wl, index) = NULL;
wl_to_p2p_bss_bssidx(wl, index) = 0;
- wl->p2p_vif_created = FALSE;
+ wl->p2p.vif_created = FALSE;
set_mode_by_netdev(wl, net, -1);
wl_cfgp2p_clear_management_ie(wl,
index);
free_vwdev_by_index(wl, index);
}
/* Another option.. Make the IF_ADD wait, if the IF_DEL is not complete.. */
- clear_bit(WLP2P_STATUS_IF_DELETING, &wl->p2p_status);
+ wl_clr_p2p_status(wl, IF_DELETING);
WL_ERR(("Cleared IF_DELETING status bit\n"));
wake_up_interruptible(&wl->dongle_event_wait);
WL_ERR(("Cleared IF_DELETING status bit DONE WAKEUP Interruptible\n"));
{
s32 is_progress = 0;
struct wl_priv *wl = WL_PRIV_GET();
- if (test_bit(WLP2P_STATUS_IF_ADD, &wl->p2p_status))
+ if (wl_get_p2p_status(wl, IF_ADD))
is_progress = 1;
return is_progress;
}
{
s32 is_progress = 0;
struct wl_priv *wl = WL_PRIV_GET();
- if (test_bit(WLP2P_STATUS_IF_CHANGING, &wl->p2p_status))
+ if (wl_get_p2p_status(wl, IF_CHANGING))
is_progress = 1;
return is_progress;
}
wl_cfg80211_notify_ifchange(void)
{
struct wl_priv *wl = WL_PRIV_GET();
- if (test_bit(WLP2P_STATUS_IF_CHANGING, &wl->p2p_status)) {
- set_bit(WLP2P_STATUS_IF_CHANGED, &wl->p2p_status);
+ if (wl_get_p2p_status(wl, IF_CHANGING)) {
+ wl_set_p2p_status(wl, IF_CHANGED);
wake_up_interruptible(&wl->dongle_event_wait);
}
return 0;
WL_DBG(("error (%d)\n", err));
return err;
}
- wl_set_mpc(ndev, 0);
wl->iscan_kickstart = true;
wl_run_iscan(iscan, &ssid, WL_SCAN_ACTION_START);
mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
if ((ndev == wl_to_prmry_ndev(wl)) &&
- !wl->p2p_scan) {
+ !p2p_scan(wl)) {
/* LEGACY SCAN TRIGGER */
WL_DBG(("LEGACY SCAN START\n"));
if (ssid && ssid->SSID_len) {
wl->escan_ioctl_buf, WLC_IOCTL_MEDLEN);
kfree(params);
}
- else if (wl->p2p_on && wl->p2p_scan) {
+ else if (p2p_on(wl) && p2p_scan(wl)) {
/* P2P SCAN TRIGGER */
if (scan_request && scan_request->n_channels) {
num_chans = scan_request->n_channels;
static s32
wl_do_escan(struct wl_priv *wl, struct wiphy *wiphy, struct net_device *ndev, wlc_ssid_t *ssid)
{
-
-
s32 err = BCME_OK;
s32 passive_scan;
wl_scan_results_t *results;
results->count = 0;
results->buflen = WL_SCAN_RESULTS_FIXED_SIZE;
- wl_set_mpc(ndev, 0);
wl_run_escan(wl, ndev, ssid, WL_SCAN_ACTION_START);
return err;
}
escan_req = true;
if (ssids->ssid_len && IS_P2P_SSID(ssids->ssid)) {
/* p2p scan trigger */
- if (wl->p2p_on == false) {
+ if (p2p_on(wl) == false) {
/* p2p on at the first time */
- wl->p2p_on = true;
+ p2p_on(wl) = true;
wl_cfgp2p_set_firm_p2p(wl);
}
- wl->p2p_scan = true;
+ p2p_scan(wl) = true;
} else {
/* legacy scan trigger
* So, we have to disable p2p discovery if p2p discovery is on
*/
- wl->p2p_scan = false;
+ p2p_scan(wl) = false;
/* If Netdevice is not equals to primary and p2p is on
* , we will do p2p scan using P2PAPI_BSSCFG_DEVICE.
*/
- if (wl->p2p_on && (ndev != wl_to_prmry_ndev(wl)))
- wl->p2p_scan = true;
+ if (p2p_on(wl) && (ndev != wl_to_prmry_ndev(wl)))
+ p2p_scan(wl) = true;
- if (wl->p2p_scan == false) {
- if (test_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status)) {
+ if (p2p_scan(wl) == false) {
+ if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
err = wl_cfgp2p_discover_enable_search(wl, FALSE);
if (unlikely(err)) {
goto scan_out;
memcpy(ssid_info.SSID, ssids->ssid, ssids->ssid_len);
ssid_info.SSID_len = ssids->ssid_len;
- if (wl->p2p_on && wl->p2p_scan) {
+ if (p2p_on(wl) && p2p_scan(wl)) {
err = wl_cfgp2p_enable_discovery(wl, ndev, request->ie, request->ie_len);
WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err));
goto scan_out;
}
- wl_set_mpc(ndev, 0);
err = wldev_ioctl(ndev, WLC_SCAN, &sr->ssid,
sizeof(sr->ssid), FALSE);
if (err) {
} else {
WL_ERR(("WLC_SCAN error (%d)\n", err));
}
- wl_set_mpc(ndev, 1);
goto scan_out;
}
}
CHECK_SYS_UP();
if (IS_P2P_SSID(sme->ssid) && (dev != wl_to_prmry_ndev(wl))) {
/* we only allow to connect using virtual interface in case of P2P */
- if (wl->p2p_on && is_wps_conn(sme)) {
+ if (p2p_on(wl) && is_wps_conn(sme)) {
WL_DBG(("p2p index : %d\n", wl_cfgp2p_find_idx(wl, dev)));
/* Have to apply WPS IE + P2P IE in assoc req frame */
wl_cfgp2p_set_managment_ie(wl, dev,
P2PAPI_BSSCFG_DEVICE).p2p_probe_req_ie_len);
wl_cfgp2p_set_managment_ie(wl, dev, wl_cfgp2p_find_idx(wl, dev),
VNDR_IE_ASSOCREQ_FLAG, sme->ie, sme->ie_len);
- } else if (wl->p2p_on && (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
+ } else if (p2p_on(wl) && (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)) {
/* This is the connect req after WPS is done [credentials exchanged]
* currently identified with WPA_VERSION_2 .
* Update the previously set IEs with
static s32 wl_cfg80211_suspend(struct wiphy *wiphy)
{
struct wl_priv *wl = WL_PRIV_GET();
- struct net_device *ndev = wl_to_prmry_ndev(wl);
s32 err = 0;
CHECK_SYS_UP();
wl_term_iscan(wl);
if (wl->scan_request) {
cfg80211_scan_done(wl->scan_request, true);
- wl_set_mpc(ndev, 1);
wl->scan_request = NULL;
}
clear_bit(WL_STATUS_SCANNING, &wl->status);
wl_event_msg_t msg;
msg.event_type = hton32(WLC_E_ESCAN_RESULT);
msg.status = WLC_E_STATUS_ABORT;
- wl_cfg80211_event(ndev, &msg, NULL, GFP_ATOMIC);
+ wl_cfg80211_event(ndev, &msg, NULL);
}
return err;
}
wl->cache_cookie = *cookie;
cfg80211_ready_on_channel(dev, *cookie, channel,
channel_type, duration, GFP_KERNEL);
- if (!wl->p2p_on) {
- wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p_dev_addr, &wl->p2p_int_addr);
+ if (!p2p_on(wl)) {
+ wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p.dev_addr, &wl->p2p.int_addr);
/* In case of p2p_listen command, supplicant send remain_on_channel
* without turning on P2P
if (unlikely(err)) {
goto exit;
}
- wl->p2p_on = true;
+ p2p_on(wl) = true;
}
- if (wl->p2p_on)
+ if (p2p_on(wl))
wl_cfgp2p_discover_listen(wl, target_channel, duration);
WL_ERR(("Can not find the bssidx for dev( %p )\n", dev));
return -ENODEV;
}
- if (wl->p2p_on) {
- wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p_dev_addr, &wl->p2p_int_addr);
+ if (p2p_on(wl)) {
+ wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p.dev_addr, &wl->p2p.int_addr);
/* Suspend P2P discovery search-listen to prevent it from changing the
* channel.
mgmt = (const struct ieee80211_mgmt *) buf;
fc = mgmt->frame_control;
if (fc != IEEE80211_STYPE_ACTION) {
- if (wl->p2p_on && (fc == IEEE80211_STYPE_PROBE_RESP)) {
+ if (p2p_on(wl) && (fc == IEEE80211_STYPE_PROBE_RESP)) {
s32 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
s32 ie_len = len - ie_offset;
if ((p2p_ie = wl_cfgp2p_find_p2pie((u8 *)(buf + ie_offset), ie_len))
memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN], action_frame->len);
- if (wl->p2p_vif_created) {
+ if (wl->p2p.vif_created) {
wifi_p2p_pub_act_frame_t *act_frm =
(wifi_p2p_pub_act_frame_t *) (action_frame->data);
/*
p2p_ie = wl_cfgp2p_find_p2pie(act_frm->elts,
action_frame->len - P2P_PUB_AF_FIXED_LEN);
#ifdef ENABLE_DRIVER_CHANGE_IFADDR /* We are now doing this in supplicant */
- wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_int_addr,
+ wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.int_addr,
P2P_SEID_INTINTADDR);
- wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_dev_addr,
+ wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.dev_addr,
P2P_SEID_DEV_INFO);
- wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p_dev_addr,
+ wl_cfg80211_change_ifaddr((u8 *)p2p_ie, &wl->p2p.dev_addr,
P2P_SEID_GROUP_ID);
#endif
}
WL_DBG(("interval (%d) dtim_period (%d) head_len (%d) tail_len (%d)\n",
info->interval, info->dtim_period, info->head_len, info->tail_len));
- /*
- * !!! The following code was NOT indented properly, PLEASE merge your code
- * to SVN verion becuase your merger tool may IGNORE tabs/spaces
- */
- if (wl->p2p_on && (bssidx >= wl_to_p2p_bss_bssidx(wl,
+
+ if (p2p_on(wl) && (bssidx >= wl_to_p2p_bss_bssidx(wl,
P2PAPI_BSSCFG_CONNECTION))) {
/* We don't need to set beacon for P2P_GO,
* but need to parse ssid from beacon_parameters
if ((ssid_ie = bcm_parse_tlvs((u8 *)&info->head[ie_offset],
info->head_len - ie_offset,
DOT11_MNG_SSID_ID)) != NULL) {
- memcpy(wl->p2p_ssid.SSID, ssid_ie->data, ssid_ie->len);
- wl->p2p_ssid.SSID_len = ssid_ie->len;
+ memcpy(wl->p2p.ssid.SSID, ssid_ie->data, ssid_ie->len);
+ wl->p2p.ssid.SSID_len = ssid_ie->len;
WL_DBG(("SSID (%s) in Head \n", ssid_ie->data));
} else {
WL_ERR(("SET INFRA error %d\n", err));
}
- err = wldev_iovar_setbuf_bsscfg(dev, "ssid", &wl->p2p_ssid,
- sizeof(wl->p2p_ssid), ioctlbuf, sizeof(ioctlbuf), bssidx);
+ err = wldev_iovar_setbuf_bsscfg(dev, "ssid", &wl->p2p.ssid,
+ sizeof(wl->p2p.ssid), ioctlbuf, sizeof(ioctlbuf), bssidx);
wl_cfgp2p_bss(dev, bssidx, 1);
}
offsetof(struct wl_cfg80211_bss_info, frame_buf));
notif_bss_info->frame_len = offsetof(struct ieee80211_mgmt,
u.beacon.variable) + wl_get_ielen(wl);
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(COMPAT_WIRELESS)
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
freq = ieee80211_channel_to_frequency(notif_bss_info->channel);
#else
freq = ieee80211_channel_to_frequency(notif_bss_info->channel, band->band);
else
band = wiphy->bands[IEEE80211_BAND_5GHZ];
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(COMPAT_WIRELESS)
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
freq = ieee80211_channel_to_frequency(channel);
#else
freq = ieee80211_channel_to_frequency(channel, band->band);
if (wl->scan_request) {
WL_ERR(("cfg80211_scan_done\n"));
cfg80211_scan_done(wl->scan_request, false);
- wl_set_mpc(ndev, 1);
wl->scan_request = NULL;
}
rtnl_unlock();
band = wiphy->bands[IEEE80211_BAND_2GHZ];
else
band = wiphy->bands[IEEE80211_BAND_5GHZ];
-
-#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(COMPAT_WIRELESS)
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 38) && !defined(WL_COMPAT_WIRELESS)
freq = ieee80211_channel_to_frequency(channel);
#else
freq = ieee80211_channel_to_frequency(channel, band->band);
static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted)
{
struct wl_priv *wl = iscan_to_wl(iscan);
- struct net_device *ndev = wl_to_prmry_ndev(wl);
WL_DBG(("Enter \n"));
if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
}
if (likely(wl->scan_request)) {
cfg80211_scan_done(wl->scan_request, aborted);
- wl_set_mpc(ndev, 1);
wl->scan_request = NULL;
}
wl->iscan_kickstart = false;
static void wl_notify_escan_complete(struct wl_priv *wl, bool aborted)
{
-
- struct net_device *ndev = wl_to_prmry_ndev(wl);
WL_DBG(("Enter \n"));
if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) {
WL_ERR(("Scan complete while device not scanning\n"));
return;
}
- if (wl->p2p_on)
- clear_bit(WLP2P_STATUS_SCANNING, &wl->p2p_status);
+ if (p2p_on(wl))
+ wl_clr_p2p_status(wl, SCANNING);
if (likely(wl->scan_request)) {
cfg80211_scan_done(wl->scan_request, aborted);
- wl_set_mpc(ndev, 1);
wl->scan_request = NULL;
}
}
dhd_pub_t *dhd = (dhd_pub_t *)data;
struct wl_priv *wl = WL_PRIV_GET();
- wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p_dev_addr, &wl->p2p_int_addr);
+ wl_cfgp2p_generate_bss_mac(&dhd->mac, &wl->p2p.dev_addr, &wl->p2p.int_addr);
- sprintf((char *)&wl_sysctl_macstring[0], MACSTR, MAC2STR(wl->p2p_dev_addr.octet));
- sprintf((char *)&wl_sysctl_macstring[1], MACSTR, MAC2STR(wl->p2p_int_addr.octet));
+ sprintf((char *)&wl_sysctl_macstring[0], MACSTR, MAC2STR(wl->p2p.dev_addr.octet));
+ sprintf((char *)&wl_sysctl_macstring[1], MACSTR, MAC2STR(wl->p2p.int_addr.octet));
return 0;
}
wl = WL_PRIV_GET();
if (wl && !test_bit(WL_STATUS_READY, &wl->status)) {
if (wl->wdev &&
- wl_cfgp2p_is_p2p_supported(wl, ndev)) {
+ wl_cfgp2p_supported(wl, ndev)) {
WL_INFO(("P2P is supported on Firmware \n"));
wl->wdev->wiphy->interface_modes |=
(BIT(NL80211_IFTYPE_P2P_CLIENT)|
}
void
-wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data, gfp_t gfp)
+wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data)
{
u32 event_type = ntoh32(e->event_type);
struct wl_priv *wl = WL_PRIV_GET();
WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr));
#endif /* (WL_DBG_LEVEL > 0) */
- if (likely(!wl_enq_event(wl, ndev, event_type, e, data, gfp)))
+ if (likely(!wl_enq_event(wl, ndev, event_type, e, data)))
wl_wakeup_event(wl);
}
static s32
wl_enq_event(struct wl_priv *wl, struct net_device *ndev, u32 event, const wl_event_msg_t *msg,
- void *data, gfp_t gfp)
+ void *data)
{
struct wl_event_q *e;
s32 err = 0;
if (data)
data_len = ntoh32(msg->datalen);
evtq_size = sizeof(struct wl_event_q) + data_len;
- e = kzalloc(evtq_size, gfp);
+ e = kzalloc(evtq_size, GFP_ATOMIC);
if (unlikely(!e)) {
WL_ERR(("event alloc failed\n"));
return -ENOMEM;
if (wl->scan_request) {
cfg80211_scan_done(wl->scan_request, true);
- /* BUG: this operation cannot help but here because sdio
- * is already down through rmmod process. Need to figure
- * out how to address this issue
- */
- /* wl_set_mpc(wl_to_ndev(wl), 1); */
-
wl->scan_request = NULL;
}
clear_bit(WL_STATUS_READY, &wl->status);
return wl->fw->nvram_name;
}
-static void wl_set_mpc(struct net_device *ndev, s32 mpc)
-{
-
- s32 err = 0;
-
- WL_TRACE(("In\n"));
- err = wl_dev_intvar_set(ndev, "mpc", mpc);
- if (unlikely(err)) {
- WL_ERR(("fail to set mpc\n"));
- return;
- }
- WL_DBG(("MPC : %d\n", mpc));
-
-}
-
static int wl_debugfs_add_netdev_params(struct wl_priv *wl)
{
char buf[10+IFNAMSIZ];
#include <net/cfg80211.h>
#include <linux/rfkill.h>
+#include <wl_cfgp2p.h>
+
struct wl_conf;
struct wl_iface;
struct wl_priv;
struct wl_security;
struct wl_ibss;
+
#define htod32(i) i
#define htod16(i) i
#define dtoh32(i) i
WL_NVRAM_LOADING_DONE
};
-/* dongle status */
-enum wl_cfgp2p_status {
- WLP2P_STATUS_DISCOVERY_ON,
- WLP2P_STATUS_SEARCH_ENABLED,
- WLP2P_STATUS_IF_ADD,
- WLP2P_STATUS_IF_DEL,
- WLP2P_STATUS_IF_DELETING,
- WLP2P_STATUS_IF_CHANGING,
- WLP2P_STATUS_IF_CHANGED,
- WLP2P_STATUS_LISTEN_EXPIRED,
- WLP2P_STATUS_ACTION_TX_COMPLETED,
- WLP2P_STATUS_SCANNING
-};
/* beacon / probe_response */
struct beacon_proberesp {
__le64 timestamp;
pmkid_list_t pmkids;
pmkid_t foo[MAXPMKID - 1];
};
-/* Enumeration of the usages of the BSSCFGs used by the P2P Library. Do not
- * confuse this with a bsscfg index. This value is an index into the
- * saved_ie[] array of structures which in turn contains a bsscfg index field.
- */
-typedef enum {
- P2PAPI_BSSCFG_PRIMARY, /* maps to driver's primary bsscfg */
- P2PAPI_BSSCFG_DEVICE, /* maps to driver's P2P device discovery bsscfg */
- P2PAPI_BSSCFG_CONNECTION, /* maps to driver's P2P connection bsscfg */
- P2PAPI_BSSCFG_MAX
-} p2p_bsscfg_type_t;
-
-#define IE_MAX_LEN 300
-/* Structure to hold all saved P2P and WPS IEs for a BSSCFG */
-typedef struct p2p_saved_ie_s {
- u8 p2p_probe_req_ie[IE_MAX_LEN];
- u32 p2p_probe_req_ie_len;
- u8 p2p_probe_res_ie[IE_MAX_LEN];
- u32 p2p_probe_res_ie_len;
- u8 p2p_assoc_req_ie[IE_MAX_LEN];
- u32 p2p_assoc_req_ie_len;
- u8 p2p_assoc_res_ie[IE_MAX_LEN];
- u32 p2p_assoc_res_ie_len;
- u8 p2p_beacon_ie[IE_MAX_LEN];
- u32 p2p_beacon_ie_len;
-} p2p_saved_ie_t;
-
-struct p2p_bss {
- u32 bssidx;
- struct net_device *dev;
- p2p_saved_ie_t saved_ie;
-};
+
#define ESCAN_BUF_SIZE (64 * 1024)
struct ieee80211_channel remain_on_chan;
enum nl80211_channel_type remain_on_chan_type;
u64 cache_cookie;
- wait_queue_head_t dongle_event_wait;
- struct timer_list *listen_timer;
+ wait_queue_head_t dongle_event_wait;
+ struct p2p_info p2p;
s8 last_eventmask[WL_EVENTING_MASK_LEN];
- bool p2p_on; /* p2p on/off switch */
- bool p2p_scan;
- bool p2p_vif_created;
- s8 p2p_vir_ifname[IFNAMSIZ];
- unsigned long p2p_status;
- struct ether_addr p2p_dev_addr;
- struct ether_addr p2p_int_addr;
- struct p2p_bss p2p_bss_idx[P2PAPI_BSSCFG_MAX];
- wlc_ssid_t p2p_ssid;
- s32 sta_generation;
u8 ci[0] __attribute__ ((__aligned__(NETDEV_ALIGN)));
};
#define wl_to_iscan(w) (w->iscan)
#define wl_to_conn(w) (&w->conn_info)
#define wiphy_from_scan(w) (w->escan_info.wiphy)
-#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(w, type) (wl->p2p_bss_idx[type])
+
static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss)
{
return bss = bss ?
extern void wl_cfg80211_detach(void);
/* event handler from dongle */
extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e,
- void *data, gfp_t gfp);
+ void *data);
extern void wl_cfg80211_set_sdio_func(void *func); /* set sdio function info */
extern struct sdio_func *wl_cfg80211_get_sdio_func(void); /* set sdio function info */
extern s32 wl_cfg80211_up(void); /* dongle up */
#include <wldev_common.h>
-/* dword align allocation */
-#define WLC_IOCTL_MAXLEN 8192
-#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
-#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
-
-#define CFGP2P_DBG_NONE 0
-#define CFGP2P_DBG_DBG (1 << 2)
-#define CFGP2P_DBG_INFO (1 << 1)
-#define CFGP2P_DBG_ERR (1 << 0)
-#define CFGP2P_DBG_MASK ((WL_DBG_DBG | WL_DBG_INFO | WL_DBG_ERR) << 1)
-
-
-#define CFGP2P_DBG_LEVEL 0xFF /* 0 invalidates all debug messages */
-
-u32 cfgp2p_dbg_level = CFGP2P_DBG_ERR | CFGP2P_DBG_INFO | CFGP2P_DBG_DBG;
-
-#define CFGP2P_ERR(args) \
- do { \
- if (cfgp2p_dbg_level & CFGP2P_DBG_ERR) { \
- printk(KERN_ERR "CFGP2P-ERROR) %s : ", __func__); \
- printk args; \
- } \
- } while (0)
-#define CFGP2P_INFO(args) \
- do { \
- if (cfgp2p_dbg_level & CFGP2P_DBG_INFO) { \
- printk(KERN_ERR "CFGP2P-INFO) %s : ", __func__); \
- printk args; \
- } \
- } while (0)
-#if (CFGP2P_DBG_LEVEL > 0)
-#define CFGP2P_DBG(args) \
- do { \
- if (cfgp2p_dbg_level & CFGP2P_DBG_DBG) { \
- printk(KERN_ERR "CFGP2P-DEBUG) %s :", __func__); \
- printk args; \
- } \
- } while (0)
-#else /* !(WL_DBG_LEVEL > 0) */
-#define CFGP2P_DBG(args)
-#endif /* (WL_DBG_LEVEL > 0) */
-
-
static s8 ioctlbuf[WLC_IOCTL_MAXLEN];
static s8 scanparambuf[WLC_IOCTL_SMLEN];
static s8 *smbuf = ioctlbuf;
void
wl_cfgp2p_init_priv(struct wl_priv *wl)
{
- wl->p2p_on = 0;
- wl->p2p_scan = 0; /* by default , legacy scan */
- wl->p2p_status = 0;
- wl->listen_timer = NULL;
+ wl->p2p.on = 0;
+ wl->p2p.scan = 0; /* by default , legacy scan */
+ wl->p2p.status = 0;
+ wl->p2p.listen_timer = NULL;
#define INIT_IE(IE_TYPE, BSS_TYPE) \
do { \
wl_cfgp2p_enable_discovery(struct wl_priv *wl, struct net_device *dev, const u8 *ie, u32 ie_len)
{
s32 ret = BCME_OK;
- if (test_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status)) {
+ if (wl_get_p2p_status(wl, DISCOVERY_ON)) {
CFGP2P_INFO((" DISCOVERY is already initialized, we have nothing to do\n"));
goto set_ie;
}
- set_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status);
+ wl_set_p2p_status(wl, DISCOVERY_ON);
CFGP2P_DBG(("enter\n"));
{
s32 ret = BCME_OK;
CFGP2P_DBG((" enter\n"));
- clear_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status);
+ wl_clr_p2p_status(wl, DISCOVERY_ON);
if (wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE) == 0) {
CFGP2P_ERR((" do nothing, not initialized\n"));
* waiting out an action frame tx dwell time.
*/
#ifdef NOT_YET
- if (test_bit(WLP2P_STATUS_SCANNING, &wl->p2p_status)) {
+ if (wl_get_p2p_status(wl, SCANNING)) {
p2pwlu_scan_abort(hdl, FALSE);
}
#endif
- clear_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status);
+ wl_clr_p2p_status(wl, DISCOVERY_ON);
ret = wl_cfgp2p_deinit_discovery(wl);
exit:
#define P2PAPI_SCAN_DWELL_TIME_MS 40
#define P2PAPI_SCAN_HOME_TIME_MS 10
- set_bit(WLP2P_STATUS_SCANNING, &wl->p2p_status);
+ wl_set_p2p_status(wl, SCANNING);
/* Allocate scan params which need space for 3 channels and 0 ssids */
eparams_size = (WL_SCAN_PARAMS_FIXED_SIZE +
OFFSETOF(wl_escan_params_t, params)) +
CFGP2P_DBG((" Enter\n"));
/* TODO : have to acquire bottom half lock ? */
- if (test_bit(WLP2P_STATUS_LISTEN_EXPIRED, &wl->p2p_status) == 0) {
- set_bit(WLP2P_STATUS_LISTEN_EXPIRED, &wl->p2p_status);
+ if (wl_get_p2p_status(wl, LISTEN_EXPIRED) == 0) {
+ wl_set_p2p_status(wl, LISTEN_EXPIRED);
- if (wl->listen_timer)
- del_timer_sync(wl->listen_timer);
+ if (wl->p2p.listen_timer)
+ del_timer_sync(wl->p2p.listen_timer);
cfg80211_remain_on_channel_expired(ndev, wl->cache_cookie, &wl->remain_on_chan,
wl->remain_on_chan_type, GFP_KERNEL);
CFGP2P_DBG((" Enter\n"));
msg.event_type = hton32(WLC_E_P2P_DISC_LISTEN_COMPLETE);
- wl_cfg80211_event(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), &msg, NULL, GFP_ATOMIC);
+ wl_cfg80211_event(wl_to_p2p_bss_ndev(wl, P2PAPI_BSSCFG_DEVICE), &msg, NULL);
}
/*
s32 ret = BCME_OK;
CFGP2P_DBG((" Enter\n"));
CFGP2P_INFO(("Channel : %d, Duration : %d\n", channel, duration_ms));
- if (unlikely(test_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status) == 0)) {
+ if (unlikely(wl_get_p2p_status(wl, DISCOVERY_ON) == 0)) {
CFGP2P_ERR((" Discovery is not set, so we have noting to do\n"));
goto exit;
}
- clear_bit(WLP2P_STATUS_LISTEN_EXPIRED, &wl->p2p_status);
+ wl_clr_p2p_status(wl, LISTEN_EXPIRED);
wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_LISTEN, channel, (u16) duration_ms,
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
- if (wl->listen_timer)
- del_timer_sync(wl->listen_timer);
+ if (wl->p2p.listen_timer)
+ del_timer_sync(wl->p2p.listen_timer);
- wl->listen_timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
+ wl->p2p.listen_timer = kmalloc(sizeof(struct timer_list), GFP_KERNEL);
- if (wl->listen_timer == NULL) {
+ if (wl->p2p.listen_timer == NULL) {
CFGP2P_ERR(("listen_timer allocation failed\n"));
return -ENOMEM;
}
/* We will wait to receive WLC_E_P2P_DISC_LISTEN_COMPLETE from dongle ,
* otherwise we will wait up to duration_ms + 10ms
*/
- INIT_TIMER(wl->listen_timer, wl_cfgp2p_listen_expired, duration_ms, 20);
+ INIT_TIMER(wl->p2p.listen_timer, wl_cfgp2p_listen_expired, duration_ms, 20);
#undef INIT_TIMER
exit:
s32
-wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 search_enable)
+wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable)
{
s32 ret = BCME_OK;
CFGP2P_DBG((" Enter\n"));
- if (!test_bit(WLP2P_STATUS_DISCOVERY_ON, &wl->p2p_status)) {
+ if (!wl_get_p2p_status(wl, DISCOVERY_ON)) {
CFGP2P_ERR((" do nothing, discovery is off\n"));
return ret;
}
- if (test_bit(WLP2P_STATUS_SEARCH_ENABLED, &wl->p2p_status) == search_enable) {
- CFGP2P_ERR(("already : %d\n", search_enable));
+ if (wl_get_p2p_status(wl, SEARCH_ENABLED) == enable) {
+ CFGP2P_ERR(("already : %d\n", enable));
return ret;
}
- change_bit(WLP2P_STATUS_SEARCH_ENABLED, &wl->p2p_status);
+ wl_chg_p2p_status(wl, SEARCH_ENABLED);
/* When disabling Search, reset the WL driver's p2p discovery state to
* WL_P2P_DISC_ST_SCAN.
*/
- if (!search_enable) {
- clear_bit(WLP2P_STATUS_SCANNING, &wl->p2p_status);
+ if (!enable) {
+ wl_clr_p2p_status(wl, SCANNING);
(void) wl_cfgp2p_set_p2p_mode(wl, WL_P2P_DISC_ST_SCAN, 0, 0,
wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE));
}
CFGP2P_INFO((" WLC_E_ACTION_FRAME_COMPLETE is received : %d\n", status));
if (status == WLC_E_STATUS_SUCCESS)
- set_bit(WLP2P_STATUS_ACTION_TX_COMPLETED, &wl->p2p_status);
+ wl_set_p2p_status(wl, ACTION_TX_COMPLETED);
else
CFGP2P_ERR(("WLC_E_ACTION_FRAME_COMPLETE : NO ACK\n"));
wake_up_interruptible(&wl->dongle_event_wait);
CFGP2P_INFO(("channel : %u , dwell time : %u\n",
af_params->channel, af_params->dwell_time));
- clear_bit(WLP2P_STATUS_ACTION_TX_COMPLETED, &wl->p2p_status);
+ wl_clr_p2p_status(wl, ACTION_TX_COMPLETED);
#define MAX_WAIT_TIME 2000
if (bssidx == P2PAPI_BSSCFG_PRIMARY)
bssidx = wl_to_p2p_bss_bssidx(wl, P2PAPI_BSSCFG_DEVICE);
goto exit;
}
timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
- (test_bit(WLP2P_STATUS_ACTION_TX_COMPLETED, &wl->p2p_status) == TRUE),
+ (wl_get_p2p_status(wl, ACTION_TX_COMPLETED) == TRUE),
msecs_to_jiffies(MAX_WAIT_TIME));
- if (timeout > 0 && test_bit(WLP2P_STATUS_ACTION_TX_COMPLETED, &wl->p2p_status)) {
+ if (timeout > 0 && wl_get_p2p_status(wl, ACTION_TX_COMPLETED)) {
CFGP2P_INFO(("tx action frame operation is completed\n"));
ret = BCME_OK;
} else {
/* Check if 'p2p' is supported in the driver */
s32
-wl_cfgp2p_is_p2p_supported(struct wl_priv *wl, struct net_device *ndev)
+wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev)
{
s32 ret = BCME_OK;
- s32 is_p2p_supported = 0;
+ s32 p2p_supported = 0;
ret = wldev_iovar_getint(ndev, "p2p",
- &is_p2p_supported);
+ &p2p_supported);
if (ret < 0) {
CFGP2P_ERR(("wl p2p error %d\n", ret));
return 0;
}
- if (is_p2p_supported)
+ if (p2p_supported)
CFGP2P_INFO(("p2p is supported\n"));
- return is_p2p_supported;
+ return p2p_supported;
}
-
+/* Cleanup P2P resources */
s32
wl_cfgp2p_down(struct wl_priv *wl)
{
- if (wl->listen_timer)
- del_timer_sync(wl->listen_timer);
+ if (wl->p2p.listen_timer)
+ del_timer_sync(wl->p2p.listen_timer);
return 0;
}
#include <proto/802.11.h>
#include <proto/p2p.h>
+struct wl_priv;
+extern u32 wl_dbg_level;
+
+/* Enumeration of the usages of the BSSCFGs used by the P2P Library. Do not
+ * confuse this with a bsscfg index. This value is an index into the
+ * saved_ie[] array of structures which in turn contains a bsscfg index field.
+ */
+typedef enum {
+ P2PAPI_BSSCFG_PRIMARY, /* maps to driver's primary bsscfg */
+ P2PAPI_BSSCFG_DEVICE, /* maps to driver's P2P device discovery bsscfg */
+ P2PAPI_BSSCFG_CONNECTION, /* maps to driver's P2P connection bsscfg */
+ P2PAPI_BSSCFG_MAX
+} p2p_bsscfg_type_t;
+
+#define IE_MAX_LEN 300
+/* Structure to hold all saved P2P and WPS IEs for a BSSCFG */
+struct p2p_saved_ie {
+ u8 p2p_probe_req_ie[IE_MAX_LEN];
+ u8 p2p_probe_res_ie[IE_MAX_LEN];
+ u8 p2p_assoc_req_ie[IE_MAX_LEN];
+ u8 p2p_assoc_res_ie[IE_MAX_LEN];
+ u8 p2p_beacon_ie[IE_MAX_LEN];
+ u32 p2p_probe_req_ie_len;
+ u32 p2p_probe_res_ie_len;
+ u32 p2p_assoc_req_ie_len;
+ u32 p2p_assoc_res_ie_len;
+ u32 p2p_beacon_ie_len;
+};
+
+struct p2p_bss {
+ u32 bssidx;
+ struct net_device *dev;
+ struct p2p_saved_ie saved_ie;
+};
+
+struct p2p_info {
+ bool on; /* p2p on/off switch */
+ bool scan;
+ bool vif_created;
+ s8 vir_ifname[IFNAMSIZ];
+ unsigned long status;
+ struct ether_addr dev_addr;
+ struct ether_addr int_addr;
+ struct p2p_bss bss_idx[P2PAPI_BSSCFG_MAX];
+ struct timer_list *listen_timer;
+ wlc_ssid_t ssid;
+};
+
+/* dongle status */
+enum wl_cfgp2p_status {
+ WLP2P_STATUS_DISCOVERY_ON = 0,
+ WLP2P_STATUS_SEARCH_ENABLED,
+ WLP2P_STATUS_IF_ADD,
+ WLP2P_STATUS_IF_DEL,
+ WLP2P_STATUS_IF_DELETING,
+ WLP2P_STATUS_IF_CHANGING,
+ WLP2P_STATUS_IF_CHANGED,
+ WLP2P_STATUS_LISTEN_EXPIRED,
+ WLP2P_STATUS_ACTION_TX_COMPLETED,
+ WLP2P_STATUS_SCANNING
+};
+
+
+#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(wl, type) ((wl)->p2p.bss_idx[type])
+#define wl_get_p2p_status(wl, stat) (test_bit(WLP2P_STATUS_ ## stat, &(wl)->p2p.status))
+#define wl_set_p2p_status(wl, stat) (set_bit(WLP2P_STATUS_ ## stat, &(wl)->p2p.status))
+#define wl_clr_p2p_status(wl, stat) (clear_bit(WLP2P_STATUS_ ## stat, &(wl)->p2p.status))
+#define wl_chg_p2p_status(wl, stat) (change_bit(WLP2P_STATUS_ ## stat, &(wl)->p2p.status))
+#define p2p_on(wl) ((wl)->p2p.on)
+#define p2p_scan(wl) ((wl)->p2p.scan)
+
+
+/* dword align allocation */
+#define WLC_IOCTL_MAXLEN 8192
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+
+#define CFGP2P_ERR(args) \
+ do { \
+ if (wl_dbg_level & WL_DBG_ERR) { \
+ printk(KERN_ERR "CFGP2P-ERROR) %s : ", __func__); \
+ printk args; \
+ } \
+ } while (0)
+#define CFGP2P_INFO(args) \
+ do { \
+ if (wl_dbg_level & WL_DBG_INFO) { \
+ printk(KERN_ERR "CFGP2P-INFO) %s : ", __func__); \
+ printk args; \
+ } \
+ } while (0)
+#define CFGP2P_DBG(args) \
+ do { \
+ if (wl_dbg_level & WL_DBG_DBG) { \
+ printk(KERN_ERR "CFGP2P-DEBUG) %s :", __func__); \
+ printk args; \
+ } \
+ } while (0)
+
+
extern void
wl_cfgp2p_init_priv(struct wl_priv *wl);
extern s32
wl_cfgp2p_discover_listen(struct wl_priv *wl, s32 channel, u32 duration_ms);
extern s32
-wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 search_enable);
+wl_cfgp2p_discover_enable_search(struct wl_priv *wl, u8 enable);
extern s32
wl_cfgp2p_action_tx_complete(struct wl_priv *wl, struct net_device *ndev,
extern s32
-wl_cfgp2p_is_p2p_supported(struct wl_priv *wl, struct net_device *ndev);
+wl_cfgp2p_supported(struct wl_priv *wl, struct net_device *ndev);
extern s32
wl_cfgp2p_down(struct wl_priv *wl);
#if defined(SOFTAP)
#define WL_SOFTAP(x)
static struct net_device *priv_dev;
-static bool ap_cfg_running = FALSE;
-bool ap_fw_loaded = FALSE;
+bool ap_cfg_running = FALSE;
+bool ap_fw_loaded = FALSE;
struct net_device *ap_net_dev = NULL;
tsk_ctl_t ap_eth_ctl;
static int wl_iw_set_ap_security(struct net_device *dev, struct ap_profile *ap);
g_onoff = G_WLAN_SET_ON;
}
- WL_TRACE(("Exited %s \n", __FUNCTION__));
+ WL_TRACE(("Exited %s\n", __FUNCTION__));
DHD_OS_MUTEX_UNLOCK(&wl_start_lock);
return ret;
iscan->iscan_ex_params_p = (wl_iscan_params_t*)kmalloc(params_size, GFP_KERNEL);
- if (!iscan->iscan_ex_params_p)
+ if (!iscan->iscan_ex_params_p) {
+ kfree(iscan);
return -ENOMEM;
+ }
iscan->iscan_ex_param_size = params_size;
#define GET_HOME_DWELL "HOME="
#define GET_SCAN_TYPE "TYPE="
-
-#define BAND_GET_CMD "BANDGET"
-#define BAND_SET_CMD "BANDSET"
+#define BAND_GET_CMD "GETBAND"
+#define BAND_SET_CMD "SETBAND"
#define DTIM_SKIP_GET_CMD "DTIMSKIPGET"
#define DTIM_SKIP_SET_CMD "DTIMSKIPSET"
#define SETSUSPEND_CMD "SETSUSPENDOPT"