2 * This file is part of wlcore
4 * Copyright (C) 2014 Texas Instruments. All rights reserved.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
11 #include <net/mac80211.h>
12 #include <net/netlink.h>
18 #include "vendor_cmd.h"
21 struct nla_policy wlcore_vendor_attr_policy[NUM_WLCORE_VENDOR_ATTR] = {
22 [WLCORE_VENDOR_ATTR_FREQ] = { .type = NLA_U32 },
23 [WLCORE_VENDOR_ATTR_GROUP_ID] = { .type = NLA_U32 },
24 [WLCORE_VENDOR_ATTR_GROUP_KEY] = { .type = NLA_BINARY,
25 .len = WLAN_MAX_KEY_LEN },
29 wlcore_vendor_cmd_smart_config_start(struct wiphy *wiphy,
30 struct wireless_dev *wdev,
31 const void *data, int data_len)
33 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
34 struct wl1271 *wl = hw->priv;
35 struct nlattr *tb[NUM_WLCORE_VENDOR_ATTR];
38 wl1271_debug(DEBUG_CMD, "vendor cmd smart config start");
43 ret = nla_parse(tb, MAX_WLCORE_VENDOR_ATTR, data, data_len,
44 wlcore_vendor_attr_policy);
48 if (!tb[WLCORE_VENDOR_ATTR_GROUP_ID])
51 mutex_lock(&wl->mutex);
53 if (unlikely(wl->state != WLCORE_STATE_ON)) {
58 ret = wl1271_ps_elp_wakeup(wl);
62 ret = wlcore_smart_config_start(wl,
63 nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID]));
65 wl1271_ps_elp_sleep(wl);
67 mutex_unlock(&wl->mutex);
73 wlcore_vendor_cmd_smart_config_stop(struct wiphy *wiphy,
74 struct wireless_dev *wdev,
75 const void *data, int data_len)
77 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
78 struct wl1271 *wl = hw->priv;
81 wl1271_debug(DEBUG_CMD, "testmode cmd smart config stop");
83 mutex_lock(&wl->mutex);
85 if (unlikely(wl->state != WLCORE_STATE_ON)) {
90 ret = wl1271_ps_elp_wakeup(wl);
94 ret = wlcore_smart_config_stop(wl);
96 wl1271_ps_elp_sleep(wl);
98 mutex_unlock(&wl->mutex);
104 wlcore_vendor_cmd_smart_config_set_group_key(struct wiphy *wiphy,
105 struct wireless_dev *wdev,
106 const void *data, int data_len)
108 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
109 struct wl1271 *wl = hw->priv;
110 struct nlattr *tb[NUM_WLCORE_VENDOR_ATTR];
113 wl1271_debug(DEBUG_CMD, "testmode cmd smart config set group key");
118 ret = nla_parse(tb, MAX_WLCORE_VENDOR_ATTR, data, data_len,
119 wlcore_vendor_attr_policy);
123 if (!tb[WLCORE_VENDOR_ATTR_GROUP_ID] ||
124 !tb[WLCORE_VENDOR_ATTR_GROUP_KEY])
127 mutex_lock(&wl->mutex);
129 if (unlikely(wl->state != WLCORE_STATE_ON)) {
134 ret = wl1271_ps_elp_wakeup(wl);
138 ret = wlcore_smart_config_set_group_key(wl,
139 nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID]),
140 nla_len(tb[WLCORE_VENDOR_ATTR_GROUP_KEY]),
141 nla_data(tb[WLCORE_VENDOR_ATTR_GROUP_KEY]));
143 wl1271_ps_elp_sleep(wl);
145 mutex_unlock(&wl->mutex);
150 static const struct wiphy_vendor_command wlcore_vendor_commands[] = {
154 .subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_START,
156 .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
157 WIPHY_VENDOR_CMD_NEED_RUNNING,
158 .doit = wlcore_vendor_cmd_smart_config_start,
163 .subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_STOP,
165 .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
166 WIPHY_VENDOR_CMD_NEED_RUNNING,
167 .doit = wlcore_vendor_cmd_smart_config_stop,
172 .subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_SET_GROUP_KEY,
174 .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
175 WIPHY_VENDOR_CMD_NEED_RUNNING,
176 .doit = wlcore_vendor_cmd_smart_config_set_group_key,
180 static const struct nl80211_vendor_cmd_info wlcore_vendor_events[] = {
183 .subcmd = WLCORE_VENDOR_EVENT_SC_SYNC,
187 .subcmd = WLCORE_VENDOR_EVENT_SC_DECODE,
191 void wlcore_set_vendor_commands(struct wiphy *wiphy)
193 wiphy->vendor_commands = wlcore_vendor_commands;
194 wiphy->n_vendor_commands = ARRAY_SIZE(wlcore_vendor_commands);
195 wiphy->vendor_events = wlcore_vendor_events;
196 wiphy->n_vendor_events = ARRAY_SIZE(wlcore_vendor_events);