mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-22 14:52:34 +00:00
uwb: improved MAS allocator and reservation conflict handling
Greatly enhance the MAS allocator: - Handle row and column reservations. - Permit all the available MAS to be allocated. - Follows the WiMedia rules on MAS selection. Take appropriate action when reservation conflicts are detected. - Correctly identify which reservation wins the conflict. - Protect alien BP reservations. - If an owned reservation loses, resize/move it. - Follow the backoff procedure before requesting additional MAS. When reservations are terminated, move the remaining reservations (if necessary) so they keep following the MAS allocation rules. Signed-off-by: Stefano Panella <stefano.panella@csr.com> Signed-off-by: David Vrabel <david.vrabel@csr.com>
This commit is contained in:
parent
c35fa3ea1a
commit
5b37717a23
12 changed files with 1605 additions and 329 deletions
|
@ -22,6 +22,96 @@
|
|||
|
||||
#include "uwb-internal.h"
|
||||
|
||||
|
||||
/*
|
||||
* Return the reason code for a reservations's DRP IE.
|
||||
*/
|
||||
int uwb_rsv_reason_code(struct uwb_rsv *rsv)
|
||||
{
|
||||
static const int reason_codes[] = {
|
||||
[UWB_RSV_STATE_O_INITIATED] = UWB_DRP_REASON_ACCEPTED,
|
||||
[UWB_RSV_STATE_O_PENDING] = UWB_DRP_REASON_ACCEPTED,
|
||||
[UWB_RSV_STATE_O_MODIFIED] = UWB_DRP_REASON_MODIFIED,
|
||||
[UWB_RSV_STATE_O_ESTABLISHED] = UWB_DRP_REASON_ACCEPTED,
|
||||
[UWB_RSV_STATE_O_TO_BE_MOVED] = UWB_DRP_REASON_ACCEPTED,
|
||||
[UWB_RSV_STATE_O_MOVE_COMBINING] = UWB_DRP_REASON_MODIFIED,
|
||||
[UWB_RSV_STATE_O_MOVE_REDUCING] = UWB_DRP_REASON_MODIFIED,
|
||||
[UWB_RSV_STATE_O_MOVE_EXPANDING] = UWB_DRP_REASON_ACCEPTED,
|
||||
[UWB_RSV_STATE_T_ACCEPTED] = UWB_DRP_REASON_ACCEPTED,
|
||||
[UWB_RSV_STATE_T_CONFLICT] = UWB_DRP_REASON_CONFLICT,
|
||||
[UWB_RSV_STATE_T_PENDING] = UWB_DRP_REASON_PENDING,
|
||||
[UWB_RSV_STATE_T_DENIED] = UWB_DRP_REASON_DENIED,
|
||||
[UWB_RSV_STATE_T_RESIZED] = UWB_DRP_REASON_ACCEPTED,
|
||||
[UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = UWB_DRP_REASON_ACCEPTED,
|
||||
[UWB_RSV_STATE_T_EXPANDING_CONFLICT] = UWB_DRP_REASON_CONFLICT,
|
||||
[UWB_RSV_STATE_T_EXPANDING_PENDING] = UWB_DRP_REASON_PENDING,
|
||||
[UWB_RSV_STATE_T_EXPANDING_DENIED] = UWB_DRP_REASON_DENIED,
|
||||
};
|
||||
|
||||
return reason_codes[rsv->state];
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the reason code for a reservations's companion DRP IE .
|
||||
*/
|
||||
int uwb_rsv_companion_reason_code(struct uwb_rsv *rsv)
|
||||
{
|
||||
static const int companion_reason_codes[] = {
|
||||
[UWB_RSV_STATE_O_MOVE_EXPANDING] = UWB_DRP_REASON_ACCEPTED,
|
||||
[UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = UWB_DRP_REASON_ACCEPTED,
|
||||
[UWB_RSV_STATE_T_EXPANDING_CONFLICT] = UWB_DRP_REASON_CONFLICT,
|
||||
[UWB_RSV_STATE_T_EXPANDING_PENDING] = UWB_DRP_REASON_PENDING,
|
||||
[UWB_RSV_STATE_T_EXPANDING_DENIED] = UWB_DRP_REASON_DENIED,
|
||||
};
|
||||
|
||||
return companion_reason_codes[rsv->state];
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the status bit for a reservations's DRP IE.
|
||||
*/
|
||||
int uwb_rsv_status(struct uwb_rsv *rsv)
|
||||
{
|
||||
static const int statuses[] = {
|
||||
[UWB_RSV_STATE_O_INITIATED] = 0,
|
||||
[UWB_RSV_STATE_O_PENDING] = 0,
|
||||
[UWB_RSV_STATE_O_MODIFIED] = 1,
|
||||
[UWB_RSV_STATE_O_ESTABLISHED] = 1,
|
||||
[UWB_RSV_STATE_O_TO_BE_MOVED] = 0,
|
||||
[UWB_RSV_STATE_O_MOVE_COMBINING] = 1,
|
||||
[UWB_RSV_STATE_O_MOVE_REDUCING] = 1,
|
||||
[UWB_RSV_STATE_O_MOVE_EXPANDING] = 1,
|
||||
[UWB_RSV_STATE_T_ACCEPTED] = 1,
|
||||
[UWB_RSV_STATE_T_CONFLICT] = 0,
|
||||
[UWB_RSV_STATE_T_PENDING] = 0,
|
||||
[UWB_RSV_STATE_T_DENIED] = 0,
|
||||
[UWB_RSV_STATE_T_RESIZED] = 1,
|
||||
[UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = 1,
|
||||
[UWB_RSV_STATE_T_EXPANDING_CONFLICT] = 1,
|
||||
[UWB_RSV_STATE_T_EXPANDING_PENDING] = 1,
|
||||
[UWB_RSV_STATE_T_EXPANDING_DENIED] = 1,
|
||||
|
||||
};
|
||||
|
||||
return statuses[rsv->state];
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the status bit for a reservations's companion DRP IE .
|
||||
*/
|
||||
int uwb_rsv_companion_status(struct uwb_rsv *rsv)
|
||||
{
|
||||
static const int companion_statuses[] = {
|
||||
[UWB_RSV_STATE_O_MOVE_EXPANDING] = 0,
|
||||
[UWB_RSV_STATE_T_EXPANDING_ACCEPTED] = 1,
|
||||
[UWB_RSV_STATE_T_EXPANDING_CONFLICT] = 0,
|
||||
[UWB_RSV_STATE_T_EXPANDING_PENDING] = 0,
|
||||
[UWB_RSV_STATE_T_EXPANDING_DENIED] = 0,
|
||||
};
|
||||
|
||||
return companion_statuses[rsv->state];
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a DRP IE.
|
||||
*
|
||||
|
@ -33,16 +123,12 @@
|
|||
static struct uwb_ie_drp *uwb_drp_ie_alloc(void)
|
||||
{
|
||||
struct uwb_ie_drp *drp_ie;
|
||||
unsigned tiebreaker;
|
||||
|
||||
drp_ie = kzalloc(sizeof(struct uwb_ie_drp) +
|
||||
UWB_NUM_ZONES * sizeof(struct uwb_drp_alloc),
|
||||
GFP_KERNEL);
|
||||
if (drp_ie) {
|
||||
drp_ie->hdr.element_id = UWB_IE_DRP;
|
||||
|
||||
get_random_bytes(&tiebreaker, sizeof(unsigned));
|
||||
uwb_ie_drp_set_tiebreaker(drp_ie, tiebreaker & 1);
|
||||
}
|
||||
return drp_ie;
|
||||
}
|
||||
|
@ -103,43 +189,17 @@ static void uwb_drp_ie_from_bm(struct uwb_ie_drp *drp_ie,
|
|||
*/
|
||||
int uwb_drp_ie_update(struct uwb_rsv *rsv)
|
||||
{
|
||||
struct device *dev = &rsv->rc->uwb_dev.dev;
|
||||
struct uwb_ie_drp *drp_ie;
|
||||
int reason_code, status;
|
||||
struct uwb_rsv_move *mv;
|
||||
int unsafe;
|
||||
|
||||
switch (rsv->state) {
|
||||
case UWB_RSV_STATE_NONE:
|
||||
if (rsv->state == UWB_RSV_STATE_NONE) {
|
||||
kfree(rsv->drp_ie);
|
||||
rsv->drp_ie = NULL;
|
||||
return 0;
|
||||
case UWB_RSV_STATE_O_INITIATED:
|
||||
reason_code = UWB_DRP_REASON_ACCEPTED;
|
||||
status = 0;
|
||||
break;
|
||||
case UWB_RSV_STATE_O_PENDING:
|
||||
reason_code = UWB_DRP_REASON_ACCEPTED;
|
||||
status = 0;
|
||||
break;
|
||||
case UWB_RSV_STATE_O_MODIFIED:
|
||||
reason_code = UWB_DRP_REASON_MODIFIED;
|
||||
status = 1;
|
||||
break;
|
||||
case UWB_RSV_STATE_O_ESTABLISHED:
|
||||
reason_code = UWB_DRP_REASON_ACCEPTED;
|
||||
status = 1;
|
||||
break;
|
||||
case UWB_RSV_STATE_T_ACCEPTED:
|
||||
reason_code = UWB_DRP_REASON_ACCEPTED;
|
||||
status = 1;
|
||||
break;
|
||||
case UWB_RSV_STATE_T_DENIED:
|
||||
reason_code = UWB_DRP_REASON_DENIED;
|
||||
status = 0;
|
||||
break;
|
||||
default:
|
||||
dev_dbg(dev, "rsv with unhandled state (%d)\n", rsv->state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
unsafe = rsv->mas.unsafe ? 1 : 0;
|
||||
|
||||
if (rsv->drp_ie == NULL) {
|
||||
rsv->drp_ie = uwb_drp_ie_alloc();
|
||||
|
@ -148,9 +208,11 @@ int uwb_drp_ie_update(struct uwb_rsv *rsv)
|
|||
}
|
||||
drp_ie = rsv->drp_ie;
|
||||
|
||||
uwb_ie_drp_set_unsafe(drp_ie, unsafe);
|
||||
uwb_ie_drp_set_tiebreaker(drp_ie, rsv->tiebreaker);
|
||||
uwb_ie_drp_set_owner(drp_ie, uwb_rsv_is_owner(rsv));
|
||||
uwb_ie_drp_set_status(drp_ie, status);
|
||||
uwb_ie_drp_set_reason_code(drp_ie, reason_code);
|
||||
uwb_ie_drp_set_status(drp_ie, uwb_rsv_status(rsv));
|
||||
uwb_ie_drp_set_reason_code(drp_ie, uwb_rsv_reason_code(rsv));
|
||||
uwb_ie_drp_set_stream_index(drp_ie, rsv->stream);
|
||||
uwb_ie_drp_set_type(drp_ie, rsv->type);
|
||||
|
||||
|
@ -168,6 +230,27 @@ int uwb_drp_ie_update(struct uwb_rsv *rsv)
|
|||
|
||||
uwb_drp_ie_from_bm(drp_ie, &rsv->mas);
|
||||
|
||||
if (uwb_rsv_has_two_drp_ies(rsv)) {
|
||||
mv = &rsv->mv;
|
||||
if (mv->companion_drp_ie == NULL) {
|
||||
mv->companion_drp_ie = uwb_drp_ie_alloc();
|
||||
if (mv->companion_drp_ie == NULL)
|
||||
return -ENOMEM;
|
||||
}
|
||||
drp_ie = mv->companion_drp_ie;
|
||||
|
||||
/* keep all the same configuration of the main drp_ie */
|
||||
memcpy(drp_ie, rsv->drp_ie, sizeof(struct uwb_ie_drp));
|
||||
|
||||
|
||||
/* FIXME: handle properly the unsafe bit */
|
||||
uwb_ie_drp_set_unsafe(drp_ie, 1);
|
||||
uwb_ie_drp_set_status(drp_ie, uwb_rsv_companion_status(rsv));
|
||||
uwb_ie_drp_set_reason_code(drp_ie, uwb_rsv_companion_reason_code(rsv));
|
||||
|
||||
uwb_drp_ie_from_bm(drp_ie, &mv->companion_mas);
|
||||
}
|
||||
|
||||
rsv->ie_valid = true;
|
||||
return 0;
|
||||
}
|
||||
|
@ -218,6 +301,8 @@ void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie)
|
|||
u8 zone;
|
||||
u16 zone_mask;
|
||||
|
||||
bitmap_zero(bm->bm, UWB_NUM_MAS);
|
||||
|
||||
for (cnt = 0; cnt < numallocs; cnt++) {
|
||||
alloc = &drp_ie->allocs[cnt];
|
||||
zone_bm = le16_to_cpu(alloc->zone_bm);
|
||||
|
@ -229,3 +314,4 @@ void uwb_drp_ie_to_bm(struct uwb_mas_bm *bm, const struct uwb_ie_drp *drp_ie)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue