Commit 3ee71285 authored by Shengzhen Li's avatar Shengzhen Li Committed by Kalle Valo

mwifiex: add get_antenna support for cfg80211

Since commit de3bb771 ("cfg80211: add more warnings for inconsistent
ops") the wireless core warns if a driver implements a cfg80211 callback
but doesn't implements the inverse operation.

The mwifiex driver defines a .set_antenna handler but not a .get_antenna
so this not only makes the core to print a warning when creating a new
wiphy but also the antenna isn't reported to user-space apps such as iw.

This patch queries the antenna to the firmware so is properly reported to
user-space. With this patch, the wireless core does not warn anymore and:

$ iw phy phy0 info | grep Antennas
        Available Antennas: TX 0x3 RX 0x3
        Configured Antennas: TX 0x3 RX 0x3
Signed-off-by: default avatarShengzhen Li <szli@marvell.com>
Signed-off-by: default avatarAmitkumar Karwar <akarwar@marvell.com>
[javier: expand the commit message]
Signed-off-by: default avatarJavier Martinez Canillas <javier@osg.samsung.com>
Tested-by: default avatarEnric Balletbo i Serra <enric.balletbo@collabora.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 7d54baca
......@@ -1830,6 +1830,21 @@ mwifiex_cfg80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant)
HostCmd_ACT_GEN_SET, 0, &ant_cfg, true);
}
static int
mwifiex_cfg80211_get_antenna(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant)
{
struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
struct mwifiex_private *priv = mwifiex_get_priv(adapter,
MWIFIEX_BSS_ROLE_ANY);
mwifiex_send_cmd(priv, HostCmd_CMD_RF_ANTENNA,
HostCmd_ACT_GEN_GET, 0, NULL, true);
*tx_ant = priv->tx_ant;
*rx_ant = priv->rx_ant;
return 0;
}
/* cfg80211 operation handler for stop ap.
* Function stops BSS running at uAP interface.
*/
......@@ -3983,6 +3998,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
.change_beacon = mwifiex_cfg80211_change_beacon,
.set_cqm_rssi_config = mwifiex_cfg80211_set_cqm_rssi_config,
.set_antenna = mwifiex_cfg80211_set_antenna,
.get_antenna = mwifiex_cfg80211_get_antenna,
.del_station = mwifiex_cfg80211_del_station,
.sched_scan_start = mwifiex_cfg80211_sched_scan_start,
.sched_scan_stop = mwifiex_cfg80211_sched_scan_stop,
......
......@@ -462,6 +462,9 @@ enum P2P_MODES {
#define HostCmd_ACT_SET_RX 0x0001
#define HostCmd_ACT_SET_TX 0x0002
#define HostCmd_ACT_SET_BOTH 0x0003
#define HostCmd_ACT_GET_RX 0x0004
#define HostCmd_ACT_GET_TX 0x0008
#define HostCmd_ACT_GET_BOTH 0x000c
#define RF_ANTENNA_AUTO 0xFFFF
......
......@@ -110,6 +110,8 @@ int mwifiex_init_priv(struct mwifiex_private *priv)
priv->tx_power_level = 0;
priv->max_tx_power_level = 0;
priv->min_tx_power_level = 0;
priv->tx_ant = 0;
priv->rx_ant = 0;
priv->tx_rate = 0;
priv->rxpd_htinfo = 0;
priv->rxpd_rate = 0;
......
......@@ -533,6 +533,8 @@ struct mwifiex_private {
u16 tx_power_level;
u8 max_tx_power_level;
u8 min_tx_power_level;
u32 tx_ant;
u32 rx_ant;
u8 tx_rate;
u8 tx_htinfo;
u8 rxpd_htinfo;
......
......@@ -313,23 +313,41 @@ static int mwifiex_cmd_rf_antenna(struct mwifiex_private *priv,
cmd->command = cpu_to_le16(HostCmd_CMD_RF_ANTENNA);
if (cmd_action != HostCmd_ACT_GEN_SET)
return 0;
if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) {
cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_rf_ant_mimo) +
S_DS_GEN);
ant_mimo->action_tx = cpu_to_le16(HostCmd_ACT_SET_TX);
ant_mimo->tx_ant_mode = cpu_to_le16((u16)ant_cfg->tx_ant);
ant_mimo->action_rx = cpu_to_le16(HostCmd_ACT_SET_RX);
ant_mimo->rx_ant_mode = cpu_to_le16((u16)ant_cfg->rx_ant);
} else {
cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_rf_ant_siso) +
S_DS_GEN);
ant_siso->action = cpu_to_le16(HostCmd_ACT_SET_BOTH);
ant_siso->ant_mode = cpu_to_le16((u16)ant_cfg->tx_ant);
switch (cmd_action) {
case HostCmd_ACT_GEN_SET:
if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) {
cmd->size = cpu_to_le16(sizeof(struct
host_cmd_ds_rf_ant_mimo)
+ S_DS_GEN);
ant_mimo->action_tx = cpu_to_le16(HostCmd_ACT_SET_TX);
ant_mimo->tx_ant_mode = cpu_to_le16((u16)ant_cfg->
tx_ant);
ant_mimo->action_rx = cpu_to_le16(HostCmd_ACT_SET_RX);
ant_mimo->rx_ant_mode = cpu_to_le16((u16)ant_cfg->
rx_ant);
} else {
cmd->size = cpu_to_le16(sizeof(struct
host_cmd_ds_rf_ant_siso) +
S_DS_GEN);
ant_siso->action = cpu_to_le16(HostCmd_ACT_SET_BOTH);
ant_siso->ant_mode = cpu_to_le16((u16)ant_cfg->tx_ant);
}
break;
case HostCmd_ACT_GEN_GET:
if (priv->adapter->hw_dev_mcs_support == HT_STREAM_2X2) {
cmd->size = cpu_to_le16(sizeof(struct
host_cmd_ds_rf_ant_mimo) +
S_DS_GEN);
ant_mimo->action_tx = cpu_to_le16(HostCmd_ACT_GET_TX);
ant_mimo->action_rx = cpu_to_le16(HostCmd_ACT_GET_RX);
} else {
cmd->size = cpu_to_le16(sizeof(struct
host_cmd_ds_rf_ant_siso) +
S_DS_GEN);
ant_siso->action = cpu_to_le16(HostCmd_ACT_GET_BOTH);
}
break;
}
return 0;
}
......
......@@ -469,7 +469,9 @@ static int mwifiex_ret_rf_antenna(struct mwifiex_private *priv,
struct host_cmd_ds_rf_ant_siso *ant_siso = &resp->params.ant_siso;
struct mwifiex_adapter *adapter = priv->adapter;
if (adapter->hw_dev_mcs_support == HT_STREAM_2X2)
if (adapter->hw_dev_mcs_support == HT_STREAM_2X2) {
priv->tx_ant = le16_to_cpu(ant_mimo->tx_ant_mode);
priv->rx_ant = le16_to_cpu(ant_mimo->rx_ant_mode);
mwifiex_dbg(adapter, INFO,
"RF_ANT_RESP: Tx action = 0x%x, Tx Mode = 0x%04x\t"
"Rx action = 0x%x, Rx Mode = 0x%04x\n",
......@@ -477,12 +479,14 @@ static int mwifiex_ret_rf_antenna(struct mwifiex_private *priv,
le16_to_cpu(ant_mimo->tx_ant_mode),
le16_to_cpu(ant_mimo->action_rx),
le16_to_cpu(ant_mimo->rx_ant_mode));
else
} else {
priv->tx_ant = le16_to_cpu(ant_siso->ant_mode);
priv->rx_ant = le16_to_cpu(ant_siso->ant_mode);
mwifiex_dbg(adapter, INFO,
"RF_ANT_RESP: action = 0x%x, Mode = 0x%04x\n",
le16_to_cpu(ant_siso->action),
le16_to_cpu(ant_siso->ant_mode));
}
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment