a185b82795c4aae7cb782b6d6ce56fe633a898ce
[linux-2.6-microblaze.git] / drivers / staging / wfx / wfx.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Common private data for Silicon Labs WFx chips.
4  *
5  * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
6  * Copyright (c) 2010, ST-Ericsson
7  * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
8  * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
9  */
10 #ifndef WFX_H
11 #define WFX_H
12
13 #include <linux/nospec.h>
14 #include <net/mac80211.h>
15
16 #include "bh.h"
17 #include "data_tx.h"
18 #include "main.h"
19 #include "queue.h"
20 #include "hif_tx.h"
21
22 #define USEC_PER_TXOP 32 // see struct ieee80211_tx_queue_params
23 #define USEC_PER_TU 1024
24
25 struct hwbus_ops;
26
27 struct wfx_dev {
28         struct wfx_platform_data pdata;
29         struct device           *dev;
30         struct ieee80211_hw     *hw;
31         struct ieee80211_vif    *vif[2];
32         struct mac_address      addresses[2];
33         const struct hwbus_ops  *hwbus_ops;
34         void                    *hwbus_priv;
35
36         u8                      keyset;
37         struct completion       firmware_ready;
38         struct hif_ind_startup  hw_caps;
39         struct wfx_hif          hif;
40         struct delayed_work     cooling_timeout_work;
41         bool                    poll_irq;
42         bool                    chip_frozen;
43         struct mutex            conf_mutex;
44
45         struct wfx_hif_cmd      hif_cmd;
46         struct sk_buff_head     tx_pending;
47         wait_queue_head_t       tx_dequeue;
48         atomic_t                tx_lock;
49
50         atomic_t                packet_id;
51         u32                     key_map;
52
53         struct hif_rx_stats     rx_stats;
54         struct mutex            rx_stats_lock;
55         struct hif_tx_power_loop_info tx_power_loop_info;
56         struct mutex            tx_power_loop_info_lock;
57         int                     force_ps_timeout;
58 };
59
60 struct wfx_vif {
61         struct wfx_dev          *wdev;
62         struct ieee80211_vif    *vif;
63         struct ieee80211_channel *channel;
64         int                     id;
65
66         u32                     link_id_map;
67
68         bool                    after_dtim_tx_allowed;
69         bool                    join_in_progress;
70
71         struct delayed_work     beacon_loss_work;
72
73         struct wfx_queue        tx_queue[4];
74         struct tx_policy_cache  tx_policy_cache;
75         struct work_struct      tx_policy_upload_work;
76
77         struct work_struct      update_tim_work;
78
79         unsigned long           uapsd_mask;
80
81         /* avoid some operations in parallel with scan */
82         struct mutex            scan_lock;
83         struct work_struct      scan_work;
84         struct completion       scan_complete;
85         bool                    scan_abort;
86         struct ieee80211_scan_request *scan_req;
87
88         struct completion       set_pm_mode_complete;
89 };
90
91 static inline struct wfx_vif *wdev_to_wvif(struct wfx_dev *wdev, int vif_id)
92 {
93         if (vif_id >= ARRAY_SIZE(wdev->vif)) {
94                 dev_dbg(wdev->dev, "requesting non-existent vif: %d\n", vif_id);
95                 return NULL;
96         }
97         vif_id = array_index_nospec(vif_id, ARRAY_SIZE(wdev->vif));
98         if (!wdev->vif[vif_id]) {
99                 dev_dbg(wdev->dev, "requesting non-allocated vif: %d\n",
100                         vif_id);
101                 return NULL;
102         }
103         return (struct wfx_vif *) wdev->vif[vif_id]->drv_priv;
104 }
105
106 static inline struct wfx_vif *wvif_iterate(struct wfx_dev *wdev,
107                                            struct wfx_vif *cur)
108 {
109         int i;
110         int mark = 0;
111         struct wfx_vif *tmp;
112
113         if (!cur)
114                 mark = 1;
115         for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
116                 tmp = wdev_to_wvif(wdev, i);
117                 if (mark && tmp)
118                         return tmp;
119                 if (tmp == cur)
120                         mark = 1;
121         }
122         return NULL;
123 }
124
125 static inline int wvif_count(struct wfx_dev *wdev)
126 {
127         int i;
128         int ret = 0;
129         struct wfx_vif *wvif;
130
131         for (i = 0; i < ARRAY_SIZE(wdev->vif); i++) {
132                 wvif = wdev_to_wvif(wdev, i);
133                 if (wvif)
134                         ret++;
135         }
136         return ret;
137 }
138
139 static inline void memreverse(u8 *src, u8 length)
140 {
141         u8 *lo = src;
142         u8 *hi = src + length - 1;
143         u8 swap;
144
145         while (lo < hi) {
146                 swap = *lo;
147                 *lo++ = *hi;
148                 *hi-- = swap;
149         }
150 }
151
152 static inline int memzcmp(void *src, unsigned int size)
153 {
154         u8 *buf = src;
155
156         if (!size)
157                 return 0;
158         if (*buf)
159                 return 1;
160         return memcmp(buf, buf + 1, size - 1);
161 }
162
163 #endif /* WFX_H */