aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wimax/i2400m/driver.c54
-rw-r--r--drivers/net/wimax/i2400m/i2400m.h2
-rw-r--r--drivers/net/wimax/i2400m/sdio.c14
-rw-r--r--drivers/net/wimax/i2400m/usb.c8
4 files changed, 64 insertions, 14 deletions
diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c
index 304f0443ca4..20d574ca918 100644
--- a/drivers/net/wimax/i2400m/driver.c
+++ b/drivers/net/wimax/i2400m/driver.c
@@ -619,6 +619,46 @@ EXPORT_SYMBOL_GPL(i2400m_dev_reset_handle);
/**
+ * i2400m_bm_buf_alloc - Alloc the command and ack buffers for boot mode
+ *
+ * Get the buffers needed to deal with boot mode messages. These
+ * buffers need to be allocated before the sdio recieve irq is setup.
+ */
+int i2400m_bm_buf_alloc(struct i2400m *i2400m)
+{
+ int result;
+
+ result = -ENOMEM;
+ i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL);
+ if (i2400m->bm_cmd_buf == NULL)
+ goto error_bm_cmd_kzalloc;
+ i2400m->bm_ack_buf = kzalloc(I2400M_BM_ACK_BUF_SIZE, GFP_KERNEL);
+ if (i2400m->bm_ack_buf == NULL)
+ goto error_bm_ack_buf_kzalloc;
+ return 0;
+
+error_bm_ack_buf_kzalloc:
+ kfree(i2400m->bm_cmd_buf);
+error_bm_cmd_kzalloc:
+ return result;
+}
+EXPORT_SYMBOL_GPL(i2400m_bm_buf_alloc);
+
+/**
+ * i2400m_bm_buf_free - Free boot mode command and ack buffers.
+ *
+ * Free the command and ack buffers
+ *
+ */
+void i2400m_bm_buf_free(struct i2400m *i2400m)
+{
+ kfree(i2400m->bm_ack_buf);
+ kfree(i2400m->bm_cmd_buf);
+ return;
+}
+EXPORT_SYMBOL_GPL(i2400m_bm_buf_free
+);
+/**
* i2400m_setup - bus-generic setup function for the i2400m device
*
* @i2400m: device descriptor (bus-specific parts have been initialized)
@@ -645,16 +685,6 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
snprintf(wimax_dev->name, sizeof(wimax_dev->name),
"i2400m-%s:%s", dev->bus->name, dev_name(dev));
- i2400m->bm_cmd_buf = kzalloc(I2400M_BM_CMD_BUF_SIZE, GFP_KERNEL);
- if (i2400m->bm_cmd_buf == NULL) {
- dev_err(dev, "cannot allocate USB command buffer\n");
- goto error_bm_cmd_kzalloc;
- }
- i2400m->bm_ack_buf = kzalloc(I2400M_BM_ACK_BUF_SIZE, GFP_KERNEL);
- if (i2400m->bm_ack_buf == NULL) {
- dev_err(dev, "cannot allocate USB ack buffer\n");
- goto error_bm_ack_buf_kzalloc;
- }
result = i2400m_bootrom_init(i2400m, bm_flags);
if (result < 0) {
dev_err(dev, "read mac addr: bootrom init "
@@ -713,10 +743,6 @@ error_dev_start:
error_register_netdev:
error_read_mac_addr:
error_bootrom_init:
- kfree(i2400m->bm_ack_buf);
-error_bm_ack_buf_kzalloc:
- kfree(i2400m->bm_cmd_buf);
-error_bm_cmd_kzalloc:
d_fnend(3, dev, "(i2400m %p) = %d\n", i2400m, result);
return result;
}
diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h
index 60330f313f2..a6e59f1c881 100644
--- a/drivers/net/wimax/i2400m/i2400m.h
+++ b/drivers/net/wimax/i2400m/i2400m.h
@@ -725,6 +725,8 @@ void i2400m_put(struct i2400m *i2400m)
}
extern int i2400m_dev_reset_handle(struct i2400m *);
+extern int i2400m_bm_buf_alloc(struct i2400m *i2400m);
+extern void i2400m_bm_buf_free(struct i2400m *i2400m);
/*
* _setup()/_release() are called by the probe/disconnect functions of
diff --git a/drivers/net/wimax/i2400m/sdio.c b/drivers/net/wimax/i2400m/sdio.c
index c67b0264a28..a68232aa291 100644
--- a/drivers/net/wimax/i2400m/sdio.c
+++ b/drivers/net/wimax/i2400m/sdio.c
@@ -451,6 +451,18 @@ int i2400ms_probe(struct sdio_func *func,
goto error_func_enable;
}
+ /*
+ * Before we are enabling the device interrupt register, make
+ * sure the buffer used during bootmode operation is setup so
+ * when the first D2H data interrupt comes, the memory is
+ * available for copying the D2H data.
+ */
+ result = i2400m_bm_buf_alloc(i2400m);
+ if (result < 0) {
+ dev_err(dev, "cannot allocate SDIO bootmode buffer\n");
+ goto error_bootmode_buf_setup;
+ }
+
result = i2400ms_rx_setup(i2400ms);
if (result < 0)
goto error_rx_setup;
@@ -474,6 +486,8 @@ error_debugfs_add:
error_setup:
i2400ms_rx_release(i2400ms);
error_rx_setup:
+ i2400m_bm_buf_free(i2400m);
+error_bootmode_buf_setup:
sdio_claim_host(func);
sdio_disable_func(func);
sdio_release_host(func);
diff --git a/drivers/net/wimax/i2400m/usb.c b/drivers/net/wimax/i2400m/usb.c
index bfa45f57134..49d7554ad70 100644
--- a/drivers/net/wimax/i2400m/usb.c
+++ b/drivers/net/wimax/i2400m/usb.c
@@ -419,6 +419,12 @@ int i2400mu_probe(struct usb_interface *iface,
usb_dev->autosuspend_disabled = 0;
#endif
+ result = i2400m_bm_buf_alloc(i2400m);
+ if (result < 0) {
+ dev_err(dev, "cannot allocate USB bootmode buffer\n");
+ goto error_bm_buf_alloc;
+ }
+
result = i2400m_setup(i2400m, I2400M_BRI_MAC_REINIT);
if (result < 0) {
dev_err(dev, "cannot setup device: %d\n", result);
@@ -434,6 +440,8 @@ int i2400mu_probe(struct usb_interface *iface,
error_debugfs_add:
i2400m_release(i2400m);
error_setup:
+ i2400m_bm_buf_free(i2400m);
+error_bm_buf_alloc:
usb_set_intfdata(iface, NULL);
usb_put_dev(i2400mu->usb_dev);
free_netdev(net_dev);