FILE
vendor_cmd.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/wireless/ti/wlcore/vendor_cmd.c
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * This file is part of wlcore 4 * 5 * Copyright (C) 2014 Texas Instruments. All rights reserved. 6 */ 7 8#include <linux/pm_runtime.h> 9 10#include <net/mac80211.h> 11#include <net/netlink.h> 12 13#include "wlcore.h" 14#include "debug.h" 15#include "hw_ops.h" 16#include "vendor_cmd.h" 17 18static const 19struct nla_policy wlcore_vendor_attr_policy[NUM_WLCORE_VENDOR_ATTR] = { 20 [WLCORE_VENDOR_ATTR_FREQ] = { .type = NLA_U32 }, 21 [WLCORE_VENDOR_ATTR_GROUP_ID] = { .type = NLA_U32 }, 22 [WLCORE_VENDOR_ATTR_GROUP_KEY] = { .type = NLA_BINARY, 23 .len = WLAN_MAX_KEY_LEN }, 24}; 25 26static int 27wlcore_vendor_cmd_smart_config_start(struct wiphy *wiphy, 28 struct wireless_dev *wdev, 29 const void *data, int data_len) 30{ 31 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 32 struct wl1271 *wl = hw->priv; 33 struct nlattr *tb[NUM_WLCORE_VENDOR_ATTR]; 34 int ret; 35 36 wl1271_debug(DEBUG_CMD, "vendor cmd smart config start"); 37 38 if (!data) 39 return -EINVAL; 40 41 ret = nla_parse_deprecated(tb, MAX_WLCORE_VENDOR_ATTR, data, data_len, 42 wlcore_vendor_attr_policy, NULL); 43 if (ret) 44 return ret; 45 46 if (!tb[WLCORE_VENDOR_ATTR_GROUP_ID]) 47 return -EINVAL; 48 49 mutex_lock(&wl->mutex); 50 51 if (unlikely(wl->state != WLCORE_STATE_ON)) { 52 ret = -EINVAL; 53 goto out; 54 } 55 56 ret = pm_runtime_resume_and_get(wl->dev); 57 if (ret < 0) 58 goto out; 59 60 ret = wlcore_smart_config_start(wl, 61 nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID])); 62 63 pm_runtime_put_autosuspend(wl->dev); 64out: 65 mutex_unlock(&wl->mutex); 66 67 return ret; 68} 69 70static int 71wlcore_vendor_cmd_smart_config_stop(struct wiphy *wiphy, 72 struct wireless_dev *wdev, 73 const void *data, int data_len) 74{ 75 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 76 struct wl1271 *wl = hw->priv; 77 int ret; 78 79 wl1271_debug(DEBUG_CMD, "testmode cmd smart config stop"); 80 81 mutex_lock(&wl->mutex); 82 83 if (unlikely(wl->state != WLCORE_STATE_ON)) { 84 ret = -EINVAL; 85 goto out; 86 } 87 88 ret = pm_runtime_resume_and_get(wl->dev); 89 if (ret < 0) 90 goto out; 91 92 ret = wlcore_smart_config_stop(wl); 93 94 pm_runtime_put_autosuspend(wl->dev); 95out: 96 mutex_unlock(&wl->mutex); 97 98 return ret; 99} 100 101static int 102wlcore_vendor_cmd_smart_config_set_group_key(struct wiphy *wiphy, 103 struct wireless_dev *wdev, 104 const void *data, int data_len) 105{ 106 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 107 struct wl1271 *wl = hw->priv; 108 struct nlattr *tb[NUM_WLCORE_VENDOR_ATTR]; 109 int ret; 110 111 wl1271_debug(DEBUG_CMD, "testmode cmd smart config set group key"); 112 113 if (!data) 114 return -EINVAL; 115 116 ret = nla_parse_deprecated(tb, MAX_WLCORE_VENDOR_ATTR, data, data_len, 117 wlcore_vendor_attr_policy, NULL); 118 if (ret) 119 return ret; 120 121 if (!tb[WLCORE_VENDOR_ATTR_GROUP_ID] || 122 !tb[WLCORE_VENDOR_ATTR_GROUP_KEY]) 123 return -EINVAL; 124 125 mutex_lock(&wl->mutex); 126 127 if (unlikely(wl->state != WLCORE_STATE_ON)) { 128 ret = -EINVAL; 129 goto out; 130 } 131 132 ret = pm_runtime_resume_and_get(wl->dev); 133 if (ret < 0) 134 goto out; 135 136 ret = wlcore_smart_config_set_group_key(wl, 137 nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID]), 138 nla_len(tb[WLCORE_VENDOR_ATTR_GROUP_KEY]), 139 nla_data(tb[WLCORE_VENDOR_ATTR_GROUP_KEY])); 140 141 pm_runtime_put_autosuspend(wl->dev); 142out: 143 mutex_unlock(&wl->mutex); 144 145 return ret; 146} 147 148static const struct wiphy_vendor_command wlcore_vendor_commands[] = { 149 { 150 .info = { 151 .vendor_id = TI_OUI, 152 .subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_START, 153 }, 154 .flags = WIPHY_VENDOR_CMD_NEED_NETDEV | 155 WIPHY_VENDOR_CMD_NEED_RUNNING, 156 .doit = wlcore_vendor_cmd_smart_config_start, 157 .policy = wlcore_vendor_attr_policy, 158 }, 159 { 160 .info = { 161 .vendor_id = TI_OUI, 162 .subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_STOP, 163 }, 164 .flags = WIPHY_VENDOR_CMD_NEED_NETDEV | 165 WIPHY_VENDOR_CMD_NEED_RUNNING, 166 .doit = wlcore_vendor_cmd_smart_config_stop, 167 .policy = wlcore_vendor_attr_policy, 168 }, 169 { 170 .info = { 171 .vendor_id = TI_OUI, 172 .subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_SET_GROUP_KEY, 173 }, 174 .flags = WIPHY_VENDOR_CMD_NEED_NETDEV | 175 WIPHY_VENDOR_CMD_NEED_RUNNING, 176 .doit = wlcore_vendor_cmd_smart_config_set_group_key, 177 .policy = wlcore_vendor_attr_policy, 178 }, 179}; 180 181static const struct nl80211_vendor_cmd_info wlcore_vendor_events[] = { 182 { 183 .vendor_id = TI_OUI, 184 .subcmd = WLCORE_VENDOR_EVENT_SC_SYNC, 185 }, 186 { 187 .vendor_id = TI_OUI, 188 .subcmd = WLCORE_VENDOR_EVENT_SC_DECODE, 189 }, 190}; 191 192void wlcore_set_vendor_commands(struct wiphy *wiphy) 193{ 194 wiphy->vendor_commands = wlcore_vendor_commands; 195 wiphy->n_vendor_commands = ARRAY_SIZE(wlcore_vendor_commands); 196 wiphy->vendor_events = wlcore_vendor_events; 197 wiphy->n_vendor_events = ARRAY_SIZE(wlcore_vendor_events); 198}
~/
Read-only file preview.