reservation.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * WUSB cluster reservation management
  4. *
  5. * Copyright (C) 2007 Cambridge Silicon Radio Ltd.
  6. */
  7. #include <linux/kernel.h>
  8. #include <linux/uwb.h>
  9. #include "wusbhc.h"
  10. /*
  11. * WUSB cluster reservations are multicast reservations with the
  12. * broadcast cluster ID (BCID) as the target DevAddr.
  13. *
  14. * FIXME: consider adjusting the reservation depending on what devices
  15. * are attached.
  16. */
  17. static int wusbhc_bwa_set(struct wusbhc *wusbhc, u8 stream,
  18. const struct uwb_mas_bm *mas)
  19. {
  20. if (mas == NULL)
  21. mas = &uwb_mas_bm_zero;
  22. return wusbhc->bwa_set(wusbhc, stream, mas);
  23. }
  24. /**
  25. * wusbhc_rsv_complete_cb - WUSB HC reservation complete callback
  26. * @rsv: the reservation
  27. *
  28. * Either set or clear the HC's view of the reservation.
  29. *
  30. * FIXME: when a reservation is denied the HC should be stopped.
  31. */
  32. static void wusbhc_rsv_complete_cb(struct uwb_rsv *rsv)
  33. {
  34. struct wusbhc *wusbhc = rsv->pal_priv;
  35. struct device *dev = wusbhc->dev;
  36. struct uwb_mas_bm mas;
  37. dev_dbg(dev, "%s: state = %d\n", __func__, rsv->state);
  38. switch (rsv->state) {
  39. case UWB_RSV_STATE_O_ESTABLISHED:
  40. uwb_rsv_get_usable_mas(rsv, &mas);
  41. dev_dbg(dev, "established reservation: %*pb\n",
  42. UWB_NUM_MAS, mas.bm);
  43. wusbhc_bwa_set(wusbhc, rsv->stream, &mas);
  44. break;
  45. case UWB_RSV_STATE_NONE:
  46. dev_dbg(dev, "removed reservation\n");
  47. wusbhc_bwa_set(wusbhc, 0, NULL);
  48. break;
  49. default:
  50. dev_dbg(dev, "unexpected reservation state: %d\n", rsv->state);
  51. break;
  52. }
  53. }
  54. /**
  55. * wusbhc_rsv_establish - establish a reservation for the cluster
  56. * @wusbhc: the WUSB HC requesting a bandwidth reservation
  57. */
  58. int wusbhc_rsv_establish(struct wusbhc *wusbhc)
  59. {
  60. struct uwb_rc *rc = wusbhc->uwb_rc;
  61. struct uwb_rsv *rsv;
  62. struct uwb_dev_addr bcid;
  63. int ret;
  64. if (rc == NULL)
  65. return -ENODEV;
  66. rsv = uwb_rsv_create(rc, wusbhc_rsv_complete_cb, wusbhc);
  67. if (rsv == NULL)
  68. return -ENOMEM;
  69. bcid.data[0] = wusbhc->cluster_id;
  70. bcid.data[1] = 0;
  71. rsv->target.type = UWB_RSV_TARGET_DEVADDR;
  72. rsv->target.devaddr = bcid;
  73. rsv->type = UWB_DRP_TYPE_PRIVATE;
  74. rsv->max_mas = 256; /* try to get as much as possible */
  75. rsv->min_mas = 15; /* one MAS per zone */
  76. rsv->max_interval = 1; /* max latency is one zone */
  77. rsv->is_multicast = true;
  78. ret = uwb_rsv_establish(rsv);
  79. if (ret == 0)
  80. wusbhc->rsv = rsv;
  81. else
  82. uwb_rsv_destroy(rsv);
  83. return ret;
  84. }
  85. /**
  86. * wusbhc_rsv_terminate - terminate the cluster reservation
  87. * @wusbhc: the WUSB host whose reservation is to be terminated
  88. */
  89. void wusbhc_rsv_terminate(struct wusbhc *wusbhc)
  90. {
  91. if (wusbhc->rsv) {
  92. uwb_rsv_terminate(wusbhc->rsv);
  93. uwb_rsv_destroy(wusbhc->rsv);
  94. wusbhc->rsv = NULL;
  95. }
  96. }