Skip to content

Commit

Permalink
libertas: convert CMD_802_11_RADIO_CONTROL to a direct command
Browse files Browse the repository at this point in the history
and return errors for operations like join & scan that aren't possible
when the radio is turned off.

Signed-off-by: Dan Williams <dcbw@redhat.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Dan Williams authored and John W. Linville committed Aug 29, 2008
1 parent 191bb40 commit d5db2df
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 100 deletions.
57 changes: 31 additions & 26 deletions drivers/net/wireless/libertas/assoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,37 +25,37 @@ static const u8 bssid_off[ETH_ALEN] __attribute__ ((aligned (2))) =
* @brief Associate to a specific BSS discovered in a scan
*
* @param priv A pointer to struct lbs_private structure
* @param pbssdesc Pointer to the BSS descriptor to associate with.
* @param assoc_req The association request describing the BSS to associate with
*
* @return 0-success, otherwise fail
*/
static int lbs_associate(struct lbs_private *priv,
struct assoc_request *assoc_req)
{
int ret;
u8 preamble = RADIO_PREAMBLE_LONG;

lbs_deb_enter(LBS_DEB_ASSOC);

ret = lbs_prepare_and_send_command(priv, CMD_802_11_AUTHENTICATE,
0, CMD_OPTION_WAITFORRSP,
0, assoc_req->bss.bssid);

if (ret)
goto done;
goto out;

/* set preamble to firmware */
/* Use short preamble only when both the BSS and firmware support it */
if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
(assoc_req->bss.capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
else
priv->preamble = CMD_TYPE_LONG_PREAMBLE;
preamble = RADIO_PREAMBLE_SHORT;

lbs_set_radio_control(priv);
ret = lbs_set_radio(priv, preamble, 1);
if (ret)
goto out;

ret = lbs_prepare_and_send_command(priv, CMD_802_11_ASSOCIATE,
0, CMD_OPTION_WAITFORRSP, 0, assoc_req);

done:
out:
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}
Expand All @@ -64,8 +64,7 @@ static int lbs_associate(struct lbs_private *priv,
* @brief Join an adhoc network found in a previous scan
*
* @param priv A pointer to struct lbs_private structure
* @param pbssdesc Pointer to a BSS descriptor found in a previous scan
* to attempt to join
* @param assoc_req The association request describing the BSS to join
*
* @return 0--success, -1--fail
*/
Expand All @@ -74,6 +73,9 @@ static int lbs_join_adhoc_network(struct lbs_private *priv,
{
struct bss_descriptor *bss = &assoc_req->bss;
int ret = 0;
u8 preamble = RADIO_PREAMBLE_LONG;

lbs_deb_enter(LBS_DEB_ASSOC);

lbs_deb_join("current SSID '%s', ssid length %u\n",
escape_essid(priv->curbssparams.ssid,
Expand Down Expand Up @@ -106,18 +108,16 @@ static int lbs_join_adhoc_network(struct lbs_private *priv,
goto out;
}

/* Use shortpreamble only when both creator and card supports
short preamble */
if (!(bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) ||
!(priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
lbs_deb_join("AdhocJoin: Long preamble\n");
priv->preamble = CMD_TYPE_LONG_PREAMBLE;
} else {
/* Use short preamble only when both the BSS and firmware support it */
if ((priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) &&
(bss->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
lbs_deb_join("AdhocJoin: Short preamble\n");
priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
preamble = RADIO_PREAMBLE_SHORT;
}

lbs_set_radio_control(priv);
ret = lbs_set_radio(priv, preamble, 1);
if (ret)
goto out;

lbs_deb_join("AdhocJoin: channel = %d\n", assoc_req->channel);
lbs_deb_join("AdhocJoin: band = %c\n", assoc_req->band);
Expand All @@ -129,39 +129,44 @@ static int lbs_join_adhoc_network(struct lbs_private *priv,
OID_802_11_SSID, assoc_req);

out:
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}

/**
* @brief Start an Adhoc Network
*
* @param priv A pointer to struct lbs_private structure
* @param adhocssid The ssid of the Adhoc Network
* @param assoc_req The association request describing the BSS to start
* @return 0--success, -1--fail
*/
static int lbs_start_adhoc_network(struct lbs_private *priv,
struct assoc_request *assoc_req)
{
int ret = 0;
u8 preamble = RADIO_PREAMBLE_LONG;

lbs_deb_enter(LBS_DEB_ASSOC);

priv->adhoccreate = 1;

if (priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) {
lbs_deb_join("AdhocStart: Short preamble\n");
priv->preamble = CMD_TYPE_SHORT_PREAMBLE;
} else {
lbs_deb_join("AdhocStart: Long preamble\n");
priv->preamble = CMD_TYPE_LONG_PREAMBLE;
preamble = RADIO_PREAMBLE_SHORT;
}

lbs_set_radio_control(priv);
ret = lbs_set_radio(priv, preamble, 1);
if (ret)
goto out;

lbs_deb_join("AdhocStart: channel = %d\n", assoc_req->channel);
lbs_deb_join("AdhocStart: band = %d\n", assoc_req->band);

ret = lbs_prepare_and_send_command(priv, CMD_802_11_AD_HOC_START,
0, CMD_OPTION_WAITFORRSP, 0, assoc_req);

out:
lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret);
return ret;
}

Expand Down
46 changes: 26 additions & 20 deletions drivers/net/wireless/libertas/cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1289,41 +1289,47 @@ void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
priv->cur_cmd = NULL;
}

int lbs_set_radio_control(struct lbs_private *priv)
int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
{
int ret = 0;
struct cmd_ds_802_11_radio_control cmd;
int ret = -EINVAL;

lbs_deb_enter(LBS_DEB_CMD);

cmd.hdr.size = cpu_to_le16(sizeof(cmd));
cmd.action = cpu_to_le16(CMD_ACT_SET);

switch (priv->preamble) {
case CMD_TYPE_SHORT_PREAMBLE:
cmd.control = cpu_to_le16(SET_SHORT_PREAMBLE);
break;

case CMD_TYPE_LONG_PREAMBLE:
cmd.control = cpu_to_le16(SET_LONG_PREAMBLE);
break;
/* Only v8 and below support setting the preamble */
if (priv->fwrelease < 0x09000000) {
switch (preamble) {
case RADIO_PREAMBLE_SHORT:
if (!(priv->capability & WLAN_CAPABILITY_SHORT_PREAMBLE))
goto out;
/* Fall through */
case RADIO_PREAMBLE_AUTO:
case RADIO_PREAMBLE_LONG:
cmd.control = cpu_to_le16(preamble);
break;
default:
goto out;
}
}

case CMD_TYPE_AUTO_PREAMBLE:
default:
cmd.control = cpu_to_le16(SET_AUTO_PREAMBLE);
break;
if (radio_on)
cmd.control |= cpu_to_le16(0x1);
else {
cmd.control &= cpu_to_le16(~0x1);
priv->txpower_cur = 0;
}

if (priv->radioon)
cmd.control |= cpu_to_le16(TURN_ON_RF);
else
cmd.control &= cpu_to_le16(~TURN_ON_RF);
lbs_deb_cmd("RADIO_CONTROL: radio %s, preamble %d\n",
radio_on ? "ON" : "OFF", preamble);

lbs_deb_cmd("RADIO_SET: radio %d, preamble %d\n", priv->radioon,
priv->preamble);
priv->radio_on = radio_on;

ret = lbs_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd);

out:
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
return ret;
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/libertas/cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,6 @@ int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
s16 *maxlevel);
int lbs_set_tx_power(struct lbs_private *priv, s16 dbm);

int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on);

#endif /* _LBS_CMD_H */
1 change: 0 additions & 1 deletion drivers/net/wireless/libertas/decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ int lbs_process_event(struct lbs_private *priv, u32 event);
void lbs_queue_event(struct lbs_private *priv, u32 event);
void lbs_notify_command_response(struct lbs_private *priv, u8 resp_idx);

int lbs_set_radio_control(struct lbs_private *priv);
u32 lbs_fw_index_to_data_rate(u8 index);
u8 lbs_data_rate_to_fw_index(u32 rate);

Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wireless/libertas/dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,7 @@ struct lbs_private {
u16 nextSNRNF;
u16 numSNRNF;

u8 radioon;
u32 preamble;
u8 radio_on;

/** data rate stuff */
u8 cur_rate;
Expand Down
15 changes: 3 additions & 12 deletions drivers/net/wireless/libertas/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,6 @@
#define CMD_ACT_MAC_ALL_MULTICAST_ENABLE 0x0100
#define CMD_ACT_MAC_STRICT_PROTECTION_ENABLE 0x0400

/* Define action or option for CMD_802_11_RADIO_CONTROL */
#define CMD_TYPE_AUTO_PREAMBLE 0x0001
#define CMD_TYPE_SHORT_PREAMBLE 0x0002
#define CMD_TYPE_LONG_PREAMBLE 0x0003

/* Event flags for CMD_802_11_SUBSCRIBE_EVENT */
#define CMD_SUBSCRIBE_RSSI_LOW 0x0001
#define CMD_SUBSCRIBE_SNR_LOW 0x0002
Expand All @@ -165,13 +160,9 @@
#define CMD_SUBSCRIBE_RSSI_HIGH 0x0010
#define CMD_SUBSCRIBE_SNR_HIGH 0x0020

#define TURN_ON_RF 0x01
#define RADIO_ON 0x01
#define RADIO_OFF 0x00

#define SET_AUTO_PREAMBLE 0x05
#define SET_SHORT_PREAMBLE 0x03
#define SET_LONG_PREAMBLE 0x01
#define RADIO_PREAMBLE_LONG 0x00
#define RADIO_PREAMBLE_SHORT 0x02
#define RADIO_PREAMBLE_AUTO 0x04

/* Define action or option for CMD_802_11_RF_CHANNEL */
#define CMD_OPT_802_11_RF_CHANNEL_GET 0x00
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/libertas/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1051,7 +1051,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
priv->mode = IW_MODE_INFRA;
priv->curbssparams.channel = DEFAULT_AD_HOC_CHANNEL;
priv->mac_control = CMD_ACT_MAC_RX_ON | CMD_ACT_MAC_TX_ON;
priv->radioon = RADIO_ON;
priv->radio_on = 1;
priv->enablehwauto = 1;
priv->capability = WLAN_CAPABILITY_SHORT_PREAMBLE;
priv->psmode = LBS802_11POWERMODECAM;
Expand Down
5 changes: 5 additions & 0 deletions drivers/net/wireless/libertas/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,11 @@ int lbs_set_scan(struct net_device *dev, struct iw_request_info *info,

lbs_deb_enter(LBS_DEB_WEXT);

if (!priv->radio_on) {
ret = -EINVAL;
goto out;
}

if (!netif_running(dev)) {
ret = -ENETDOWN;
goto out;
Expand Down
Loading

0 comments on commit d5db2df

Please sign in to comment.