Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5db2dfa authored by Dan Williams's avatar Dan Williams Committed by John W. Linville
Browse files

libertas: convert CMD_802_11_RADIO_CONTROL to a direct command



and return errors for operations like join & scan that aren't possible
when the radio is turned off.

Signed-off-by: default avatarDan Williams <dcbw@redhat.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 191bb40e
Loading
Loading
Loading
Loading
+31 −26
Original line number Diff line number Diff line
@@ -25,7 +25,7 @@ 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
 */
@@ -33,29 +33,29 @@ 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;
}
@@ -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
 */
@@ -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,
@@ -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);
@@ -129,6 +129,7 @@ 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;
}

@@ -136,25 +137,27 @@ static int lbs_join_adhoc_network(struct lbs_private *priv,
 *  @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);
@@ -162,6 +165,8 @@ static int lbs_start_adhoc_network(struct lbs_private *priv,
	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;
}

+26 −20
Original line number Diff line number Diff line
@@ -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);
	/* 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;

	case CMD_TYPE_AUTO_PREAMBLE:
		default:
		cmd.control = cpu_to_le16(SET_AUTO_PREAMBLE);
		break;
			goto out;
		}
	}

	if (priv->radioon)
		cmd.control |= cpu_to_le16(TURN_ON_RF);
	else
		cmd.control &= cpu_to_le16(~TURN_ON_RF);
	if (radio_on)
		cmd.control |= cpu_to_le16(0x1);
	else {
		cmd.control &= cpu_to_le16(~0x1);
		priv->txpower_cur = 0;
	}

	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;
}
+2 −0
Original line number Diff line number Diff line
@@ -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 */
+0 −1
Original line number Diff line number Diff line
@@ -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);

+1 −2
Original line number Diff line number Diff line
@@ -293,8 +293,7 @@ struct lbs_private {
	u16 nextSNRNF;
	u16 numSNRNF;

	u8 radioon;
	u32 preamble;
	u8 radio_on;

	/** data rate stuff */
	u8 cur_rate;
Loading