blob: fec5661401b0673c29ee56460d6a136ba157fbb0 [file] [log] [blame]
Ravi Joshi1c2cfb62017-01-18 14:40:08 -08001/*
2 * Copyright (c) 2017 The Linux Foundation. All rights reserved.
3 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
Ravi Joshi106ffe02017-01-18 18:09:05 -080027#include "wlan_hdd_includes.h"
28#include <linux/netdevice.h>
29#include <linux/skbuff.h>
30#include <linux/etherdevice.h>
31#include <linux/if_ether.h>
32#include <cds_sched.h>
33#include <cds_utils.h>
Ravi Joshi1c2cfb62017-01-18 14:40:08 -080034#include "wlan_hdd_rx_monitor.h"
Ravi Joshi106ffe02017-01-18 18:09:05 -080035
36/**
37 * hdd_rx_monitor_callback(): Callback function for receive monitor mode
38 * @vdev: Handle to vdev object
39 * @mpdu: pointer to mpdu to be delivered to os
40 * @rx_status: receive status
41 *
42 * Returns: None
43 */
44void hdd_rx_monitor_callback(ol_osif_vdev_handle context,
45 qdf_nbuf_t rxbuf,
46 void *rx_status)
47{
Jeff Johnson215e34e2017-08-29 14:24:00 -070048 struct hdd_adapter *adapter;
Ravi Joshi106ffe02017-01-18 18:09:05 -080049 int rxstat;
50 struct sk_buff *skb;
51 struct sk_buff *skb_next;
52 unsigned int cpu_index;
53
54 qdf_assert(context);
55 qdf_assert(rxbuf);
56
Jeff Johnson215e34e2017-08-29 14:24:00 -070057 adapter = (struct hdd_adapter *)context;
Ravi Joshi106ffe02017-01-18 18:09:05 -080058 if (WLAN_HDD_ADAPTER_MAGIC != adapter->magic) {
59 QDF_TRACE(QDF_MODULE_ID_HDD_DATA, QDF_TRACE_LEVEL_ERROR,
60 "invalid adapter %p", adapter);
61 return;
62 }
63
64 cpu_index = wlan_hdd_get_cpu();
65
66 /* walk the chain until all are processed */
67 skb = (struct sk_buff *)rxbuf;
68 while (NULL != skb) {
69 skb_next = skb->next;
70 skb->dev = adapter->dev;
71
72 ++adapter->hdd_stats.hddTxRxStats.rxPackets[cpu_index];
73 ++adapter->stats.rx_packets;
74 adapter->stats.rx_bytes += skb->len;
75
76 /* Remove SKB from internal tracking table before submitting
77 * it to stack
78 */
79 qdf_net_buf_debug_release_skb(skb);
80
81 /*
82 * If this is not a last packet on the chain
83 * Just put packet into backlog queue, not scheduling RX sirq
84 */
85 if (skb->next) {
86 rxstat = netif_rx(skb);
87 } else {
88 /*
89 * This is the last packet on the chain
90 * Scheduling rx sirq
91 */
92 rxstat = netif_rx_ni(skb);
93 }
94
95 if (NET_RX_SUCCESS == rxstat)
96 ++adapter->
97 hdd_stats.hddTxRxStats.rxDelivered[cpu_index];
98 else
99 ++adapter->hdd_stats.hddTxRxStats.rxRefused[cpu_index];
100
101 skb = skb_next;
102 }
103
Ravi Joshi106ffe02017-01-18 18:09:05 -0800104 return;
105}
106
107/**
108 * hdd_monitor_set_rx_monitor_cb(): Set rx monitor mode callback function
109 * @txrx: pointer to txrx ops
110 * @rx_monitor_cb: pointer to callback function
111 *
112 * Returns: None
113 */
114void hdd_monitor_set_rx_monitor_cb(struct ol_txrx_ops *txrx,
115 ol_txrx_rx_mon_fp rx_monitor_cb)
116{
117 txrx->rx.mon = rx_monitor_cb;
118}
Ravi Joshi4f095952017-06-29 15:39:19 -0700119
120/**
121 * hdd_enable_monitor_mode() - Enable monitor mode
122 * @dev: Pointer to the net_device structure
123 *
124 * This function invokes cdp interface API to enable
125 * monitor mode configuration on the hardware. In this
126 * case sends HTT messages to FW to setup hardware rings
127 *
128 * Return: 0 for success; non-zero for failure
129 */
130int hdd_enable_monitor_mode(struct net_device *dev)
131{
132 void *soc = cds_get_context(QDF_MODULE_ID_SOC);
133 void *pdev = cds_get_context(QDF_MODULE_ID_TXRX);
Jeff Johnson215e34e2017-08-29 14:24:00 -0700134 struct hdd_adapter *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
Ravi Joshi4f095952017-06-29 15:39:19 -0700135
136 ENTER_DEV(dev);
137
138 return cdp_set_monitor_mode(soc,
139 (struct cdp_vdev *)cdp_get_vdev_from_vdev_id(soc,
140 (struct cdp_pdev *)pdev, adapter->sessionId), false);
141}