summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2010-02-16 15:07:36 -0800
committerDmitry Shmidt <dimitrysh@google.com>2010-02-16 15:07:36 -0800
commita05cf6aee61444a6f415731b3c1e9529904da85d (patch)
treefe8eadf9d3528484d7884872a56ac89c464abd18
parentda5e159cc38bf239524302d634473f6ef2a6614d (diff)
downloadandroid_hardware_broadcom_wlan-a05cf6aee61444a6f415731b3c1e9529904da85d.tar.gz
android_hardware_broadcom_wlan-a05cf6aee61444a6f415731b3c1e9529904da85d.tar.bz2
android_hardware_broadcom_wlan-a05cf6aee61444a6f415731b3c1e9529904da85d.zip
bcm4329: Sync with kernel tree (add kernel 2.6.32 support)
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
-rw-r--r--bcm4329/src/bcmsdio/sys/bcmsdh_linux.c4
-rw-r--r--bcm4329/src/dhd/sys/dhd_cdc.c10
-rw-r--r--bcm4329/src/dhd/sys/dhd_linux.c112
-rw-r--r--bcm4329/src/dhd/sys/dhd_sdio.c2
-rw-r--r--bcm4329/src/include/linuxver.h2
-rw-r--r--bcm4329/src/wl/sys/wl_iw.c95
6 files changed, 166 insertions, 59 deletions
diff --git a/bcm4329/src/bcmsdio/sys/bcmsdh_linux.c b/bcm4329/src/bcmsdio/sys/bcmsdh_linux.c
index d7d5b73..8787904 100644
--- a/bcm4329/src/bcmsdio/sys/bcmsdh_linux.c
+++ b/bcm4329/src/bcmsdio/sys/bcmsdh_linux.c
@@ -539,7 +539,7 @@ static irqreturn_t wlan_oob_irq(int irq, void *dev_id)
{
dhd_pub_t *dhdp;
- dhdp = (dhd_pub_t *)sdhcinfo->dev->driver_data;
+ dhdp = (dhd_pub_t *)dev_get_drvdata(sdhcinfo->dev);
if (dhdp == NULL) {
disable_irq(sdhcinfo->oob_irq);
@@ -558,7 +558,7 @@ int bcmsdh_register_oob_intr(void * dhdp)
SDLX_MSG(("%s Enter\n", __FUNCTION__));
- sdhcinfo->dev->driver_data = dhdp;
+ dev_set_drvdata(sdhcinfo->dev, dhdp);
/* Refer to customer Host IRQ docs about proper irqflags definition */
error = request_irq(sdhcinfo->oob_irq, wlan_oob_irq, sdhcinfo->oob_flags,
diff --git a/bcm4329/src/dhd/sys/dhd_cdc.c b/bcm4329/src/dhd/sys/dhd_cdc.c
index e433667..935a766 100644
--- a/bcm4329/src/dhd/sys/dhd_cdc.c
+++ b/bcm4329/src/dhd/sys/dhd_cdc.c
@@ -524,6 +524,7 @@ int dhd_set_suspend(int value, dhd_pub_t *dhd)
#define htod32(i) i
if (dhd && dhd->up) {
+ dhd_os_proto_block(dhd);
if (value) {
dhdcdc_set_ioctl(dhd, 0, WLC_SET_PM,
(char *)&power_mode, sizeof(power_mode));
@@ -563,6 +564,7 @@ int dhd_set_suspend(int value, dhd_pub_t *dhd)
dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
#endif /* CUSTOMER_HW2 */
}
+ dhd_os_proto_unblock(dhd);
}
return 0;
@@ -626,11 +628,13 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
char buf[256];
uint filter_mode = 1;
+ dhd_os_proto_block(dhd);
/* Get the device MAC address */
strcpy(iovbuf, "cur_etheraddr");
if ((ret = dhdcdc_query_ioctl(dhd, 0, WLC_GET_VAR, iovbuf, sizeof(iovbuf))) < 0) {
DHD_ERROR(("%s: can't get MAC address , error=%d\n", __FUNCTION__, ret));
- return BCME_NOTUP;
+ dhd_os_proto_unblock(dhd);
+ return -BCME_NOTUP;
}
memcpy(dhd->mac.octet, iovbuf, ETHER_ADDR_LEN);
@@ -734,7 +738,8 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
if (mask_size != pattern_size) {
printk("Mask and pattern not the same size\n");
- return -1;
+ dhd_os_proto_unblock(dhd);
+ return -EINVAL;
}
pkt_filter.u.pattern.size_bytes = mask_size;
@@ -754,6 +759,7 @@ dhd_preinit_ioctls(dhd_pub_t *dhd)
bcm_mkiovar("pkt_filter_mode", (char *)&filter_mode, 4, iovbuf, sizeof(iovbuf));
dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, iovbuf, sizeof(iovbuf));
+ dhd_os_proto_unblock(dhd);
return 0;
}
diff --git a/bcm4329/src/dhd/sys/dhd_linux.c b/bcm4329/src/dhd/sys/dhd_linux.c
index eda41d7..df46938 100644
--- a/bcm4329/src/dhd/sys/dhd_linux.c
+++ b/bcm4329/src/dhd/sys/dhd_linux.c
@@ -1747,7 +1747,11 @@ dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen)
if (dhd_add_if(dhd, 0, (void *)net, net->name, NULL, 0, 0) == DHD_BAD_IF)
goto fail;
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
net->open = NULL;
+#else
+ net->netdev_ops = NULL;
+#endif
init_MUTEX(&dhd->proto_sem);
/* Initialize other structure content */
@@ -1941,6 +1945,26 @@ dhd_iovar(dhd_pub_t *pub, int ifidx, char *name, char *cmd_buf, uint cmd_len, in
return ret;
}
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
+static struct net_device_ops dhd_ops_pri = {
+ .ndo_open = dhd_open,
+ .ndo_stop = dhd_stop,
+ .ndo_get_stats = dhd_get_stats,
+ .ndo_do_ioctl = dhd_ioctl_entry,
+ .ndo_start_xmit = dhd_start_xmit,
+ .ndo_set_mac_address = dhd_set_mac_address,
+ .ndo_set_multicast_list = dhd_set_multicast_list,
+};
+
+static struct net_device_ops dhd_ops_virt = {
+ .ndo_get_stats = dhd_get_stats,
+ .ndo_do_ioctl = dhd_ioctl_entry,
+ .ndo_start_xmit = dhd_start_xmit,
+ .ndo_set_mac_address = dhd_set_mac_address,
+ .ndo_set_multicast_list = dhd_set_multicast_list,
+};
+#endif
+
int
dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
{
@@ -1951,30 +1975,40 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
DHD_TRACE(("%s: ifidx %d\n", __FUNCTION__, ifidx));
ASSERT(dhd && dhd->iflist[ifidx]);
- ASSERT(dhd->iflist[ifidx]->net);
- ASSERT(!dhd->iflist[ifidx]->net->open);
+ net = dhd->iflist[ifidx]->net;
+
+ ASSERT(net);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
+ ASSERT(!net->open);
+ net->get_stats = dhd_get_stats;
+ net->do_ioctl = dhd_ioctl_entry;
+ net->hard_start_xmit = dhd_start_xmit;
+ net->set_mac_address = dhd_set_mac_address;
+ net->set_multicast_list = dhd_set_multicast_list;
+ net->open = net->stop = NULL;
+#else
+ ASSERT(!net->netdev_ops);
+ net->netdev_ops = &dhd_ops_virt;
+#endif
/* Ok, link into the network layer... */
- net = dhd->iflist[ifidx]->net;
if (ifidx == 0) {
/*
* device functions for the primary interface only
*/
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
net->open = dhd_open;
net->stop = dhd_stop;
+#else
+ net->netdev_ops = &dhd_ops_pri;
+#endif
} else {
- net->open = net->stop = NULL;
/*
* We have to use the primary MAC for virtual interfaces
*/
memcpy(temp_addr, dhd->iflist[ifidx]->mac_addr, ETHER_ADDR_LEN);
}
- net->get_stats = dhd_get_stats;
- net->do_ioctl = dhd_ioctl_entry;
- net->hard_start_xmit = dhd_start_xmit;
net->hard_header_len = ETH_HLEN + dhd->pub.hdrlen;
- net->set_mac_address = dhd_set_mac_address;
- net->set_multicast_list = dhd_set_multicast_list;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24)
net->ethtool_ops = &dhd_ethtool_ops;
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) */
@@ -2007,7 +2041,11 @@ dhd_net_attach(dhd_pub_t *dhdp, int ifidx)
return 0;
fail:
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
net->open = NULL;
+#else
+ net->netdev_ops = NULL;
+#endif
return BCME_ERROR;
}
@@ -2068,7 +2106,11 @@ dhd_detach(dhd_pub_t *dhdp)
ifp = dhd->iflist[0];
ASSERT(ifp);
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
if (ifp->net->open) {
+#else
+ if (ifp->net->netdev_ops == &dhd_ops_pri) {
+#endif
dhd_stop(ifp->net);
unregister_netdev(ifp->net);
}
@@ -2127,22 +2169,27 @@ dhd_module_init(void)
return -EINVAL;
} while (0);
+ /* Call customer gpio to turn on power with WL_REG_ON signal */
+ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON);
+
#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
sema_init(&wifi_control_sem, 0);
- wifi_add_dev();
+
+ error = wifi_add_dev();
+ if (error) {
+ DHD_ERROR(("%s: platform_driver_register failed\n", __FUNCTION__));
+ goto fail_0;
+ }
/* Waiting callback after platform_driver_register is done or exit with error */
if (down_timeout(&wifi_control_sem, msecs_to_jiffies(5000)) != 0) {
error = -EINVAL;
- DHD_ERROR(("%s: platform_driver_register callback timeout\n", __FUNCTION__));
- goto fail;
+ DHD_ERROR(("%s: platform_driver_register timeout\n", __FUNCTION__));
+ goto fail_1;
}
#endif /* #if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */
- /* Call customer gpio to turn on power with WL_REG_ON signal */
- dhd_customer_gpio_wlan_ctrl(WLAN_POWER_ON);
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && 1
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
sema_init(&dhd_registration_sem, 0);
#endif
@@ -2150,8 +2197,11 @@ dhd_module_init(void)
if (!error)
printf("\n%s\n", dhd_version);
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)) && 1
+ else {
+ DHD_ERROR(("%s: sdio_register_driver failed\n", __FUNCTION__));
+ goto fail_1;
+ }
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
/*
* Wait till MMC sdio_register_driver callback called and made driver attach.
* It's needed to make sync up exit from dhd insmod and
@@ -2159,14 +2209,24 @@ dhd_module_init(void)
*/
if (down_timeout(&dhd_registration_sem, msecs_to_jiffies(10000)) != 0) {
error = -EINVAL;
- DHD_ERROR(("%s: sdio_register_driver failed \n", __FUNCTION__));
+ DHD_ERROR(("%s: sdio_register_driver timeout\n", __FUNCTION__));
+ goto fail_2;
}
-#endif
-
+#endif
+ return error;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27))
+fail_2:
+ dhd_bus_unregister();
+#endif
+fail_1:
#if defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC)
-fail:
+ wifi_del_dev();
+fail_0:
#endif /* defined(CUSTOMER_HW2) && defined(CONFIG_WIFI_CONTROL_FUNC) */
+ /* Call customer gpio to turn off power with WL_REG_ON signal */
+ dhd_customer_gpio_wlan_ctrl(WLAN_POWER_OFF);
+
return error;
}
@@ -2503,8 +2563,16 @@ dhd_dev_reset(struct net_device *dev, uint8 flag)
{
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);
+ /* 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;
diff --git a/bcm4329/src/dhd/sys/dhd_sdio.c b/bcm4329/src/dhd/sys/dhd_sdio.c
index fe8c8d7..427600f 100644
--- a/bcm4329/src/dhd/sys/dhd_sdio.c
+++ b/bcm4329/src/dhd/sys/dhd_sdio.c
@@ -5379,9 +5379,11 @@ dhd_bus_devreset(dhd_pub_t *dhdp, uint8 flag)
/* Force flow control as protection when stop come before ifconfig_down */
dhd_txflowcontrol(bus->dhd, 0, ON);
#endif /* !defined(IGNORE_ETH0_DOWN) */
+ dhd_os_proto_block(dhdp);
/* save country settinng if was pre-setup with priv ioctl */
dhdcdc_query_ioctl(bus->dhd, 0, WLC_GET_COUNTRY,
bus->dhd->country_code, sizeof(bus->dhd->country_code));
+ dhd_os_proto_unblock(dhdp);
/* Expect app to have torn down any connection before calling */
/* Stop the bus, disable F2 */
dhd_bus_stop(bus, FALSE);
diff --git a/bcm4329/src/include/linuxver.h b/bcm4329/src/include/linuxver.h
index e765667..a36de95 100644
--- a/bcm4329/src/include/linuxver.h
+++ b/bcm4329/src/include/linuxver.h
@@ -429,7 +429,7 @@ pci_restore_state(struct pci_dev *dev, u32 *buffer)
#define KILL_PROC(pid, sig) \
{ \
struct task_struct *tsk; \
- tsk = find_task_by_vpid(pid); \
+ tsk = pid_task(find_vpid(pid), PIDTYPE_PID); \
if (tsk) send_sig(sig, tsk, 1); \
}
#else
diff --git a/bcm4329/src/wl/sys/wl_iw.c b/bcm4329/src/wl/sys/wl_iw.c
index 535439c..0f04aab 100644
--- a/bcm4329/src/wl/sys/wl_iw.c
+++ b/bcm4329/src/wl/sys/wl_iw.c
@@ -258,24 +258,35 @@ dev_wlc_ioctl(
struct ifreq ifr;
wl_ioctl_t ioc;
mm_segment_t fs;
- int ret;
+ int ret = -EINVAL;
- memset(&ioc, 0, sizeof(ioc));
- ioc.cmd = cmd;
- ioc.buf = arg;
- ioc.len = len;
-
- strcpy(ifr.ifr_name, dev->name);
- ifr.ifr_data = (caddr_t) &ioc;
-
-
- dev_open(dev);
-
- fs = get_fs();
- set_fs(get_ds());
- ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
- set_fs(fs);
+ if (g_onoff == G_WLAN_SET_ON) {
+ memset(&ioc, 0, sizeof(ioc));
+ ioc.cmd = cmd;
+ ioc.buf = arg;
+ ioc.len = len;
+
+ strcpy(ifr.ifr_name, dev->name);
+ ifr.ifr_data = (caddr_t) &ioc;
+
+ ret = dev_open(dev);
+ if (ret) {
+ WL_ERROR(("%s: Error dev_open: %d\n", __func__, ret));
+ return ret;
+ }
+ fs = get_fs();
+ set_fs(get_ds());
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
+ ret = dev->do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+#else
+ ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE);
+#endif
+ set_fs(fs);
+ }
+ else {
+ WL_TRACE(("%s: call after driver stop\n", __FUNCTION__));
+ }
return ret;
}
@@ -522,9 +533,9 @@ wl_iw_set_country(
int country_offset;
int country_code_size;
+ WL_TRACE(("%s\n", __FUNCTION__));
memset(country_code, 0, sizeof(country_code));
-
country_offset = strcspn(extra, " ");
country_code_size = strlen(extra) - country_offset;
@@ -1769,10 +1780,14 @@ static void wl_iw_send_scan_complete(iscan_info_t *iscan)
union iwreq_data wrqu;
char extra[IW_CUSTOM_MAX + 1];
- memset(&wrqu, 0, sizeof(wrqu));
- memset(extra, 0, sizeof(extra));
- wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, extra);
- WL_TRACE(("Send Event SCAN complete\n"));
+ memset(&wrqu, 0, sizeof(wrqu));
+ memset(extra, 0, sizeof(extra));
+#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 31))
+ wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, extra);
+#else
+ wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL);
+#endif
+ WL_TRACE(("Send Event SCAN complete\n"));
#endif
}
static int
@@ -2376,16 +2391,18 @@ wl_iw_get_scan_prep(
if (bi->rateset.count) {
- value = event + IW_EV_LCP_LEN;
- iwe.cmd = SIOCGIWRATE;
-
- iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
- for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) {
- iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000;
- value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe,
- IW_EV_PARAM_LEN);
+ if (((event - extra) + IW_EV_LCP_LEN) <= (int)end) {
+ value = event + IW_EV_LCP_LEN;
+ iwe.cmd = SIOCGIWRATE;
+
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+ for (j = 0; j < bi->rateset.count && j < IW_MAX_BITRATES; j++) {
+ iwe.u.bitrate.value = (bi->rateset.rates[j] & 0x7f) * 500000;
+ value = IWE_STREAM_ADD_VALUE(info, event, value, end, &iwe,
+ IW_EV_PARAM_LEN);
+ }
+ event = value;
}
- event = value;
}
}
@@ -2474,6 +2491,14 @@ wl_iw_get_scan(
list->version = dtoh32(list->version);
list->count = dtoh32(list->count);
+ if (list->version != WL_BSS_INFO_VERSION) {
+ WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n",
+ __FUNCTION__, list->version));
+ if (g_scan_specified_ssid)
+ kfree(list);
+ return -EINVAL;
+ }
+
if (g_scan_specified_ssid) {
wl_iw_add_bss_to_ss_cache(list);
@@ -4302,7 +4327,7 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
uint16 flags = ntoh16(e->flags);
uint32 datalen = ntoh32(e->datalen);
uint32 status = ntoh32(e->status);
- uint32 toto;
+ uint32 toto;
memset(&wrqu, 0, sizeof(wrqu));
memset(extra, 0, sizeof(extra));
@@ -4444,8 +4469,14 @@ wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void* data)
break;
}
#ifndef SANDGATE2G
- if (cmd)
+ if (cmd) {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 31))
+ if (cmd == SIOCGIWSCAN)
+ wireless_send_event(dev, cmd, &wrqu, NULL);
+ else
+#endif
wireless_send_event(dev, cmd, &wrqu, extra);
+ }
#endif
#if WIRELESS_EXT > 14