1 // SPDX-License-Identifier: ISC
3 * Copyright (c) 2014 Broadcom Corporation
6 #include <linux/vmalloc.h>
7 #include <net/cfg80211.h>
8 #include <net/netlink.h>
10 #include <brcmu_wifi.h>
11 #include "fwil_types.h"
19 static int brcmf_cfg80211_vndr_cmds_dcmd_handler(struct wiphy
*wiphy
,
20 struct wireless_dev
*wdev
,
21 const void *data
, int len
)
23 struct brcmf_cfg80211_vif
*vif
;
25 const struct brcmf_vndr_dcmd_hdr
*cmdhdr
= data
;
26 struct sk_buff
*reply
;
27 unsigned int payload
, ret_len
;
28 void *dcmd_buf
= NULL
, *wr_pointer
;
29 u16 msglen
, maxmsglen
= PAGE_SIZE
- 0x100;
32 if (len
< sizeof(*cmdhdr
)) {
33 brcmf_err("vendor command too short: %d\n", len
);
37 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
40 brcmf_dbg(TRACE
, "ifidx=%d, cmd=%d\n", ifp
->ifidx
, cmdhdr
->cmd
);
42 if (cmdhdr
->offset
> len
) {
43 brcmf_err("bad buffer offset %d > %d\n", cmdhdr
->offset
, len
);
47 len
-= cmdhdr
->offset
;
48 ret_len
= cmdhdr
->len
;
49 if (ret_len
> 0 || len
> 0) {
50 if (len
> BRCMF_DCMD_MAXLEN
) {
51 brcmf_err("oversize input buffer %d\n", len
);
52 len
= BRCMF_DCMD_MAXLEN
;
54 if (ret_len
> BRCMF_DCMD_MAXLEN
) {
55 brcmf_err("oversize return buffer %d\n", ret_len
);
56 ret_len
= BRCMF_DCMD_MAXLEN
;
58 payload
= max_t(unsigned int, ret_len
, len
) + 1;
59 dcmd_buf
= vzalloc(payload
);
63 memcpy(dcmd_buf
, (void *)cmdhdr
+ cmdhdr
->offset
, len
);
64 *(char *)(dcmd_buf
+ len
) = '\0';
68 ret
= brcmf_fil_cmd_data_set(ifp
, cmdhdr
->cmd
, dcmd_buf
,
71 ret
= brcmf_fil_cmd_data_get(ifp
, cmdhdr
->cmd
, dcmd_buf
,
76 wr_pointer
= dcmd_buf
;
78 msglen
= ret_len
> maxmsglen
? maxmsglen
: ret_len
;
80 payload
= msglen
+ sizeof(msglen
);
81 reply
= cfg80211_vendor_cmd_alloc_reply_skb(wiphy
, payload
);
87 if (nla_put(reply
, BRCMF_NLATTR_DATA
, msglen
, wr_pointer
) ||
88 nla_put_u16(reply
, BRCMF_NLATTR_LEN
, msglen
)) {
94 ret
= cfg80211_vendor_cmd_reply(reply
);
107 const struct wiphy_vendor_command brcmf_vendor_cmds
[] = {
110 .vendor_id
= BROADCOM_OUI
,
111 .subcmd
= BRCMF_VNDR_CMDS_DCMD
113 .flags
= WIPHY_VENDOR_CMD_NEED_WDEV
|
114 WIPHY_VENDOR_CMD_NEED_NETDEV
,
115 .policy
= VENDOR_CMD_RAW_DATA
,
116 .doit
= brcmf_cfg80211_vndr_cmds_dcmd_handler