Skip to contentSkip to conversation

WiMAX patches for 2.6.33 (batch #1)

PATCH In review Inaky Perez-Gonzalez 2 participants 17 messages Nov 4, 2009 – Nov 6, 2009

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover WiMAX patches for 2.6.33 (batch #1)

[this series of patches has been split in four batches as it was too long; the grouping is just sequential as they are not really related, except for dependencies].

Misc fixes: add minimal ethtool support, silly typo fixes, and dwelve in a set of bad SDIO subdriver's boot-mode interactions with the hardware timings and ways it managed to corner itself into a deadlock.

Please pull from:

git://git.kernel.org/pub/scm/linux/kernel/git/inaky/wimax.git

Patches follow for ease of review.

Cindy H Kao (4):
wimax/i2400m: fix the bootmode RX deadlock in SDIO driver wimax/iwmc3200: overwrite SDIO IOR timeout value to avoid platform
hang
wimax/iwmc3200: don't disable the SDIO function if enable fails wimax/iwmc3200: increase wait time before enable retry

Dan Williams (1):
i2400m: minimal ethtool support

Dirk Brandewie (3):
wimax/i2400m: Update comments to talk about SDIO reset and not USB. wimax/i2400m: Ensure boot mode cmd and ack buffers are alloc'd before
first message
wimax/i2400m: Make boot retries a BUS-specific parameter

Inaky Perez-Gonzalez (1):
wimax: indicate initial SW rfkill state is "blocked"

Oliver Neukum (1):
wimax/i2400m/usb: remove unnecessary power management primitive in

    i2400m

Roel Kluin (2):
i2400m: keep index within ms_to_errno[]
wimax: misplaced parenthesis

 drivers/net/wimax/i2400m/control.c     |    2 +-
 drivers/net/wimax/i2400m/driver.c      |   54 +++++++++++++++++++++++--------
 drivers/net/wimax/i2400m/fw.c          |    2 +-
 drivers/net/wimax/i2400m/i2400m-sdio.h |    5 ++-
 drivers/net/wimax/i2400m/i2400m-usb.h  |    1 +
 drivers/net/wimax/i2400m/i2400m.h      |    5 +--
 drivers/net/wimax/i2400m/netdev.c      |   18 ++++++++++
 drivers/net/wimax/i2400m/sdio-fw.c     |    8 ++--
 drivers/net/wimax/i2400m/sdio-rx.c     |    7 ++++
 drivers/net/wimax/i2400m/sdio.c        |   38 +++++++++++++++++-----
 drivers/net/wimax/i2400m/tx.c          |    2 +-
 drivers/net/wimax/i2400m/usb.c         |   11 +++++-
 net/wimax/op-rfkill.c                  |    1 +
 13 files changed, 118 insertions(+), 36 deletions(-)
#1 lore raw

PATCH 1/12 wimax/i2400m/usb: remove unnecessary power management primitive in i2400m

From: Oliver Neukum <[email protected]>

This patch removes an unneeded power management primitive. Power management is automatically enabled as probe ends.

---
 drivers/net/wimax/i2400m/usb.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)
drivers/net/wimax/i2400m/usb.c +0 -1
index 7eadd11..bfa45f5 100644
@@ -415,7 +415,6 @@ int i2400mu_probe(struct usb_interface *iface,
 #ifdef CONFIG_PM
 	iface->needs_remote_wakeup = 1;		/* autosuspend (15s delay) */
 	device_init_wakeup(dev, 1);
-	usb_autopm_enable(i2400mu->usb_iface);
 	usb_dev->autosuspend_delay = 15 * HZ;
 	usb_dev->autosuspend_disabled = 0;
 #endif
Signature · 1 line
1.6.2.5
#2 lore raw

PATCH 2/12 wimax/i2400m: fix the bootmode RX deadlock in SDIO driver

In reply to Inaky Perez-Gonzalez

From: Cindy H Kao <[email protected]>

i2400ms_bus_bm_wait_for_ack() causes a race condition. It happens because this function clears i2400ms->bm_ack_size before waiting for an interrupt, which is set by the interrupt service routine i2400ms_rx() to indicate reception and size of received data; thus, if the interrupt came right before the clearing/waiting, it is lost.

The fix is clear the bm_ack_size to -EINPROGRESS before we are enabling the RX interrupt configuration in i2400ms_rx_setup(). Then everytime when the interrupt service routine i2400ms_rx() is invoked during bootmode, bm_ack_size is updated with the actual rx_size and it is cleared to -EINPROGRESS again after the RX data is handled.

---
 drivers/net/wimax/i2400m/sdio-fw.c |    8 ++++----
 drivers/net/wimax/i2400m/sdio-rx.c |    7 +++++++
 2 files changed, 11 insertions(+), 4 deletions(-)
drivers/net/wimax/i2400m/sdio-fw.c +4 -4
index 7d6ec0f..c8dc538 100644
@@ -177,10 +177,6 @@ ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *i2400m,
 	d_fnstart(5, dev, "(i2400m %p ack %p size %zu)\n",
 		  i2400m, ack, ack_size);
 
-	spin_lock(&i2400m->rx_lock);
-	i2400ms->bm_ack_size = -EINPROGRESS;
-	spin_unlock(&i2400m->rx_lock);
-
 	result = wait_event_timeout(i2400ms->bm_wfa_wq,
 				    i2400ms->bm_ack_size != -EINPROGRESS,
 				    2 * HZ);
@@ -199,6 +195,10 @@ ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *i2400m,
 		size = min(ack_size, i2400ms->bm_ack_size);
 		memcpy(ack, i2400m->bm_ack_buf, size);
 	}
+	/*
+	 * Remember always to clear the bm_ack_size to -EINPROGRESS
+	 * after the RX data is processed
+	 */
 	i2400ms->bm_ack_size = -EINPROGRESS;
 	spin_unlock(&i2400m->rx_lock);
 
drivers/net/wimax/i2400m/sdio-rx.c +7 -0
index 321bead..f6ca51a 100644
@@ -234,6 +234,13 @@ int i2400ms_rx_setup(struct i2400ms *i2400ms)
 	init_waitqueue_head(&i2400ms->bm_wfa_wq);
 	spin_lock(&i2400m->rx_lock);
 	i2400ms->bm_wait_result = -EINPROGRESS;
+	/*
+	 * Before we are about to enable the RX interrupt, make sure
+	 * bm_ack_size is cleared to -EINPROGRESS which indicates
+	 * no RX interrupt happened yet or the previous interrupt
+	 * has been handled, we are ready to take the new interrupt
+	 */
+	i2400ms->bm_ack_size = -EINPROGRESS;
 	spin_unlock(&i2400m->rx_lock);
 
 	sdio_claim_host(func);
Signature · 1 line
1.6.2.5
#3 lore raw

PATCH 3/12 wimax: indicate initial SW rfkill state is "blocked"

In reply to Inaky Perez-Gonzalez

The WiMAX stack assumes that all WiMAX devices are SW OFF when they are initialized. The recent changes in the RFKILL stack thus cause an initial call after rfkill_register(), because by default, rfkill considers devices to be SW ON upon registration.

So call rfkill_init_sw_state() to set it to SW OFF so rfkill_register() doesn't do that unnecessary step.

---
 net/wimax/op-rfkill.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)
net/wimax/op-rfkill.c +1 -0
index 70ef4df..40e1210 100644
@@ -355,6 +355,7 @@ int wimax_rfkill_add(struct wimax_dev *wimax_dev)
 
 	wimax_dev->rfkill = rfkill;
 
+	rfkill_init_sw_state(rfkill, 1);
 	result = rfkill_register(wimax_dev->rfkill);
 	if (result < 0)
 		goto error_rfkill_register;
Signature · 1 line
1.6.2.5
#4 lore raw

PATCH 4/12 i2400m: keep index within ms_to_errno[]

In reply to Inaky Perez-Gonzalez

From: Roel Kluin <[email protected]>

Ensure that index `status' remains within ms_to_errno[]

---
 drivers/net/wimax/i2400m/control.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wimax/i2400m/control.c +1 -1
index 0730868..8fe70e7 100644
@@ -263,7 +263,7 @@ int i2400m_msg_check_status(const struct i2400m_l3l4_hdr *l3l4_hdr,
 
 	if (status == 0)
 		return 0;
-	if (status > ARRAY_SIZE(ms_to_errno)) {
+	if (status >= ARRAY_SIZE(ms_to_errno)) {
 		str = "unknown status code";
 		result = -EBADR;
 	} else {
Signature · 1 line
1.6.2.5
#5 lore raw

PATCH 5/12 wimax: misplaced parenthesis

In reply to Inaky Perez-Gonzalez

From: Roel Kluin <[email protected]>

Fix misplaced parenthesis

---
 drivers/net/wimax/i2400m/tx.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wimax/i2400m/tx.c +1 -1
index fa16ccf..8c20802 100644
@@ -310,7 +310,7 @@ size_t __i2400m_tx_tail_room(struct i2400m *i2400m)
 	size_t tail_room;
 	size_t tx_in;
 
-	if (unlikely(i2400m->tx_in) == 0)
+	if (unlikely(i2400m->tx_in == 0))
 		return I2400M_TX_BUF_SIZE;
 	tx_in = i2400m->tx_in % I2400M_TX_BUF_SIZE;
 	tail_room = I2400M_TX_BUF_SIZE - tx_in;
Signature · 1 line
1.6.2.5
#6 lore raw

PATCH 6/12 i2400m: minimal ethtool support

In reply to Inaky Perez-Gonzalez

From: Dan Williams <[email protected]>

Add minimal ethtool support for carrier detection.

---
 drivers/net/wimax/i2400m/netdev.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)
drivers/net/wimax/i2400m/netdev.c +18 -0
index 796396c..960fb54 100644
@@ -74,6 +74,7 @@
  */
 #include <linux/if_arp.h>
 #include <linux/netdevice.h>
+#include <linux/ethtool.h>
 #include "i2400m.h"
 
 
@@ -559,6 +560,22 @@ static const struct net_device_ops i2400m_netdev_ops = {
 	.ndo_change_mtu = i2400m_change_mtu,
 };
 
+static void i2400m_get_drvinfo(struct net_device *net_dev,
+			       struct ethtool_drvinfo *info)
+{
+	struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
+
+	strncpy(info->driver, KBUILD_MODNAME, sizeof(info->driver) - 1);
+	strncpy(info->fw_version, i2400m->fw_name, sizeof(info->fw_version) - 1);
+	if (net_dev->dev.parent)
+		strncpy(info->bus_info, dev_name(net_dev->dev.parent),
+			sizeof(info->bus_info) - 1);
+}
+
+static const struct ethtool_ops i2400m_ethtool_ops = {
+	.get_drvinfo = i2400m_get_drvinfo,
+	.get_link = ethtool_op_get_link,
+};
 
 /**
  * i2400m_netdev_setup - Setup setup @net_dev's i2400m private data
@@ -580,6 +597,7 @@ void i2400m_netdev_setup(struct net_device *net_dev)
 		   & ~IFF_MULTICAST);
 	net_dev->watchdog_timeo = I2400M_TX_TIMEOUT;
 	net_dev->netdev_ops = &i2400m_netdev_ops;
+	net_dev->ethtool_ops = &i2400m_ethtool_ops;
 	d_fnend(3, NULL, "(net_dev %p) = void\n", net_dev);
 }
 EXPORT_SYMBOL_GPL(i2400m_netdev_setup);
Signature · 1 line
1.6.2.5
#7 lore raw

PATCH 7/12 wimax/i2400m: Update comments to talk about SDIO reset and not USB.

In reply to Inaky Perez-Gonzalez

From: Dirk Brandewie <[email protected]>

Fixing comments from original cut and paste error

---
 drivers/net/wimax/i2400m/sdio.c |   13 ++++++-------
 1 files changed, 6 insertions(+), 7 deletions(-)
drivers/net/wimax/i2400m/sdio.c +6 -7
index 2981e21..c67b026 100644
@@ -233,18 +233,17 @@ error_kzalloc:
  * Warm reset:
  *
  * The device will be fully reset internally, but won't be
- * disconnected from the USB bus (so no reenumeration will
+ * disconnected from the bus (so no reenumeration will
  * happen). Firmware upload will be neccessary.
  *
- * The device will send a reboot barker in the notification endpoint
- * that will trigger the driver to reinitialize the state
- * automatically from notif.c:i2400m_notification_grok() into
- * i2400m_dev_bootstrap_delayed().
+ * The device will send a reboot barker that will trigger the driver
+ * to reinitialize the state via __i2400m_dev_reset_handle.
  *
- * Cold and bus (USB) reset:
+ *
+ * Cold and bus reset:
  *
  * The device will be fully reset internally, disconnected from the
- * USB bus an a reenumeration will happen. Firmware upload will be
+ * bus an a reenumeration will happen. Firmware upload will be
  * neccessary. Thus, we don't do any locking or struct
  * reinitialization, as we are going to be fully disconnected and
  * reenumerated.
Signature · 1 line
1.6.2.5
#8 lore raw

PATCH 8/12 wimax/i2400m: Ensure boot mode cmd and ack buffers are alloc'd before first message

In reply to Inaky Perez-Gonzalez

From: Dirk Brandewie <[email protected]>

The change to the SDIO boot mode RX chain could try to use the cmd and ack buffers befor they were allocated. USB does not have the problem but both were changed for consistency's sake.

---
 drivers/net/wimax/i2400m/driver.c |   54 +++++++++++++++++++++++++++---------
 drivers/net/wimax/i2400m/i2400m.h |    2 +
 drivers/net/wimax/i2400m/sdio.c   |   14 +++++++++
 drivers/net/wimax/i2400m/usb.c    |    8 +++++
 4 files changed, 64 insertions(+), 14 deletions(-)
drivers/net/wimax/i2400m/driver.c +40 -14
index 304f044..20d574c 100644
@@ -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;
 }
drivers/net/wimax/i2400m/i2400m.h +2 -0
index 60330f3..a6e59f1 100644
@@ -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
drivers/net/wimax/i2400m/sdio.c +14 -0
index c67b026..a68232a 100644
@@ -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);
drivers/net/wimax/i2400m/usb.c +8 -0
index bfa45f5..49d7554 100644
@@ -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);
Signature · 1 line
1.6.2.5
#9 lore raw

PATCH 9/12 wimax/i2400m: Make boot retries a BUS-specific parameter

In reply to Inaky Perez-Gonzalez

From: Dirk Brandewie <[email protected]>

In i2400m-based devices, the driver's bootloader will retry to load the firmware when things go wrong. The driver currently has a constant (I2400M_BOOT_RETRIES) which governs the max number of tries.

However, different SKUs of the same hardware may admit or require different numbers of retries due to it's particulars, so it is made a BUS specific parameter and different values are assigned for 5x50 devices versus the 3200 ones.

---
 drivers/net/wimax/i2400m/fw.c          |    2 +-
 drivers/net/wimax/i2400m/i2400m-sdio.h |    1 +
 drivers/net/wimax/i2400m/i2400m-usb.h  |    1 +
 drivers/net/wimax/i2400m/i2400m.h      |    3 ---
 drivers/net/wimax/i2400m/sdio.c        |    2 +-
 drivers/net/wimax/i2400m/usb.c         |    2 +-
 6 files changed, 5 insertions(+), 6 deletions(-)
drivers/net/wimax/i2400m/fw.c +1 -1
index e81750e..55bd69e 100644
@@ -602,7 +602,7 @@ int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags)
 	struct device *dev = i2400m_dev(i2400m);
 	struct i2400m_bootrom_header *cmd;
 	struct i2400m_bootrom_header ack;
-	int count = I2400M_BOOT_RETRIES;
+	int count = i2400m->bus_bm_retries;
 	int ack_timeout_cnt = 1;
 
 	BUILD_BUG_ON(sizeof(*cmd) != sizeof(i2400m_NBOOT_BARKER));
drivers/net/wimax/i2400m/i2400m-sdio.h +1 -0
index 9c4e318..66884eb 100644
@@ -67,6 +67,7 @@
 
 /* Host-Device interface for SDIO */
 enum {
+	I2400M_SDIO_BOOT_RETRIES = 3,
 	I2400MS_BLK_SIZE = 256,
 	I2400MS_PL_SIZE_MAX = 0x3E00,
 
drivers/net/wimax/i2400m/i2400m-usb.h +1 -0
index 6f76558..79c3753 100644
@@ -137,6 +137,7 @@ static inline int edc_inc(struct edc *edc, u16 max_err, u16 timeframe)
 
 /* Host-Device interface for USB */
 enum {
+	I2400M_USB_BOOT_RETRIES = 3,
 	I2400MU_MAX_NOTIFICATION_LEN = 256,
 	I2400MU_BLK_SIZE = 16,
 	I2400MU_PL_SIZE_MAX = 0x3EFF,
drivers/net/wimax/i2400m/i2400m.h +0 -3
index a6e59f1..73b4e6a 100644
@@ -148,9 +148,6 @@
 
 /* Misc constants */
 enum {
-	/* Firmware uploading */
-	I2400M_BOOT_RETRIES = 3,
-	I3200_BOOT_RETRIES = 3,
 	/* Size of the Boot Mode Command buffer */
 	I2400M_BM_CMD_BUF_SIZE = 16 * 1024,
 	I2400M_BM_ACK_BUF_SIZE = 256,
drivers/net/wimax/i2400m/sdio.c +1 -1
index a68232a..1429608 100644
@@ -430,7 +430,7 @@ int i2400ms_probe(struct sdio_func *func,
 	i2400m->bus_reset = i2400ms_bus_reset;
 	/* The iwmc3200-wimax sometimes requires the driver to try
 	 * hard when we paint it into a corner. */
-	i2400m->bus_bm_retries = I3200_BOOT_RETRIES;
+	i2400m->bus_bm_retries = I2400M_SDIO_BOOT_RETRIES;
 	i2400m->bus_bm_cmd_send = i2400ms_bus_bm_cmd_send;
 	i2400m->bus_bm_wait_for_ack = i2400ms_bus_bm_wait_for_ack;
 	i2400m->bus_fw_names = i2400ms_bus_fw_names;
drivers/net/wimax/i2400m/usb.c +1 -1
index 49d7554..8f7b16a 100644
@@ -406,7 +406,7 @@ int i2400mu_probe(struct usb_interface *iface,
 	i2400m->bus_dev_stop = i2400mu_bus_dev_stop;
 	i2400m->bus_tx_kick = i2400mu_bus_tx_kick;
 	i2400m->bus_reset = i2400mu_bus_reset;
-	i2400m->bus_bm_retries = I2400M_BOOT_RETRIES;
+	i2400m->bus_bm_retries = I2400M_USB_BOOT_RETRIES;
 	i2400m->bus_bm_cmd_send = i2400mu_bus_bm_cmd_send;
 	i2400m->bus_bm_wait_for_ack = i2400mu_bus_bm_wait_for_ack;
 	i2400m->bus_fw_names = i2400mu_bus_fw_names;
Signature · 1 line
1.6.2.5
#10 lore raw

PATCH 10/12 wimax/iwmc3200: overwrite SDIO IOR timeout value to avoid platform hang

In reply to Inaky Perez-Gonzalez

From: Cindy H Kao <[email protected]>

The default SDIO IOE wait timeout returned from iwmc3200-wimax's CCCR is not efficient. This inefficiency will actually cause problems on Moorestown platforms (system hang).

This is a sillicon bug that requires a software patch to by overwritting func->enable_timeout. The new value I2400MS_IOR_TIMEOUT is recommended and verified from the system integration results.

Future sillicon releases will have this default value corrected in the future.

---
 drivers/net/wimax/i2400m/i2400m-sdio.h |    2 ++
 drivers/net/wimax/i2400m/sdio.c        |    8 ++++++++
 2 files changed, 10 insertions(+), 0 deletions(-)
drivers/net/wimax/i2400m/i2400m-sdio.h +2 -0
index 66884eb..cfaedfa 100644
@@ -81,6 +81,8 @@ enum {
 	I2400MS_INIT_SLEEP_INTERVAL = 10,
 	/* How long to wait for the device to settle after reset */
 	I2400MS_SETTLE_TIME = 40,
+	/* The number of msec to wait for IOR after sending IOE */
+	IWMC3200_IOR_TIMEOUT = 10,
 };
 
 
drivers/net/wimax/i2400m/sdio.c +8 -0
index 1429608..0d64d16 100644
@@ -115,6 +115,14 @@ int i2400ms_enable_function(struct sdio_func *func)
 	err = -ENODEV;
 	while (err != 0 && time_before64(get_jiffies_64(), timeout)) {
 		sdio_claim_host(func);
+		/*
+		 * There is a sillicon bug on the IWMC3200, where the
+		 * IOE timeout will cause problems on Moorestown
+		 * platforms (system hang). We explicitly overwrite
+		 * func->enable_timeout here to work around the issue.
+		 */
+		if (func->device == SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX)
+			func->enable_timeout = IWMC3200_IOR_TIMEOUT;
 		err = sdio_enable_func(func);
 		if (0 == err) {
 			sdio_release_host(func);
Signature · 1 line
1.6.2.5
#11 lore raw

PATCH 11/12 wimax/iwmc3200: don't disable the SDIO function if enable fails

In reply to Inaky Perez-Gonzalez

From: Cindy H Kao <[email protected]>

In the iwmc3200, disabling the WiMAX SDIO function when enable fails would possibly result in a device reset triggered by the iwmc3200's top controller since it monitors the bus reset activities from each SDIO function. In any case, the disable makes no sense; if the enable fails, it should not be disabled.

Thus we remove the unecessary sdio_disable_func() in i2400ms_enable_function().

---
 drivers/net/wimax/i2400m/sdio.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)
drivers/net/wimax/i2400m/sdio.c +0 -1
index 0d64d16..9d6046f 100644
@@ -130,7 +130,6 @@ int i2400ms_enable_function(struct sdio_func *func)
 			goto function_enabled;
 		}
 		d_printf(2, dev, "SDIO function failed to enable: %d\n", err);
-		sdio_disable_func(func);
 		sdio_release_host(func);
 		msleep(I2400MS_INIT_SLEEP_INTERVAL);
 	}
Signature · 1 line
1.6.2.5
#12 lore raw

PATCH 12/12 wimax/iwmc3200: increase wait time before enable retry

In reply to Inaky Perez-Gonzalez

From: Cindy H Kao <[email protected]>

When trying to enable the iwmc3200 WiMAX SDIO function, we loop waiting for the top controller to be up and running (at which point we can succesfully enable the function). Between each try we wait for I2400MS_INIT_SLEEP_INTERVAL ms.

Integration tests have found the current value of 10ms to be too short; it was upped to 100ms to give more time to the top controller to be ready.

---
 drivers/net/wimax/i2400m/i2400m-sdio.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/net/wimax/i2400m/i2400m-sdio.h +1 -1
index cfaedfa..18218a2 100644
@@ -78,7 +78,7 @@ enum {
 	I2400MS_INTR_GET_SIZE_ADDR = 0x2C,
 	/* The number of ticks to wait for the device to signal that
 	 * it is ready */
-	I2400MS_INIT_SLEEP_INTERVAL = 10,
+	I2400MS_INIT_SLEEP_INTERVAL = 100,
 	/* How long to wait for the device to settle after reset */
 	I2400MS_SETTLE_TIME = 40,
 	/* The number of msec to wait for IOR after sending IOE */
Signature · 1 line
1.6.2.5
maintainer
#13 lore raw
In reply to Inaky Perez-Gonzalez

From: Inaky Perez-Gonzalez <[email protected]>
Date: Wed, 4 Nov 2009 13:39:36 -0800

Quoted 3 lines

Please pull from:

git://git.kernel.org/pub/scm/linux/kernel/git/inaky/wimax.git

Well you screwed up the patch posting and you screwed up the GIT tree too :-/

This git tree is not based upon a clone of net-next-2.6, instead it's a mish-mash of net-next-2.6 and some by-hand net-2.6 pulls you've done yourself.

Do NOT do this.

I even saw a random kbuild: change in there as well, which also shouldn't have been there.

Fix up your tree and make it pull cleanly before submitting this work again.

Also, when you give ma GIT URL you have to give me the branch to pull from at the end of the URL, if I just give that URL without the branch specifier to GIT for the pull it's going to fail.

#14 lore raw
Quoted 5 lines · David Miller

From: Inaky Perez-Gonzalez <[email protected]>
Date: Wed, 4 Nov 2009 13:39:36 -0800

Quoted 2 lines

Please pull from:

Quoted 8 lines
Quoted 1 line

git://git.kernel.org/pub/scm/linux/kernel/git/inaky/wimax.git

Well you screwed up the patch posting and you screwed up the GIT tree too :-/

This git tree is not based upon a clone of net-next-2.6, instead it's a mish-mash of net-next-2.6 and some by-hand net-2.6 pulls you've done yourself.

Yes I did -- I didn't give you the linux-2.6.33.y branch; my apologies. The master branch is my testing tree and yes, that is not for merging.

So this pull should be against:

REPO git://git.kernel.org/pub/scm/linux/kernel/git/inaky/wimax.git
BRANCH linux-2.6.33.y

which is purely based off net-next-2.6

$ git merge-base net-next-2.6/master linux-2.6.33.y
eb2ff967a587a4a784fd2390f38e324a5bec01ec
$ git log -1 eb2ff967a587a4a784fd2390f38e324a5bec01ec
eb2ff967a587a4a784fd2390f38e324a5bec01ec xfrm: remove skb_icv_walk
Quoted 11 lines

Do NOT do this.

I even saw a random kbuild: change in there as well, which also shouldn't have been there.

Fix up your tree and make it pull cleanly before submitting this work again.

Also, when you give ma GIT URL you have to give me the branch to pull from at the end of the URL, if I just give that URL without the branch specifier to GIT for the pull it's going to fail.

This was my mistake too -- request-pull fails to detect the branch properly when it is not given an end argument that matches HEAD and I failed to realize that I was generating cover letter messages without the branch.

This happened because I was breaking up the whole list of commits in smaller chunks. Another item for the checklist.

It's maddening that I always manage to screw up somewhere :( My apologies again.

maintainer
#15 lore raw

From: Inaky Perez-Gonzalez <[email protected]>
Date: Thu, 05 Nov 2009 10:17:31 -0800

Quoted 4 lines

So this pull should be against:

REPO git://git.kernel.org/pub/scm/linux/kernel/git/inaky/wimax.git
BRANCH linux-2.6.33.y

This looks a lot better, pulled and pushed back out to net-next-2.6

Thanks.

#16 lore raw
Quoted 9 lines · David Miller

From: Inaky Perez-Gonzalez <[email protected]>
Date: Thu, 05 Nov 2009 10:17:31 -0800

Quoted 4 lines

So this pull should be against:

REPO git://git.kernel.org/pub/scm/linux/kernel/git/inaky/wimax.git
BRANCH linux-2.6.33.y

This looks a lot better, pulled and pushed back out to net-next-2.6

Thanks

/me starts the countdown to the next screwup.