qtnfmac: add support for getting/setting transmit power
Add new command for getting/setting current transmit power and propagate requests from user space to firmware. Signed-off-by: Mikhail Karpenko <mkarpenko@quantenna.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
parent
239ce8a797
commit
0756e913fc
@ -897,6 +897,45 @@ static int qtnf_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qtnf_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
int *dbm)
|
||||
{
|
||||
struct qtnf_vif *vif = qtnf_netdev_get_priv(wdev->netdev);
|
||||
int ret;
|
||||
|
||||
ret = qtnf_cmd_get_tx_power(vif, dbm);
|
||||
if (ret)
|
||||
pr_err("MAC%u: failed to get Tx power\n", vif->mac->macid);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int qtnf_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
enum nl80211_tx_power_setting type, int mbm)
|
||||
{
|
||||
struct qtnf_vif *vif;
|
||||
int ret;
|
||||
|
||||
if (wdev) {
|
||||
vif = qtnf_netdev_get_priv(wdev->netdev);
|
||||
} else {
|
||||
struct qtnf_wmac *mac = wiphy_priv(wiphy);
|
||||
|
||||
vif = qtnf_mac_get_base_vif(mac);
|
||||
if (!vif) {
|
||||
pr_err("MAC%u: primary VIF is not configured\n",
|
||||
mac->macid);
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
ret = qtnf_cmd_set_tx_power(vif, type, mbm);
|
||||
if (ret)
|
||||
pr_err("MAC%u: failed to set Tx power\n", vif->mac->macid);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int qtnf_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wowlan)
|
||||
{
|
||||
@ -991,6 +1030,8 @@ static struct cfg80211_ops qtn_cfg80211_ops = {
|
||||
.start_radar_detection = qtnf_start_radar_detection,
|
||||
.set_mac_acl = qtnf_set_mac_acl,
|
||||
.set_power_mgmt = qtnf_set_power_mgmt,
|
||||
.get_tx_power = qtnf_get_tx_power,
|
||||
.set_tx_power = qtnf_set_tx_power,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = qtnf_suspend,
|
||||
.resume = qtnf_resume,
|
||||
|
@ -2643,6 +2643,71 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qtnf_cmd_get_tx_power(const struct qtnf_vif *vif, int *dbm)
|
||||
{
|
||||
struct qtnf_bus *bus = vif->mac->bus;
|
||||
const struct qlink_resp_txpwr *resp;
|
||||
struct sk_buff *resp_skb = NULL;
|
||||
struct qlink_cmd_txpwr *cmd;
|
||||
struct sk_buff *cmd_skb;
|
||||
int ret = 0;
|
||||
|
||||
cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
|
||||
QLINK_CMD_TXPWR, sizeof(*cmd));
|
||||
if (!cmd_skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct qlink_cmd_txpwr *)cmd_skb->data;
|
||||
cmd->op_type = QLINK_TXPWR_GET;
|
||||
|
||||
qtnf_bus_lock(bus);
|
||||
|
||||
ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb,
|
||||
sizeof(*resp), NULL);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
resp = (const struct qlink_resp_txpwr *)resp_skb->data;
|
||||
*dbm = MBM_TO_DBM(le32_to_cpu(resp->txpwr));
|
||||
|
||||
out:
|
||||
qtnf_bus_unlock(bus);
|
||||
consume_skb(resp_skb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qtnf_cmd_set_tx_power(const struct qtnf_vif *vif,
|
||||
enum nl80211_tx_power_setting type, int mbm)
|
||||
{
|
||||
struct qtnf_bus *bus = vif->mac->bus;
|
||||
const struct qlink_resp_txpwr *resp;
|
||||
struct sk_buff *resp_skb = NULL;
|
||||
struct qlink_cmd_txpwr *cmd;
|
||||
struct sk_buff *cmd_skb;
|
||||
int ret = 0;
|
||||
|
||||
cmd_skb = qtnf_cmd_alloc_new_cmdskb(vif->mac->macid, vif->vifid,
|
||||
QLINK_CMD_TXPWR, sizeof(*cmd));
|
||||
if (!cmd_skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct qlink_cmd_txpwr *)cmd_skb->data;
|
||||
cmd->op_type = QLINK_TXPWR_SET;
|
||||
cmd->txpwr_setting = type;
|
||||
cmd->txpwr = cpu_to_le32(mbm);
|
||||
|
||||
qtnf_bus_lock(bus);
|
||||
|
||||
ret = qtnf_cmd_send_with_reply(bus, cmd_skb, &resp_skb,
|
||||
sizeof(*resp), NULL);
|
||||
|
||||
qtnf_bus_unlock(bus);
|
||||
consume_skb(resp_skb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int qtnf_cmd_send_wowlan_set(const struct qtnf_vif *vif,
|
||||
const struct cfg80211_wowlan *wowl)
|
||||
{
|
||||
|
@ -70,6 +70,9 @@ int qtnf_cmd_start_cac(const struct qtnf_vif *vif,
|
||||
int qtnf_cmd_set_mac_acl(const struct qtnf_vif *vif,
|
||||
const struct cfg80211_acl_data *params);
|
||||
int qtnf_cmd_send_pm_set(const struct qtnf_vif *vif, u8 pm_mode, int timeout);
|
||||
int qtnf_cmd_get_tx_power(const struct qtnf_vif *vif, int *dbm);
|
||||
int qtnf_cmd_set_tx_power(const struct qtnf_vif *vif,
|
||||
enum nl80211_tx_power_setting type, int mbm);
|
||||
int qtnf_cmd_send_wowlan_set(const struct qtnf_vif *vif,
|
||||
const struct cfg80211_wowlan *wowl);
|
||||
|
||||
|
@ -217,6 +217,8 @@ struct qlink_sta_info_state {
|
||||
* command is supported only if device reports QLINK_HW_SUPPORTS_REG_UPDATE
|
||||
* capability.
|
||||
* @QLINK_CMD_START_CAC: start radar detection procedure on a specified channel.
|
||||
* @QLINK_CMD_TXPWR: get or set current channel transmit power for
|
||||
* the specified MAC.
|
||||
*/
|
||||
enum qlink_cmd_type {
|
||||
QLINK_CMD_FW_INIT = 0x0001,
|
||||
@ -254,6 +256,7 @@ enum qlink_cmd_type {
|
||||
QLINK_CMD_PM_SET = 0x0062,
|
||||
QLINK_CMD_WOWLAN_SET = 0x0063,
|
||||
QLINK_CMD_EXTERNAL_AUTH = 0x0066,
|
||||
QLINK_CMD_TXPWR = 0x0067,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -718,6 +721,32 @@ struct qlink_cmd_pm_set {
|
||||
u8 pm_mode;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* enum qlink_txpwr_op - transmit power operation type
|
||||
* @QLINK_TXPWR_SET: set tx power
|
||||
* @QLINK_TXPWR_GET: get current tx power setting
|
||||
*/
|
||||
enum qlink_txpwr_op {
|
||||
QLINK_TXPWR_SET,
|
||||
QLINK_TXPWR_GET
|
||||
};
|
||||
|
||||
/**
|
||||
* struct qlink_cmd_txpwr - get or set current transmit power
|
||||
*
|
||||
* @txpwr: new transmit power setting, in mBm
|
||||
* @txpwr_setting: transmit power setting type, one of
|
||||
* &enum nl80211_tx_power_setting
|
||||
* @op_type: type of operation, one of &enum qlink_txpwr_op
|
||||
*/
|
||||
struct qlink_cmd_txpwr {
|
||||
struct qlink_cmd chdr;
|
||||
__le32 txpwr;
|
||||
u8 txpwr_setting;
|
||||
u8 op_type;
|
||||
u8 rsvd[2];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* enum qlink_wowlan_trigger
|
||||
*
|
||||
@ -944,6 +973,19 @@ struct qlink_resp_channel_get {
|
||||
struct qlink_chandef chan;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct qlink_resp_txpwr - response for QLINK_CMD_TXPWR command
|
||||
*
|
||||
* This response is intended for QLINK_TXPWR_GET operation and does not
|
||||
* contain any meaningful information in case of QLINK_TXPWR_SET operation.
|
||||
*
|
||||
* @txpwr: current transmit power setting, in mBm
|
||||
*/
|
||||
struct qlink_resp_txpwr {
|
||||
struct qlink_resp rhdr;
|
||||
__le32 txpwr;
|
||||
} __packed;
|
||||
|
||||
/* QLINK Events messages related definitions
|
||||
*/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user