Skip to content

Commit

Permalink
[Bug 455] Fix frequent channel change generates firmware fatal error.
Browse files Browse the repository at this point in the history
Because of the frequent channel change, it is possible that when we are
try to associate with channel 1 (authenticated but not associated).
Another channel change comes at this time, then the driver will issue
disassociate command to the firmware which will cause the fatal error.

It seems that the association/disassociation procedure should not be
interrupted.

The patch attached adds test on STATUS_ASSOCIATING | STATUS_DISASSOCIATING
in ipw_send_cmd(), when ensures that commands will not be sent to firmware
when we are in these two status.

Signed-off-by: Hong Liu <hong.liu@intel.com>
Signed-off-by: Zhu Yi <yi.zhu@intel.com>
  • Loading branch information
Hong Liu authored and James Ketrenos committed Nov 7, 2005
1 parent a0e04ab commit 7b99659
Showing 1 changed file with 25 additions and 6 deletions.
31 changes: 25 additions & 6 deletions drivers/net/wireless/ipw2200.c
Original file line number Diff line number Diff line change
Expand Up @@ -1884,6 +1884,18 @@ static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
return -EAGAIN;
}

if (priv->status & STATUS_ASSOCIATING) {
IPW_DEBUG_HC("abandon a command while associating\n");
spin_unlock_irqrestore(&priv->lock, flags);
return -1;
}

if (priv->status & STATUS_DISASSOCIATING) {
IPW_DEBUG_HC("abandon a command while disassociating\n");
spin_unlock_irqrestore(&priv->lock, flags);
return -1;
}

priv->status |= STATUS_HCMD_ACTIVE;

if (priv->cmdlog) {
Expand Down Expand Up @@ -3671,7 +3683,13 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
{
int err;

if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))) {
if (priv->status & STATUS_ASSOCIATING) {
IPW_DEBUG_ASSOC("Disassociating while associating.\n");
queue_work(priv->workqueue, &priv->disassociate);
return;
}

if (!(priv->status & STATUS_ASSOCIATED)) {
IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
return;
}
Expand All @@ -3681,9 +3699,6 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
MAC_ARG(priv->assoc_request.bssid),
priv->assoc_request.channel);

priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
priv->status |= STATUS_DISASSOCIATING;

if (quiet)
priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
else
Expand All @@ -3695,6 +3710,9 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)
return;
}

priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
priv->status |= STATUS_DISASSOCIATING;

}

static int ipw_disassociate(void *data)
Expand Down Expand Up @@ -7625,8 +7643,6 @@ static int ipw_associate_network(struct ipw_priv *priv,
*/
priv->channel = network->channel;
memcpy(priv->bssid, network->bssid, ETH_ALEN);
priv->status |= STATUS_ASSOCIATING;
priv->status &= ~STATUS_SECURITY_UPDATED;

priv->assoc_network = network;

Expand All @@ -7640,6 +7656,9 @@ static int ipw_associate_network(struct ipw_priv *priv,
return err;
}

priv->status |= STATUS_ASSOCIATING;
priv->status &= ~STATUS_SECURITY_UPDATED;

IPW_DEBUG(IPW_DL_STATE, "associating: '%s' " MAC_FMT " \n",
escape_essid(priv->essid, priv->essid_len),
MAC_ARG(priv->bssid));
Expand Down

0 comments on commit 7b99659

Please sign in to comment.