1 // SPDX-License-Identifier: GPL-2.0-only
3 * This file is part of wl1271
5 * Copyright (C) 2010 Nokia Corporation
7 * Contact: Luciano Coelho <luciano.coelho@nokia.com>
11 #include <linux/pm_runtime.h>
12 #include <linux/slab.h>
13 #include <net/genetlink.h>
20 #define WL1271_TM_MAX_DATA_LENGTH 1024
22 enum wl1271_tm_commands
{
25 WL1271_TM_CMD_INTERROGATE
,
26 WL1271_TM_CMD_CONFIGURE
,
27 WL1271_TM_CMD_NVS_PUSH
, /* Not in use. Keep to not break ABI */
28 WL1271_TM_CMD_SET_PLT_MODE
,
29 WL1271_TM_CMD_RECOVER
, /* Not in use. Keep to not break ABI */
30 WL1271_TM_CMD_GET_MAC
,
32 __WL1271_TM_CMD_AFTER_LAST
34 #define WL1271_TM_CMD_MAX (__WL1271_TM_CMD_AFTER_LAST - 1)
36 enum wl1271_tm_attrs
{
37 WL1271_TM_ATTR_UNSPEC
,
38 WL1271_TM_ATTR_CMD_ID
,
39 WL1271_TM_ATTR_ANSWER
,
42 WL1271_TM_ATTR_PLT_MODE
,
44 __WL1271_TM_ATTR_AFTER_LAST
46 #define WL1271_TM_ATTR_MAX (__WL1271_TM_ATTR_AFTER_LAST - 1)
48 static struct nla_policy wl1271_tm_policy
[WL1271_TM_ATTR_MAX
+ 1] = {
49 [WL1271_TM_ATTR_CMD_ID
] = { .type
= NLA_U32
},
50 [WL1271_TM_ATTR_ANSWER
] = { .type
= NLA_U8
},
51 [WL1271_TM_ATTR_DATA
] = { .type
= NLA_BINARY
,
52 .len
= WL1271_TM_MAX_DATA_LENGTH
},
53 [WL1271_TM_ATTR_IE_ID
] = { .type
= NLA_U32
},
54 [WL1271_TM_ATTR_PLT_MODE
] = { .type
= NLA_U32
},
58 static int wl1271_tm_cmd_test(struct wl1271
*wl
, struct nlattr
*tb
[])
60 int buf_len
, ret
, len
;
65 wl1271_debug(DEBUG_TESTMODE
, "testmode cmd test");
67 if (!tb
[WL1271_TM_ATTR_DATA
])
70 buf
= nla_data(tb
[WL1271_TM_ATTR_DATA
]);
71 buf_len
= nla_len(tb
[WL1271_TM_ATTR_DATA
]);
73 if (tb
[WL1271_TM_ATTR_ANSWER
])
74 answer
= nla_get_u8(tb
[WL1271_TM_ATTR_ANSWER
]);
76 if (buf_len
> sizeof(struct wl1271_command
))
79 mutex_lock(&wl
->mutex
);
81 if (unlikely(wl
->state
!= WLCORE_STATE_ON
)) {
86 ret
= pm_runtime_get_sync(wl
->dev
);
88 pm_runtime_put_noidle(wl
->dev
);
92 ret
= wl1271_cmd_test(wl
, buf
, buf_len
, answer
);
94 wl1271_warning("testmode cmd test failed: %d", ret
);
99 /* If we got bip calibration answer print radio status */
100 struct wl1271_cmd_cal_p2g
*params
=
101 (struct wl1271_cmd_cal_p2g
*) buf
;
103 s16 radio_status
= (s16
) le16_to_cpu(params
->radio_status
);
105 if (params
->test
.id
== TEST_CMD_P2G_CAL
&&
107 wl1271_warning("testmode cmd: radio status=%d",
110 wl1271_info("testmode cmd: radio status=%d",
113 len
= nla_total_size(buf_len
);
114 skb
= cfg80211_testmode_alloc_reply_skb(wl
->hw
->wiphy
, len
);
120 if (nla_put(skb
, WL1271_TM_ATTR_DATA
, buf_len
, buf
)) {
126 ret
= cfg80211_testmode_reply(skb
);
132 pm_runtime_mark_last_busy(wl
->dev
);
133 pm_runtime_put_autosuspend(wl
->dev
);
135 mutex_unlock(&wl
->mutex
);
140 static int wl1271_tm_cmd_interrogate(struct wl1271
*wl
, struct nlattr
*tb
[])
143 struct wl1271_command
*cmd
;
147 wl1271_debug(DEBUG_TESTMODE
, "testmode cmd interrogate");
149 if (!tb
[WL1271_TM_ATTR_IE_ID
])
152 ie_id
= nla_get_u8(tb
[WL1271_TM_ATTR_IE_ID
]);
154 mutex_lock(&wl
->mutex
);
156 if (unlikely(wl
->state
!= WLCORE_STATE_ON
)) {
161 ret
= pm_runtime_get_sync(wl
->dev
);
163 pm_runtime_put_noidle(wl
->dev
);
167 cmd
= kzalloc(sizeof(*cmd
), GFP_KERNEL
);
173 ret
= wl1271_cmd_interrogate(wl
, ie_id
, cmd
,
174 sizeof(struct acx_header
), sizeof(*cmd
));
176 wl1271_warning("testmode cmd interrogate failed: %d", ret
);
180 skb
= cfg80211_testmode_alloc_reply_skb(wl
->hw
->wiphy
, sizeof(*cmd
));
186 if (nla_put(skb
, WL1271_TM_ATTR_DATA
, sizeof(*cmd
), cmd
)) {
192 ret
= cfg80211_testmode_reply(skb
);
199 pm_runtime_mark_last_busy(wl
->dev
);
200 pm_runtime_put_autosuspend(wl
->dev
);
202 mutex_unlock(&wl
->mutex
);
207 static int wl1271_tm_cmd_configure(struct wl1271
*wl
, struct nlattr
*tb
[])
213 wl1271_debug(DEBUG_TESTMODE
, "testmode cmd configure");
215 if (!tb
[WL1271_TM_ATTR_DATA
])
217 if (!tb
[WL1271_TM_ATTR_IE_ID
])
220 ie_id
= nla_get_u8(tb
[WL1271_TM_ATTR_IE_ID
]);
221 buf
= nla_data(tb
[WL1271_TM_ATTR_DATA
]);
222 buf_len
= nla_len(tb
[WL1271_TM_ATTR_DATA
]);
224 if (buf_len
> sizeof(struct wl1271_command
))
227 mutex_lock(&wl
->mutex
);
228 ret
= wl1271_cmd_configure(wl
, ie_id
, buf
, buf_len
);
229 mutex_unlock(&wl
->mutex
);
232 wl1271_warning("testmode cmd configure failed: %d", ret
);
239 static int wl1271_tm_detect_fem(struct wl1271
*wl
, struct nlattr
*tb
[])
241 /* return FEM type */
245 ret
= wl1271_plt_start(wl
, PLT_FEM_DETECT
);
249 mutex_lock(&wl
->mutex
);
251 len
= nla_total_size(sizeof(wl
->fem_manuf
));
252 skb
= cfg80211_testmode_alloc_reply_skb(wl
->hw
->wiphy
, len
);
258 if (nla_put(skb
, WL1271_TM_ATTR_DATA
, sizeof(wl
->fem_manuf
),
265 ret
= cfg80211_testmode_reply(skb
);
268 mutex_unlock(&wl
->mutex
);
270 /* We always stop plt after DETECT mode */
276 static int wl1271_tm_cmd_set_plt_mode(struct wl1271
*wl
, struct nlattr
*tb
[])
281 wl1271_debug(DEBUG_TESTMODE
, "testmode cmd set plt mode");
283 if (!tb
[WL1271_TM_ATTR_PLT_MODE
])
286 val
= nla_get_u32(tb
[WL1271_TM_ATTR_PLT_MODE
]);
290 ret
= wl1271_plt_stop(wl
);
294 ret
= wl1271_plt_start(wl
, val
);
297 ret
= wl1271_tm_detect_fem(wl
, tb
);
307 static int wl12xx_tm_cmd_get_mac(struct wl1271
*wl
, struct nlattr
*tb
[])
310 u8 mac_addr
[ETH_ALEN
];
313 mutex_lock(&wl
->mutex
);
320 if (wl
->fuse_oui_addr
== 0 && wl
->fuse_nic_addr
== 0) {
325 mac_addr
[0] = (u8
)(wl
->fuse_oui_addr
>> 16);
326 mac_addr
[1] = (u8
)(wl
->fuse_oui_addr
>> 8);
327 mac_addr
[2] = (u8
) wl
->fuse_oui_addr
;
328 mac_addr
[3] = (u8
)(wl
->fuse_nic_addr
>> 16);
329 mac_addr
[4] = (u8
)(wl
->fuse_nic_addr
>> 8);
330 mac_addr
[5] = (u8
) wl
->fuse_nic_addr
;
332 skb
= cfg80211_testmode_alloc_reply_skb(wl
->hw
->wiphy
, ETH_ALEN
);
338 if (nla_put(skb
, WL1271_TM_ATTR_DATA
, ETH_ALEN
, mac_addr
)) {
344 ret
= cfg80211_testmode_reply(skb
);
349 mutex_unlock(&wl
->mutex
);
353 int wl1271_tm_cmd(struct ieee80211_hw
*hw
, struct ieee80211_vif
*vif
,
356 struct wl1271
*wl
= hw
->priv
;
357 struct nlattr
*tb
[WL1271_TM_ATTR_MAX
+ 1];
361 err
= nla_parse_deprecated(tb
, WL1271_TM_ATTR_MAX
, data
, len
,
362 wl1271_tm_policy
, NULL
);
366 if (!tb
[WL1271_TM_ATTR_CMD_ID
])
369 nla_cmd
= nla_get_u32(tb
[WL1271_TM_ATTR_CMD_ID
]);
371 /* Only SET_PLT_MODE is allowed in case of mode PLT_CHIP_AWAKE */
372 if (wl
->plt_mode
== PLT_CHIP_AWAKE
&&
373 nla_cmd
!= WL1271_TM_CMD_SET_PLT_MODE
)
377 case WL1271_TM_CMD_TEST
:
378 return wl1271_tm_cmd_test(wl
, tb
);
379 case WL1271_TM_CMD_INTERROGATE
:
380 return wl1271_tm_cmd_interrogate(wl
, tb
);
381 case WL1271_TM_CMD_CONFIGURE
:
382 return wl1271_tm_cmd_configure(wl
, tb
);
383 case WL1271_TM_CMD_SET_PLT_MODE
:
384 return wl1271_tm_cmd_set_plt_mode(wl
, tb
);
385 case WL1271_TM_CMD_GET_MAC
:
386 return wl12xx_tm_cmd_get_mac(wl
, tb
);