root/drivers/net/wireless/ti/wlcore/vendor_cmd.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wlcore_vendor_cmd_smart_config_start
  2. wlcore_vendor_cmd_smart_config_stop
  3. wlcore_vendor_cmd_smart_config_set_group_key
  4. wlcore_set_vendor_commands

   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 
  18 static const
  19 struct 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 
  26 static int
  27 wlcore_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_get_sync(wl->dev);
  57         if (ret < 0) {
  58                 pm_runtime_put_noidle(wl->dev);
  59                 goto out;
  60         }
  61 
  62         ret = wlcore_smart_config_start(wl,
  63                         nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID]));
  64 
  65         pm_runtime_mark_last_busy(wl->dev);
  66         pm_runtime_put_autosuspend(wl->dev);
  67 out:
  68         mutex_unlock(&wl->mutex);
  69 
  70         return ret;
  71 }
  72 
  73 static int
  74 wlcore_vendor_cmd_smart_config_stop(struct wiphy *wiphy,
  75                                     struct wireless_dev *wdev,
  76                                     const void *data, int data_len)
  77 {
  78         struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
  79         struct wl1271 *wl = hw->priv;
  80         int ret;
  81 
  82         wl1271_debug(DEBUG_CMD, "testmode cmd smart config stop");
  83 
  84         mutex_lock(&wl->mutex);
  85 
  86         if (unlikely(wl->state != WLCORE_STATE_ON)) {
  87                 ret = -EINVAL;
  88                 goto out;
  89         }
  90 
  91         ret = pm_runtime_get_sync(wl->dev);
  92         if (ret < 0) {
  93                 pm_runtime_put_noidle(wl->dev);
  94                 goto out;
  95         }
  96 
  97         ret = wlcore_smart_config_stop(wl);
  98 
  99         pm_runtime_mark_last_busy(wl->dev);
 100         pm_runtime_put_autosuspend(wl->dev);
 101 out:
 102         mutex_unlock(&wl->mutex);
 103 
 104         return ret;
 105 }
 106 
 107 static int
 108 wlcore_vendor_cmd_smart_config_set_group_key(struct wiphy *wiphy,
 109                                              struct wireless_dev *wdev,
 110                                              const void *data, int data_len)
 111 {
 112         struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
 113         struct wl1271 *wl = hw->priv;
 114         struct nlattr *tb[NUM_WLCORE_VENDOR_ATTR];
 115         int ret;
 116 
 117         wl1271_debug(DEBUG_CMD, "testmode cmd smart config set group key");
 118 
 119         if (!data)
 120                 return -EINVAL;
 121 
 122         ret = nla_parse_deprecated(tb, MAX_WLCORE_VENDOR_ATTR, data, data_len,
 123                                    wlcore_vendor_attr_policy, NULL);
 124         if (ret)
 125                 return ret;
 126 
 127         if (!tb[WLCORE_VENDOR_ATTR_GROUP_ID] ||
 128             !tb[WLCORE_VENDOR_ATTR_GROUP_KEY])
 129                 return -EINVAL;
 130 
 131         mutex_lock(&wl->mutex);
 132 
 133         if (unlikely(wl->state != WLCORE_STATE_ON)) {
 134                 ret = -EINVAL;
 135                 goto out;
 136         }
 137 
 138         ret = pm_runtime_get_sync(wl->dev);
 139         if (ret < 0) {
 140                 pm_runtime_put_noidle(wl->dev);
 141                 goto out;
 142         }
 143 
 144         ret = wlcore_smart_config_set_group_key(wl,
 145                         nla_get_u32(tb[WLCORE_VENDOR_ATTR_GROUP_ID]),
 146                         nla_len(tb[WLCORE_VENDOR_ATTR_GROUP_KEY]),
 147                         nla_data(tb[WLCORE_VENDOR_ATTR_GROUP_KEY]));
 148 
 149         pm_runtime_mark_last_busy(wl->dev);
 150         pm_runtime_put_autosuspend(wl->dev);
 151 out:
 152         mutex_unlock(&wl->mutex);
 153 
 154         return ret;
 155 }
 156 
 157 static const struct wiphy_vendor_command wlcore_vendor_commands[] = {
 158         {
 159                 .info = {
 160                         .vendor_id = TI_OUI,
 161                         .subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_START,
 162                 },
 163                 .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
 164                          WIPHY_VENDOR_CMD_NEED_RUNNING,
 165                 .doit = wlcore_vendor_cmd_smart_config_start,
 166                 .policy = wlcore_vendor_attr_policy,
 167         },
 168         {
 169                 .info = {
 170                         .vendor_id = TI_OUI,
 171                         .subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_STOP,
 172                 },
 173                 .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
 174                          WIPHY_VENDOR_CMD_NEED_RUNNING,
 175                 .doit = wlcore_vendor_cmd_smart_config_stop,
 176                 .policy = wlcore_vendor_attr_policy,
 177         },
 178         {
 179                 .info = {
 180                         .vendor_id = TI_OUI,
 181                         .subcmd = WLCORE_VENDOR_CMD_SMART_CONFIG_SET_GROUP_KEY,
 182                 },
 183                 .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
 184                          WIPHY_VENDOR_CMD_NEED_RUNNING,
 185                 .doit = wlcore_vendor_cmd_smart_config_set_group_key,
 186                 .policy = wlcore_vendor_attr_policy,
 187         },
 188 };
 189 
 190 static const struct nl80211_vendor_cmd_info wlcore_vendor_events[] = {
 191         {
 192                 .vendor_id = TI_OUI,
 193                 .subcmd = WLCORE_VENDOR_EVENT_SC_SYNC,
 194         },
 195         {
 196                 .vendor_id = TI_OUI,
 197                 .subcmd = WLCORE_VENDOR_EVENT_SC_DECODE,
 198         },
 199 };
 200 
 201 void wlcore_set_vendor_commands(struct wiphy *wiphy)
 202 {
 203         wiphy->vendor_commands = wlcore_vendor_commands;
 204         wiphy->n_vendor_commands = ARRAY_SIZE(wlcore_vendor_commands);
 205         wiphy->vendor_events = wlcore_vendor_events;
 206         wiphy->n_vendor_events = ARRAY_SIZE(wlcore_vendor_events);
 207 }

/* [<][>][^][v][top][bottom][index][help] */