2017-11-03 13:28:30 +03:00
// SPDX-License-Identifier: GPL-2.0
2008-09-17 19:34:23 +04:00
/*
* WUSB cluster reservation management
*
* Copyright ( C ) 2007 Cambridge Silicon Radio Ltd .
*/
# include <linux/kernel.h>
# include <linux/uwb.h>
# include "wusbhc.h"
/*
* WUSB cluster reservations are multicast reservations with the
* broadcast cluster ID ( BCID ) as the target DevAddr .
*
* FIXME : consider adjusting the reservation depending on what devices
* are attached .
*/
static int wusbhc_bwa_set ( struct wusbhc * wusbhc , u8 stream ,
const struct uwb_mas_bm * mas )
{
if ( mas = = NULL )
mas = & uwb_mas_bm_zero ;
return wusbhc - > bwa_set ( wusbhc , stream , mas ) ;
}
/**
* wusbhc_rsv_complete_cb - WUSB HC reservation complete callback
* @ rsv : the reservation
*
* Either set or clear the HC ' s view of the reservation .
*
* FIXME : when a reservation is denied the HC should be stopped .
*/
static void wusbhc_rsv_complete_cb ( struct uwb_rsv * rsv )
{
struct wusbhc * wusbhc = rsv - > pal_priv ;
struct device * dev = wusbhc - > dev ;
2008-12-12 16:00:06 +03:00
struct uwb_mas_bm mas ;
2008-09-17 19:34:23 +04:00
2013-12-20 21:45:02 +04:00
dev_dbg ( dev , " %s: state = %d \n " , __func__ , rsv - > state ) ;
2008-09-17 19:34:23 +04:00
switch ( rsv - > state ) {
case UWB_RSV_STATE_O_ESTABLISHED :
2008-12-12 16:00:06 +03:00
uwb_rsv_get_usable_mas ( rsv , & mas ) ;
2015-02-14 01:37:53 +03:00
dev_dbg ( dev , " established reservation: %*pb \n " ,
UWB_NUM_MAS , mas . bm ) ;
2008-12-12 16:00:06 +03:00
wusbhc_bwa_set ( wusbhc , rsv - > stream , & mas ) ;
2008-09-17 19:34:23 +04:00
break ;
case UWB_RSV_STATE_NONE :
dev_dbg ( dev , " removed reservation \n " ) ;
wusbhc_bwa_set ( wusbhc , 0 , NULL ) ;
break ;
default :
dev_dbg ( dev , " unexpected reservation state: %d \n " , rsv - > state ) ;
break ;
}
}
/**
* wusbhc_rsv_establish - establish a reservation for the cluster
2011-03-31 05:57:33 +04:00
* @ wusbhc : the WUSB HC requesting a bandwidth reservation
2008-09-17 19:34:23 +04:00
*/
int wusbhc_rsv_establish ( struct wusbhc * wusbhc )
{
struct uwb_rc * rc = wusbhc - > uwb_rc ;
struct uwb_rsv * rsv ;
struct uwb_dev_addr bcid ;
int ret ;
2013-06-24 23:26:35 +04:00
if ( rc = = NULL )
return - ENODEV ;
2008-09-17 19:34:23 +04:00
rsv = uwb_rsv_create ( rc , wusbhc_rsv_complete_cb , wusbhc ) ;
if ( rsv = = NULL )
return - ENOMEM ;
bcid . data [ 0 ] = wusbhc - > cluster_id ;
bcid . data [ 1 ] = 0 ;
rsv - > target . type = UWB_RSV_TARGET_DEVADDR ;
rsv - > target . devaddr = bcid ;
rsv - > type = UWB_DRP_TYPE_PRIVATE ;
2008-12-12 16:00:06 +03:00
rsv - > max_mas = 256 ; /* try to get as much as possible */
rsv - > min_mas = 15 ; /* one MAS per zone */
rsv - > max_interval = 1 ; /* max latency is one zone */
2008-09-17 19:34:23 +04:00
rsv - > is_multicast = true ;
ret = uwb_rsv_establish ( rsv ) ;
if ( ret = = 0 )
wusbhc - > rsv = rsv ;
else
uwb_rsv_destroy ( rsv ) ;
return ret ;
}
/**
2008-10-27 18:22:46 +03:00
* wusbhc_rsv_terminate - terminate the cluster reservation
2008-09-17 19:34:23 +04:00
* @ wusbhc : the WUSB host whose reservation is to be terminated
*/
void wusbhc_rsv_terminate ( struct wusbhc * wusbhc )
{
2008-12-12 16:25:21 +03:00
if ( wusbhc - > rsv ) {
uwb_rsv_terminate ( wusbhc - > rsv ) ;
uwb_rsv_destroy ( wusbhc - > rsv ) ;
wusbhc - > rsv = NULL ;
}
2008-09-17 19:34:23 +04:00
}