diff options
Diffstat (limited to 'drivers/uwb/drp-ie.c')
-rw-r--r-- | drivers/uwb/drp-ie.c | 161 |
1 files changed, 123 insertions, 38 deletions
diff --git a/drivers/uwb/drp-ie.c b/drivers/uwb/drp-ie.c index 882724c5f126..2840d7bf9e67 100644 --- a/drivers/uwb/drp-ie.c +++ b/drivers/uwb/drp-ie.c | |||
@@ -16,13 +16,102 @@ | |||
16 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 17 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
18 | */ | 18 | */ |
19 | #include <linux/version.h> | ||
20 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
21 | #include <linux/random.h> | 20 | #include <linux/random.h> |
22 | #include <linux/uwb.h> | 21 | #include <linux/uwb.h> |
23 | 22 | ||
24 | #include "uwb-internal.h" | 23 | #include "uwb-internal.h" |
25 | 24 | ||
25 | |||
26 | /* | ||
27 | * Return the reason code for a reservations's DRP IE. | ||
28 | */ | ||
29 | int uwb_rsv_reason_code(struct uwb_rsv *rsv) | ||
30 | { | ||
31 | static const int reason_codes[] = { | ||
32 | [UWB_RSV_STATE_O_INITIATED] = UWB_DRP_REASON_ACCEPTED, | ||
33 | [UWB_RSV_STATE_O_PENDING] = UWB_DRP_REASON_ACCEPTED, | ||
34 | [UWB_RSV_STATE_O_MODIFIED] = UWB_DRP_REASON_MODIFIED, | ||
35 | [UWB_RSV_STATE_O_ESTABLISHED] = UWB_DRP_REASON_ACCEPTED, | ||
36 | [UWB_RSV_STATE_O_TO_BE_MOVED] = UWB_DRP_REASON_ACCEPTED, | ||
37 | [UWB_RSV_STATE_O_MOVE_COMBINING] = UWB_DRP_REASON_MODIFIED, | ||
38 | [UWB_RSV_STATE_O_MOVE_REDUCING] = UWB_DRP_REASON_MODIFIED, | ||
39 | [UWB_RSV_STATE_O_MOVE_EXPANDING] = UWB_DRP_REASON_ACCEPTED, | ||
40 | [UWB_RSV_STATE_T_ACCEPTED] = UWB_DRP_REASON_ACCEPTED, | ||
41 | [UWB_RSV_STATE_T_CONFLICT] = UWB_DRP_REASON_CONFLICT, | ||
42 | [UWB_RSV_STATE_T_PENDING] = UWB_DRP_REASON_PENDING, | ||
43 | [UWB_RSV_STATE_T_DENIED] = UWB_DRP_REASON_DENIED, | ||
44 | [UWB_RSV_STATE_T_RESIZED] = UWB_DRP_REASON_ACCEPTED, | ||
45 | [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = UWB_DRP_REASON_ACCEPTED, | ||
46 | [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = UWB_DRP_REASON_CONFLICT, | ||
47 | [UWB_RSV_STATE_T_EXPANDING_PENDING] = UWB_DRP_REASON_PENDING, | ||
48 | [UWB_RSV_STATE_T_EXPANDING_DENIED] = UWB_DRP_REASON_DENIED, | ||
49 | }; | ||
50 | |||
51 | return reason_codes[rsv->state]; | ||
52 | } | ||
53 | |||
54 | /* | ||
55 | * Return the reason code for a reservations's companion DRP IE . | ||
56 | */ | ||
57 | int uwb_rsv_companion_reason_code(struct uwb_rsv *rsv) | ||
58 | { | ||
59 | static const int companion_reason_codes[] = { | ||
60 | [UWB_RSV_STATE_O_MOVE_EXPANDING] = UWB_DRP_REASON_ACCEPTED, | ||
61 | [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = UWB_DRP_REASON_ACCEPTED, | ||
62 | [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = UWB_DRP_REASON_CONFLICT, | ||
63 | [UWB_RSV_STATE_T_EXPANDING_PENDING] = UWB_DRP_REASON_PENDING, | ||
64 | [UWB_RSV_STATE_T_EXPANDING_DENIED] = UWB_DRP_REASON_DENIED, | ||
65 | }; | ||
66 | |||
67 | return companion_reason_codes[rsv->state]; | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | * Return the status bit for a reservations's DRP IE. | ||
72 | */ | ||
73 | int uwb_rsv_status(struct uwb_rsv *rsv) | ||
74 | { | ||
75 | static const int statuses[] = { | ||
76 | [UWB_RSV_STATE_O_INITIATED] = 0, | ||
77 | [UWB_RSV_STATE_O_PENDING] = 0, | ||
78 | [UWB_RSV_STATE_O_MODIFIED] = 1, | ||
79 | [UWB_RSV_STATE_O_ESTABLISHED] = 1, | ||
80 | [UWB_RSV_STATE_O_TO_BE_MOVED] = 0, | ||
81 | [UWB_RSV_STATE_O_MOVE_COMBINING] = 1, | ||
82 | [UWB_RSV_STATE_O_MOVE_REDUCING] = 1, | ||
83 | [UWB_RSV_STATE_O_MOVE_EXPANDING] = 1, | ||
84 | [UWB_RSV_STATE_T_ACCEPTED] = 1, | ||
85 | [UWB_RSV_STATE_T_CONFLICT] = 0, | ||
86 | [UWB_RSV_STATE_T_PENDING] = 0, | ||
87 | [UWB_RSV_STATE_T_DENIED] = 0, | ||
88 | [UWB_RSV_STATE_T_RESIZED] = 1, | ||
89 | [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = 1, | ||
90 | [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = 1, | ||
91 | [UWB_RSV_STATE_T_EXPANDING_PENDING] = 1, | ||
92 | [UWB_RSV_STATE_T_EXPANDING_DENIED] = 1, | ||
93 | |||
94 | }; | ||
95 | |||
96 | return statuses[rsv->state]; | ||
97 | } | ||
98 | |||
99 | /* | ||
100 | * Return the status bit for a reservations's companion DRP IE . | ||
101 | */ | ||
102 | int uwb_rsv_companion_status(struct uwb_rsv *rsv) | ||
103 | { | ||
104 | static const int companion_statuses[] = { | ||
105 | [UWB_RSV_STATE_O_MOVE_EXPANDING] = 0, | ||
106 | [UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = 1, | ||
107 | [UWB_RSV_STATE_T_EXPANDING_CONFLICT] = 0, | ||
108 | [UWB_RSV_STATE_T_EXPANDING_PENDING] = 0, | ||
109 | [UWB_RSV_STATE_T_EXPANDING_DENIED] = 0, | ||
110 | }; | ||
111 | |||
112 | return companion_statuses[rsv->state]; | ||
113 | } | ||
114 | |||
26 | /* | 115 | /* |
27 | * Allocate a DRP IE. | 116 | * Allocate a DRP IE. |
28 | * | 117 | * |
@@ -34,16 +123,12 @@ | |||
34 | static struct uwb_ie_drp *uwb_drp_ie_alloc(void) | 123 | static struct uwb_ie_drp *uwb_drp_ie_alloc(void) |
35 | { | 124 | { |
36 | struct uwb_ie_drp *drp_ie; | 125 | struct uwb_ie_drp *drp_ie; |
37 | unsigned tiebreaker; | ||
38 | 126 | ||
39 | drp_ie = kzalloc(sizeof(struct uwb_ie_drp) + | 127 | drp_ie = kzalloc(sizeof(struct uwb_ie_drp) + |
40 | UWB_NUM_ZONES * sizeof(struct uwb_drp_alloc), | 128 | UWB_NUM_ZONES * sizeof(struct uwb_drp_alloc), |
41 | GFP_KERNEL); | 129 | GFP_KERNEL); |
42 | if (drp_ie) { | 130 | if (drp_ie) { |
43 | drp_ie->hdr.element_id = UWB_IE_DRP; | 131 | drp_ie->hdr.element_id = UWB_IE_DRP; |
44 | |||
45 | get_random_bytes(&tiebreaker, sizeof(unsigned)); | ||
46 | uwb_ie_drp_set_tiebreaker(drp_ie, tiebreaker & 1); | ||
47 | } | 132 | } |
48 | return drp_ie; | 133 | return drp_ie; |
49 | } | 134 | } |
@@ -104,43 +189,17 @@ static void uwb_drp_ie_from_bm(struct uwb_ie_drp *drp_ie, | |||
104 | */ | 189 | */ |
105 | int uwb_drp_ie_update(struct uwb_rsv *rsv) | 190 | int uwb_drp_ie_update(struct uwb_rsv *rsv) |
106 | { | 191 | { |
107 | struct device *dev = &rsv->rc->uwb_dev.dev; | ||
108 | struct uwb_ie_drp *drp_ie; | 192 | struct uwb_ie_drp *drp_ie; |
109 | int reason_code, status; | 193 | struct uwb_rsv_move *mv; |
194 | int unsafe; | ||
110 | 195 | ||
111 | switch (rsv->state) { | 196 | if (rsv->state == UWB_RSV_STATE_NONE) { |
112 | case UWB_RSV_STATE_NONE: | ||
113 | kfree(rsv->drp_ie); | 197 | kfree(rsv->drp_ie); |
114 | rsv->drp_ie = NULL; | 198 | rsv->drp_ie = NULL; |
115 | return 0; | 199 | return 0; |
116 | case UWB_RSV_STATE_O_INITIATED: | ||
117 | reason_code = UWB_DRP_REASON_ACCEPTED; | ||
118 | status = 0; | ||
119 | break; | ||
120 | case UWB_RSV_STATE_O_PENDING: | ||
121 | reason_code = UWB_DRP_REASON_ACCEPTED; | ||
122 | status = 0; | ||
123 | break; | ||
124 | case UWB_RSV_STATE_O_MODIFIED: | ||
125 | reason_code = UWB_DRP_REASON_MODIFIED; | ||
126 | status = 1; | ||
127 | break; | ||
128 | case UWB_RSV_STATE_O_ESTABLISHED: | ||
129 | reason_code = UWB_DRP_REASON_ACCEPTED; | ||
130 | status = 1; | ||
131 | break; | ||
132 | case UWB_RSV_STATE_T_ACCEPTED: | ||
133 | reason_code = UWB_DRP_REASON_ACCEPTED; | ||
134 | status = 1; | ||
135 | break; | ||
136 | case UWB_RSV_STATE_T_DENIED: | ||
137 | reason_code = UWB_DRP_REASON_DENIED; | ||
138 | status = 0; | ||
139 | break; | ||
140 | default: | ||
141 | dev_dbg(dev, "rsv with unhandled state (%d)\n", rsv->state); | ||
142 | return -EINVAL; | ||
143 | } | 200 | } |
201 | |||
202 | unsafe = rsv->mas.unsafe ? 1 : 0; | ||
144 | 203 | ||
145 | if (rsv->drp_ie == NULL) { | 204 | if (rsv->drp_ie == NULL) { |
146 | rsv->drp_ie = uwb_drp_ie_alloc(); | 205 | rsv->drp_ie = uwb_drp_ie_alloc(); |
@@ -149,9 +208,11 @@ int uwb_drp_ie_update(struct uwb_rsv *rsv) | |||
149 | } | 208 | } |
150 | drp_ie = rsv->drp_ie; | 209 | drp_ie = rsv->drp_ie; |
151 | 210 | ||
211 | uwb_ie_drp_set_unsafe(drp_ie, unsafe); | ||
212 | uwb_ie_drp_set_tiebreaker(drp_ie, rsv->tiebreaker); | ||
152 | uwb_ie_drp_set_owner(drp_ie, uwb_rsv_is_owner(rsv)); | 213 | uwb_ie_drp_set_owner(drp_ie, uwb_rsv_is_owner(rsv)); |
153 | uwb_ie_drp_set_status(drp_ie, status); | 214 | uwb_ie_drp_set_status(drp_ie, uwb_rsv_status(rsv)); |
154 | uwb_ie_drp_set_reason_code(drp_ie, reason_code); | 215 | uwb_ie_drp_set_reason_code(drp_ie, uwb_rsv_reason_code(rsv)); |
155 | uwb_ie_drp_set_stream_index(drp_ie, rsv->stream); | 216 | uwb_ie_drp_set_stream_index(drp_ie, rsv->stream); |
156 | uwb_ie_drp_set_type(drp_ie, rsv->type); | 217 | uwb_ie_drp_set_type(drp_ie, rsv->type); |
157 | 218 | ||
@@ -169,6 +230,27 @@ int uwb_drp_ie_update(struct uwb_rsv *rsv) | |||
169 | 230 | ||
170 | uwb_drp_ie_from_bm(drp_ie, &rsv->mas); | 231 | uwb_drp_ie_from_bm(drp_ie, &rsv->mas); |
171 | 232 | ||
233 | if (uwb_rsv_has_two_drp_ies(rsv)) { | ||
234 | mv = &rsv->mv; | ||
235 | if (mv->companion_drp_ie == NULL) { | ||
236 | mv->companion_drp_ie = uwb_drp_ie_alloc(); | ||
237 | if (mv->companion_drp_ie == NULL) | ||
238 | return -ENOMEM; | ||
239 | } | ||
240 | drp_ie = mv->companion_drp_ie; | ||
241 | |||
242 | /* keep all the same configuration of the main drp_ie */ | ||
243 | memcpy(drp_ie, rsv->drp_ie, sizeof(struct uwb_ie_drp)); | ||
244 | |||
245 | |||
246 | /* FIXME: handle properly the unsafe bit */ | ||
247 | uwb_ie_drp_set_unsafe(drp_ie, 1); | ||
248 | uwb_ie_drp_set_status(drp_ie, uwb_rsv_companion_status(rsv)); | ||
249 | uwb_ie_drp_set_reason_code(drp_ie, uwb_rsv_companion_reason_code(rsv)); | ||
250 | |||
251 | uwb_drp_ie_from_bm(drp_ie, &mv->companion_mas); | ||
252 | } | ||
253 | |||
172 | rsv->ie_valid = true; | 254 | rsv->ie_valid = true; |
173 | return 0; | 255 | return 0; |
174 | } | 256 | } |
@@ -219,6 +301,8 @@ void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie) | |||
219 | u8 zone; | 301 | u8 zone; |
220 | u16 zone_mask; | 302 | u16 zone_mask; |
221 | 303 | ||
304 | bitmap_zero(bm->bm, UWB_NUM_MAS); | ||
305 | |||
222 | for (cnt = 0; cnt < numallocs; cnt++) { | 306 | for (cnt = 0; cnt < numallocs; cnt++) { |
223 | alloc = &drp_ie->allocs[cnt]; | 307 | alloc = &drp_ie->allocs[cnt]; |
224 | zone_bm = le16_to_cpu(alloc->zone_bm); | 308 | zone_bm = le16_to_cpu(alloc->zone_bm); |
@@ -230,3 +314,4 @@ void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie) | |||
230 | } | 314 | } |
231 | } | 315 | } |
232 | } | 316 | } |
317 | |||