On Tue, 2012-09-11 at 11:38 -0400, Daniel Drake wrote: > 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@xxxxxxxxxx> Thanks! Signed-off-by: Dan Williams <dcbw@xxxxxxxxxx> > drivers/net/wireless/libertas/cmd.c | 16 ++++++++++++++++ > drivers/net/wireless/libertas/cmd.h | 1 + > drivers/net/wireless/libertas/main.c | 4 +++- > 3 files changed, 20 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c > index 26e6832..aaa2973 100644 > --- a/drivers/net/wireless/libertas/cmd.c > +++ b/drivers/net/wireless/libertas/cmd.c > @@ -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 > diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h > index ab07608..4279e8a 100644 > --- a/drivers/net/wireless/libertas/cmd.h > +++ b/drivers/net/wireless/libertas/cmd.h > @@ -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); > diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c > index fe1ea43..0c02f04 100644 > --- a/drivers/net/wireless/libertas/main.c > +++ b/drivers/net/wireless/libertas/main.c > @@ -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; -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html