aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKalimochoAz <calimochoazucarado@gmail.com>2012-04-01 20:09:04 +0200
committerKalimochoAz <calimochoazucarado@gmail.com>2012-04-01 20:09:04 +0200
commit910d38a37b414ee4af1199071667b2ac19a4151e (patch)
tree91138a9a0239df0910a5581caf0926b1d2ccb81c
parent96b165e5470cb58e747c257dadc44e427274fa83 (diff)
parent665612374970f5dba43b65510b52b72130818541 (diff)
downloadkernel_samsung_crespo-910d38a37b414ee4af1199071667b2ac19a4151e.zip
kernel_samsung_crespo-910d38a37b414ee4af1199071667b2ac19a4151e.tar.gz
kernel_samsung_crespo-910d38a37b414ee4af1199071667b2ac19a4151e.tar.bz2
Merge branch 'ics.googleupdate.4.0.4' into cm.ics
Conflicts: fs/proc/base.c
-rw-r--r--arch/arm/kernel/process.c2
-rwxr-xr-xarch/arm/mach-s5pv210/dev-herring-phone.c5
-rwxr-xr-xarch/arm/mach-s5pv210/mach-herring.c104
-rw-r--r--arch/arm/mach-s5pv210/power-domain.c15
-rwxr-xr-xdrivers/misc/fsa9480.c43
-rwxr-xr-xdrivers/misc/samsung_modemctl/modem_ctl.c4
-rw-r--r--drivers/misc/samsung_modemctl/modem_ctl.h1
-rw-r--r--drivers/misc/samsung_modemctl/modem_ctl_p.h3
-rw-r--r--drivers/misc/samsung_modemctl/modem_io.c90
-rw-r--r--drivers/mmc/core/bus.c24
-rw-r--r--drivers/net/wireless/bcm4329/dhd_common.c43
-rw-r--r--drivers/net/wireless/bcmdhd/Kconfig7
-rw-r--r--drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c16
-rw-r--r--drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c4
-rw-r--r--drivers/net/wireless/bcmdhd/dhd.h8
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_cdc.c4
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_common.c7
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux.c20
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_linux_mon.c10
-rw-r--r--drivers/net/wireless/bcmdhd/dhd_sdio.c6
-rw-r--r--drivers/net/wireless/bcmdhd/include/epivers.h2
-rw-r--r--drivers/net/wireless/bcmdhd/include/linux_osl.h2
-rw-r--r--drivers/net/wireless/bcmdhd/linux_osl.c52
-rw-r--r--drivers/net/wireless/bcmdhd/wl_android.c16
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.c70
-rw-r--r--drivers/net/wireless/bcmdhd/wl_cfg80211.h9
-rw-r--r--drivers/net/wireless/bcmdhd/wl_iw.c2
-rw-r--r--drivers/usb/gadget/android.c31
-rw-r--r--drivers/usb/gadget/rndis.c23
-rw-r--r--drivers/video/samsung/s3cfb_fimd6x.c17
-rwxr-xr-xdrivers/video/samsung/s3cfb_nt35580.c1
-rwxr-xr-xdrivers/video/samsung/s3cfb_tl2796.c2
-rw-r--r--fs/proc/base.c4
-rwxr-xr-x[-rw-r--r--]net/bluetooth/hci_event.c12
-rw-r--r--net/wireless/reg.c5
35 files changed, 463 insertions, 201 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 81c137d..e5cfa6a 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -223,8 +223,8 @@ void cpu_idle(void)
/* endless idle loop with no priority at all */
while (1) {
- tick_nohz_stop_sched_tick(1);
idle_notifier_call_chain(IDLE_START);
+ tick_nohz_stop_sched_tick(1);
while (!need_resched()) {
#ifdef CONFIG_HOTPLUG_CPU
if (cpu_is_offline(smp_processor_id()))
diff --git a/arch/arm/mach-s5pv210/dev-herring-phone.c b/arch/arm/mach-s5pv210/dev-herring-phone.c
index f8798b3..b605e02 100755
--- a/arch/arm/mach-s5pv210/dev-herring-phone.c
+++ b/arch/arm/mach-s5pv210/dev-herring-phone.c
@@ -31,6 +31,7 @@ static struct modemctl_data mdmctl_data = {
.gpio_cp_reset = GPIO_CP_RST,
.gpio_phone_on = GPIO_PHONE_ON,
.is_cdma_modem = 0,
+ .num_pdp_contexts = 3,
};
static struct resource mdmctl_res[] = {
@@ -67,8 +68,10 @@ static struct platform_device modemctl = {
static int __init herring_init_phone_interface(void)
{
/* CDMA device */
- if (herring_is_cdma_wimax_dev())
+ if (herring_is_cdma_wimax_dev()) {
mdmctl_data.is_cdma_modem = 1;
+ mdmctl_data.num_pdp_contexts = 1;
+ }
platform_device_register(&modemctl);
return 0;
diff --git a/arch/arm/mach-s5pv210/mach-herring.c b/arch/arm/mach-s5pv210/mach-herring.c
index 88ef01a..7efb07c 100755
--- a/arch/arm/mach-s5pv210/mach-herring.c
+++ b/arch/arm/mach-s5pv210/mach-herring.c
@@ -4790,8 +4790,8 @@ static unsigned int herring_cdma_wimax_sleep_gpio_table[][3] = {
{ S5PV210_GPC1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
/*WIMAX EEPROM I2C LINES*/
- { S5PV210_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
- { S5PV210_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPC1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPC1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
/*WIMAX DBGEN*/
{ S5PV210_GPD0(0), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
@@ -4800,7 +4800,7 @@ static unsigned int herring_cdma_wimax_sleep_gpio_table[][3] = {
{ S5PV210_GPD0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
/*WIMAX RESET_N*/
- { S5PV210_GPD0(3), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPD0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_UP},
{ S5PV210_GPD1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
{ S5PV210_GPD1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
@@ -4862,20 +4862,20 @@ static unsigned int herring_cdma_wimax_sleep_gpio_table[][3] = {
{ S5PV210_GPG0(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
- { S5PV210_GPG0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG0(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
{ S5PV210_GPG0(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
- { S5PV210_GPG0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
- { S5PV210_GPG0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
- { S5PV210_GPG0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
- { S5PV210_GPG0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG0(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG0(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG0(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG0(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
{ S5PV210_GPG1(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
{ S5PV210_GPG1(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
{ S5PV210_GPG1(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
- { S5PV210_GPG1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
- { S5PV210_GPG1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
- { S5PV210_GPG1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
- { S5PV210_GPG1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPG1(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG1(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG1(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPG1(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
/*wimax SDIO pins*/
{ S5PV210_GPG2(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_NONE},
@@ -4931,11 +4931,11 @@ static unsigned int herring_cdma_wimax_sleep_gpio_table[][3] = {
{ S5PV210_GPJ2(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
{ S5PV210_GPJ2(2), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
{ S5PV210_GPJ2(3), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
- { S5PV210_GPJ2(4), S3C_GPIO_SLP_PREV, S3C_GPIO_PULL_DOWN},
+ { S5PV210_GPJ2(4), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
{ S5PV210_GPJ2(5), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
{ S5PV210_GPJ2(6), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
- { S5PV210_GPJ2(7), S3C_GPIO_SLP_OUT1, S3C_GPIO_PULL_NONE},
+ { S5PV210_GPJ2(7), S3C_GPIO_SLP_OUT0, S3C_GPIO_PULL_NONE},
{ S5PV210_GPJ3(0), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
{ S5PV210_GPJ3(1), S3C_GPIO_SLP_INPUT, S3C_GPIO_PULL_DOWN},
@@ -5363,11 +5363,82 @@ int __init herring_init_wifi_mem(void)
return -ENOMEM;
}
+
+/* Customized Locale table : OPTIONAL feature */
+#define WLC_CNTRY_BUF_SZ 4
+typedef struct cntry_locales_custom {
+ char iso_abbrev[WLC_CNTRY_BUF_SZ];
+ char custom_locale[WLC_CNTRY_BUF_SZ];
+ int custom_locale_rev;
+} cntry_locales_custom_t;
+
+static cntry_locales_custom_t herring_wlan_translate_custom_table[] = {
+/* Table should be filled out based on custom platform regulatory requirement */
+ {"", "XY", 4}, /* universal */
+ {"US", "US", 69}, /* input ISO "US" to : US regrev 69 */
+ {"CA", "US", 69}, /* input ISO "CA" to : US regrev 69 */
+ {"EU", "EU", 5}, /* European union countries */
+ {"AT", "EU", 5},
+ {"BE", "EU", 5},
+ {"BG", "EU", 5},
+ {"CY", "EU", 5},
+ {"CZ", "EU", 5},
+ {"DK", "EU", 5},
+ {"EE", "EU", 5},
+ {"FI", "EU", 5},
+ {"FR", "EU", 5},
+ {"DE", "EU", 5},
+ {"GR", "EU", 5},
+ {"HU", "EU", 5},
+ {"IE", "EU", 5},
+ {"IT", "EU", 5},
+ {"LV", "EU", 5},
+ {"LI", "EU", 5},
+ {"LT", "EU", 5},
+ {"LU", "EU", 5},
+ {"MT", "EU", 5},
+ {"NL", "EU", 5},
+ {"PL", "EU", 5},
+ {"PT", "EU", 5},
+ {"RO", "EU", 5},
+ {"SK", "EU", 5},
+ {"SI", "EU", 5},
+ {"ES", "EU", 5},
+ {"SE", "EU", 5},
+ {"GB", "EU", 5}, /* input ISO "GB" to : EU regrev 05 */
+ {"IL", "IL", 0},
+ {"CH", "CH", 0},
+ {"TR", "TR", 0},
+ {"NO", "NO", 0},
+ {"KR", "XY", 3},
+ {"AU", "XY", 3},
+ {"CN", "XY", 3}, /* input ISO "CN" to : XY regrev 03 */
+ {"TW", "XY", 3},
+ {"AR", "XY", 3},
+ {"MX", "XY", 3}
+};
+
+static void *herring_wlan_get_country_code(char *ccode)
+{
+ int size = ARRAY_SIZE(herring_wlan_translate_custom_table);
+ int i;
+
+ if (!ccode)
+ return NULL;
+
+ for (i = 0; i < size; i++)
+ if (strcmp(ccode, herring_wlan_translate_custom_table[i].iso_abbrev) == 0)
+ return &herring_wlan_translate_custom_table[i];
+ return &herring_wlan_translate_custom_table[0];
+}
+
+
static struct wifi_platform_data wifi_pdata = {
.set_power = wlan_power_en,
.set_reset = wlan_reset_en,
.set_carddetect = wlan_carddetect_en,
.mem_prealloc = herring_mem_prealloc,
+ .get_country_code = herring_wlan_get_country_code,
};
static struct platform_device sec_device_wifi = {
@@ -5926,9 +5997,8 @@ void otg_phy_init(void)
writel(readl(S3C_USBOTG_PHYTUNE) | (0x1<<20),
S3C_USBOTG_PHYTUNE);
- /* set DC level as 6 (6%) */
- writel((readl(S3C_USBOTG_PHYTUNE) & ~(0xf)) | (0x1<<2) | (0x1<<1),
- S3C_USBOTG_PHYTUNE);
+ /* set DC level as 0xf (24%) */
+ writel(readl(S3C_USBOTG_PHYTUNE) | 0xf, S3C_USBOTG_PHYTUNE);
}
EXPORT_SYMBOL(otg_phy_init);
diff --git a/arch/arm/mach-s5pv210/power-domain.c b/arch/arm/mach-s5pv210/power-domain.c
index 3383878..59a1a98 100644
--- a/arch/arm/mach-s5pv210/power-domain.c
+++ b/arch/arm/mach-s5pv210/power-domain.c
@@ -38,6 +38,7 @@ struct clk_should_be_running {
const char *clk_name;
struct device *dev;
};
+static spinlock_t pd_lock;
static struct regulator_consumer_supply s5pv210_pd_audio_supply[] = {
REGULATOR_SUPPLY("pd", "samsung-i2s.0"),
@@ -332,18 +333,25 @@ static int s5pv210_pd_pwr_off(int ctrl)
static int s5pv210_pd_ctrl(int ctrlbit, int enable)
{
- u32 pd_reg = __raw_readl(S5P_NORMAL_CFG);
+ u32 pd_reg;
+ spin_lock(&pd_lock);
+ pd_reg = __raw_readl(S5P_NORMAL_CFG);
if (enable) {
__raw_writel((pd_reg | ctrlbit), S5P_NORMAL_CFG);
if (s5pv210_pd_pwr_done(ctrlbit))
- return -ETIME;
+ goto out;
} else {
__raw_writel((pd_reg & ~(ctrlbit)), S5P_NORMAL_CFG);
if (s5pv210_pd_pwr_off(ctrlbit))
- return -ETIME;
+ goto out;
}
+ spin_unlock(&pd_lock);
return 0;
+out:
+ spin_unlock(&pd_lock);
+ return -ETIME;
+
}
static int s5pv210_pd_clk_enable(struct clk_should_be_running *clk_run)
@@ -497,6 +505,7 @@ static int __devinit reg_s5pv210_pd_probe(struct platform_device *pdev)
drvdata->clk_run = config->clk_run;
drvdata->ctrlbit = config->ctrlbit;
+ spin_lock_init(&pd_lock);
drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
config->init_data, drvdata);
diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c
index ca6b8e2..8098f82 100755
--- a/drivers/misc/fsa9480.c
+++ b/drivers/misc/fsa9480.c
@@ -30,6 +30,7 @@
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
+#include <linux/delay.h>
/* FSA9480 I2C registers */
#define FSA9480_REG_DEVID 0x01
@@ -397,18 +398,40 @@ static irqreturn_t fsa9480_irq_thread(int irq, void *data)
struct fsa9480_usbsw *usbsw = data;
struct i2c_client *client = usbsw->client;
int intr;
-
- /* read and clear interrupt status bits */
- intr = i2c_smbus_read_word_data(client, FSA9480_REG_INT1);
- if (intr < 0) {
- dev_err(&client->dev, "%s: err %d\n", __func__, intr);
- } else if (intr == 0) {
- /* interrupt was fired, but no status bits were set,
- so device was reset. In this case, the registers were
- reset to defaults so they need to be reinitialised. */
+ int max_events = 100;
+ int events_seen = 0;
+
+ /*
+ * the fsa could have queued up a few events if we haven't processed
+ * them promptly
+ */
+ while (max_events-- > 0) {
+ intr = i2c_smbus_read_word_data(client, FSA9480_REG_INT1);
+ if (intr < 0)
+ dev_err(&client->dev, "%s: err %d\n", __func__, intr);
+ else if (intr == 0)
+ break;
+ else if (intr > 0)
+ events_seen++;
+ }
+ if (!max_events)
+ dev_warn(&client->dev, "too many events. fsa hosed?\n");
+
+ if (!events_seen) {
+ /*
+ * interrupt was fired, but no status bits were set,
+ * so device was reset. In this case, the registers were
+ * reset to defaults so they need to be reinitialised.
+ */
fsa9480_reg_init(usbsw);
}
+ /*
+ * fsa may take some time to update the dev_type reg after reading
+ * the int reg.
+ */
+ usleep_range(200, 300);
+
/* device detection */
fsa9480_detect_dev(usbsw);
@@ -422,7 +445,7 @@ static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw)
if (client->irq) {
ret = request_threaded_irq(client->irq, NULL,
- fsa9480_irq_thread, IRQF_TRIGGER_FALLING,
+ fsa9480_irq_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"fsa9480 micro USB", usbsw);
if (ret) {
dev_err(&client->dev, "failed to reqeust IRQ\n");
diff --git a/drivers/misc/samsung_modemctl/modem_ctl.c b/drivers/misc/samsung_modemctl/modem_ctl.c
index e7504fd..f99f17c 100755
--- a/drivers/misc/samsung_modemctl/modem_ctl.c
+++ b/drivers/misc/samsung_modemctl/modem_ctl.c
@@ -1092,6 +1092,10 @@ static int __devinit modemctl_probe(struct platform_device *pdev)
mc->gpio_cp_reset = pdata->gpio_cp_reset;
mc->gpio_phone_on = pdata->gpio_phone_on;
mc->is_cdma_modem = pdata->is_cdma_modem;
+ if (pdata->num_pdp_contexts)
+ mc->num_pdp_contexts = pdata->num_pdp_contexts;
+ else
+ mc->num_pdp_contexts = 1;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
diff --git a/drivers/misc/samsung_modemctl/modem_ctl.h b/drivers/misc/samsung_modemctl/modem_ctl.h
index 7c23165..b4ad920 100644
--- a/drivers/misc/samsung_modemctl/modem_ctl.h
+++ b/drivers/misc/samsung_modemctl/modem_ctl.h
@@ -39,6 +39,7 @@ struct modemctl_data {
unsigned gpio_cp_reset;
unsigned gpio_phone_on;
bool is_cdma_modem; /* 1:CDMA Modem */
+ int num_pdp_contexts;
};
#endif
diff --git a/drivers/misc/samsung_modemctl/modem_ctl_p.h b/drivers/misc/samsung_modemctl/modem_ctl_p.h
index 3de2231..6223b20 100644
--- a/drivers/misc/samsung_modemctl/modem_ctl_p.h
+++ b/drivers/misc/samsung_modemctl/modem_ctl_p.h
@@ -121,7 +121,7 @@ struct modemctl {
struct wake_lock ip_tx_wakelock;
struct wake_lock ip_rx_wakelock;
- struct net_device *ndev;
+ struct net_device **ndev;
int open_count;
int status;
@@ -137,6 +137,7 @@ struct modemctl {
unsigned gpio_cp_reset;
unsigned gpio_phone_on;
bool is_cdma_modem;
+ int num_pdp_contexts;
bool is_modem_delta_update;
unsigned dpram_prev_phone_active;
unsigned dpram_prev_status;
diff --git a/drivers/misc/samsung_modemctl/modem_io.c b/drivers/misc/samsung_modemctl/modem_io.c
index fe50da6..5c815ef 100644
--- a/drivers/misc/samsung_modemctl/modem_io.c
+++ b/drivers/misc/samsung_modemctl/modem_io.c
@@ -40,7 +40,8 @@
#include "modem_ctl_p.h"
#define RAW_CH_VNET0 10
-
+#define CHANNEL_TO_NETDEV_ID(id) (id - RAW_CH_VNET0)
+#define NETDEV_TO_CHANNEL_ID(id) (id + RAW_CH_VNET0)
/* general purpose fifo access routines */
@@ -309,6 +310,7 @@ struct raw_hdr {
struct vnet {
struct modemctl *mc;
struct sk_buff_head txq;
+ int rmnet_ch_id;
};
static void handle_raw_rx(struct modemctl *mc)
@@ -319,17 +321,19 @@ static void handle_raw_rx(struct modemctl *mc)
/* process inbound packets */
while (fifo_read(&mc->raw_rx, &raw, sizeof(raw)) == sizeof(raw)) {
- struct net_device *dev = mc->ndev;
+ struct net_device *dev;
unsigned sz = raw.len - (sizeof(raw) - 1);
- if (unlikely(raw.channel != RAW_CH_VNET0)) {
+ if (unlikely(!(raw.channel >= RAW_CH_VNET0 && raw.channel <
+ NETDEV_TO_CHANNEL_ID(mc->num_pdp_contexts)))) {
+
MODEM_COUNT(mc, rx_unknown);
pr_err("[VNET] unknown channel %d\n", raw.channel);
if (fifo_skip(&mc->raw_rx, sz + 1) != (sz + 1))
goto purge_raw_fifo;
continue;
}
-
+ dev = mc->ndev[CHANNEL_TO_NETDEV_ID(raw.channel)];
skb = dev_alloc_skb(sz + NET_IP_ALIGN);
if (skb == NULL) {
MODEM_COUNT(mc, rx_dropped);
@@ -379,6 +383,9 @@ int handle_raw_tx(struct modemctl *mc, struct sk_buff *skb)
struct raw_hdr raw;
unsigned char ftr = 0x7e;
unsigned sz;
+ int netdev_id;
+ struct vnet *vn = netdev_priv(skb->dev);
+
sz = skb->len + sizeof(raw) + 1;
@@ -389,15 +396,16 @@ int handle_raw_tx(struct modemctl *mc, struct sk_buff *skb)
raw.start = 0x7f;
raw.len = 6 + skb->len;
- raw.channel = RAW_CH_VNET0;
+ raw.channel = vn->rmnet_ch_id;
raw.control = 0;
fifo_write(&mc->raw_tx, &raw, sizeof(raw));
fifo_write(&mc->raw_tx, skb->data, skb->len);
fifo_write(&mc->raw_tx, &ftr, 1);
- mc->ndev->stats.tx_packets++;
- mc->ndev->stats.tx_bytes += skb->len;
+ netdev_id = CHANNEL_TO_NETDEV_ID(vn->rmnet_ch_id);
+ mc->ndev[netdev_id]->stats.tx_packets++;
+ mc->ndev[netdev_id]->stats.tx_bytes += skb->len;
mc->mmio_signal_bits |= MBD_SEND_RAW;
@@ -408,17 +416,24 @@ int handle_raw_tx(struct modemctl *mc, struct sk_buff *skb)
void modem_handle_io(struct modemctl *mc)
{
struct sk_buff *skb;
- struct vnet *vn = netdev_priv(mc->ndev);
+ struct vnet *vn;
+ int i;
+ int cnt = 0;
handle_raw_rx(mc);
- while ((skb = skb_dequeue(&vn->txq)))
- if (handle_raw_tx(mc, skb)) {
- skb_queue_head(&vn->txq, skb);
- break;
- }
- if (skb == NULL)
- wake_unlock(&vn->mc->ip_tx_wakelock);
+ for (i = 0; i < mc->num_pdp_contexts; i++) {
+ vn = netdev_priv(mc->ndev[i]);
+ while ((skb = skb_dequeue(&vn->txq)))
+ if (handle_raw_tx(mc, skb)) {
+ skb_queue_head(&vn->txq, skb);
+ break;
+ }
+ if (skb == NULL)
+ cnt++;
+ }
+ if (cnt == mc->num_pdp_contexts)
+ wake_unlock(&mc->ip_tx_wakelock);
}
static int vnet_open(struct net_device *ndev)
@@ -639,9 +654,10 @@ static int modem_pipe_register(struct m_pipe *pipe, const char *devname)
int modem_io_init(struct modemctl *mc, void __iomem *mmio)
{
- struct net_device *ndev;
struct vnet *vn;
int r;
+ int i;
+ int ch_id;
INIT_M_FIFO(mc->fmt_tx, FMT, TX, mmio);
INIT_M_FIFO(mc->fmt_rx, FMT, RX, mmio);
@@ -650,16 +666,30 @@ int modem_io_init(struct modemctl *mc, void __iomem *mmio)
INIT_M_FIFO(mc->rfs_tx, RFS, TX, mmio);
INIT_M_FIFO(mc->rfs_rx, RFS, RX, mmio);
- ndev = alloc_netdev(0, "rmnet%d", vnet_setup);
- if (ndev) {
- vn = netdev_priv(ndev);
- vn->mc = mc;
- skb_queue_head_init(&vn->txq);
- r = register_netdev(ndev);
- if (r)
- free_netdev(ndev);
- else
- mc->ndev = ndev;
+ mc->ndev = kmalloc(sizeof(struct net_device *) * mc->num_pdp_contexts,
+ GFP_KERNEL);
+ if (!mc->ndev) {
+ pr_err("memory allocation failed for netdev\n");
+ return -ENOMEM;
+ }
+ for (i = 0, ch_id = RAW_CH_VNET0; i < mc->num_pdp_contexts;
+ i++, ch_id++) {
+ mc->ndev[i] = alloc_netdev(0, "rmnet%d", vnet_setup);
+ if (mc->ndev[i]) {
+ vn = netdev_priv(mc->ndev[i]);
+ vn->mc = mc;
+ vn->rmnet_ch_id = ch_id;
+ skb_queue_head_init(&vn->txq);
+ r = register_netdev(mc->ndev[i]);
+ if (r) {
+ free_netdev(mc->ndev[i]);
+ pr_err("failed to register rmnet%d\n", i);
+ goto free;
+ }
+ } else {
+ pr_err("failed to alloc rmnet%d\n", i);
+ goto free;
+ }
}
mc->cmd_pipe.tx = &mc->fmt_tx;
@@ -683,4 +713,12 @@ int modem_io_init(struct modemctl *mc, void __iomem *mmio)
pr_err("failed to register modem_rfs pipe\n");
return 0;
+
+free:
+ /* Unregister and free any alloced netdevs */
+ while (--i >= 0) {
+ unregister_netdev(mc->ndev[i]);
+ free_netdev(mc->ndev[i]);
+ }
+ return -ENOMEM;
}
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 393d817..e07d6c9 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -120,18 +120,19 @@ static int mmc_bus_remove(struct device *dev)
return 0;
}
-static int mmc_bus_suspend(struct device *dev, pm_message_t state)
+static int mmc_bus_pm_suspend(struct device *dev)
{
struct mmc_driver *drv = to_mmc_driver(dev->driver);
struct mmc_card *card = mmc_dev_to_card(dev);
int ret = 0;
+ pm_message_t state = { PM_EVENT_SUSPEND };
if (dev->driver && drv->suspend)
ret = drv->suspend(card, state);
return ret;
}
-static int mmc_bus_resume(struct device *dev)
+static int mmc_bus_pm_resume(struct device *dev)
{
struct mmc_driver *drv = to_mmc_driver(dev->driver);
struct mmc_card *card = mmc_dev_to_card(dev);
@@ -143,7 +144,6 @@ static int mmc_bus_resume(struct device *dev)
}
#ifdef CONFIG_PM_RUNTIME
-
static int mmc_runtime_suspend(struct device *dev)
{
struct mmc_card *card = mmc_dev_to_card(dev);
@@ -162,21 +162,13 @@ static int mmc_runtime_idle(struct device *dev)
{
return pm_runtime_suspend(dev);
}
+#endif /* CONFIG_PM_RUNTIME */
static const struct dev_pm_ops mmc_bus_pm_ops = {
- .runtime_suspend = mmc_runtime_suspend,
- .runtime_resume = mmc_runtime_resume,
- .runtime_idle = mmc_runtime_idle,
+ SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_pm_suspend, mmc_bus_pm_resume)
+ SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, mmc_runtime_idle)
};
-#define MMC_PM_OPS_PTR (&mmc_bus_pm_ops)
-
-#else /* !CONFIG_PM_RUNTIME */
-
-#define MMC_PM_OPS_PTR NULL
-
-#endif /* !CONFIG_PM_RUNTIME */
-
static struct bus_type mmc_bus_type = {
.name = "mmc",
.dev_attrs = mmc_dev_attrs,
@@ -184,9 +176,7 @@ static struct bus_type mmc_bus_type = {
.uevent = mmc_bus_uevent,
.probe = mmc_bus_probe,
.remove = mmc_bus_remove,
- .suspend = mmc_bus_suspend,
- .resume = mmc_bus_resume,
- .pm = MMC_PM_OPS_PTR,
+ .pm = &mmc_bus_pm_ops,
};
int mmc_register_bus(void)
diff --git a/drivers/net/wireless/bcm4329/dhd_common.c b/drivers/net/wireless/bcm4329/dhd_common.c
index f7cd372..8b89e39 100644
--- a/drivers/net/wireless/bcm4329/dhd_common.c
+++ b/drivers/net/wireless/bcm4329/dhd_common.c
@@ -1896,6 +1896,41 @@ fail:
#endif
+/*
+ * returns = TRUE if associated, FALSE if not associated
+ */
+bool is_associated(dhd_pub_t *dhd, void *bss_buf)
+{
+ char bssid[ETHER_ADDR_LEN], zbuf[ETHER_ADDR_LEN];
+ int ret = -1;
+
+ bzero(bssid, ETHER_ADDR_LEN);
+ bzero(zbuf, ETHER_ADDR_LEN);
+
+ ret = dhdcdc_set_ioctl(dhd, 0, WLC_GET_BSSID, (char *)bssid, ETHER_ADDR_LEN);
+ DHD_TRACE((" %s WLC_GET_BSSID ioctl res = %d\n", __FUNCTION__, ret));
+
+ if (ret == BCME_NOTASSOCIATED) {
+ DHD_TRACE(("%s: not associated! res:%d\n", __FUNCTION__, ret));
+ }
+
+ if (ret < 0)
+ return FALSE;
+
+ if ((memcmp(bssid, zbuf, ETHER_ADDR_LEN) != 0)) {
+ /* STA is assocoated BSSID is non zero */
+
+ if (bss_buf) {
+ /* return bss if caller provided buf */
+ memcpy(bss_buf, bssid, ETHER_ADDR_LEN);
+ }
+ return TRUE;
+ } else {
+ DHD_TRACE(("%s: WLC_GET_BSSID ioctl returned zero bssid\n", __FUNCTION__));
+ return FALSE;
+ }
+}
+
/* Function to estimate possible DTIM_SKIP value */
int dhd_get_dtim_skip(dhd_pub_t *dhd)
{
@@ -1979,7 +2014,6 @@ int dhd_pno_clean(dhd_pub_t *dhd)
int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
{
char iovbuf[128];
- uint8 bssid[6];
int ret = -1;
if ((!dhd) && ((pfn_enabled != 0) || (pfn_enabled != 1))) {
@@ -1990,12 +2024,7 @@ int dhd_pno_enable(dhd_pub_t *dhd, int pfn_enabled)
memset(iovbuf, 0, sizeof(iovbuf));
/* Check if disassoc to enable pno */
- if ((pfn_enabled) && \
- ((ret = dhdcdc_set_ioctl(dhd, 0, WLC_GET_BSSID, \
- (char *)&bssid, ETHER_ADDR_LEN)) == BCME_NOTASSOCIATED)) {
- DHD_TRACE(("%s pno enable called in disassoc mode\n", __FUNCTION__));
- }
- else if (pfn_enabled) {
+ if (pfn_enabled && (is_associated(dhd, NULL) == TRUE)) {
DHD_ERROR(("%s pno enable called in assoc mode ret=%d\n", \
__FUNCTION__, ret));
return ret;
diff --git a/drivers/net/wireless/bcmdhd/Kconfig b/drivers/net/wireless/bcmdhd/Kconfig
index db434ab..205c813 100644
--- a/drivers/net/wireless/bcmdhd/Kconfig
+++ b/drivers/net/wireless/bcmdhd/Kconfig
@@ -31,3 +31,10 @@ config BCMDHD_WEXT
select WEXT_PRIV
help
Enables WEXT support
+
+config DHD_USE_STATIC_BUF
+ bool "Enable memory preallocation"
+ depends on BCMDHD
+ default n
+ ---help---
+ Use memory preallocated in platform \ No newline at end of file
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
index 70bacbd3..aedb508 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc.c
@@ -1002,11 +1002,11 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u
if (pkt == NULL) {
sd_data(("%s: Creating new %s Packet, len=%d\n",
__FUNCTION__, write ? "TX" : "RX", buflen_u));
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
if (!(mypkt = PKTGET_STATIC(sd->osh, buflen_u, write ? TRUE : FALSE))) {
#else
if (!(mypkt = PKTGET(sd->osh, buflen_u, write ? TRUE : FALSE))) {
-#endif /* DHD_USE_STATIC_BUF */
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
sd_err(("%s: PKTGET failed: len %d\n",
__FUNCTION__, buflen_u));
return SDIOH_API_RC_FAIL;
@@ -1023,11 +1023,11 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u
if (!write) {
bcopy(PKTDATA(sd->osh, mypkt), buffer, buflen_u);
}
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE);
#else
PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE);
-#endif /* DHD_USE_STATIC_BUF */
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
} else if (((uint32)(PKTDATA(sd->osh, pkt)) & DMA_ALIGN_MASK) != 0) {
/* Case 2: We have a packet, but it is unaligned. */
@@ -1036,11 +1036,11 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u
sd_data(("%s: Creating aligned %s Packet, len=%d\n",
__FUNCTION__, write ? "TX" : "RX", PKTLEN(sd->osh, pkt)));
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
if (!(mypkt = PKTGET_STATIC(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) {
#else
if (!(mypkt = PKTGET(sd->osh, PKTLEN(sd->osh, pkt), write ? TRUE : FALSE))) {
-#endif /* DHD_USE_STATIC_BUF */
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
sd_err(("%s: PKTGET failed: len %d\n",
__FUNCTION__, PKTLEN(sd->osh, pkt)));
return SDIOH_API_RC_FAIL;
@@ -1061,11 +1061,11 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, u
PKTDATA(sd->osh, pkt),
PKTLEN(sd->osh, mypkt));
}
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
PKTFREE_STATIC(sd->osh, mypkt, write ? TRUE : FALSE);
#else
PKTFREE(sd->osh, mypkt, write ? TRUE : FALSE);
-#endif /* DHD_USE_STATIC_BUF */
+#endif /* CONFIG_DHD_USE_STATIC_BUF */
} else { /* case 3: We have a packet and it is aligned. */
sd_data(("%s: Aligned %s Packet, direct DMA\n",
__FUNCTION__, write ? "Tx" : "Rx"));
diff --git a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
index 726b639..0fa2329 100644
--- a/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
+++ b/drivers/net/wireless/bcmdhd/bcmsdh_sdmmc_linux.c
@@ -181,11 +181,9 @@ static int bcmsdh_sdmmc_resume(struct device *pdev)
{
struct sdio_func *func = dev_to_sdio_func(pdev);
- if (func->num != 2)
- return 0;
dhd_mmc_suspend = FALSE;
#if defined(OOB_INTR_ONLY)
- if (dhd_os_check_if_up(bcmsdh_get_drvdata()))
+ if ((func->num == 2) && dhd_os_check_if_up(bcmsdh_get_drvdata()))
bcmsdh_oob_intr_set(1);
#endif
smp_mb();
diff --git a/drivers/net/wireless/bcmdhd/dhd.h b/drivers/net/wireless/bcmdhd/dhd.h
index c87f6cf..84d1761 100644
--- a/drivers/net/wireless/bcmdhd/dhd.h
+++ b/drivers/net/wireless/bcmdhd/dhd.h
@@ -116,7 +116,7 @@ typedef enum {
} dhd_if_state_t;
-#if defined(DHD_USE_STATIC_BUF)
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
uint8* dhd_os_prealloc(void *osh, int section, uint size);
void dhd_os_prefree(void *osh, void *addr, uint size);
@@ -128,7 +128,7 @@ void dhd_os_prefree(void *osh, void *addr, uint size);
#define DHD_OS_PREALLOC(osh, section, size) MALLOC(osh, size)
#define DHD_OS_PREFREE(osh, addr, size) MFREE(osh, addr, size)
-#endif /* defined(DHD_USE_STATIC_BUF) */
+#endif /* defined(CONFIG_DHD_USE_STATIC_BUF) */
/* Packet alignment for most efficient SDIO (can change based on platform) */
#ifndef DHD_SDALIGN
@@ -314,8 +314,8 @@ inline static void MUTEX_UNLOCK_SOFTAP_SET(dhd_pub_t * dhdp)
#define DHD_OS_WAKE_LOCK_TIMEOUT(pub) dhd_os_wake_lock_timeout(pub)
#define DHD_OS_WAKE_LOCK_TIMEOUT_ENABLE(pub, val) dhd_os_wake_lock_timeout_enable(pub, val)
-#define DHD_PACKET_TIMEOUT 1
-#define DHD_EVENT_TIMEOUT 2
+#define DHD_PACKET_TIMEOUT_MS 1000
+#define DHD_EVENT_TIMEOUT_MS 1500
/* interface operations (register, remove) should be atomic, use this lock to prevent race
* condition among wifi on/off and interface operation functions
diff --git a/drivers/net/wireless/bcmdhd/dhd_cdc.c b/drivers/net/wireless/bcmdhd/dhd_cdc.c
index 3a4de96..8460992 100644
--- a/drivers/net/wireless/bcmdhd/dhd_cdc.c
+++ b/drivers/net/wireless/bcmdhd/dhd_cdc.c
@@ -2460,7 +2460,7 @@ dhd_prot_attach(dhd_pub_t *dhd)
return 0;
fail:
-#ifndef DHD_USE_STATIC_BUF
+#ifndef CONFIG_DHD_USE_STATIC_BUF
if (cdc != NULL)
MFREE(dhd->osh, cdc, sizeof(dhd_prot_t));
#endif
@@ -2474,7 +2474,7 @@ dhd_prot_detach(dhd_pub_t *dhd)
#ifdef PROP_TXSTATUS
dhd_wlfc_deinit(dhd);
#endif
-#ifndef DHD_USE_STATIC_BUF
+#ifndef CONFIG_DHD_USE_STATIC_BUF
MFREE(dhd->osh, dhd->prot, sizeof(dhd_prot_t));
#endif
dhd->prot = NULL;
diff --git a/drivers/net/wireless/bcmdhd/dhd_common.c b/drivers/net/wireless/bcmdhd/dhd_common.c
index a29c2fa..9df70a0 100644
--- a/drivers/net/wireless/bcmdhd/dhd_common.c
+++ b/drivers/net/wireless/bcmdhd/dhd_common.c
@@ -1489,7 +1489,7 @@ dhd_arp_get_arp_hostip_table(dhd_pub_t *dhd, void *buf, int buflen)
return -1;
iov_len = bcm_mkiovar("arp_hostip", 0, 0, buf, buflen);
- retcode = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, buflen, TRUE, 0);
+ retcode = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, buf, buflen, FALSE, 0);
if (retcode) {
DHD_TRACE(("%s: ioctl WLC_GET_VAR error %d\n",
@@ -1902,6 +1902,7 @@ dhd_pno_set(dhd_pub_t *dhd, wlc_ssid_t* ssids_local, int nssid, ushort scan_fr,
if ((!dhd) && (!ssids_local)) {
DHD_ERROR(("%s error exit\n", __FUNCTION__));
err = -1;
+ return err;
}
if (dhd_check_ap_wfd_mode_set(dhd) == TRUE)
@@ -2155,14 +2156,14 @@ wl_iw_parse_channel_list_tlv(char** list_str, uint16* channel_list,
int
wl_iw_parse_ssid_list_tlv(char** list_str, wlc_ssid_t* ssid, int max, int *bytes_left)
{
- char* str = *list_str;
+ char* str;
int idx = 0;
if ((list_str == NULL) || (*list_str == NULL) || (*bytes_left < 0)) {
DHD_ERROR(("%s error paramters\n", __FUNCTION__));
return -1;
}
-
+ str = *list_str;
while (*bytes_left > 0) {
if (str[0] != CSCAN_TLV_TYPE_SSID_IE) {
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux.c b/drivers/net/wireless/bcmdhd/dhd_linux.c
index 92cdc9b..d4cc56f 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux.c
@@ -1032,6 +1032,9 @@ dhd_op_if(dhd_if_t *ifp)
if (ret < 0) {
ifp->set_multicast = FALSE;
if (ifp->net) {
+#ifdef WL_CFG80211
+ wl_cfg80211_post_del((void*)(ifp->net));
+#endif
free_netdev(ifp->net);
}
dhd->iflist[ifp->idx] = NULL;
@@ -1397,7 +1400,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
int i;
dhd_if_t *ifp;
wl_event_msg_t event;
- int tout = DHD_PACKET_TIMEOUT;
+ int tout = DHD_PACKET_TIMEOUT_MS;
DHD_TRACE(("%s: Enter\n", __FUNCTION__));
@@ -1501,7 +1504,7 @@ dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt, uint8 chan)
if (event.event_type == WLC_E_BTA_HCI_EVENT) {
dhd_bta_doevt(dhdp, data, event.datalen);
}
- tout = DHD_EVENT_TIMEOUT;
+ tout = DHD_EVENT_TIMEOUT_MS;
}
ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]);
@@ -2029,7 +2032,7 @@ dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd)
/* send to dongle only if we are not waiting for reload already */
if (dhd->pub.hang_was_sent) {
DHD_ERROR(("%s: HANG was sent up earlier\n", __FUNCTION__));
- DHD_OS_WAKE_LOCK_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT);
+ DHD_OS_WAKE_LOCK_TIMEOUT_ENABLE(&dhd->pub, DHD_EVENT_TIMEOUT_MS);
DHD_OS_WAKE_UNLOCK(&dhd->pub);
return OSL_ERROR(BCME_DONGLE_DOWN);
}
@@ -2296,7 +2299,6 @@ dhd_stop(struct net_device *net)
if (ifidx == 0 && !dhd_download_fw_on_driverload)
wl_android_wifi_off(net);
#endif
- dhd->pub.hang_was_sent = 0;
dhd->pub.rxcnt_timeout = 0;
dhd->pub.txcnt_timeout = 0;
OLD_MOD_DEC_USE_COUNT;
@@ -2325,6 +2327,8 @@ dhd_open(struct net_device *net)
firmware_path[0] = '\0';
}
+ dhd->pub.hang_was_sent = 0;
+
#if !defined(WL_CFG80211)
/*
* Force start if ifconfig_up gets called before START command
@@ -3915,7 +3919,7 @@ dhd_os_sdtxunlock(dhd_pub_t *pub)
dhd_os_sdunlock(pub);
}
-#if defined(DHD_USE_STATIC_BUF)
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
uint8* dhd_os_prealloc(void *osh, int section, uint size)
{
return (uint8*)wl_android_prealloc(section, size);
@@ -3924,7 +3928,7 @@ uint8* dhd_os_prealloc(void *osh, int section, uint size)
void dhd_os_prefree(void *osh, void *addr, uint size)
{
}
-#endif /* defined(CONFIG_WIFI_CONTROL_FUNC) */
+#endif /* defined(CONFIG_DHD_USE_STATIC_BUF) */
#if defined(CONFIG_WIRELESS_EXT)
struct iw_statistics *
@@ -4282,6 +4286,8 @@ int net_os_send_hang_message(struct net_device *dev)
#endif
#if defined(WL_CFG80211)
ret = wl_cfg80211_hang(dev, WLAN_REASON_UNSPECIFIED);
+ dev_close(dev);
+ dev_open(dev);
#endif
}
}
@@ -4421,7 +4427,7 @@ int dhd_os_wake_lock_timeout(dhd_pub_t *pub)
#ifdef CONFIG_HAS_WAKELOCK
if (dhd->wakelock_timeout_enable)
wake_lock_timeout(&dhd->wl_rxwake,
- dhd->wakelock_timeout_enable * HZ);
+ msecs_to_jiffies(dhd->wakelock_timeout_enable));
#endif
dhd->wakelock_timeout_enable = 0;
spin_unlock_irqrestore(&dhd->wakelock_spinlock, flags);
diff --git a/drivers/net/wireless/bcmdhd/dhd_linux_mon.c b/drivers/net/wireless/bcmdhd/dhd_linux_mon.c
index dd9c71f..ce94ff9 100644
--- a/drivers/net/wireless/bcmdhd/dhd_linux_mon.c
+++ b/drivers/net/wireless/bcmdhd/dhd_linux_mon.c
@@ -225,9 +225,10 @@ static void dhd_mon_if_set_multicast_list(struct net_device *ndev)
mon_if = ndev_to_monif(ndev);
if (mon_if == NULL || mon_if->real_ndev == NULL) {
MON_PRINT(" cannot find matched net dev, skip the packet\n");
+ } else {
+ MON_PRINT("enter, if name: %s, matched if name %s\n",
+ ndev->name, mon_if->real_ndev->name);
}
-
- MON_PRINT("enter, if name: %s, matched if name %s\n", ndev->name, mon_if->real_ndev->name);
}
static int dhd_mon_if_change_mac(struct net_device *ndev, void *addr)
@@ -238,9 +239,10 @@ static int dhd_mon_if_change_mac(struct net_device *ndev, void *addr)
mon_if = ndev_to_monif(ndev);
if (mon_if == NULL || mon_if->real_ndev == NULL) {
MON_PRINT(" cannot find matched net dev, skip the packet\n");
+ } else {
+ MON_PRINT("enter, if name: %s, matched if name %s\n",
+ ndev->name, mon_if->real_ndev->name);
}
-
- MON_PRINT("enter, if name: %s, matched if name %s\n", ndev->name, mon_if->real_ndev->name);
return ret;
}
diff --git a/drivers/net/wireless/bcmdhd/dhd_sdio.c b/drivers/net/wireless/bcmdhd/dhd_sdio.c
index 2930115..1bdc7d5 100644
--- a/drivers/net/wireless/bcmdhd/dhd_sdio.c
+++ b/drivers/net/wireless/bcmdhd/dhd_sdio.c
@@ -382,7 +382,7 @@ static bool dhd_readahead;
/* To check if there's window offered */
#define DATAOK(bus) \
- (((uint8)(bus->tx_max - bus->tx_seq) > 2) && \
+ (((uint8)(bus->tx_max - bus->tx_seq) > 1) && \
(((uint8)(bus->tx_max - bus->tx_seq) & 0x80) == 0))
/* To check if there's window offered for ctrl frame */
@@ -5736,7 +5736,7 @@ dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh)
return;
if (bus->rxbuf) {
-#ifndef DHD_USE_STATIC_BUF
+#ifndef CONFIG_DHD_USE_STATIC_BUF
MFREE(osh, bus->rxbuf, bus->rxblen);
#endif
bus->rxctl = bus->rxbuf = NULL;
@@ -5744,7 +5744,7 @@ dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh)
}
if (bus->databuf) {
-#ifndef DHD_USE_STATIC_BUF
+#ifndef CONFIG_DHD_USE_STATIC_BUF
MFREE(osh, bus->databuf, MAX_DATA_BUF);
#endif
bus->databuf = NULL;
diff --git a/drivers/net/wireless/bcmdhd/include/epivers.h b/drivers/net/wireless/bcmdhd/include/epivers.h
index ae1f975..fe71e16 100644
--- a/drivers/net/wireless/bcmdhd/include/epivers.h
+++ b/drivers/net/wireless/bcmdhd/include/epivers.h
@@ -44,6 +44,6 @@
#define EPI_VERSION_DEV 5.90.125
-#define EPI_VERSION_STR "5.90.125.94"
+#define EPI_VERSION_STR "5.90.125.94.1"
#endif
diff --git a/drivers/net/wireless/bcmdhd/include/linux_osl.h b/drivers/net/wireless/bcmdhd/include/linux_osl.h
index 1ec136e..38de298 100644
--- a/drivers/net/wireless/bcmdhd/include/linux_osl.h
+++ b/drivers/net/wireless/bcmdhd/include/linux_osl.h
@@ -268,7 +268,7 @@ extern int osl_error(int bcmerror);
#define PKTLIST_DUMP(osh, buf)
#define PKTDBG_TRACE(osh, pkt, bit)
#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send))
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
#define PKTGET_STATIC(osh, len, send) osl_pktget_static((osh), (len))
#define PKTFREE_STATIC(osh, skb, send) osl_pktfree_static((osh), (skb), (send))
#endif
diff --git a/drivers/net/wireless/bcmdhd/linux_osl.c b/drivers/net/wireless/bcmdhd/linux_osl.c
index 1a54437..b3fcdd2 100644
--- a/drivers/net/wireless/bcmdhd/linux_osl.c
+++ b/drivers/net/wireless/bcmdhd/linux_osl.c
@@ -47,7 +47,7 @@
#define OS_HANDLE_MAGIC 0x1234abcd
#define BCM_MEM_FILENAME_LEN 24
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
#define STATIC_BUF_MAX_NUM 16
#define STATIC_BUF_SIZE (PAGE_SIZE * 2)
#define STATIC_BUF_TOTAL_LEN (STATIC_BUF_MAX_NUM * STATIC_BUF_SIZE)
@@ -70,7 +70,7 @@ typedef struct bcm_static_pkt {
} bcm_static_pkt_t;
static bcm_static_pkt_t *bcm_static_skb = 0;
-#endif
+#endif
typedef struct bcm_mem_link {
struct bcm_mem_link *prev;
@@ -211,7 +211,7 @@ osl_attach(void *pdev, uint bustype, bool pkttag)
break;
}
-#if defined(DHD_USE_STATIC_BUF)
+#if defined(CONFIG_DHD_USE_STATIC_BUF)
if (!bcm_static_buf) {
if (!(bcm_static_buf = (bcm_static_buf_t *)dhd_os_prealloc(osh, 3, STATIC_BUF_SIZE+
STATIC_BUF_TOTAL_LEN))) {
@@ -220,25 +220,25 @@ osl_attach(void *pdev, uint bustype, bool pkttag)
else
printk("alloc static buf at %x!\n", (unsigned int)bcm_static_buf);
-
sema_init(&bcm_static_buf->static_sem, 1);
bcm_static_buf->buf_ptr = (unsigned char *)bcm_static_buf + STATIC_BUF_SIZE;
}
if (!bcm_static_skb) {
- int i;
- void *skb_buff_ptr = 0;
- bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048);
- skb_buff_ptr = dhd_os_prealloc(osh, 4, 0);
-
- bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *) * 16);
- for (i = 0; i < STATIC_PKT_MAX_NUM * 2; i++)
- bcm_static_skb->pkt_use[i] = 0;
-
- sema_init(&bcm_static_skb->osl_pkt_sem, 1);
+ void *skb_buff_ptr = dhd_os_prealloc(osh, 4, 0);
+
+ if (skb_buff_ptr) {
+ bcm_static_skb = (bcm_static_pkt_t *)((char *)bcm_static_buf + 2048);
+ bcopy(skb_buff_ptr, bcm_static_skb, sizeof(struct sk_buff *) * 16);
+ for (i = 0; i < STATIC_PKT_MAX_NUM * 2; i++)
+ bcm_static_skb->pkt_use[i] = 0;
+ sema_init(&bcm_static_skb->osl_pkt_sem, 1);
+ } else {
+ printk("can not alloc static skb buffers\n");
+ }
}
-#endif
+#endif
return osh;
}
@@ -388,7 +388,7 @@ osl_ctfpool_stats(osl_t *osh, void *b)
if ((osh == NULL) || (osh->ctfpool == NULL))
return;
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
if (bcm_static_buf) {
bcm_static_buf = 0;
}
@@ -548,14 +548,14 @@ osl_pktfree(osl_t *osh, void *p, bool send)
}
}
-#ifdef DHD_USE_STATIC_BUF
+#ifdef CONFIG_DHD_USE_STATIC_BUF
void *
osl_pktget_static(osl_t *osh, uint len)
{
int i;
struct sk_buff *skb;
- if (len > (PAGE_SIZE * 2)) {
+ if (!bcm_static_skb || (len > (PAGE_SIZE * 2))) {
printk("%s: attempt to allocate huge packet (0x%x)\n", __FUNCTION__, len);
return osl_pktget(osh, len);
}
@@ -570,10 +570,10 @@ osl_pktget_static(osl_t *osh, uint len)
if (i != STATIC_PKT_MAX_NUM) {
bcm_static_skb->pkt_use[i] = 1;
- up(&bcm_static_skb->osl_pkt_sem);
skb = bcm_static_skb->skb_4k[i];
skb->tail = skb->data + len;
skb->len = len;
+ up(&bcm_static_skb->osl_pkt_sem);
return skb;
}
}
@@ -586,10 +586,10 @@ osl_pktget_static(osl_t *osh, uint len)
if (i != STATIC_PKT_MAX_NUM) {
bcm_static_skb->pkt_use[i+STATIC_PKT_MAX_NUM] = 1;
- up(&bcm_static_skb->osl_pkt_sem);
skb = bcm_static_skb->skb_8k[i];
skb->tail = skb->data + len;
skb->len = len;
+ up(&bcm_static_skb->osl_pkt_sem);
return skb;
}
@@ -603,9 +603,14 @@ osl_pktfree_static(osl_t *osh, void *p, bool send)
{
int i;
+ if (!bcm_static_skb) {
+ osl_pktfree(osh, p, send);
+ return;
+ }
+
+ down(&bcm_static_skb->osl_pkt_sem);
for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
if (p == bcm_static_skb->skb_4k[i]) {
- down(&bcm_static_skb->osl_pkt_sem);
bcm_static_skb->pkt_use[i] = 0;
up(&bcm_static_skb->osl_pkt_sem);
return;
@@ -614,14 +619,15 @@ osl_pktfree_static(osl_t *osh, void *p, bool send)
for (i = 0; i < STATIC_PKT_MAX_NUM; i++) {
if (p == bcm_static_skb->skb_8k[i]) {
- down(&bcm_static_skb->osl_pkt_sem);
bcm_static_skb->pkt_use[i + STATIC_PKT_MAX_NUM] = 0;
up(&bcm_static_skb->osl_pkt_sem);
return;
}
}
+ up(&bcm_static_skb->osl_pkt_sem);
- return osl_pktfree(osh, p, send);
+ osl_pktfree(osh, p, send);
+ return;
}
#endif
diff --git a/drivers/net/wireless/bcmdhd/wl_android.c b/drivers/net/wireless/bcmdhd/wl_android.c
index 9ca3d60..b680481 100644
--- a/drivers/net/wireless/bcmdhd/wl_android.c
+++ b/drivers/net/wireless/bcmdhd/wl_android.c
@@ -559,8 +559,10 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
bytes_written = strlen("OK");
}
- if (bytes_written > 0) {
- if (bytes_written > priv_cmd.total_len) {
+ if (bytes_written >= 0) {
+ if ((bytes_written == 0) && (priv_cmd.total_len > 0))
+ command[0] = '\0';
+ if (bytes_written >= priv_cmd.total_len) {
DHD_ERROR(("%s: bytes_written = %d\n", __FUNCTION__, bytes_written));
bytes_written = priv_cmd.total_len;
} else {
@@ -571,7 +573,8 @@ int wl_android_priv_cmd(struct net_device *net, struct ifreq *ifr, int cmd)
DHD_ERROR(("%s: failed to copy data to user buffer\n", __FUNCTION__));
ret = -EFAULT;
}
- } else {
+ }
+ else {
ret = bytes_written;
}
@@ -675,20 +678,21 @@ void wl_android_wifictrl_func_del(void)
}
}
-void* wl_android_prealloc(int section, unsigned long size)
+void *wl_android_prealloc(int section, unsigned long size)
{
void *alloc_ptr = NULL;
if (wifi_control_data && wifi_control_data->mem_prealloc) {
alloc_ptr = wifi_control_data->mem_prealloc(section, size);
if (alloc_ptr) {
DHD_INFO(("success alloc section %d\n", section));
- bzero(alloc_ptr, size);
+ if (size != 0L)
+ bzero(alloc_ptr, size);
return alloc_ptr;
}
}
DHD_ERROR(("can't alloc section %d\n", section));
- return 0;
+ return NULL;
}
int wifi_get_irq_number(unsigned long *irq_flags_ptr)
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.c b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
index daa7d26..32241d5 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.c
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.c
@@ -16,7 +16,7 @@
* the license of that module. An independent module is a module which is not
* derived from this software. The special exception does not apply to any
* modifications of the software.
- *
+ *
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
@@ -589,7 +589,7 @@ static const u32 __wl_cipher_suites[] = {
WLAN_CIPHER_SUITE_WEP104,
WLAN_CIPHER_SUITE_TKIP,
WLAN_CIPHER_SUITE_CCMP,
- WLAN_CIPHER_SUITE_AES_CMAC,
+ WLAN_CIPHER_SUITE_AES_CMAC
};
/* There isn't a lot of sense in it, but you can transmit anything you like */
@@ -844,8 +844,10 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
wl_set_p2p_status(wl, IF_ADD);
err = wl_cfgp2p_ifadd(wl, &wl->p2p->int_addr, htod32(wlif_type), chspec);
- if (unlikely(err))
+ if (unlikely(err)) {
+ WL_ERR((" virtual iface add failed (%d) \n", err));
return ERR_PTR(-ENOMEM);
+ }
timeout = wait_event_interruptible_timeout(wl->dongle_event_wait,
(wl_get_p2p_status(wl, IF_ADD) == false),
@@ -860,7 +862,7 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
}
vwdev->wiphy = wl->wdev->wiphy;
WL_INFO((" virtual interface(%s) is created memalloc done \n",
- wl->p2p->vir_ifname));
+ wl->p2p->vir_ifname));
index = alloc_idx_vwdev(wl);
wl->vwdev[index] = vwdev;
vwdev->iftype =
@@ -873,6 +875,8 @@ wl_cfg80211_add_virtual_iface(struct wiphy *wiphy, char *name,
wl_set_drv_status(wl, READY);
wl->p2p->vif_created = true;
set_mode_by_netdev(wl, _ndev, mode);
+ WL_DBG((" virtual interface(%s) wl->wdev %p wl->wdev->netdev %p vwdev %p vwdev->netdev %p\n",
+ wl->p2p->vir_ifname, wl->wdev, wl->wdev->netdev, vwdev, vwdev->netdev));
net_attach = wl_to_p2p_bss_private(wl, P2PAPI_BSSCFG_CONNECTION);
if (rtnl_is_locked()) {
rtnl_unlock();
@@ -927,10 +931,14 @@ wl_cfg80211_del_virtual_iface(struct wiphy *wiphy, struct net_device *dev)
* ifconfig <inter> down and up sequnce, which will reload the fw
* however we should cleanup the linux network virtual interfaces
*/
- dhd_pub_t *dhd = (dhd_pub_t *)(wl->pub);
- WL_ERR(("Firmware returned an error from p2p_ifdel\n"));
- WL_ERR(("try to remove linux virtual interface %s\n", dev->name));
- dhd_del_if(dhd->info, dhd_net2idx(dhd->info, dev));
+ /* Request framework to RESET and clean up */
+ struct net_device *ndev = wl_to_prmry_ndev(wl);
+ WL_ERR(("Firmware returned an error (%d) from p2p_ifdel"
+ "HANG Notification sent to %s dev %p wdev %p ndev %p\n", ret, ndev->name, dev, wl->wdev, wl_to_prmry_ndev(wl)));
+ wl_cfg80211_hang(ndev, WLAN_REASON_UNSPECIFIED);
+ }
+ else {
+ WL_ERR(("Firmware success from p2p_ifdel dev %p wdev %p ndev %p", dev, wl->wdev, wl_to_prmry_ndev(wl)));
}
/* Wait for any pending scan req to get aborted from the sysioc context */
@@ -1035,7 +1043,7 @@ int (*_net_attach)(dhd_pub_t *dhdp, int ifidx))
WL_ERR(("net is NULL\n"));
return 0;
}
- if (wl->p2p_supported) {
+ if (wl->p2p_supported && wl_get_p2p_status(wl, IF_ADD)) {
WL_DBG(("IF_ADD event called from dongle, old interface name: %s,"
"new name: %s\n", ndev->name, wl->p2p->vir_ifname));
/* Assign the net device to CONNECT BSSCFG */
@@ -1047,6 +1055,8 @@ int (*_net_attach)(dhd_pub_t *dhdp, int ifidx))
wl_clr_p2p_status(wl, IF_ADD);
wake_up_interruptible(&wl->dongle_event_wait);
+ } else {
+ ret = BCME_NOTREADY;
}
return ret;
}
@@ -1063,7 +1073,8 @@ wl_cfg80211_notify_ifdel(struct net_device *ndev)
return 0;
}
- if (p2p_is_on(wl) && wl->p2p->vif_created) {
+ if (p2p_is_on(wl) && wl->p2p->vif_created &&
+ wl_get_p2p_status(wl, IF_DELETING)) {
if (wl->scan_request) {
/* Abort any pending scan requests */
wl->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
@@ -1096,6 +1107,18 @@ wl_cfg80211_notify_ifdel(struct net_device *ndev)
return 0;
}
+s32 wl_cfg80211_post_del(void* ndev)
+{
+ int index;
+ struct wl_priv *wl = wlcfg_drv_priv;
+ index = get_idx_vwdev_by_netdev(wl, (struct net_device *)ndev);
+ WL_DBG(("index : %d\n", index));
+ if (index >= 0) {
+ free_vwdev_by_index(wl, index);
+ }
+ return 0;
+}
+
s32
wl_cfg80211_is_progress_ifadd(void)
{
@@ -1130,8 +1153,8 @@ wl_cfg80211_notify_ifchange(void)
static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_request *request)
{
- u32 n_ssids = request->n_ssids;
- u32 n_channels = request->n_channels;
+ u32 n_ssids;
+ u32 n_channels;
u16 channel;
chanspec_t chanspec;
s32 i, offset;
@@ -1160,6 +1183,12 @@ static void wl_scan_prep(struct wl_scan_params *params, struct cfg80211_scan_req
params->passive_time = htod32(params->passive_time);
params->home_time = htod32(params->home_time);
+ if (!request)
+ return;
+
+ n_ssids = request->n_ssids;
+ n_channels = request->n_channels;
+
/* Copy channel array if applicable */
WL_SCAN(("### List of channelspecs to scan ###\n"));
if (n_channels > 0) {
@@ -1248,8 +1277,7 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct cfg80211_scan_request *request,
return -ENOMEM;
}
- if (request != NULL)
- wl_scan_prep(&params->params, request);
+ wl_scan_prep(&params->params, request);
params->version = htod32(ISCAN_REQ_VERSION);
params->action = htod16(action);
@@ -1340,8 +1368,7 @@ wl_run_escan(struct wl_priv *wl, struct net_device *ndev,
goto exit;
}
- if (request != NULL)
- wl_scan_prep(&params->params, request);
+ wl_scan_prep(&params->params, request);
params->version = htod32(ESCAN_REQ_VERSION);
params->action = htod16(action);
params->sync_id = htod16(0x1234);
@@ -1461,7 +1488,7 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
(int)wl->status));
return -EAGAIN;
}
- if (request->n_ssids > WL_SCAN_PARAMS_SSID_MAX) {
+ if (request && request->n_ssids > WL_SCAN_PARAMS_SSID_MAX) {
WL_ERR(("n_ssids > WL_SCAN_PARAMS_SSID_MAX\n"));
return -EOPNOTSUPP;
}
@@ -4155,6 +4182,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
struct wl_cfg80211_bss_info *notif_bss_info;
struct wl_scan_req *sr = wl_to_sr(wl);
struct beacon_proberesp *beacon_proberesp;
+ struct cfg80211_bss *cbss = NULL;
s32 mgmt_type;
s32 signal;
u32 freq;
@@ -4213,13 +4241,15 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi)
signal = notif_bss_info->rssi * 100;
- if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt,
- le16_to_cpu(notif_bss_info->frame_len),
- signal, GFP_KERNEL))) {
+ cbss = cfg80211_inform_bss_frame(wiphy, channel, mgmt,
+ le16_to_cpu(notif_bss_info->frame_len), signal, GFP_KERNEL);
+ if (unlikely(!cbss)) {
WL_ERR(("cfg80211_inform_bss_frame error\n"));
kfree(notif_bss_info);
return -EINVAL;
}
+
+ cfg80211_put_bss(cbss);
kfree(notif_bss_info);
return err;
diff --git a/drivers/net/wireless/bcmdhd/wl_cfg80211.h b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
index 262335e..232db1b 100644
--- a/drivers/net/wireless/bcmdhd/wl_cfg80211.h
+++ b/drivers/net/wireless/bcmdhd/wl_cfg80211.h
@@ -2,13 +2,13 @@
* Linux cfg80211 driver
*
* Copyright (C) 1999-2011, Broadcom Corporation
- *
+ *
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software, this software is licensed to you
* under the terms of the GNU General Public License version 2 (the "GPL"),
* available at http://www.broadcom.com/licenses/GPLv2.php, with the
* following added to such license:
- *
+ *
* As a special exception, the copyright holders of this software give you
* permission to link this software with independent modules, and to copy and
* distribute the resulting executable under terms of your choice, provided that
@@ -16,7 +16,7 @@
* the license of that module. An independent module is a module which is not
* derived from this software. The special exception does not apply to any
* modifications of the software.
- *
+ *
* Notwithstanding the above, under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a license
* other than the GPL, without Broadcom's express prior written consent.
@@ -452,6 +452,7 @@ static inline s32 alloc_idx_vwdev(struct wl_priv *wl)
if (wl->vwdev[i] == NULL)
return i;
}
+ WL_ERR((" *********alloc_idx_vwdev failed (%d) \n", -1));
return -1;
}
@@ -462,6 +463,7 @@ static inline s32 get_idx_vwdev_by_netdev(struct wl_priv *wl, struct net_device
if ((wl->vwdev[i] != NULL) && (wl->vwdev[i]->netdev == ndev))
return i;
}
+ WL_ERR((" *********get_idx_vwdev_by_netdev failed (%d) \n", -1));
return -1;
}
@@ -531,6 +533,7 @@ extern s32 wl_cfg80211_down(void); /* dongle down */
extern s32 wl_cfg80211_notify_ifadd(struct net_device *net, s32 idx, s32 bssidx,
int (*_net_attach)(dhd_pub_t *dhdp, int ifidx));
extern s32 wl_cfg80211_notify_ifdel(struct net_device *ndev);
+extern s32 wl_cfg80211_post_del(void *ndev);
extern s32 wl_cfg80211_is_progress_ifadd(void);
extern s32 wl_cfg80211_is_progress_ifchange(void);
extern s32 wl_cfg80211_is_progress_ifadd(void);
diff --git a/drivers/net/wireless/bcmdhd/wl_iw.c b/drivers/net/wireless/bcmdhd/wl_iw.c
index ba3cc6c..32f7b57 100644
--- a/drivers/net/wireless/bcmdhd/wl_iw.c
+++ b/drivers/net/wireless/bcmdhd/wl_iw.c
@@ -1626,7 +1626,7 @@ wl_iw_send_priv_event(
strcpy(extra, flag);
wrqu.data.length = strlen(extra);
wireless_send_event(dev, cmd, &wrqu, extra);
- net_os_wake_lock_timeout_enable(dev, DHD_EVENT_TIMEOUT);
+ net_os_wake_lock_timeout_enable(dev, DHD_EVENT_TIMEOUT_MS);
WL_TRACE(("Send IWEVCUSTOM Event as %s\n", extra));
return 0;
diff --git a/drivers/usb/gadget/android.c b/drivers/usb/gadget/android.c
index d109bfb..00a446b 100644
--- a/drivers/usb/gadget/android.c
+++ b/drivers/usb/gadget/android.c
@@ -100,6 +100,7 @@ struct android_dev {
struct device *dev;
bool enabled;
+ struct mutex mutex;
bool connected;
bool sw_connected;
struct work_struct work;
@@ -774,8 +775,13 @@ functions_show(struct device *pdev, struct device_attribute *attr, char *buf)
struct android_usb_function *f;
char *buff = buf;
+ mutex_lock(&dev->mutex);
+
list_for_each_entry(f, &dev->enabled_functions, enabled_list)
buff += sprintf(buff, "%s,", f->name);
+
+ mutex_unlock(&dev->mutex);
+
if (buff != buf)
*(buff-1) = '\n';
return buff - buf;
@@ -790,6 +796,13 @@ functions_store(struct device *pdev, struct device_attribute *attr,
char buf[256], *b;
int err;
+ mutex_lock(&dev->mutex);
+
+ if (dev->enabled) {
+ mutex_unlock(&dev->mutex);
+ return -EBUSY;
+ }
+
INIT_LIST_HEAD(&dev->enabled_functions);
strncpy(buf, buff, sizeof(buf));
@@ -804,6 +817,8 @@ functions_store(struct device *pdev, struct device_attribute *attr,
}
}
+ mutex_unlock(&dev->mutex);
+
return size;
}
@@ -821,8 +836,11 @@ static ssize_t enable_store(struct device *pdev, struct device_attribute *attr,
struct usb_composite_dev *cdev = dev->cdev;
int enabled = 0;
+ mutex_lock(&dev->mutex);
+
sscanf(buff, "%d", &enabled);
if (enabled && !dev->enabled) {
+ cdev->next_string_id = 0;
/* update values in composite driver's copy of device descriptor */
cdev->desc.idVendor = device_desc.idVendor;
cdev->desc.idProduct = device_desc.idProduct;
@@ -836,12 +854,16 @@ static ssize_t enable_store(struct device *pdev, struct device_attribute *attr,
dev->enabled = true;
} else if (!enabled && dev->enabled) {
usb_gadget_disconnect(cdev->gadget);
+ /* Cancel pending control requests */
+ usb_ep_dequeue(cdev->gadget->ep0, cdev->req);
usb_remove_config(cdev, &android_config_driver);
dev->enabled = false;
} else {
pr_err("android_usb: already %s\n",
dev->enabled ? "enabled" : "disabled");
}
+
+ mutex_unlock(&dev->mutex);
return size;
}
@@ -875,9 +897,9 @@ field ## _show(struct device *dev, struct device_attribute *attr, \
} \
static ssize_t \
field ## _store(struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t size) \
+ const char *buf, size_t size) \
{ \
- int value; \
+ int value; \
if (sscanf(buf, format_string, &value) == 1) { \
device_desc.field = value; \
return size; \
@@ -895,10 +917,10 @@ field ## _show(struct device *dev, struct device_attribute *attr, \
} \
static ssize_t \
field ## _store(struct device *dev, struct device_attribute *attr, \
- const char *buf, size_t size) \
+ const char *buf, size_t size) \
{ \
if (size >= sizeof(buffer)) return -EINVAL; \
- if (sscanf(buf, "%s", buffer) == 1) { \
+ if (sscanf(buf, "%s", buffer) == 1) { \
return size; \
} \
return -1; \
@@ -1133,6 +1155,7 @@ static int __init init(void)
dev->functions = supported_functions;
INIT_LIST_HEAD(&dev->enabled_functions);
INIT_WORK(&dev->work, android_work);
+ mutex_init(&dev->mutex);
err = android_create_device(dev);
if (err) {
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 6cea2e1..d3cdffe 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -159,25 +159,6 @@ static const u32 oid_supported_list[] =
#endif /* RNDIS_PM */
};
-/* HACK: copied from net/core/dev.c to replace dev_get_stats since
- * dev_get_stats cannot be called from atomic context */
-static void netdev_stats_to_stats64(struct rtnl_link_stats64 *stats64,
- const struct net_device_stats *netdev_stats)
-{
-#if BITS_PER_LONG == 64
- BUILD_BUG_ON(sizeof(*stats64) != sizeof(*netdev_stats));
- memcpy(stats64, netdev_stats, sizeof(*stats64));
-#else
- size_t i, n = sizeof(*stats64) / sizeof(u64);
- const unsigned long *src = (const unsigned long *)netdev_stats;
- u64 *dst = (u64 *)stats64;
-
- BUILD_BUG_ON(sizeof(*netdev_stats) / sizeof(unsigned long) !=
- sizeof(*stats64) / sizeof(u64));
- for (i = 0; i < n; i++)
- dst[i] = src[i];
-#endif
-}
/* NDIS Functions */
static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf,
@@ -190,7 +171,7 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf,
rndis_query_cmplt_type *resp;
struct net_device *net;
struct rtnl_link_stats64 temp;
- struct rtnl_link_stats64 *stats = &temp;
+ const struct rtnl_link_stats64 *stats;
if (!r) return -ENOMEM;
resp = (rndis_query_cmplt_type *)r->buf;
@@ -213,7 +194,7 @@ static int gen_ndis_query_resp(int configNr, u32 OID, u8 *buf,
resp->InformationBufferOffset = cpu_to_le32(16);
net = rndis_per_dev_params[configNr].dev;
- netdev_stats_to_stats64(stats, &net->stats);
+ stats = dev_get_stats(net, &temp);
switch (OID) {
diff --git a/drivers/video/samsung/s3cfb_fimd6x.c b/drivers/video/samsung/s3cfb_fimd6x.c
index 360f1f6..b5b73a1 100644
--- a/drivers/video/samsung/s3cfb_fimd6x.c
+++ b/drivers/video/samsung/s3cfb_fimd6x.c
@@ -152,6 +152,19 @@ int s3cfb_frame_off(struct s3cfb_global *ctrl)
return 0;
}
+void s3cfb_readjust_pixclock(struct s3cfb_global *ctrl, u32 src_clk, u32 div)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ int i;
+ u32 pixclock;
+
+ pixclock = KHZ2PICOS(src_clk / 1000) * div;
+ dev_info(ctrl->dev, "pixclock adjusted from %d to %d\n",
+ ctrl->fb[0]->var.pixclock, pixclock);
+ for (i = 0; i < pdata->nr_wins; i++)
+ ctrl->fb[i]->var.pixclock = pixclock;
+}
+
int s3cfb_set_clock(struct s3cfb_global *ctrl)
{
struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
@@ -162,7 +175,8 @@ int s3cfb_set_clock(struct s3cfb_global *ctrl)
/* fixed clock source: hclk */
cfg = readl(ctrl->regs + S3C_VIDCON0);
cfg &= ~(S3C_VIDCON0_CLKSEL_MASK | S3C_VIDCON0_CLKVALUP_MASK |
- S3C_VIDCON0_VCLKEN_MASK | S3C_VIDCON0_CLKDIR_MASK);
+ S3C_VIDCON0_VCLKEN_MASK | S3C_VIDCON0_CLKDIR_MASK |
+ S3C_VIDCON0_CLKVAL_F(-1));
cfg |= (S3C_VIDCON0_CLKVALUP_ALWAYS | S3C_VIDCON0_VCLKEN_NORMAL |
S3C_VIDCON0_CLKDIR_DIVIDED);
@@ -199,6 +213,7 @@ int s3cfb_set_clock(struct s3cfb_global *ctrl)
dev_dbg(ctrl->dev, "parent clock: %d, vclk: %d, vclk div: %d\n",
src_clk, vclk, div);
+ s3cfb_readjust_pixclock(ctrl, src_clk, div);
return 0;
}
diff --git a/drivers/video/samsung/s3cfb_nt35580.c b/drivers/video/samsung/s3cfb_nt35580.c
index 2779ce7..3a76083 100755
--- a/drivers/video/samsung/s3cfb_nt35580.c
+++ b/drivers/video/samsung/s3cfb_nt35580.c
@@ -214,6 +214,7 @@ static int __devinit nt35580_probe(struct spi_device *spi)
}
lcd->bl_dev->props.max_brightness = 255;
+ lcd->bl_dev->props.brightness = lcd->bl;
spi_set_drvdata(spi, lcd);
lcd->ldi_enable = 1;
diff --git a/drivers/video/samsung/s3cfb_tl2796.c b/drivers/video/samsung/s3cfb_tl2796.c
index b491bd7..e5c98e0 100755
--- a/drivers/video/samsung/s3cfb_tl2796.c
+++ b/drivers/video/samsung/s3cfb_tl2796.c
@@ -1139,7 +1139,7 @@ static int __devinit tl2796_probe(struct spi_device *spi)
}
lcd->bl_dev->props.max_brightness = 255;
- lcd->bl_dev->props.brightness = 255;
+ lcd->bl_dev->props.brightness = lcd->bl;
tl2796_ldi_enable(lcd);
#ifdef CONFIG_HAS_EARLYSUSPEND
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 0da2379..d2de026 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -796,6 +796,9 @@ static int mem_open(struct inode* inode, struct file* file)
return 0;
}
+#define mem_write NULL
+
+#ifndef mem_write
static ssize_t mem_rw(struct file *file, char __user *buf,
size_t count, loff_t *ppos, int write)
{
@@ -847,6 +850,7 @@ free:
free_page((unsigned long) page);
return copied;
}
+#endif
static ssize_t mem_read(struct file *file, char __user *buf,
size_t count, loff_t *ppos)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index a32571a..5a7074a 100644..100755
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1462,6 +1462,15 @@ unlock:
hci_conn_check_pending(hdev);
}
+static inline bool is_sco_active(struct hci_dev *hdev)
+{
+ if (hci_conn_hash_lookup_state(hdev, SCO_LINK, BT_CONNECTED) ||
+ (hci_conn_hash_lookup_state(hdev, ESCO_LINK,
+ BT_CONNECTED)))
+ return true;
+ return false;
+}
+
static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_conn_request *ev = (void *) skb->data;
@@ -1505,7 +1514,8 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
bacpy(&cp.bdaddr, &ev->bdaddr);
- if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
+ if (lmp_rswitch_capable(hdev) && ((mask & HCI_LM_MASTER)
+ || is_sco_active(hdev)))
cp.role = 0x00; /* Become master */
else
cp.role = 0x01; /* Remain slave */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index ca76d8b..72f7fee 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -1773,6 +1773,7 @@ static void restore_alpha2(char *alpha2, bool reset_user)
static void restore_regulatory_settings(bool reset_user)
{
char alpha2[2];
+ char world_alpha2[2];
struct reg_beacon *reg_beacon, *btmp;
struct regulatory_request *reg_request, *tmp;
LIST_HEAD(tmp_reg_req_list);
@@ -1823,11 +1824,13 @@ static void restore_regulatory_settings(bool reset_user)
/* First restore to the basic regulatory settings */
cfg80211_regdomain = cfg80211_world_regdom;
+ world_alpha2[0] = cfg80211_regdomain->alpha2[0];
+ world_alpha2[1] = cfg80211_regdomain->alpha2[1];
mutex_unlock(&reg_mutex);
mutex_unlock(&cfg80211_mutex);
- regulatory_hint_core(cfg80211_regdomain->alpha2);
+ regulatory_hint_core(world_alpha2);
/*
* This restores the ieee80211_regdom module parameter