forked from Minki/linux
wil6210: Tx management frame
Implement management frame passing. In order to receive frame on the other side, remain_on_channel() should be implemented as well Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
c98db0bec7
commit
1647f12f1b
@ -352,6 +352,40 @@ static int wil_cfg80211_disconnect(struct wiphy *wiphy,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wil_cfg80211_mgmt_tx(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
struct cfg80211_mgmt_tx_params *params,
|
||||
u64 *cookie)
|
||||
{
|
||||
const u8 *buf = params->buf;
|
||||
size_t len = params->len;
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
int rc;
|
||||
struct ieee80211_mgmt *mgmt_frame = (void *)buf;
|
||||
struct wmi_sw_tx_req_cmd *cmd;
|
||||
struct {
|
||||
struct wil6210_mbox_hdr_wmi wmi;
|
||||
struct wmi_sw_tx_complete_event evt;
|
||||
} __packed evt;
|
||||
|
||||
cmd = kmalloc(sizeof(*cmd) + len, GFP_KERNEL);
|
||||
if (!cmd)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(cmd->dst_mac, mgmt_frame->da, WMI_MAC_LEN);
|
||||
cmd->len = cpu_to_le16(len);
|
||||
memcpy(cmd->payload, buf, len);
|
||||
|
||||
rc = wmi_call(wil, WMI_SW_TX_REQ_CMDID, cmd, sizeof(*cmd) + len,
|
||||
WMI_SW_TX_COMPLETE_EVENTID, &evt, sizeof(evt), 2000);
|
||||
if (rc == 0)
|
||||
rc = evt.evt.status;
|
||||
|
||||
kfree(cmd);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wil_cfg80211_set_channel(struct wiphy *wiphy,
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
@ -402,6 +436,41 @@ static int wil_cfg80211_set_default_key(struct wiphy *wiphy,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_remain_on_channel(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
struct ieee80211_channel *chan,
|
||||
unsigned int duration,
|
||||
u64 *cookie)
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
int rc;
|
||||
|
||||
/* TODO: handle duration */
|
||||
wil_info(wil, "%s(%d, %d ms)\n", __func__, chan->center_freq, duration);
|
||||
|
||||
rc = wmi_set_channel(wil, chan->hw_value);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = wmi_rxon(wil, true);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wil_cancel_remain_on_channel(struct wiphy *wiphy,
|
||||
struct wireless_dev *wdev,
|
||||
u64 cookie)
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
int rc;
|
||||
|
||||
wil_info(wil, "%s()\n", __func__);
|
||||
|
||||
rc = wmi_rxon(wil, false);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wil_fix_bcon(struct wil6210_priv *wil,
|
||||
struct cfg80211_beacon_data *bcon)
|
||||
{
|
||||
@ -510,6 +579,9 @@ static struct cfg80211_ops wil_cfg80211_ops = {
|
||||
.disconnect = wil_cfg80211_disconnect,
|
||||
.change_virtual_intf = wil_cfg80211_change_iface,
|
||||
.get_station = wil_cfg80211_get_station,
|
||||
.remain_on_channel = wil_remain_on_channel,
|
||||
.cancel_remain_on_channel = wil_cancel_remain_on_channel,
|
||||
.mgmt_tx = wil_cfg80211_mgmt_tx,
|
||||
.set_monitor_channel = wil_cfg80211_set_channel,
|
||||
.add_key = wil_cfg80211_add_key,
|
||||
.del_key = wil_cfg80211_del_key,
|
||||
|
@ -357,6 +357,7 @@ int wmi_echo(struct wil6210_priv *wil);
|
||||
int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie);
|
||||
int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring);
|
||||
int wmi_p2p_cfg(struct wil6210_priv *wil, int channel);
|
||||
int wmi_rxon(struct wil6210_priv *wil, bool on);
|
||||
int wmi_get_temperature(struct wil6210_priv *wil, u32 *t_m, u32 *t_r);
|
||||
|
||||
int wil6210_init_irq(struct wil6210_priv *wil, int irq);
|
||||
|
@ -893,6 +893,38 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* wmi_rxon - turn radio on/off
|
||||
* @on: turn on if true, off otherwise
|
||||
*
|
||||
* Only switch radio. Channel should be set separately.
|
||||
* No timeout for rxon - radio turned on forever unless some other call
|
||||
* turns it off
|
||||
*/
|
||||
int wmi_rxon(struct wil6210_priv *wil, bool on)
|
||||
{
|
||||
int rc;
|
||||
struct {
|
||||
struct wil6210_mbox_hdr_wmi wmi;
|
||||
struct wmi_listen_started_event evt;
|
||||
} __packed reply;
|
||||
|
||||
wil_info(wil, "%s(%s)\n", __func__, on ? "on" : "off");
|
||||
|
||||
if (on) {
|
||||
rc = wmi_call(wil, WMI_START_LISTEN_CMDID, NULL, 0,
|
||||
WMI_LISTEN_STARTED_EVENTID,
|
||||
&reply, sizeof(reply), 100);
|
||||
if ((rc == 0) && (reply.evt.status != WMI_FW_STATUS_SUCCESS))
|
||||
rc = -EINVAL;
|
||||
} else {
|
||||
rc = wmi_call(wil, WMI_DISCOVERY_STOP_CMDID, NULL, 0,
|
||||
WMI_DISCOVERY_STOPPED_EVENTID, NULL, 0, 20);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
|
||||
{
|
||||
struct wireless_dev *wdev = wil->wdev;
|
||||
|
Loading…
Reference in New Issue
Block a user