23 #include <linux/slab.h>
58 static void uwb_rc_set_drp_cmd_done(
struct uwb_rc *
rc,
void *
arg,
113 num_bytes += rsv->
drp_ie->hdr.length + 2;
115 (rsv->
mv.companion_drp_ie !=
NULL)) {
122 cmd = kzalloc(
sizeof(*cmd) + num_bytes,
GFP_KERNEL);
139 rsv->
drp_ie->hdr.length + 2);
140 IEDataptr += rsv->
drp_ie->hdr.length + 2;
143 (rsv->
mv.companion_drp_ie !=
NULL)) {
154 uwb_rc_set_drp_cmd_done,
NULL);
168 static int evaluate_conflict_action(
struct uwb_ie_drp *ext_drp_ie,
int ext_beacon_slot,
172 int our_type = rsv->
type;
173 int our_beacon_slot = rsv->
rc->uwb_dev.beacon_slot;
175 int ext_tie_breaker = uwb_ie_drp_tiebreaker(ext_drp_ie);
176 int ext_status = uwb_ie_drp_status(ext_drp_ie);
177 int ext_type = uwb_ie_drp_type(ext_drp_ie);
197 if (our_status == 0 && ext_status == 1) {
202 if (our_status == 1 && ext_status == 0) {
207 if (our_tie_breaker == ext_tie_breaker &&
208 our_beacon_slot < ext_beacon_slot) {
213 if (our_tie_breaker != ext_tie_breaker &&
214 our_beacon_slot > ext_beacon_slot) {
218 if (our_status == 0) {
219 if (our_tie_breaker == ext_tie_breaker) {
221 if (our_beacon_slot > ext_beacon_slot) {
226 if (our_beacon_slot < ext_beacon_slot) {
231 if (our_tie_breaker == ext_tie_breaker) {
233 if (our_beacon_slot > ext_beacon_slot) {
238 if (our_beacon_slot < ext_beacon_slot) {
246 static void handle_conflict_normal(
struct uwb_ie_drp *drp_ie,
256 action = evaluate_conflict_action(drp_ie, ext_beacon_slot, rsv,
uwb_rsv_status(rsv));
258 if (uwb_rsv_is_owner(rsv)) {
289 static void handle_conflict_expanding(
struct uwb_ie_drp *drp_ie,
int ext_beacon_slot,
290 struct uwb_rsv *rsv,
bool companion_only,
298 if (companion_only) {
300 action = evaluate_conflict_action(drp_ie, ext_beacon_slot, rsv, 0);
301 if (uwb_rsv_is_owner(rsv)) {
320 if (uwb_rsv_is_owner(rsv)) {
337 static void uwb_drp_handle_conflict_rsv(
struct uwb_rc *rc,
struct uwb_rsv *rsv,
347 if (bitmap_intersects(rsv->
mas.bm, conflicting_mas->bm,
UWB_NUM_MAS)) {
349 rsv,
false, conflicting_mas);
353 rsv,
true, conflicting_mas);
356 }
else if (bitmap_intersects(rsv->
mas.bm, conflicting_mas->bm,
UWB_NUM_MAS)) {
361 static void uwb_drp_handle_all_conflict_rsv(
struct uwb_rc *rc,
369 uwb_drp_handle_conflict_rsv(rc, rsv, drp_evt, drp_ie, conflicting_mas);
377 static void uwb_drp_process_target(
struct uwb_rc *rc,
struct uwb_rsv *rsv,
386 status = uwb_ie_drp_status(drp_ie);
387 reason_code = uwb_ie_drp_reason_code(drp_ie);
390 switch (reason_code) {
411 uwb_drp_handle_all_conflict_rsv(rc, drp_evt, drp_ie, &mas);
444 dev_warn(dev,
"ignoring invalid DRP IE state (%d/%d)\n",
445 reason_code, status);
453 static void uwb_drp_process_owner(
struct uwb_rc *rc,
struct uwb_rsv *rsv,
463 status = uwb_ie_drp_status(drp_ie);
464 reason_code = uwb_ie_drp_reason_code(drp_ie);
468 switch (reason_code) {
470 switch (rsv->
state) {
510 dev_warn(dev,
"ignoring invalid DRP IE state (%d/%d)\n",
511 reason_code, status);
514 switch (reason_code) {
523 bitmap_complement(mas.bm, src->last_availability_bm,
525 uwb_drp_handle_conflict_rsv(rc, rsv, drp_evt, drp_ie, &mas);
528 dev_warn(dev,
"ignoring invalid DRP IE state (%d/%d)\n",
529 reason_code, status);
534 static void uwb_cnflt_alien_stroke_timer(
struct uwb_cnflt_alien *cnflt)
567 static void uwb_cnflt_timer(
unsigned long arg)
578 static void uwb_drp_handle_alien_drp(
struct uwb_rc *rc,
struct uwb_ie_drp *drp_ie)
593 uwb_cnflt_alien_stroke_timer(cnflt);
603 dev_err(dev,
"failed to alloc uwb_cnflt_alien struct\n");
604 INIT_LIST_HEAD(&cnflt->
rc_node);
606 cnflt->
timer.function = uwb_cnflt_timer;
607 cnflt->
timer.data = (
unsigned long)cnflt;
622 uwb_cnflt_alien_stroke_timer(cnflt);
625 static void uwb_drp_process_not_involved(
struct uwb_rc *rc,
632 uwb_drp_handle_all_conflict_rsv(rc, drp_evt, drp_ie, &mas);
635 static void uwb_drp_process_involved(
struct uwb_rc *rc,
struct uwb_dev *src,
660 if (uwb_ie_drp_owner(drp_ie))
661 uwb_drp_process_target(rc, rsv, drp_ie, drp_evt);
663 uwb_drp_process_owner(rc, rsv, src, drp_ie, drp_evt);
668 static bool uwb_drp_involves_us(
struct uwb_rc *rc,
struct uwb_ie_drp *drp_ie)
670 return uwb_dev_addr_cmp(&rc->
uwb_dev.dev_addr, &drp_ie->
dev_addr) == 0;
680 uwb_drp_handle_alien_drp(rc, drp_ie);
681 else if (uwb_drp_involves_us(rc, drp_ie))
682 uwb_drp_process_involved(rc, src, drp_evt, drp_ie);
684 uwb_drp_process_not_involved(rc, drp_evt, drp_ie);
690 static void uwb_drp_availability_process(
struct uwb_rc *rc,
struct uwb_dev *src,
693 bitmap_copy(src->last_availability_bm,
703 size_t ielen,
struct uwb_dev *src_dev)
717 uwb_drp_availability_process(rc, src_dev, (
struct uwb_ie_drp_avail *)ie_hdr);
720 uwb_drp_process(rc, drp_evt, src_dev, (
struct uwb_ie_drp *)ie_hdr);
723 dev_warn(dev,
"unexpected IE in DRP notification\n");
729 dev_warn(dev,
"%d octets remaining in DRP notification\n",
767 struct device *dev = &evt->
rc->uwb_dev.dev;
770 size_t ielength, bytes_left;
776 if (evt->
notif.size <
sizeof(*drp_evt)) {
777 dev_err(dev,
"DRP event: Not enough data to decode event "
778 "[%zu bytes left, %zu needed]\n",
779 evt->
notif.size,
sizeof(*drp_evt));
782 bytes_left = evt->
notif.size -
sizeof(*drp_evt);
785 if (bytes_left != ielength) {
786 dev_err(dev,
"DRP event: Not enough data in payload [%zu"
787 "bytes left, %zu declared in the event]\n",
788 bytes_left, ielength);
809 uwb_drp_process_all(rc, drp_evt, ielength, src_dev);
813 uwb_dev_put(src_dev);