libertas: set mac control synchronously during init
authorDaniel Drake <dsd@laptop.org>
Tue, 11 Sep 2012 15:38:11 +0000 (11:38 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 11 Sep 2012 19:32:02 +0000 (15:32 -0400)
CMD_MAC_CONTROL is currently sent async to the firmware, and is sent
from the lbs_setup_firmware() path during device init.

This means that device init can complete with commands pending, and
the if_sdio driver will sometimes power down the device (after init)
with this command still pending.

This was causing an occasional spurious command timeout after init,
leading to a device reset.

Fix this by making CMD_MAC_CONTROL synchronous when called from the
lbs_setup_firmware() path.

Signed-off-by: Daniel Drake <dsd@laptop.org>
Signed-off-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/cmd.h
drivers/net/wireless/libertas/main.c

index 26e68326710b04bce2a9e4e08f42ddf1ba645ce2..aaa297315c47102df73b6fd3948e4b8fd4cbba25 100644 (file)
@@ -1159,6 +1159,22 @@ void lbs_set_mac_control(struct lbs_private *priv)
        lbs_deb_leave(LBS_DEB_CMD);
 }
 
+int lbs_set_mac_control_sync(struct lbs_private *priv)
+{
+       struct cmd_ds_mac_control cmd;
+       int ret = 0;
+
+       lbs_deb_enter(LBS_DEB_CMD);
+
+       cmd.hdr.size = cpu_to_le16(sizeof(cmd));
+       cmd.action = cpu_to_le16(priv->mac_control);
+       cmd.reserved = 0;
+       ret = lbs_cmd_with_response(priv, CMD_MAC_CONTROL, &cmd);
+
+       lbs_deb_leave(LBS_DEB_CMD);
+       return ret;
+}
+
 /**
  *  lbs_allocate_cmd_buffer - allocates the command buffer and links
  *  it to command free queue
index ab07608e13d07031bda8f3a7d6f712b1a01b73ac..4279e8ab95f2aa4545cef71daa5649b1314fdf3b 100644 (file)
@@ -96,6 +96,7 @@ void lbs_ps_confirm_sleep(struct lbs_private *priv);
 int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on);
 
 void lbs_set_mac_control(struct lbs_private *priv);
+int lbs_set_mac_control_sync(struct lbs_private *priv);
 
 int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
                     s16 *maxlevel);
index fe1ea43c5149ef03e9ed0e2809695773fa2a576d..0c02f0483d1fd65e8b2a61b55ab57cbcc95ad5f2 100644 (file)
@@ -682,8 +682,10 @@ static int lbs_setup_firmware(struct lbs_private *priv)
 
        /* Send cmd to FW to enable 11D function */
        ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_11D_ENABLE, 1);
+       if (ret)
+               goto done;
 
-       lbs_set_mac_control(priv);
+       ret = lbs_set_mac_control_sync(priv);
 done:
        lbs_deb_leave_args(LBS_DEB_FW, "ret %d", ret);
        return ret;