1 /*****************************************************************************
3 * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd. All rights reserved
5 ****************************************************************************/
7 #include "dev.h" /* sdev access */
14 static int slsi_src_sink_fake_sta_start(struct slsi_dev
*sdev
, struct net_device
*dev
)
16 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
17 struct slsi_peer
*peer
;
18 u8 device_address
[ETH_ALEN
] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
19 u8 fake_peer_mac
[ETH_ALEN
] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
21 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
23 ndev_vif
->iftype
= NL80211_IFTYPE_STATION
;
24 dev
->ieee80211_ptr
->iftype
= NL80211_IFTYPE_STATION
;
25 ndev_vif
->vif_type
= FAPI_VIFTYPE_STATION
;
27 if (WARN(slsi_mlme_add_vif(sdev
, dev
, dev
->dev_addr
, device_address
) != 0, "add VIF failed")) {
28 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
32 if (WARN(slsi_vif_activated(sdev
, dev
) != 0, "activate VIF failed")) {
33 slsi_mlme_del_vif(sdev
, dev
);
34 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
38 peer
= slsi_peer_add(sdev
, dev
, fake_peer_mac
, SLSI_STA_PEER_QUEUESET
+ 1);
39 if (WARN(!peer
, "add fake peer failed")) {
40 slsi_vif_deactivated(sdev
, dev
);
41 slsi_mlme_del_vif(sdev
, dev
);
42 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
45 peer
->qos_enabled
= true;
46 slsi_ps_port_control(sdev
, dev
, peer
, SLSI_STA_CONN_STATE_CONNECTED
);
47 netif_carrier_on(dev
);
48 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
52 static void slsi_src_sink_fake_sta_stop(struct slsi_dev
*sdev
, struct net_device
*dev
)
54 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
55 struct slsi_peer
*peer
= slsi_get_peer_from_qs(sdev
, dev
, SLSI_STA_PEER_QUEUESET
);
57 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
59 SLSI_NET_DBG1(dev
, SLSI_SRC_SINK
, "station stop(vif:%d)\n", ndev_vif
->ifnum
);
61 if (WARN(!ndev_vif
->activated
, "not activated")) {
62 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
66 netif_carrier_off(dev
);
68 slsi_peer_remove(sdev
, dev
, peer
);
69 slsi_vif_deactivated(sdev
, dev
);
70 slsi_mlme_del_vif(sdev
, dev
);
71 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
74 static int slsi_src_sink_loopback_start(struct slsi_dev
*sdev
)
76 struct net_device
*dev
;
77 struct netdev_vif
*ndev_vif
;
80 for (i
= SLSI_NET_INDEX_WLAN
; i
<= SLSI_NET_INDEX_P2P
; i
++) {
81 dev
= slsi_get_netdev_locked(sdev
, i
);
82 if (WARN(!dev
, "no netdev (index:%d)", i
))
85 ndev_vif
= netdev_priv(dev
);
86 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
88 /* for p2p0 interface the peer database is not created during init;
89 * peer database is needed for dataplane to be functional.
90 * so create the peer records for p2p0 now and undo it during loopback stop
92 if (i
== SLSI_NET_INDEX_P2P
) {
93 for (queue_idx
= 0; queue_idx
< SLSI_ADHOC_PEER_CONNECTIONS_MAX
; queue_idx
++) {
94 ndev_vif
->peer_sta_record
[queue_idx
] = kzalloc(sizeof(*ndev_vif
->peer_sta_record
[queue_idx
]), GFP_KERNEL
);
95 if (!ndev_vif
->peer_sta_record
[queue_idx
]) {
98 SLSI_NET_ERR(dev
, "Could not allocate memory for peer entry (queue_idx:%d)\n", queue_idx
);
100 /* free previously allocated peer database memory till current queue_idx */
101 for (j
= 0; j
< queue_idx
; j
++) {
102 kfree(ndev_vif
->peer_sta_record
[j
]);
103 ndev_vif
->peer_sta_record
[j
] = NULL
;
105 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
110 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
111 if (WARN(slsi_src_sink_fake_sta_start(sdev
, dev
) != 0, "fake STA setup failed (vif:%d)\n", i
))
117 static void slsi_src_sink_loopback_stop(struct slsi_dev
*sdev
)
119 struct net_device
*dev
;
120 struct netdev_vif
*ndev_vif
;
123 for (i
= SLSI_NET_INDEX_WLAN
; i
<= SLSI_NET_INDEX_P2P
; i
++) {
124 dev
= slsi_get_netdev_locked(sdev
, i
);
125 if (WARN(!dev
, "no netdev (index:%d)", i
))
128 slsi_src_sink_fake_sta_stop(sdev
, dev
);
130 ndev_vif
= netdev_priv(dev
);
131 SLSI_MUTEX_LOCK(ndev_vif
->vif_mutex
);
133 /* undo peer database creation for p2p0 interface on loopback stop */
134 if (i
== SLSI_NET_INDEX_P2P
) {
135 for (queue_idx
= 0; queue_idx
< SLSI_ADHOC_PEER_CONNECTIONS_MAX
; queue_idx
++) {
136 kfree(ndev_vif
->peer_sta_record
[queue_idx
]);
137 ndev_vif
->peer_sta_record
[queue_idx
] = NULL
;
140 SLSI_MUTEX_UNLOCK(ndev_vif
->vif_mutex
);
144 long slsi_src_sink_cdev_ioctl_cfg(struct slsi_dev
*sdev
, unsigned long arg
)
147 struct unifiio_src_sink_arg_t src_sink_arg
;
148 struct net_device
*dev
;
149 struct netdev_vif
*ndev_vif
;
150 struct sk_buff
*req
= NULL
;
151 struct sk_buff
*ind
= NULL
;
153 memset((void *)&src_sink_arg
, 0, sizeof(struct unifiio_src_sink_arg_t
));
154 if (copy_from_user((void *)(&src_sink_arg
), (void *)arg
, sizeof(struct unifiio_src_sink_arg_t
)))
157 SLSI_DBG2(sdev
, SLSI_SRC_SINK
, "Source/Sink\n");
158 SLSI_DBG2(sdev
, SLSI_SRC_SINK
, "====================================================\n");
159 SLSI_DBG2(sdev
, SLSI_SRC_SINK
, " #action : [0x%04X]\n", src_sink_arg
.common
.action
);
160 SLSI_DBG2(sdev
, SLSI_SRC_SINK
, " #direction : [0x%04X]\n", src_sink_arg
.common
.direction
);
161 SLSI_DBG2(sdev
, SLSI_SRC_SINK
, " #vif : [0x%04X]\n", src_sink_arg
.common
.vif
);
162 SLSI_DBG2(sdev
, SLSI_SRC_SINK
, " #endpoint : [0x%04X]\n", src_sink_arg
.common
.endpoint
);
163 SLSI_DBG2(sdev
, SLSI_SRC_SINK
, "====================================================\n");
165 SLSI_MUTEX_LOCK(sdev
->netdev_add_remove_mutex
);
166 dev
= slsi_get_netdev_locked(sdev
, src_sink_arg
.common
.vif
);
168 SLSI_ERR(sdev
, "netdev for input vif:%d is NULL\n", src_sink_arg
.common
.vif
);
172 ndev_vif
= netdev_priv(dev
);
174 switch (src_sink_arg
.common
.action
) {
175 case SRC_SINK_ACTION_SINK_START
:
176 if (WARN(slsi_src_sink_fake_sta_start(sdev
, dev
) != 0, "fake STA setup failed\n")) {
180 req
= fapi_alloc(debug_pkt_sink_start_req
, DEBUG_PKT_SINK_START_REQ
, src_sink_arg
.common
.vif
, 0);
185 fapi_set_u16(req
, u
.debug_pkt_sink_start_req
.end_point
, src_sink_arg
.common
.endpoint
);
186 fapi_set_u16(req
, u
.debug_pkt_sink_start_req
.direction
, src_sink_arg
.common
.direction
);
187 fapi_set_u32(req
, u
.debug_pkt_sink_start_req
.interval
, src_sink_arg
.u
.config
.interval
);
188 fapi_set_u16(req
, u
.debug_pkt_sink_start_req
.packets_per_interval
, src_sink_arg
.u
.config
.pkts_per_int
);
189 SLSI_DBG1(sdev
, SLSI_SRC_SINK
, "debug_pkt_sink_start_req->\n");
190 r
= slsi_mlme_req(sdev
, dev
, req
);
192 case SRC_SINK_ACTION_SINK_STOP
:
193 req
= fapi_alloc(debug_pkt_sink_stop_req
, DEBUG_PKT_SINK_STOP_REQ
, src_sink_arg
.common
.vif
, 0);
198 fapi_set_u16(req
, u
.debug_pkt_sink_stop_req
.direction
, src_sink_arg
.common
.direction
);
199 fapi_set_u16(req
, u
.debug_pkt_sink_stop_req
.end_point
, src_sink_arg
.common
.endpoint
);
200 SLSI_DBG1(sdev
, SLSI_SRC_SINK
, "debug_pkt_sink_stop_req->\n");
201 r
= slsi_mlme_req(sdev
, dev
, req
);
202 slsi_src_sink_fake_sta_stop(sdev
, dev
);
204 case SRC_SINK_ACTION_GEN_START
:
205 if (WARN(slsi_src_sink_fake_sta_start(sdev
, dev
) != 0, "fake STA setup failed\n")) {
209 req
= fapi_alloc(debug_pkt_gen_start_req
, DEBUG_PKT_GEN_START_REQ
, src_sink_arg
.common
.vif
, 0);
214 fapi_set_u16(req
, u
.debug_pkt_gen_start_req
.direction
, src_sink_arg
.common
.direction
);
215 fapi_set_u16(req
, u
.debug_pkt_gen_start_req
.end_point
, src_sink_arg
.common
.endpoint
);
216 fapi_set_u32(req
, u
.debug_pkt_gen_start_req
.interval
, src_sink_arg
.u
.config
.interval
);
217 fapi_set_u16(req
, u
.debug_pkt_gen_start_req
.packets_per_interval
, src_sink_arg
.u
.config
.pkts_per_int
);
218 fapi_set_u16(req
, u
.debug_pkt_gen_start_req
.size
, src_sink_arg
.u
.config
.u
.gen
.size
);
219 fapi_set_u16(req
, u
.debug_pkt_gen_start_req
.use_streaming
, src_sink_arg
.u
.config
.u
.gen
.use_streaming
);
220 fapi_set_u32(req
, u
.debug_pkt_gen_start_req
.ipv4destination_address
, src_sink_arg
.u
.config
.u
.gen
.ipv4_dest
);
221 fapi_set_u16(req
, u
.debug_pkt_gen_start_req
.packets_per_interrupt
, src_sink_arg
.u
.config
.u
.gen
.pkts_per_intr
);
223 SLSI_DBG3(sdev
, SLSI_SRC_SINK
,
224 "int:%u, pkts_per_int:%u, vif:%u, size:%u, use_streaming:%u, ipv4_dest:0x%04X, pkts_per_intr:%u\n",
225 src_sink_arg
.u
.config
.interval
,
226 src_sink_arg
.u
.config
.pkts_per_int
,
227 src_sink_arg
.common
.vif
,
228 src_sink_arg
.u
.config
.u
.gen
.size
,
229 src_sink_arg
.u
.config
.u
.gen
.use_streaming
,
230 src_sink_arg
.u
.config
.u
.gen
.ipv4_dest
,
231 src_sink_arg
.u
.config
.u
.gen
.pkts_per_intr
);
232 SLSI_DBG1(sdev
, SLSI_SRC_SINK
, "debug_pkt_gen_start_req->\n");
233 r
= slsi_mlme_req(sdev
, dev
, req
);
235 case SRC_SINK_ACTION_GEN_STOP
:
236 req
= fapi_alloc(debug_pkt_gen_stop_req
, DEBUG_PKT_GEN_STOP_REQ
, src_sink_arg
.common
.vif
, 0);
241 fapi_set_u16(req
, u
.debug_pkt_gen_stop_req
.direction
, src_sink_arg
.common
.direction
);
242 fapi_set_u16(req
, u
.debug_pkt_gen_stop_req
.end_point
, src_sink_arg
.common
.endpoint
);
243 SLSI_DBG1(sdev
, SLSI_SRC_SINK
, "debug_pkt_gen_stop_req->\n");
244 r
= slsi_mlme_req(sdev
, dev
, req
);
245 slsi_src_sink_fake_sta_stop(sdev
, dev
);
247 case SRC_SINK_ACTION_LOOPBACK_START
:
248 if (WARN(slsi_src_sink_loopback_start(sdev
) != 0, "loopback setup failed\n")) {
252 req
= fapi_alloc(debug_pkt_sink_start_req
, DEBUG_PKT_SINK_START_REQ
, 1, 0);
257 fapi_set_u16(req
, u
.debug_pkt_sink_start_req
.end_point
, SRC_SINK_ENDPOINT_HOSTIO
);
258 fapi_set_u16(req
, u
.debug_pkt_sink_start_req
.direction
, SRC_SINK_DIRECTION_RX
);
259 fapi_set_u32(req
, u
.debug_pkt_sink_start_req
.interval
, src_sink_arg
.u
.config
.interval
);
260 fapi_set_u16(req
, u
.debug_pkt_sink_start_req
.packets_per_interval
, src_sink_arg
.u
.config
.pkts_per_int
);
261 SLSI_DBG1(sdev
, SLSI_SRC_SINK
, "debug_pkt_loopback_start_req->\n");
262 r
= slsi_mlme_req(sdev
, dev
, req
);
264 case SRC_SINK_ACTION_LOOPBACK_STOP
:
265 req
= fapi_alloc(debug_pkt_sink_stop_req
, DEBUG_PKT_SINK_STOP_REQ
, 1, 0);
270 fapi_set_u16(req
, u
.debug_pkt_sink_stop_req
.direction
, SRC_SINK_DIRECTION_RX
);
271 fapi_set_u16(req
, u
.debug_pkt_sink_stop_req
.end_point
, SRC_SINK_ENDPOINT_HOSTIO
);
272 SLSI_DBG1(sdev
, SLSI_SRC_SINK
, "debug_pkt_loopback_stop_req->\n");
273 r
= slsi_mlme_req(sdev
, dev
, req
);
274 slsi_src_sink_loopback_stop(sdev
);
276 case SRC_SINK_ACTION_SINK_REPORT
:
277 req
= fapi_alloc(debug_pkt_sink_report_req
, DEBUG_PKT_SINK_REPORT_REQ
, src_sink_arg
.common
.vif
, 0);
282 fapi_set_u16(req
, u
.debug_pkt_sink_report_req
.end_point
, src_sink_arg
.common
.endpoint
);
283 fapi_set_u16(req
, u
.debug_pkt_sink_report_req
.direction
, src_sink_arg
.common
.direction
);
284 fapi_set_u32(req
, u
.debug_pkt_sink_report_req
.report_interval
, src_sink_arg
.u
.report
.interval
);
285 SLSI_DBG1(sdev
, SLSI_SRC_SINK
, "debug_pkt_sink_report_req->\n");
287 ind
= slsi_mlme_req_ind(sdev
, dev
, req
, DEBUG_PKT_SINK_REPORT_IND
);
289 SLSI_ERR(sdev
, "slsi_mlme_req_ind [SINK_REPORT] failed\n");
294 src_sink_arg
.u
.report
.duration
= fapi_get_u32(ind
, u
.debug_pkt_sink_report_ind
.duration
);
295 src_sink_arg
.u
.report
.count
= fapi_get_u32(ind
, u
.debug_pkt_sink_report_ind
.received_packets
);
296 src_sink_arg
.u
.report
.octet
= fapi_get_u32(ind
, u
.debug_pkt_sink_report_ind
.received_octets
);
297 src_sink_arg
.u
.report
.kbps
= fapi_get_u32(ind
, u
.debug_pkt_sink_report_ind
.kbps
);
298 src_sink_arg
.u
.report
.idle_ratio
= fapi_get_u16(ind
, u
.debug_pkt_sink_report_ind
.idle_ratio
);
299 src_sink_arg
.u
.report
.interrupt_latency
= fapi_get_u16(ind
, u
.debug_pkt_sink_report_ind
.int_latency
);
300 src_sink_arg
.u
.report
.free_kbytes
= fapi_get_u16(ind
, u
.debug_pkt_sink_report_ind
.free_kbytes
);
301 src_sink_arg
.u
.report
.timestamp
= jiffies_to_msecs(jiffies
);
303 memset(&ndev_vif
->src_sink_params
.sink_report
, 0, sizeof(struct unifiio_src_sink_report
));
305 /* copy the report to userspace */
306 if (copy_to_user((void *)arg
, (void *)(&src_sink_arg
), sizeof(struct unifiio_src_sink_arg_t
)))
310 case SRC_SINK_ACTION_GEN_REPORT
:
311 req
= fapi_alloc(debug_pkt_gen_report_req
, DEBUG_PKT_GEN_REPORT_REQ
, src_sink_arg
.common
.vif
, 0);
316 fapi_set_u16(req
, u
.debug_pkt_gen_report_req
.end_point
, src_sink_arg
.common
.endpoint
);
317 fapi_set_u16(req
, u
.debug_pkt_gen_report_req
.direction
, src_sink_arg
.common
.direction
);
318 fapi_set_u32(req
, u
.debug_pkt_gen_report_req
.report_interval
, src_sink_arg
.u
.report
.interval
);
319 SLSI_DBG1(sdev
, SLSI_SRC_SINK
, "debug_pkt_gen_report_req->\n");
321 ind
= slsi_mlme_req_ind(sdev
, dev
, req
, DEBUG_PKT_GEN_REPORT_IND
);
323 SLSI_ERR(sdev
, "slsi_mlme_req_ind [GEN_REPORT] failed\n");
328 src_sink_arg
.u
.report
.duration
= fapi_get_u32(ind
, u
.debug_pkt_gen_report_ind
.duration
);
329 src_sink_arg
.u
.report
.count
= fapi_get_u32(ind
, u
.debug_pkt_gen_report_ind
.received_packets
);
330 src_sink_arg
.u
.report
.failed_count
= fapi_get_u32(ind
, u
.debug_pkt_gen_report_ind
.failed_count
);
331 src_sink_arg
.u
.report
.octet
= fapi_get_u32(ind
, u
.debug_pkt_gen_report_ind
.received_octets
);
332 src_sink_arg
.u
.report
.kbps
= fapi_get_u32(ind
, u
.debug_pkt_gen_report_ind
.kbps
);
333 src_sink_arg
.u
.report
.idle_ratio
= fapi_get_u16(ind
, u
.debug_pkt_gen_report_ind
.idle_ratio
);
334 src_sink_arg
.u
.report
.interrupt_latency
= fapi_get_u16(ind
, u
.debug_pkt_gen_report_ind
.int_latency
);
335 src_sink_arg
.u
.report
.free_kbytes
= fapi_get_u16(ind
, u
.debug_pkt_gen_report_ind
.free_kbytes
);
337 src_sink_arg
.u
.report
.timestamp
= jiffies_to_msecs(jiffies
);
339 memset(&ndev_vif
->src_sink_params
.gen_report
, 0, sizeof(struct unifiio_src_sink_report
));
341 /* copy the report to userspace */
342 if (copy_to_user((void *)arg
, (void *)(&src_sink_arg
), sizeof(struct unifiio_src_sink_arg_t
)))
346 case SRC_SINK_ACTION_SINK_REPORT_CACHED
:
347 SLSI_DBG1(sdev
, SLSI_SRC_SINK
, "cached sink_report\n");
348 memcpy(&src_sink_arg
.u
.report
, &ndev_vif
->src_sink_params
.sink_report
, sizeof(struct unifiio_src_sink_report
));
349 memset(&ndev_vif
->src_sink_params
.sink_report
, 0, sizeof(struct unifiio_src_sink_report
));
351 if (copy_to_user((void *)arg
, (void *)(&src_sink_arg
), sizeof(struct unifiio_src_sink_arg_t
)))
355 case SRC_SINK_ACTION_GEN_REPORT_CACHED
:
356 SLSI_DBG1(sdev
, SLSI_SRC_SINK
, "cached gen_report\n");
357 memcpy(&src_sink_arg
.u
.report
, &ndev_vif
->src_sink_params
.gen_report
, sizeof(struct unifiio_src_sink_report
));
358 memset(&ndev_vif
->src_sink_params
.gen_report
, 0, sizeof(struct unifiio_src_sink_report
));
360 if (copy_to_user((void *)arg
, (void *)(&src_sink_arg
), sizeof(struct unifiio_src_sink_arg_t
)))
364 SLSI_ERR(sdev
, "Invalid input for action: 0x%04X\n", src_sink_arg
.common
.action
);
370 SLSI_MUTEX_UNLOCK(sdev
->netdev_add_remove_mutex
);
372 SLSI_ERR(sdev
, "slsi_src_sink_cdev_ioctl_cfg(vif:%d) failed with %ld\n", src_sink_arg
.common
.vif
, r
);
376 void slsi_rx_sink_report(struct slsi_dev
*sdev
, struct net_device
*dev
, struct sk_buff
*skb
)
378 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
379 struct unifiio_src_sink_report
*report
= &ndev_vif
->src_sink_params
.sink_report
;
381 SLSI_DBG3(sdev
, SLSI_SRC_SINK
, "RX debug_pkt_sink_report_ind\n");
383 SLSI_MUTEX_LOCK(sdev
->netdev_add_remove_mutex
);
384 memset(report
, 0, sizeof(struct unifiio_src_sink_report
));
385 report
->duration
= fapi_get_u32(skb
, u
.debug_pkt_sink_report_ind
.duration
);
386 report
->count
= fapi_get_u32(skb
, u
.debug_pkt_sink_report_ind
.received_packets
);
387 report
->octet
= fapi_get_u32(skb
, u
.debug_pkt_sink_report_ind
.received_octets
);
388 report
->kbps
= fapi_get_u32(skb
, u
.debug_pkt_sink_report_ind
.kbps
);
389 report
->idle_ratio
= fapi_get_u16(skb
, u
.debug_pkt_sink_report_ind
.idle_ratio
);
390 report
->interrupt_latency
= fapi_get_u16(skb
, u
.debug_pkt_sink_report_ind
.int_latency
);
391 report
->free_kbytes
= fapi_get_u16(skb
, u
.debug_pkt_sink_report_ind
.free_kbytes
);
392 report
->timestamp
= jiffies_to_msecs(jiffies
);
393 SLSI_MUTEX_UNLOCK(sdev
->netdev_add_remove_mutex
);
397 void slsi_rx_gen_report(struct slsi_dev
*sdev
, struct net_device
*dev
, struct sk_buff
*skb
)
399 struct netdev_vif
*ndev_vif
= netdev_priv(dev
);
400 struct unifiio_src_sink_report
*report
= &ndev_vif
->src_sink_params
.gen_report
;
402 SLSI_DBG3(sdev
, SLSI_SRC_SINK
, "RX debug_pkt_gen_report_ind\n");
404 SLSI_MUTEX_LOCK(sdev
->netdev_add_remove_mutex
);
405 memset(report
, 0, sizeof(struct unifiio_src_sink_report
));
406 report
->duration
= fapi_get_u32(skb
, u
.debug_pkt_gen_report_ind
.duration
);
407 report
->count
= fapi_get_u32(skb
, u
.debug_pkt_gen_report_ind
.received_packets
);
408 report
->failed_count
= fapi_get_u32(skb
, u
.debug_pkt_gen_report_ind
.failed_count
);
409 report
->octet
= fapi_get_u32(skb
, u
.debug_pkt_gen_report_ind
.received_octets
);
410 report
->kbps
= fapi_get_u32(skb
, u
.debug_pkt_gen_report_ind
.kbps
);
411 report
->idle_ratio
= fapi_get_u16(skb
, u
.debug_pkt_gen_report_ind
.idle_ratio
);
412 report
->interrupt_latency
= fapi_get_u16(skb
, u
.debug_pkt_gen_report_ind
.int_latency
);
413 report
->free_kbytes
= fapi_get_u16(skb
, u
.debug_pkt_gen_report_ind
.free_kbytes
);
414 report
->timestamp
= jiffies_to_msecs(jiffies
);
415 SLSI_MUTEX_UNLOCK(sdev
->netdev_add_remove_mutex
);