···11+/*22+ * Ultra Wide Band33+ * UWB API44+ *55+ * Copyright (C) 2005-2006 Intel Corporation66+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>77+ *88+ * This program is free software; you can redistribute it and/or99+ * modify it under the terms of the GNU General Public License version1010+ * 2 as published by the Free Software Foundation.1111+ *1212+ * This program is distributed in the hope that it will be useful,1313+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1414+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1515+ * GNU General Public License for more details.1616+ *1717+ * You should have received a copy of the GNU General Public License1818+ * along with this program; if not, write to the Free Software1919+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA2020+ * 02110-1301, USA.2121+ *2222+ *2323+ * FIXME: doc: overview of the API, different parts and pointers2424+ */2525+2626+#ifndef __LINUX__UWB_H__2727+#define __LINUX__UWB_H__2828+2929+#include <linux/limits.h>3030+#include <linux/device.h>3131+#include <linux/mutex.h>3232+#include <linux/timer.h>3333+#include <linux/workqueue.h>3434+#include <linux/uwb/spec.h>3535+3636+struct uwb_dev;3737+struct uwb_beca_e;3838+struct uwb_rc;3939+struct uwb_rsv;4040+struct uwb_dbg;4141+4242+/**4343+ * struct uwb_dev - a UWB Device4444+ * @rc: UWB Radio Controller that discovered the device (kind of its4545+ * parent).4646+ * @bce: a beacon cache entry for this device; or NULL if the device4747+ * is a local radio controller.4848+ * @mac_addr: the EUI-48 address of this device.4949+ * @dev_addr: the current DevAddr used by this device.5050+ * @beacon_slot: the slot number the beacon is using.5151+ * @streams: bitmap of streams allocated to reservations targeted at5252+ * this device. For an RC, this is the streams allocated for5353+ * reservations targeted at DevAddrs.5454+ *5555+ * A UWB device may either by a neighbor or part of a local radio5656+ * controller.5757+ */5858+struct uwb_dev {5959+ struct mutex mutex;6060+ struct list_head list_node;6161+ struct device dev;6262+ struct uwb_rc *rc; /* radio controller */6363+ struct uwb_beca_e *bce; /* Beacon Cache Entry */6464+6565+ struct uwb_mac_addr mac_addr;6666+ struct uwb_dev_addr dev_addr;6767+ int beacon_slot;6868+ DECLARE_BITMAP(streams, UWB_NUM_STREAMS);6969+};7070+#define to_uwb_dev(d) container_of(d, struct uwb_dev, dev)7171+7272+/**7373+ * UWB HWA/WHCI Radio Control {Command|Event} Block context IDs7474+ *7575+ * RC[CE]Bs have a 'context ID' field that matches the command with7676+ * the event received to confirm it.7777+ *7878+ * Maximum number of context IDs7979+ */8080+enum { UWB_RC_CTX_MAX = 256 };8181+8282+8383+/** Notification chain head for UWB generated events to listeners */8484+struct uwb_notifs_chain {8585+ struct list_head list;8686+ struct mutex mutex;8787+};8888+8989+/**9090+ * struct uwb_mas_bm - a bitmap of all MAS in a superframe9191+ * @bm: a bitmap of length #UWB_NUM_MAS9292+ */9393+struct uwb_mas_bm {9494+ DECLARE_BITMAP(bm, UWB_NUM_MAS);9595+};9696+9797+/**9898+ * uwb_rsv_state - UWB Reservation state.9999+ *100100+ * NONE - reservation is not active (no DRP IE being transmitted).101101+ *102102+ * Owner reservation states:103103+ *104104+ * INITIATED - owner has sent an initial DRP request.105105+ * PENDING - target responded with pending Reason Code.106106+ * MODIFIED - reservation manager is modifying an established107107+ * reservation with a different MAS allocation.108108+ * ESTABLISHED - the reservation has been successfully negotiated.109109+ *110110+ * Target reservation states:111111+ *112112+ * DENIED - request is denied.113113+ * ACCEPTED - request is accepted.114114+ * PENDING - PAL has yet to make a decision to whether to accept or115115+ * deny.116116+ *117117+ * FIXME: further target states TBD.118118+ */119119+enum uwb_rsv_state {120120+ UWB_RSV_STATE_NONE,121121+ UWB_RSV_STATE_O_INITIATED,122122+ UWB_RSV_STATE_O_PENDING,123123+ UWB_RSV_STATE_O_MODIFIED,124124+ UWB_RSV_STATE_O_ESTABLISHED,125125+ UWB_RSV_STATE_T_ACCEPTED,126126+ UWB_RSV_STATE_T_DENIED,127127+ UWB_RSV_STATE_T_PENDING,128128+129129+ UWB_RSV_STATE_LAST,130130+};131131+132132+enum uwb_rsv_target_type {133133+ UWB_RSV_TARGET_DEV,134134+ UWB_RSV_TARGET_DEVADDR,135135+};136136+137137+/**138138+ * struct uwb_rsv_target - the target of a reservation.139139+ *140140+ * Reservations unicast and targeted at a single device141141+ * (UWB_RSV_TARGET_DEV); or (e.g., in the case of WUSB) targeted at a142142+ * specific (private) DevAddr (UWB_RSV_TARGET_DEVADDR).143143+ */144144+struct uwb_rsv_target {145145+ enum uwb_rsv_target_type type;146146+ union {147147+ struct uwb_dev *dev;148148+ struct uwb_dev_addr devaddr;149149+ };150150+};151151+152152+/*153153+ * Number of streams reserved for reservations targeted at DevAddrs.154154+ */155155+#define UWB_NUM_GLOBAL_STREAMS 1156156+157157+typedef void (*uwb_rsv_cb_f)(struct uwb_rsv *rsv);158158+159159+/**160160+ * struct uwb_rsv - a DRP reservation161161+ *162162+ * Data structure management:163163+ *164164+ * @rc: the radio controller this reservation is for165165+ * (as target or owner)166166+ * @rc_node: a list node for the RC167167+ * @pal_node: a list node for the PAL168168+ *169169+ * Owner and target parameters:170170+ *171171+ * @owner: the UWB device owning this reservation172172+ * @target: the target UWB device173173+ * @type: reservation type174174+ *175175+ * Owner parameters:176176+ *177177+ * @max_mas: maxiumum number of MAS178178+ * @min_mas: minimum number of MAS179179+ * @sparsity: owner selected sparsity180180+ * @is_multicast: true iff multicast181181+ *182182+ * @callback: callback function when the reservation completes183183+ * @pal_priv: private data for the PAL making the reservation184184+ *185185+ * Reservation status:186186+ *187187+ * @status: negotiation status188188+ * @stream: stream index allocated for this reservation189189+ * @mas: reserved MAS190190+ * @drp_ie: the DRP IE191191+ * @ie_valid: true iff the DRP IE matches the reservation parameters192192+ *193193+ * DRP reservations are uniquely identified by the owner, target and194194+ * stream index. However, when using a DevAddr as a target (e.g., for195195+ * a WUSB cluster reservation) the responses may be received from196196+ * devices with different DevAddrs. In this case, reservations are197197+ * uniquely identified by just the stream index. A number of stream198198+ * indexes (UWB_NUM_GLOBAL_STREAMS) are reserved for this.199199+ */200200+struct uwb_rsv {201201+ struct uwb_rc *rc;202202+ struct list_head rc_node;203203+ struct list_head pal_node;204204+205205+ struct uwb_dev *owner;206206+ struct uwb_rsv_target target;207207+ enum uwb_drp_type type;208208+ int max_mas;209209+ int min_mas;210210+ int sparsity;211211+ bool is_multicast;212212+213213+ uwb_rsv_cb_f callback;214214+ void *pal_priv;215215+216216+ enum uwb_rsv_state state;217217+ u8 stream;218218+ struct uwb_mas_bm mas;219219+ struct uwb_ie_drp *drp_ie;220220+ bool ie_valid;221221+ struct timer_list timer;222222+ bool expired;223223+};224224+225225+static const226226+struct uwb_mas_bm uwb_mas_bm_zero = { .bm = { 0 } };227227+228228+static inline void uwb_mas_bm_copy_le(void *dst, const struct uwb_mas_bm *mas)229229+{230230+ bitmap_copy_le(dst, mas->bm, UWB_NUM_MAS);231231+}232232+233233+/**234234+ * struct uwb_drp_avail - a radio controller's view of MAS usage235235+ * @global: MAS unused by neighbors (excluding reservations targetted236236+ * or owned by the local radio controller) or the beaon period237237+ * @local: MAS unused by local established reservations238238+ * @pending: MAS unused by local pending reservations239239+ * @ie: DRP Availability IE to be included in the beacon240240+ * @ie_valid: true iff @ie is valid and does not need to regenerated from241241+ * @global and @local242242+ *243243+ * Each radio controller maintains a view of MAS usage or244244+ * availability. MAS available for a new reservation are determined245245+ * from the intersection of @global, @local, and @pending.246246+ *247247+ * The radio controller must transmit a DRP Availability IE that's the248248+ * intersection of @global and @local.249249+ *250250+ * A set bit indicates the MAS is unused and available.251251+ *252252+ * rc->rsvs_mutex should be held before accessing this data structure.253253+ *254254+ * [ECMA-368] section 17.4.3.255255+ */256256+struct uwb_drp_avail {257257+ DECLARE_BITMAP(global, UWB_NUM_MAS);258258+ DECLARE_BITMAP(local, UWB_NUM_MAS);259259+ DECLARE_BITMAP(pending, UWB_NUM_MAS);260260+ struct uwb_ie_drp_avail ie;261261+ bool ie_valid;262262+};263263+264264+265265+const char *uwb_rsv_state_str(enum uwb_rsv_state state);266266+const char *uwb_rsv_type_str(enum uwb_drp_type type);267267+268268+struct uwb_rsv *uwb_rsv_create(struct uwb_rc *rc, uwb_rsv_cb_f cb,269269+ void *pal_priv);270270+void uwb_rsv_destroy(struct uwb_rsv *rsv);271271+272272+int uwb_rsv_establish(struct uwb_rsv *rsv);273273+int uwb_rsv_modify(struct uwb_rsv *rsv,274274+ int max_mas, int min_mas, int sparsity);275275+void uwb_rsv_terminate(struct uwb_rsv *rsv);276276+277277+void uwb_rsv_accept(struct uwb_rsv *rsv, uwb_rsv_cb_f cb, void *pal_priv);278278+279279+/**280280+ * Radio Control Interface instance281281+ *282282+ *283283+ * Life cycle rules: those of the UWB Device.284284+ *285285+ * @index: an index number for this radio controller, as used in the286286+ * device name.287287+ * @version: version of protocol supported by this device288288+ * @priv: Backend implementation; rw with uwb_dev.dev.sem taken.289289+ * @cmd: Backend implementation to execute commands; rw and call290290+ * only with uwb_dev.dev.sem taken.291291+ * @reset: Hardware reset of radio controller and any PAL controllers.292292+ * @filter: Backend implementation to manipulate data to and from device293293+ * to be compliant to specification assumed by driver (WHCI294294+ * 0.95).295295+ *296296+ * uwb_dev.dev.mutex is used to execute commands and update297297+ * the corresponding structures; can't use a spinlock298298+ * because rc->cmd() can sleep.299299+ * @ies: This is a dynamically allocated array cacheing the300300+ * IEs (settable by the host) that the beacon of this301301+ * radio controller is currently sending.302302+ *303303+ * In reality, we store here the full command we set to304304+ * the radio controller (which is basically a command305305+ * prefix followed by all the IEs the beacon currently306306+ * contains). This way we don't have to realloc and307307+ * memcpy when setting it.308308+ *309309+ * We set this up in uwb_rc_ie_setup(), where we alloc310310+ * this struct, call get_ie() [so we know which IEs are311311+ * currently being sent, if any].312312+ *313313+ * @ies_capacity:Amount of space (in bytes) allocated in @ies. The314314+ * amount used is given by sizeof(*ies) plus ies->wIELength315315+ * (which is a little endian quantity all the time).316316+ * @ies_mutex: protect the IE cache317317+ * @dbg: information for the debug interface318318+ */319319+struct uwb_rc {320320+ struct uwb_dev uwb_dev;321321+ int index;322322+ u16 version;323323+324324+ struct module *owner;325325+ void *priv;326326+ int (*start)(struct uwb_rc *rc);327327+ void (*stop)(struct uwb_rc *rc);328328+ int (*cmd)(struct uwb_rc *, const struct uwb_rccb *, size_t);329329+ int (*reset)(struct uwb_rc *rc);330330+ int (*filter_cmd)(struct uwb_rc *, struct uwb_rccb **, size_t *);331331+ int (*filter_event)(struct uwb_rc *, struct uwb_rceb **, const size_t,332332+ size_t *, size_t *);333333+334334+ spinlock_t neh_lock; /* protects neh_* and ctx_* */335335+ struct list_head neh_list; /* Open NE handles */336336+ unsigned long ctx_bm[UWB_RC_CTX_MAX / 8 / sizeof(unsigned long)];337337+ u8 ctx_roll;338338+339339+ int beaconing; /* Beaconing state [channel number] */340340+ int scanning;341341+ enum uwb_scan_type scan_type:3;342342+ unsigned ready:1;343343+ struct uwb_notifs_chain notifs_chain;344344+345345+ struct uwb_drp_avail drp_avail;346346+ struct list_head reservations;347347+ struct mutex rsvs_mutex;348348+ struct workqueue_struct *rsv_workq;349349+ struct work_struct rsv_update_work;350350+351351+ struct mutex ies_mutex;352352+ struct uwb_rc_cmd_set_ie *ies;353353+ size_t ies_capacity;354354+355355+ spinlock_t pal_lock;356356+ struct list_head pals;357357+358358+ struct uwb_dbg *dbg;359359+};360360+361361+362362+/**363363+ * struct uwb_pal - a UWB PAL364364+ * @new_rsv: called when a peer requests a reservation (may be NULL if365365+ * the PAL cannot accept reservation requests).366366+ *367367+ * A Protocol Adaptation Layer (PAL) is a user of the WiMedia UWB368368+ * radio platform (e.g., WUSB, WLP or Bluetooth UWB AMP).369369+ *370370+ * The PALs using a radio controller must register themselves to371371+ * permit the UWB stack to coordinate usage of the radio between the372372+ * various PALs or to allow PALs to response to certain requests from373373+ * peers.374374+ *375375+ * A struct uwb_pal should be embedded in a containing structure376376+ * belonging to the PAL and initialized with uwb_pal_init()). Fields377377+ * should be set appropriately by the PAL before registering the PAL378378+ * with uwb_pal_register().379379+ */380380+struct uwb_pal {381381+ struct list_head node;382382+383383+ void (*new_rsv)(struct uwb_rsv *rsv);384384+};385385+386386+void uwb_pal_init(struct uwb_pal *pal);387387+int uwb_pal_register(struct uwb_rc *rc, struct uwb_pal *pal);388388+void uwb_pal_unregister(struct uwb_rc *rc, struct uwb_pal *pal);389389+390390+/*391391+ * General public API392392+ *393393+ * This API can be used by UWB device drivers or by those implementing394394+ * UWB Radio Controllers395395+ */396396+struct uwb_dev *uwb_dev_get_by_devaddr(struct uwb_rc *rc,397397+ const struct uwb_dev_addr *devaddr);398398+struct uwb_dev *uwb_dev_get_by_rc(struct uwb_dev *, struct uwb_rc *);399399+static inline void uwb_dev_get(struct uwb_dev *uwb_dev)400400+{401401+ get_device(&uwb_dev->dev);402402+}403403+static inline void uwb_dev_put(struct uwb_dev *uwb_dev)404404+{405405+ put_device(&uwb_dev->dev);406406+}407407+struct uwb_dev *uwb_dev_try_get(struct uwb_rc *rc, struct uwb_dev *uwb_dev);408408+409409+/**410410+ * Callback function for 'uwb_{dev,rc}_foreach()'.411411+ *412412+ * @dev: Linux device instance413413+ * 'uwb_dev = container_of(dev, struct uwb_dev, dev)'414414+ * @priv: Data passed by the caller to 'uwb_{dev,rc}_foreach()'.415415+ *416416+ * @returns: 0 to continue the iterations, any other val to stop417417+ * iterating and return the value to the caller of418418+ * _foreach().419419+ */420420+typedef int (*uwb_dev_for_each_f)(struct device *dev, void *priv);421421+int uwb_dev_for_each(struct uwb_rc *rc, uwb_dev_for_each_f func, void *priv);422422+423423+struct uwb_rc *uwb_rc_alloc(void);424424+struct uwb_rc *uwb_rc_get_by_dev(const struct uwb_dev_addr *);425425+struct uwb_rc *uwb_rc_get_by_grandpa(const struct device *);426426+void uwb_rc_put(struct uwb_rc *rc);427427+428428+typedef void (*uwb_rc_cmd_cb_f)(struct uwb_rc *rc, void *arg,429429+ struct uwb_rceb *reply, ssize_t reply_size);430430+431431+int uwb_rc_cmd_async(struct uwb_rc *rc, const char *cmd_name,432432+ struct uwb_rccb *cmd, size_t cmd_size,433433+ u8 expected_type, u16 expected_event,434434+ uwb_rc_cmd_cb_f cb, void *arg);435435+ssize_t uwb_rc_cmd(struct uwb_rc *rc, const char *cmd_name,436436+ struct uwb_rccb *cmd, size_t cmd_size,437437+ struct uwb_rceb *reply, size_t reply_size);438438+ssize_t uwb_rc_vcmd(struct uwb_rc *rc, const char *cmd_name,439439+ struct uwb_rccb *cmd, size_t cmd_size,440440+ u8 expected_type, u16 expected_event,441441+ struct uwb_rceb **preply);442442+ssize_t uwb_rc_get_ie(struct uwb_rc *, struct uwb_rc_evt_get_ie **);443443+int uwb_bg_joined(struct uwb_rc *rc);444444+445445+size_t __uwb_addr_print(char *, size_t, const unsigned char *, int);446446+447447+int uwb_rc_dev_addr_set(struct uwb_rc *, const struct uwb_dev_addr *);448448+int uwb_rc_dev_addr_get(struct uwb_rc *, struct uwb_dev_addr *);449449+int uwb_rc_mac_addr_set(struct uwb_rc *, const struct uwb_mac_addr *);450450+int uwb_rc_mac_addr_get(struct uwb_rc *, struct uwb_mac_addr *);451451+int __uwb_mac_addr_assigned_check(struct device *, void *);452452+int __uwb_dev_addr_assigned_check(struct device *, void *);453453+454454+/* Print in @buf a pretty repr of @addr */455455+static inline size_t uwb_dev_addr_print(char *buf, size_t buf_size,456456+ const struct uwb_dev_addr *addr)457457+{458458+ return __uwb_addr_print(buf, buf_size, addr->data, 0);459459+}460460+461461+/* Print in @buf a pretty repr of @addr */462462+static inline size_t uwb_mac_addr_print(char *buf, size_t buf_size,463463+ const struct uwb_mac_addr *addr)464464+{465465+ return __uwb_addr_print(buf, buf_size, addr->data, 1);466466+}467467+468468+/* @returns 0 if device addresses @addr2 and @addr1 are equal */469469+static inline int uwb_dev_addr_cmp(const struct uwb_dev_addr *addr1,470470+ const struct uwb_dev_addr *addr2)471471+{472472+ return memcmp(addr1, addr2, sizeof(*addr1));473473+}474474+475475+/* @returns 0 if MAC addresses @addr2 and @addr1 are equal */476476+static inline int uwb_mac_addr_cmp(const struct uwb_mac_addr *addr1,477477+ const struct uwb_mac_addr *addr2)478478+{479479+ return memcmp(addr1, addr2, sizeof(*addr1));480480+}481481+482482+/* @returns !0 if a MAC @addr is a broadcast address */483483+static inline int uwb_mac_addr_bcast(const struct uwb_mac_addr *addr)484484+{485485+ struct uwb_mac_addr bcast = {486486+ .data = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }487487+ };488488+ return !uwb_mac_addr_cmp(addr, &bcast);489489+}490490+491491+/* @returns !0 if a MAC @addr is all zeroes*/492492+static inline int uwb_mac_addr_unset(const struct uwb_mac_addr *addr)493493+{494494+ struct uwb_mac_addr unset = {495495+ .data = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }496496+ };497497+ return !uwb_mac_addr_cmp(addr, &unset);498498+}499499+500500+/* @returns !0 if the address is in use. */501501+static inline unsigned __uwb_dev_addr_assigned(struct uwb_rc *rc,502502+ struct uwb_dev_addr *addr)503503+{504504+ return uwb_dev_for_each(rc, __uwb_dev_addr_assigned_check, addr);505505+}506506+507507+/*508508+ * UWB Radio Controller API509509+ *510510+ * This API is used (in addition to the general API) to implement UWB511511+ * Radio Controllers.512512+ */513513+void uwb_rc_init(struct uwb_rc *);514514+int uwb_rc_add(struct uwb_rc *, struct device *dev, void *rc_priv);515515+void uwb_rc_rm(struct uwb_rc *);516516+void uwb_rc_neh_grok(struct uwb_rc *, void *, size_t);517517+void uwb_rc_neh_error(struct uwb_rc *, int);518518+void uwb_rc_reset_all(struct uwb_rc *rc);519519+520520+/**521521+ * uwb_rsv_is_owner - is the owner of this reservation the RC?522522+ * @rsv: the reservation523523+ */524524+static inline bool uwb_rsv_is_owner(struct uwb_rsv *rsv)525525+{526526+ return rsv->owner == &rsv->rc->uwb_dev;527527+}528528+529529+/**530530+ * Events generated by UWB that can be passed to any listeners531531+ *532532+ * Higher layers can register callback functions with the radio533533+ * controller using uwb_notifs_register(). The radio controller534534+ * maintains a list of all registered handlers and will notify all535535+ * nodes when an event occurs.536536+ */537537+enum uwb_notifs {538538+ UWB_NOTIF_BG_JOIN = 0, /* radio controller joined a beacon group */539539+ UWB_NOTIF_BG_LEAVE = 1, /* radio controller left a beacon group */540540+ UWB_NOTIF_ONAIR,541541+ UWB_NOTIF_OFFAIR,542542+};543543+544544+/* Callback function registered with UWB */545545+struct uwb_notifs_handler {546546+ struct list_head list_node;547547+ void (*cb)(void *, struct uwb_dev *, enum uwb_notifs);548548+ void *data;549549+};550550+551551+int uwb_notifs_register(struct uwb_rc *, struct uwb_notifs_handler *);552552+int uwb_notifs_deregister(struct uwb_rc *, struct uwb_notifs_handler *);553553+554554+555555+/**556556+ * UWB radio controller Event Size Entry (for creating entry tables)557557+ *558558+ * WUSB and WHCI define events and notifications, and they might have559559+ * fixed or variable size.560560+ *561561+ * Each event/notification has a size which is not necessarily known562562+ * in advance based on the event code. As well, vendor specific563563+ * events/notifications will have a size impossible to determine564564+ * unless we know about the device's specific details.565565+ *566566+ * It was way too smart of the spec writers not to think that it would567567+ * be impossible for a generic driver to skip over vendor specific568568+ * events/notifications if there are no LENGTH fields in the HEADER of569569+ * each message...the transaction size cannot be counted on as the570570+ * spec does not forbid to pack more than one event in a single571571+ * transaction.572572+ *573573+ * Thus, we guess sizes with tables (or for events, when you know the574574+ * size ahead of time you can use uwb_rc_neh_extra_size*()). We575575+ * register tables with the known events and their sizes, and then we576576+ * traverse those tables. For those with variable length, we provide a577577+ * way to lookup the size inside the event/notification's578578+ * payload. This allows device-specific event size tables to be579579+ * registered.580580+ *581581+ * @size: Size of the payload582582+ *583583+ * @offset: if != 0, at offset @offset-1 starts a field with a length584584+ * that has to be added to @size. The format of the field is585585+ * given by @type.586586+ *587587+ * @type: Type and length of the offset field. Most common is LE 16588588+ * bits (that's why that is zero); others are there mostly to589589+ * cover for bugs and weirdos.590590+ */591591+struct uwb_est_entry {592592+ size_t size;593593+ unsigned offset;594594+ enum { UWB_EST_16 = 0, UWB_EST_8 = 1 } type;595595+};596596+597597+int uwb_est_register(u8 type, u8 code_high, u16 vendor, u16 product,598598+ const struct uwb_est_entry *, size_t entries);599599+int uwb_est_unregister(u8 type, u8 code_high, u16 vendor, u16 product,600600+ const struct uwb_est_entry *, size_t entries);601601+ssize_t uwb_est_find_size(struct uwb_rc *rc, const struct uwb_rceb *rceb,602602+ size_t len);603603+604604+/* -- Misc */605605+606606+enum {607607+ EDC_MAX_ERRORS = 10,608608+ EDC_ERROR_TIMEFRAME = HZ,609609+};610610+611611+/* error density counter */612612+struct edc {613613+ unsigned long timestart;614614+ u16 errorcount;615615+};616616+617617+static inline618618+void edc_init(struct edc *edc)619619+{620620+ edc->timestart = jiffies;621621+}622622+623623+/* Called when an error occured.624624+ * This is way to determine if the number of acceptable errors per time625625+ * period has been exceeded. It is not accurate as there are cases in which626626+ * this scheme will not work, for example if there are periodic occurences627627+ * of errors that straddle updates to the start time. This scheme is628628+ * sufficient for our usage.629629+ *630630+ * @returns 1 if maximum acceptable errors per timeframe has been exceeded.631631+ */632632+static inline int edc_inc(struct edc *err_hist, u16 max_err, u16 timeframe)633633+{634634+ unsigned long now;635635+636636+ now = jiffies;637637+ if (now - err_hist->timestart > timeframe) {638638+ err_hist->errorcount = 1;639639+ err_hist->timestart = now;640640+ } else if (++err_hist->errorcount > max_err) {641641+ err_hist->errorcount = 0;642642+ err_hist->timestart = now;643643+ return 1;644644+ }645645+ return 0;646646+}647647+648648+649649+/* Information Element handling */650650+651651+/* For representing the state of writing to a buffer when iterating */652652+struct uwb_buf_ctx {653653+ char *buf;654654+ size_t bytes, size;655655+};656656+657657+typedef int (*uwb_ie_f)(struct uwb_dev *, const struct uwb_ie_hdr *,658658+ size_t, void *);659659+struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len);660660+ssize_t uwb_ie_for_each(struct uwb_dev *uwb_dev, uwb_ie_f fn, void *data,661661+ const void *buf, size_t size);662662+int uwb_ie_dump_hex(struct uwb_dev *, const struct uwb_ie_hdr *,663663+ size_t, void *);664664+int uwb_rc_set_ie(struct uwb_rc *, struct uwb_rc_cmd_set_ie *);665665+struct uwb_ie_hdr *uwb_ie_next(void **ptr, size_t *len);666666+667667+668668+/*669669+ * Transmission statistics670670+ *671671+ * UWB uses LQI and RSSI (one byte values) for reporting radio signal672672+ * strength and line quality indication. We do quick and dirty673673+ * averages of those. They are signed values, btw.674674+ *675675+ * For 8 bit quantities, we keep the min, the max, an accumulator676676+ * (@sigma) and a # of samples. When @samples gets to 255, we compute677677+ * the average (@sigma / @samples), place it in @sigma and reset678678+ * @samples to 1 (so we use it as the first sample).679679+ *680680+ * Now, statistically speaking, probably I am kicking the kidneys of681681+ * some books I have in my shelves collecting dust, but I just want to682682+ * get an approx, not the Nobel.683683+ *684684+ * LOCKING: there is no locking per se, but we try to keep a lockless685685+ * schema. Only _add_samples() modifies the values--as long as you686686+ * have other locking on top that makes sure that no two calls of687687+ * _add_sample() happen at the same time, then we are fine. Now, for688688+ * resetting the values we just set @samples to 0 and that makes the689689+ * next _add_sample() to start with defaults. Reading the values in690690+ * _show() currently can race, so you need to make sure the calls are691691+ * under the same lock that protects calls to _add_sample(). FIXME:692692+ * currently unlocked (It is not ultraprecise but does the trick. Bite693693+ * me).694694+ */695695+struct stats {696696+ s8 min, max;697697+ s16 sigma;698698+ atomic_t samples;699699+};700700+701701+static inline702702+void stats_init(struct stats *stats)703703+{704704+ atomic_set(&stats->samples, 0);705705+ wmb();706706+}707707+708708+static inline709709+void stats_add_sample(struct stats *stats, s8 sample)710710+{711711+ s8 min, max;712712+ s16 sigma;713713+ unsigned samples = atomic_read(&stats->samples);714714+ if (samples == 0) { /* it was zero before, so we initialize */715715+ min = 127;716716+ max = -128;717717+ sigma = 0;718718+ } else {719719+ min = stats->min;720720+ max = stats->max;721721+ sigma = stats->sigma;722722+ }723723+724724+ if (sample < min) /* compute new values */725725+ min = sample;726726+ else if (sample > max)727727+ max = sample;728728+ sigma += sample;729729+730730+ stats->min = min; /* commit */731731+ stats->max = max;732732+ stats->sigma = sigma;733733+ if (atomic_add_return(1, &stats->samples) > 255) {734734+ /* wrapped around! reset */735735+ stats->sigma = sigma / 256;736736+ atomic_set(&stats->samples, 1);737737+ }738738+}739739+740740+static inline ssize_t stats_show(struct stats *stats, char *buf)741741+{742742+ int min, max, avg;743743+ int samples = atomic_read(&stats->samples);744744+ if (samples == 0)745745+ min = max = avg = 0;746746+ else {747747+ min = stats->min;748748+ max = stats->max;749749+ avg = stats->sigma / samples;750750+ }751751+ return scnprintf(buf, PAGE_SIZE, "%d %d %d\n", min, max, avg);752752+}753753+754754+static inline ssize_t stats_store(struct stats *stats, const char *buf,755755+ size_t size)756756+{757757+ stats_init(stats);758758+ return size;759759+}760760+761761+#endif /* #ifndef __LINUX__UWB_H__ */
+57
include/linux/uwb/debug-cmd.h
···11+/*22+ * Ultra Wide Band33+ * Debug interface commands44+ *55+ * Copyright (C) 2008 Cambridge Silicon Radio Ltd.66+ *77+ * This program is free software; you can redistribute it and/or88+ * modify it under the terms of the GNU General Public License version99+ * 2 as published by the Free Software Foundation.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ *1616+ * You should have received a copy of the GNU General Public License1717+ * along with this program. If not, see <http://www.gnu.org/licenses/>.1818+ */1919+#ifndef __LINUX__UWB__DEBUG_CMD_H__2020+#define __LINUX__UWB__DEBUG_CMD_H__2121+2222+#include <linux/types.h>2323+2424+/*2525+ * Debug interface commands2626+ *2727+ * UWB_DBG_CMD_RSV_ESTABLISH: Establish a new unicast reservation.2828+ *2929+ * UWB_DBG_CMD_RSV_TERMINATE: Terminate the Nth reservation.3030+ */3131+3232+enum uwb_dbg_cmd_type {3333+ UWB_DBG_CMD_RSV_ESTABLISH = 1,3434+ UWB_DBG_CMD_RSV_TERMINATE = 2,3535+};3636+3737+struct uwb_dbg_cmd_rsv_establish {3838+ __u8 target[6];3939+ __u8 type;4040+ __u16 max_mas;4141+ __u16 min_mas;4242+ __u8 sparsity;4343+};4444+4545+struct uwb_dbg_cmd_rsv_terminate {4646+ int index;4747+};4848+4949+struct uwb_dbg_cmd {5050+ __u32 type;5151+ union {5252+ struct uwb_dbg_cmd_rsv_establish rsv_establish;5353+ struct uwb_dbg_cmd_rsv_terminate rsv_terminate;5454+ };5555+};5656+5757+#endif /* #ifndef __LINUX__UWB__DEBUG_CMD_H__ */
+82
include/linux/uwb/debug.h
···11+/*22+ * Ultra Wide Band33+ * Debug Support44+ *55+ * Copyright (C) 2005-2006 Intel Corporation66+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>77+ *88+ * This program is free software; you can redistribute it and/or99+ * modify it under the terms of the GNU General Public License version1010+ * 2 as published by the Free Software Foundation.1111+ *1212+ * This program is distributed in the hope that it will be useful,1313+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1414+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1515+ * GNU General Public License for more details.1616+ *1717+ * You should have received a copy of the GNU General Public License1818+ * along with this program; if not, write to the Free Software1919+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA2020+ * 02110-1301, USA.2121+ *2222+ *2323+ * FIXME: doc2424+ * Invoke like:2525+ *2626+ * #define D_LOCAL 42727+ * #include <linux/uwb/debug.h>2828+ *2929+ * At the end of your include files.3030+ */3131+#include <linux/types.h>3232+3333+struct device;3434+extern void dump_bytes(struct device *dev, const void *_buf, size_t rsize);3535+3636+/* Master debug switch; !0 enables, 0 disables */3737+#define D_MASTER (!0)3838+3939+/* Local (per-file) debug switch; #define before #including */4040+#ifndef D_LOCAL4141+#define D_LOCAL 04242+#endif4343+4444+#undef __d_printf4545+#undef d_fnstart4646+#undef d_fnend4747+#undef d_printf4848+#undef d_dump4949+5050+#define __d_printf(l, _tag, _dev, f, a...) \5151+do { \5252+ struct device *__dev = (_dev); \5353+ if (D_MASTER && D_LOCAL >= (l)) { \5454+ char __head[64] = ""; \5555+ if (_dev != NULL) { \5656+ if ((unsigned long)__dev < 4096) \5757+ printk(KERN_ERR "E: Corrupt dev %p\n", \5858+ __dev); \5959+ else \6060+ snprintf(__head, sizeof(__head), \6161+ "%s %s: ", \6262+ dev_driver_string(__dev), \6363+ __dev->bus_id); \6464+ } \6565+ printk(KERN_ERR "%s%s" _tag ": " f, __head, \6666+ __func__, ## a); \6767+ } \6868+} while (0 && _dev)6969+7070+#define d_fnstart(l, _dev, f, a...) \7171+ __d_printf(l, " FNSTART", _dev, f, ## a)7272+#define d_fnend(l, _dev, f, a...) \7373+ __d_printf(l, " FNEND", _dev, f, ## a)7474+#define d_printf(l, _dev, f, a...) \7575+ __d_printf(l, "", _dev, f, ## a)7676+#define d_dump(l, _dev, ptr, size) \7777+do { \7878+ struct device *__dev = _dev; \7979+ if (D_MASTER && D_LOCAL >= (l)) \8080+ dump_bytes(__dev, ptr, size); \8181+} while (0 && _dev)8282+#define d_test(l) (D_MASTER && D_LOCAL >= (l))
+727
include/linux/uwb/spec.h
···11+/*22+ * Ultra Wide Band33+ * UWB Standard definitions44+ *55+ * Copyright (C) 2005-2006 Intel Corporation66+ * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>77+ *88+ * This program is free software; you can redistribute it and/or99+ * modify it under the terms of the GNU General Public License version1010+ * 2 as published by the Free Software Foundation.1111+ *1212+ * This program is distributed in the hope that it will be useful,1313+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1414+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1515+ * GNU General Public License for more details.1616+ *1717+ * You should have received a copy of the GNU General Public License1818+ * along with this program; if not, write to the Free Software1919+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA2020+ * 02110-1301, USA.2121+ *2222+ *2323+ * All these definitions are based on the ECMA-368 standard.2424+ *2525+ * Note all definitions are Little Endian in the wire, and we will2626+ * convert them to host order before operating on the bitfields (that2727+ * yes, we use extensively).2828+ */2929+3030+#ifndef __LINUX__UWB_SPEC_H__3131+#define __LINUX__UWB_SPEC_H__3232+3333+#include <linux/types.h>3434+#include <linux/bitmap.h>3535+3636+#define i1480_FW 0x000003033737+/* #define i1480_FW 0x00000302 */3838+3939+/**4040+ * Number of Medium Access Slots in a superframe.4141+ *4242+ * UWB divides time in SuperFrames, each one divided in 256 pieces, or4343+ * Medium Access Slots. See MBOA MAC[5.4.5] for details. The MAS is the4444+ * basic bandwidth allocation unit in UWB.4545+ */4646+enum { UWB_NUM_MAS = 256 };4747+4848+/**4949+ * Number of Zones in superframe.5050+ *5151+ * UWB divides the superframe into zones with numbering starting from BPST.5252+ * See MBOA MAC[16.8.6]5353+ */5454+enum { UWB_NUM_ZONES = 16 };5555+5656+/*5757+ * Number of MAS in a zone.5858+ */5959+#define UWB_MAS_PER_ZONE (UWB_NUM_MAS / UWB_NUM_ZONES)6060+6161+/*6262+ * Number of streams per DRP reservation between a pair of devices.6363+ *6464+ * [ECMA-368] section 16.8.6.6565+ */6666+enum { UWB_NUM_STREAMS = 8 };6767+6868+/*6969+ * mMasLength7070+ *7171+ * The length of a MAS in microseconds.7272+ *7373+ * [ECMA-368] section 17.16.7474+ */7575+enum { UWB_MAS_LENGTH_US = 256 };7676+7777+/*7878+ * mBeaconSlotLength7979+ *8080+ * The length of the beacon slot in microseconds.8181+ *8282+ * [ECMA-368] section 17.168383+ */8484+enum { UWB_BEACON_SLOT_LENGTH_US = 85 };8585+8686+/*8787+ * mMaxLostBeacons8888+ *8989+ * The number beacons missing in consecutive superframes before a9090+ * device can be considered as unreachable.9191+ *9292+ * [ECMA-368] section 17.169393+ */9494+enum { UWB_MAX_LOST_BEACONS = 3 };9595+9696+/*9797+ * Length of a superframe in microseconds.9898+ */9999+#define UWB_SUPERFRAME_LENGTH_US (UWB_MAS_LENGTH_US * UWB_NUM_MAS)100100+101101+/**102102+ * UWB MAC address103103+ *104104+ * It is *imperative* that this struct is exactly 6 packed bytes (as105105+ * it is also used to define headers sent down and up the wire/radio).106106+ */107107+struct uwb_mac_addr {108108+ u8 data[6];109109+} __attribute__((packed));110110+111111+112112+/**113113+ * UWB device address114114+ *115115+ * It is *imperative* that this struct is exactly 6 packed bytes (as116116+ * it is also used to define headers sent down and up the wire/radio).117117+ */118118+struct uwb_dev_addr {119119+ u8 data[2];120120+} __attribute__((packed));121121+122122+123123+/**124124+ * Types of UWB addresses125125+ *126126+ * Order matters (by size).127127+ */128128+enum uwb_addr_type {129129+ UWB_ADDR_DEV = 0,130130+ UWB_ADDR_MAC = 1,131131+};132132+133133+134134+/** Size of a char buffer for printing a MAC/device address */135135+enum { UWB_ADDR_STRSIZE = 32 };136136+137137+138138+/** UWB WiMedia protocol IDs. */139139+enum uwb_prid {140140+ UWB_PRID_WLP_RESERVED = 0x0000,141141+ UWB_PRID_WLP = 0x0001,142142+ UWB_PRID_WUSB_BOT = 0x0010,143143+ UWB_PRID_WUSB = 0x0010,144144+ UWB_PRID_WUSB_TOP = 0x001F,145145+};146146+147147+148148+/** PHY Rate (MBOA MAC[7.8.12, Table 61]) */149149+enum uwb_phy_rate {150150+ UWB_PHY_RATE_53 = 0,151151+ UWB_PHY_RATE_80,152152+ UWB_PHY_RATE_106,153153+ UWB_PHY_RATE_160,154154+ UWB_PHY_RATE_200,155155+ UWB_PHY_RATE_320,156156+ UWB_PHY_RATE_400,157157+ UWB_PHY_RATE_480,158158+ UWB_PHY_RATE_INVALID159159+};160160+161161+162162+/**163163+ * Different ways to scan (MBOA MAC[6.2.2, Table 8], WUSB[Table 8-78])164164+ */165165+enum uwb_scan_type {166166+ UWB_SCAN_ONLY = 0,167167+ UWB_SCAN_OUTSIDE_BP,168168+ UWB_SCAN_WHILE_INACTIVE,169169+ UWB_SCAN_DISABLED,170170+ UWB_SCAN_ONLY_STARTTIME,171171+ UWB_SCAN_TOP172172+};173173+174174+175175+/** ACK Policy types (MBOA MAC[7.2.1.3]) */176176+enum uwb_ack_pol {177177+ UWB_ACK_NO = 0,178178+ UWB_ACK_INM = 1,179179+ UWB_ACK_B = 2,180180+ UWB_ACK_B_REQ = 3,181181+};182182+183183+184184+/** DRP reservation types ([ECMA-368 table 106) */185185+enum uwb_drp_type {186186+ UWB_DRP_TYPE_ALIEN_BP = 0,187187+ UWB_DRP_TYPE_HARD,188188+ UWB_DRP_TYPE_SOFT,189189+ UWB_DRP_TYPE_PRIVATE,190190+ UWB_DRP_TYPE_PCA,191191+};192192+193193+194194+/** DRP Reason Codes ([ECMA-368] table 107) */195195+enum uwb_drp_reason {196196+ UWB_DRP_REASON_ACCEPTED = 0,197197+ UWB_DRP_REASON_CONFLICT,198198+ UWB_DRP_REASON_PENDING,199199+ UWB_DRP_REASON_DENIED,200200+ UWB_DRP_REASON_MODIFIED,201201+};202202+203203+/**204204+ * DRP Notification Reason Codes (WHCI 0.95 [3.1.4.9])205205+ */206206+enum uwb_drp_notif_reason {207207+ UWB_DRP_NOTIF_DRP_IE_RCVD = 0,208208+ UWB_DRP_NOTIF_CONFLICT,209209+ UWB_DRP_NOTIF_TERMINATE,210210+};211211+212212+213213+/** Allocation of MAS slots in a DRP request MBOA MAC[7.8.7] */214214+struct uwb_drp_alloc {215215+ __le16 zone_bm;216216+ __le16 mas_bm;217217+} __attribute__((packed));218218+219219+220220+/** General MAC Header format (ECMA-368[16.2]) */221221+struct uwb_mac_frame_hdr {222222+ __le16 Frame_Control;223223+ struct uwb_dev_addr DestAddr;224224+ struct uwb_dev_addr SrcAddr;225225+ __le16 Sequence_Control;226226+ __le16 Access_Information;227227+} __attribute__((packed));228228+229229+230230+/**231231+ * uwb_beacon_frame - a beacon frame including MAC headers232232+ *233233+ * [ECMA] section 16.3.234234+ */235235+struct uwb_beacon_frame {236236+ struct uwb_mac_frame_hdr hdr;237237+ struct uwb_mac_addr Device_Identifier; /* may be a NULL EUI-48 */238238+ u8 Beacon_Slot_Number;239239+ u8 Device_Control;240240+ u8 IEData[];241241+} __attribute__((packed));242242+243243+244244+/** Information Element codes (MBOA MAC[T54]) */245245+enum uwb_ie {246246+ UWB_PCA_AVAILABILITY = 2,247247+ UWB_IE_DRP_AVAILABILITY = 8,248248+ UWB_IE_DRP = 9,249249+ UWB_BP_SWITCH_IE = 11,250250+ UWB_MAC_CAPABILITIES_IE = 12,251251+ UWB_PHY_CAPABILITIES_IE = 13,252252+ UWB_APP_SPEC_PROBE_IE = 15,253253+ UWB_IDENTIFICATION_IE = 19,254254+ UWB_MASTER_KEY_ID_IE = 20,255255+ UWB_IE_WLP = 250, /* WiMedia Logical Link Control Protocol WLP 0.99 */256256+ UWB_APP_SPEC_IE = 255,257257+};258258+259259+260260+/**261261+ * Header common to all Information Elements (IEs)262262+ */263263+struct uwb_ie_hdr {264264+ u8 element_id; /* enum uwb_ie */265265+ u8 length;266266+} __attribute__((packed));267267+268268+269269+/** Dynamic Reservation Protocol IE (MBOA MAC[7.8.6]) */270270+struct uwb_ie_drp {271271+ struct uwb_ie_hdr hdr;272272+ __le16 drp_control;273273+ struct uwb_dev_addr dev_addr;274274+ struct uwb_drp_alloc allocs[];275275+} __attribute__((packed));276276+277277+static inline int uwb_ie_drp_type(struct uwb_ie_drp *ie)278278+{279279+ return (le16_to_cpu(ie->drp_control) >> 0) & 0x7;280280+}281281+282282+static inline int uwb_ie_drp_stream_index(struct uwb_ie_drp *ie)283283+{284284+ return (le16_to_cpu(ie->drp_control) >> 3) & 0x7;285285+}286286+287287+static inline int uwb_ie_drp_reason_code(struct uwb_ie_drp *ie)288288+{289289+ return (le16_to_cpu(ie->drp_control) >> 6) & 0x7;290290+}291291+292292+static inline int uwb_ie_drp_status(struct uwb_ie_drp *ie)293293+{294294+ return (le16_to_cpu(ie->drp_control) >> 9) & 0x1;295295+}296296+297297+static inline int uwb_ie_drp_owner(struct uwb_ie_drp *ie)298298+{299299+ return (le16_to_cpu(ie->drp_control) >> 10) & 0x1;300300+}301301+302302+static inline int uwb_ie_drp_tiebreaker(struct uwb_ie_drp *ie)303303+{304304+ return (le16_to_cpu(ie->drp_control) >> 11) & 0x1;305305+}306306+307307+static inline int uwb_ie_drp_unsafe(struct uwb_ie_drp *ie)308308+{309309+ return (le16_to_cpu(ie->drp_control) >> 12) & 0x1;310310+}311311+312312+static inline void uwb_ie_drp_set_type(struct uwb_ie_drp *ie, enum uwb_drp_type type)313313+{314314+ u16 drp_control = le16_to_cpu(ie->drp_control);315315+ drp_control = (drp_control & ~(0x7 << 0)) | (type << 0);316316+ ie->drp_control = cpu_to_le16(drp_control);317317+}318318+319319+static inline void uwb_ie_drp_set_stream_index(struct uwb_ie_drp *ie, int stream_index)320320+{321321+ u16 drp_control = le16_to_cpu(ie->drp_control);322322+ drp_control = (drp_control & ~(0x7 << 3)) | (stream_index << 3);323323+ ie->drp_control = cpu_to_le16(drp_control);324324+}325325+326326+static inline void uwb_ie_drp_set_reason_code(struct uwb_ie_drp *ie,327327+ enum uwb_drp_reason reason_code)328328+{329329+ u16 drp_control = le16_to_cpu(ie->drp_control);330330+ drp_control = (ie->drp_control & ~(0x7 << 6)) | (reason_code << 6);331331+ ie->drp_control = cpu_to_le16(drp_control);332332+}333333+334334+static inline void uwb_ie_drp_set_status(struct uwb_ie_drp *ie, int status)335335+{336336+ u16 drp_control = le16_to_cpu(ie->drp_control);337337+ drp_control = (drp_control & ~(0x1 << 9)) | (status << 9);338338+ ie->drp_control = cpu_to_le16(drp_control);339339+}340340+341341+static inline void uwb_ie_drp_set_owner(struct uwb_ie_drp *ie, int owner)342342+{343343+ u16 drp_control = le16_to_cpu(ie->drp_control);344344+ drp_control = (drp_control & ~(0x1 << 10)) | (owner << 10);345345+ ie->drp_control = cpu_to_le16(drp_control);346346+}347347+348348+static inline void uwb_ie_drp_set_tiebreaker(struct uwb_ie_drp *ie, int tiebreaker)349349+{350350+ u16 drp_control = le16_to_cpu(ie->drp_control);351351+ drp_control = (drp_control & ~(0x1 << 11)) | (tiebreaker << 11);352352+ ie->drp_control = cpu_to_le16(drp_control);353353+}354354+355355+static inline void uwb_ie_drp_set_unsafe(struct uwb_ie_drp *ie, int unsafe)356356+{357357+ u16 drp_control = le16_to_cpu(ie->drp_control);358358+ drp_control = (drp_control & ~(0x1 << 12)) | (unsafe << 12);359359+ ie->drp_control = cpu_to_le16(drp_control);360360+}361361+362362+/** Dynamic Reservation Protocol IE (MBOA MAC[7.8.7]) */363363+struct uwb_ie_drp_avail {364364+ struct uwb_ie_hdr hdr;365365+ DECLARE_BITMAP(bmp, UWB_NUM_MAS);366366+} __attribute__((packed));367367+368368+/**369369+ * The Vendor ID is set to an OUI that indicates the vendor of the device.370370+ * ECMA-368 [16.8.10]371371+ */372372+struct uwb_vendor_id {373373+ u8 data[3];374374+} __attribute__((packed));375375+376376+/**377377+ * The device type ID378378+ * FIXME: clarify what this means379379+ * ECMA-368 [16.8.10]380380+ */381381+struct uwb_device_type_id {382382+ u8 data[3];383383+} __attribute__((packed));384384+385385+386386+/**387387+ * UWB device information types388388+ * ECMA-368 [16.8.10]389389+ */390390+enum uwb_dev_info_type {391391+ UWB_DEV_INFO_VENDOR_ID = 0,392392+ UWB_DEV_INFO_VENDOR_TYPE,393393+ UWB_DEV_INFO_NAME,394394+};395395+396396+/**397397+ * UWB device information found in Identification IE398398+ * ECMA-368 [16.8.10]399399+ */400400+struct uwb_dev_info {401401+ u8 type; /* enum uwb_dev_info_type */402402+ u8 length;403403+ u8 data[];404404+} __attribute__((packed));405405+406406+/**407407+ * UWB Identification IE408408+ * ECMA-368 [16.8.10]409409+ */410410+struct uwb_identification_ie {411411+ struct uwb_ie_hdr hdr;412412+ struct uwb_dev_info info[];413413+} __attribute__((packed));414414+415415+/*416416+ * UWB Radio Controller417417+ *418418+ * These definitions are common to the Radio Control layers as419419+ * exported by the WUSB1.0 HWA and WHCI interfaces.420420+ */421421+422422+/** Radio Control Command Block (WUSB1.0[Table 8-65] and WHCI 0.95) */423423+struct uwb_rccb {424424+ u8 bCommandType; /* enum hwa_cet */425425+ __le16 wCommand; /* Command code */426426+ u8 bCommandContext; /* Context ID */427427+} __attribute__((packed));428428+429429+430430+/** Radio Control Event Block (WUSB[table 8-66], WHCI 0.95) */431431+struct uwb_rceb {432432+ u8 bEventType; /* enum hwa_cet */433433+ __le16 wEvent; /* Event code */434434+ u8 bEventContext; /* Context ID */435435+} __attribute__((packed));436436+437437+438438+enum {439439+ UWB_RC_CET_GENERAL = 0, /* General Command/Event type */440440+ UWB_RC_CET_EX_TYPE_1 = 1, /* Extended Type 1 Command/Event type */441441+};442442+443443+/* Commands to the radio controller */444444+enum uwb_rc_cmd {445445+ UWB_RC_CMD_CHANNEL_CHANGE = 16,446446+ UWB_RC_CMD_DEV_ADDR_MGMT = 17, /* Device Address Management */447447+ UWB_RC_CMD_GET_IE = 18, /* GET Information Elements */448448+ UWB_RC_CMD_RESET = 19,449449+ UWB_RC_CMD_SCAN = 20, /* Scan management */450450+ UWB_RC_CMD_SET_BEACON_FILTER = 21,451451+ UWB_RC_CMD_SET_DRP_IE = 22, /* Dynamic Reservation Protocol IEs */452452+ UWB_RC_CMD_SET_IE = 23, /* Information Element management */453453+ UWB_RC_CMD_SET_NOTIFICATION_FILTER = 24,454454+ UWB_RC_CMD_SET_TX_POWER = 25,455455+ UWB_RC_CMD_SLEEP = 26,456456+ UWB_RC_CMD_START_BEACON = 27,457457+ UWB_RC_CMD_STOP_BEACON = 28,458458+ UWB_RC_CMD_BP_MERGE = 29,459459+ UWB_RC_CMD_SEND_COMMAND_FRAME = 30,460460+ UWB_RC_CMD_SET_ASIE_NOTIF = 31,461461+};462462+463463+/* Notifications from the radio controller */464464+enum uwb_rc_evt {465465+ UWB_RC_EVT_IE_RCV = 0,466466+ UWB_RC_EVT_BEACON = 1,467467+ UWB_RC_EVT_BEACON_SIZE = 2,468468+ UWB_RC_EVT_BPOIE_CHANGE = 3,469469+ UWB_RC_EVT_BP_SLOT_CHANGE = 4,470470+ UWB_RC_EVT_BP_SWITCH_IE_RCV = 5,471471+ UWB_RC_EVT_DEV_ADDR_CONFLICT = 6,472472+ UWB_RC_EVT_DRP_AVAIL = 7,473473+ UWB_RC_EVT_DRP = 8,474474+ UWB_RC_EVT_BP_SWITCH_STATUS = 9,475475+ UWB_RC_EVT_CMD_FRAME_RCV = 10,476476+ UWB_RC_EVT_CHANNEL_CHANGE_IE_RCV = 11,477477+ /* Events (command responses) use the same code as the command */478478+ UWB_RC_EVT_UNKNOWN_CMD_RCV = 65535,479479+};480480+481481+enum uwb_rc_extended_type_1_cmd {482482+ UWB_RC_SET_DAA_ENERGY_MASK = 32,483483+ UWB_RC_SET_NOTIFICATION_FILTER_EX = 33,484484+};485485+486486+enum uwb_rc_extended_type_1_evt {487487+ UWB_RC_DAA_ENERGY_DETECTED = 0,488488+};489489+490490+/* Radio Control Result Code. [WHCI] table 3-3. */491491+enum {492492+ UWB_RC_RES_SUCCESS = 0,493493+ UWB_RC_RES_FAIL,494494+ UWB_RC_RES_FAIL_HARDWARE,495495+ UWB_RC_RES_FAIL_NO_SLOTS,496496+ UWB_RC_RES_FAIL_BEACON_TOO_LARGE,497497+ UWB_RC_RES_FAIL_INVALID_PARAMETER,498498+ UWB_RC_RES_FAIL_UNSUPPORTED_PWR_LEVEL,499499+ UWB_RC_RES_FAIL_INVALID_IE_DATA,500500+ UWB_RC_RES_FAIL_BEACON_SIZE_EXCEEDED,501501+ UWB_RC_RES_FAIL_CANCELLED,502502+ UWB_RC_RES_FAIL_INVALID_STATE,503503+ UWB_RC_RES_FAIL_INVALID_SIZE,504504+ UWB_RC_RES_FAIL_ACK_NOT_RECEIVED,505505+ UWB_RC_RES_FAIL_NO_MORE_ASIE_NOTIF,506506+ UWB_RC_RES_FAIL_TIME_OUT = 255,507507+};508508+509509+/* Confirm event. [WHCI] section 3.1.3.1 etc. */510510+struct uwb_rc_evt_confirm {511511+ struct uwb_rceb rceb;512512+ u8 bResultCode;513513+} __attribute__((packed));514514+515515+/* Device Address Management event. [WHCI] section 3.1.3.2. */516516+struct uwb_rc_evt_dev_addr_mgmt {517517+ struct uwb_rceb rceb;518518+ u8 baAddr[6];519519+ u8 bResultCode;520520+} __attribute__((packed));521521+522522+523523+/* Get IE Event. [WHCI] section 3.1.3.3. */524524+struct uwb_rc_evt_get_ie {525525+ struct uwb_rceb rceb;526526+ __le16 wIELength;527527+ u8 IEData[];528528+} __attribute__((packed));529529+530530+/* Set DRP IE Event. [WHCI] section 3.1.3.7. */531531+struct uwb_rc_evt_set_drp_ie {532532+ struct uwb_rceb rceb;533533+ __le16 wRemainingSpace;534534+ u8 bResultCode;535535+} __attribute__((packed));536536+537537+/* Set IE Event. [WHCI] section 3.1.3.8. */538538+struct uwb_rc_evt_set_ie {539539+ struct uwb_rceb rceb;540540+ __le16 RemainingSpace;541541+ u8 bResultCode;542542+} __attribute__((packed));543543+544544+/* Scan command. [WHCI] 3.1.3.5. */545545+struct uwb_rc_cmd_scan {546546+ struct uwb_rccb rccb;547547+ u8 bChannelNumber;548548+ u8 bScanState;549549+ __le16 wStartTime;550550+} __attribute__((packed));551551+552552+/* Set DRP IE command. [WHCI] section 3.1.3.7. */553553+struct uwb_rc_cmd_set_drp_ie {554554+ struct uwb_rccb rccb;555555+ __le16 wIELength;556556+ struct uwb_ie_drp IEData[];557557+} __attribute__((packed));558558+559559+/* Set IE command. [WHCI] section 3.1.3.8. */560560+struct uwb_rc_cmd_set_ie {561561+ struct uwb_rccb rccb;562562+ __le16 wIELength;563563+ u8 IEData[];564564+} __attribute__((packed));565565+566566+/* Set DAA Energy Mask event. [WHCI 0.96] section 3.1.3.17. */567567+struct uwb_rc_evt_set_daa_energy_mask {568568+ struct uwb_rceb rceb;569569+ __le16 wLength;570570+ u8 result;571571+} __attribute__((packed));572572+573573+/* Set Notification Filter Extended event. [WHCI 0.96] section 3.1.3.18. */574574+struct uwb_rc_evt_set_notification_filter_ex {575575+ struct uwb_rceb rceb;576576+ __le16 wLength;577577+ u8 result;578578+} __attribute__((packed));579579+580580+/* IE Received notification. [WHCI] section 3.1.4.1. */581581+struct uwb_rc_evt_ie_rcv {582582+ struct uwb_rceb rceb;583583+ struct uwb_dev_addr SrcAddr;584584+ __le16 wIELength;585585+ u8 IEData[];586586+} __attribute__((packed));587587+588588+/* Type of the received beacon. [WHCI] section 3.1.4.2. */589589+enum uwb_rc_beacon_type {590590+ UWB_RC_BEACON_TYPE_SCAN = 0,591591+ UWB_RC_BEACON_TYPE_NEIGHBOR,592592+ UWB_RC_BEACON_TYPE_OL_ALIEN,593593+ UWB_RC_BEACON_TYPE_NOL_ALIEN,594594+};595595+596596+/* Beacon received notification. [WHCI] 3.1.4.2. */597597+struct uwb_rc_evt_beacon {598598+ struct uwb_rceb rceb;599599+ u8 bChannelNumber;600600+ u8 bBeaconType;601601+ __le16 wBPSTOffset;602602+ u8 bLQI;603603+ u8 bRSSI;604604+ __le16 wBeaconInfoLength;605605+ u8 BeaconInfo[];606606+} __attribute__((packed));607607+608608+609609+/* Beacon Size Change notification. [WHCI] section 3.1.4.3 */610610+struct uwb_rc_evt_beacon_size {611611+ struct uwb_rceb rceb;612612+ __le16 wNewBeaconSize;613613+} __attribute__((packed));614614+615615+616616+/* BPOIE Change notification. [WHCI] section 3.1.4.4. */617617+struct uwb_rc_evt_bpoie_change {618618+ struct uwb_rceb rceb;619619+ __le16 wBPOIELength;620620+ u8 BPOIE[];621621+} __attribute__((packed));622622+623623+624624+/* Beacon Slot Change notification. [WHCI] section 3.1.4.5. */625625+struct uwb_rc_evt_bp_slot_change {626626+ struct uwb_rceb rceb;627627+ u8 slot_info;628628+} __attribute__((packed));629629+630630+static inline int uwb_rc_evt_bp_slot_change_slot_num(631631+ const struct uwb_rc_evt_bp_slot_change *evt)632632+{633633+ return evt->slot_info & 0x7f;634634+}635635+636636+static inline int uwb_rc_evt_bp_slot_change_no_slot(637637+ const struct uwb_rc_evt_bp_slot_change *evt)638638+{639639+ return (evt->slot_info & 0x80) >> 7;640640+}641641+642642+/* BP Switch IE Received notification. [WHCI] section 3.1.4.6. */643643+struct uwb_rc_evt_bp_switch_ie_rcv {644644+ struct uwb_rceb rceb;645645+ struct uwb_dev_addr wSrcAddr;646646+ __le16 wIELength;647647+ u8 IEData[];648648+} __attribute__((packed));649649+650650+/* DevAddr Conflict notification. [WHCI] section 3.1.4.7. */651651+struct uwb_rc_evt_dev_addr_conflict {652652+ struct uwb_rceb rceb;653653+} __attribute__((packed));654654+655655+/* DRP notification. [WHCI] section 3.1.4.9. */656656+struct uwb_rc_evt_drp {657657+ struct uwb_rceb rceb;658658+ struct uwb_dev_addr src_addr;659659+ u8 reason;660660+ u8 beacon_slot_number;661661+ __le16 ie_length;662662+ u8 ie_data[];663663+} __attribute__((packed));664664+665665+static inline enum uwb_drp_notif_reason uwb_rc_evt_drp_reason(struct uwb_rc_evt_drp *evt)666666+{667667+ return evt->reason & 0x0f;668668+}669669+670670+671671+/* DRP Availability Change notification. [WHCI] section 3.1.4.8. */672672+struct uwb_rc_evt_drp_avail {673673+ struct uwb_rceb rceb;674674+ DECLARE_BITMAP(bmp, UWB_NUM_MAS);675675+} __attribute__((packed));676676+677677+/* BP switch status notification. [WHCI] section 3.1.4.10. */678678+struct uwb_rc_evt_bp_switch_status {679679+ struct uwb_rceb rceb;680680+ u8 status;681681+ u8 slot_offset;682682+ __le16 bpst_offset;683683+ u8 move_countdown;684684+} __attribute__((packed));685685+686686+/* Command Frame Received notification. [WHCI] section 3.1.4.11. */687687+struct uwb_rc_evt_cmd_frame_rcv {688688+ struct uwb_rceb rceb;689689+ __le16 receive_time;690690+ struct uwb_dev_addr wSrcAddr;691691+ struct uwb_dev_addr wDstAddr;692692+ __le16 control;693693+ __le16 reserved;694694+ __le16 dataLength;695695+ u8 data[];696696+} __attribute__((packed));697697+698698+/* Channel Change IE Received notification. [WHCI] section 3.1.4.12. */699699+struct uwb_rc_evt_channel_change_ie_rcv {700700+ struct uwb_rceb rceb;701701+ struct uwb_dev_addr wSrcAddr;702702+ __le16 wIELength;703703+ u8 IEData[];704704+} __attribute__((packed));705705+706706+/* DAA Energy Detected notification. [WHCI 0.96] section 3.1.4.14. */707707+struct uwb_rc_evt_daa_energy_detected {708708+ struct uwb_rceb rceb;709709+ __le16 wLength;710710+ u8 bandID;711711+ u8 reserved;712712+ u8 toneBmp[16];713713+} __attribute__((packed));714714+715715+716716+/**717717+ * Radio Control Interface Class Descriptor718718+ *719719+ * WUSB 1.0 [8.6.1.2]720720+ */721721+struct uwb_rc_control_intf_class_desc {722722+ u8 bLength;723723+ u8 bDescriptorType;724724+ __le16 bcdRCIVersion;725725+} __attribute__((packed));726726+727727+#endif /* #ifndef __LINUX__UWB_SPEC_H__ */
+735
include/linux/wlp.h
···11+/*22+ * WiMedia Logical Link Control Protocol (WLP)33+ *44+ * Copyright (C) 2005-2006 Intel Corporation55+ * Reinette Chatre <reinette.chatre@intel.com>66+ *77+ * This program is free software; you can redistribute it and/or88+ * modify it under the terms of the GNU General Public License version99+ * 2 as published by the Free Software Foundation.1010+ *1111+ * This program is distributed in the hope that it will be useful,1212+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1313+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1414+ * GNU General Public License for more details.1515+ *1616+ * You should have received a copy of the GNU General Public License1717+ * along with this program; if not, write to the Free Software1818+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA1919+ * 02110-1301, USA.2020+ *2121+ *2222+ * FIXME: docs2323+ *2424+ * - Does not (yet) include support for WLP control frames2525+ * WLP Draft 0.99 [6.5].2626+ *2727+ * A visual representation of the data structures.2828+ *2929+ * wssidB wssidB3030+ * ^ ^3131+ * | |3232+ * wssidA wssidA3333+ * wlp interface { ^ ^3434+ * ... | |3535+ * ... ... wssid wssid ...3636+ * wlp --- ... | |3737+ * }; neighbors --> neighbA --> neighbB3838+ * ...3939+ * wss4040+ * ...4141+ * eda cache --> neighborA --> neighborB --> neighborC ...4242+ */4343+4444+#ifndef __LINUX__WLP_H_4545+#define __LINUX__WLP_H_4646+4747+#include <linux/netdevice.h>4848+#include <linux/skbuff.h>4949+#include <linux/list.h>5050+#include <linux/uwb.h>5151+5252+/**5353+ * WLP Protocol ID5454+ * WLP Draft 0.99 [6.2]5555+ *5656+ * The MUX header for all WLP frames5757+ */5858+#define WLP_PROTOCOL_ID 0x01005959+6060+/**6161+ * WLP Version6262+ * WLP version placed in the association frames (WLP 0.99 [6.6])6363+ */6464+#define WLP_VERSION 0x106565+6666+/**6767+ * Bytes needed to print UUID as string6868+ */6969+#define WLP_WSS_UUID_STRSIZE 487070+7171+/**7272+ * Bytes needed to print nonce as string7373+ */7474+#define WLP_WSS_NONCE_STRSIZE 487575+7676+7777+/**7878+ * Size used for WLP name size7979+ *8080+ * The WSS name is set to 65 bytes, 1 byte larger than the maximum8181+ * allowed by the WLP spec. This is to have a null terminated string8282+ * for display to the user. A maximum of 64 bytes will still be used8383+ * when placing the WSS name field in association frames.8484+ */8585+#define WLP_WSS_NAME_SIZE 658686+8787+/**8888+ * Number of bytes added by WLP to data frame8989+ *9090+ * A data frame transmitted from a host will be placed in a Standard or9191+ * Abbreviated WLP frame. These have an extra 4 bytes of header (struct9292+ * wlp_frame_std_abbrv_hdr).9393+ * When the stack sends this data frame for transmission it needs to ensure9494+ * there is enough headroom for this header.9595+ */9696+#define WLP_DATA_HLEN 49797+9898+/**9999+ * State of device regarding WLP Service Set100100+ *101101+ * WLP_WSS_STATE_NONE: the host does not participate in any WSS102102+ * WLP_WSS_STATE_PART_ENROLLED: used as part of the enrollment sequence103103+ * ("Partial Enroll"). This state is used to104104+ * indicate the first part of enrollment that is105105+ * unsecure. If the WSS is unsecure then the106106+ * state will promptly go to WLP_WSS_STATE_ENROLLED,107107+ * if the WSS is not secure then the enrollment108108+ * procedure is a few more steps before we are109109+ * enrolled.110110+ * WLP_WSS_STATE_ENROLLED: the host is enrolled in a WSS111111+ * WLP_WSS_STATE_ACTIVE: WSS is activated112112+ * WLP_WSS_STATE_CONNECTED: host is connected to neighbor in WSS113113+ *114114+ */115115+enum wlp_wss_state {116116+ WLP_WSS_STATE_NONE = 0,117117+ WLP_WSS_STATE_PART_ENROLLED,118118+ WLP_WSS_STATE_ENROLLED,119119+ WLP_WSS_STATE_ACTIVE,120120+ WLP_WSS_STATE_CONNECTED,121121+};122122+123123+/**124124+ * WSS Secure status125125+ * WLP 0.99 Table 6126126+ *127127+ * Set to one if the WSS is secure, zero if it is not secure128128+ */129129+enum wlp_wss_sec_status {130130+ WLP_WSS_UNSECURE = 0,131131+ WLP_WSS_SECURE,132132+};133133+134134+/**135135+ * WLP frame type136136+ * WLP Draft 0.99 [6.2 Table 1]137137+ */138138+enum wlp_frame_type {139139+ WLP_FRAME_STANDARD = 0,140140+ WLP_FRAME_ABBREVIATED,141141+ WLP_FRAME_CONTROL,142142+ WLP_FRAME_ASSOCIATION,143143+};144144+145145+/**146146+ * WLP Association Message Type147147+ * WLP Draft 0.99 [6.6.1.2 Table 8]148148+ */149149+enum wlp_assoc_type {150150+ WLP_ASSOC_D1 = 2,151151+ WLP_ASSOC_D2 = 3,152152+ WLP_ASSOC_M1 = 4,153153+ WLP_ASSOC_M2 = 5,154154+ WLP_ASSOC_M3 = 7,155155+ WLP_ASSOC_M4 = 8,156156+ WLP_ASSOC_M5 = 9,157157+ WLP_ASSOC_M6 = 10,158158+ WLP_ASSOC_M7 = 11,159159+ WLP_ASSOC_M8 = 12,160160+ WLP_ASSOC_F0 = 14,161161+ WLP_ASSOC_E1 = 32,162162+ WLP_ASSOC_E2 = 33,163163+ WLP_ASSOC_C1 = 34,164164+ WLP_ASSOC_C2 = 35,165165+ WLP_ASSOC_C3 = 36,166166+ WLP_ASSOC_C4 = 37,167167+};168168+169169+/**170170+ * WLP Attribute Type171171+ * WLP Draft 0.99 [6.6.1 Table 6]172172+ */173173+enum wlp_attr_type {174174+ WLP_ATTR_AUTH = 0x1005, /* Authenticator */175175+ WLP_ATTR_DEV_NAME = 0x1011, /* Device Name */176176+ WLP_ATTR_DEV_PWD_ID = 0x1012, /* Device Password ID */177177+ WLP_ATTR_E_HASH1 = 0x1014, /* E-Hash1 */178178+ WLP_ATTR_E_HASH2 = 0x1015, /* E-Hash2 */179179+ WLP_ATTR_E_SNONCE1 = 0x1016, /* E-SNonce1 */180180+ WLP_ATTR_E_SNONCE2 = 0x1017, /* E-SNonce2 */181181+ WLP_ATTR_ENCR_SET = 0x1018, /* Encrypted Settings */182182+ WLP_ATTR_ENRL_NONCE = 0x101A, /* Enrollee Nonce */183183+ WLP_ATTR_KEYWRAP_AUTH = 0x101E, /* Key Wrap Authenticator */184184+ WLP_ATTR_MANUF = 0x1021, /* Manufacturer */185185+ WLP_ATTR_MSG_TYPE = 0x1022, /* Message Type */186186+ WLP_ATTR_MODEL_NAME = 0x1023, /* Model Name */187187+ WLP_ATTR_MODEL_NR = 0x1024, /* Model Number */188188+ WLP_ATTR_PUB_KEY = 0x1032, /* Public Key */189189+ WLP_ATTR_REG_NONCE = 0x1039, /* Registrar Nonce */190190+ WLP_ATTR_R_HASH1 = 0x103D, /* R-Hash1 */191191+ WLP_ATTR_R_HASH2 = 0x103E, /* R-Hash2 */192192+ WLP_ATTR_R_SNONCE1 = 0x103F, /* R-SNonce1 */193193+ WLP_ATTR_R_SNONCE2 = 0x1040, /* R-SNonce2 */194194+ WLP_ATTR_SERIAL = 0x1042, /* Serial number */195195+ WLP_ATTR_UUID_E = 0x1047, /* UUID-E */196196+ WLP_ATTR_UUID_R = 0x1048, /* UUID-R */197197+ WLP_ATTR_PRI_DEV_TYPE = 0x1054, /* Primary Device Type */198198+ WLP_ATTR_SEC_DEV_TYPE = 0x1055, /* Secondary Device Type */199199+ WLP_ATTR_PORT_DEV = 0x1056, /* Portable Device */200200+ WLP_ATTR_APP_EXT = 0x1058, /* Application Extension */201201+ WLP_ATTR_WLP_VER = 0x2000, /* WLP Version */202202+ WLP_ATTR_WSSID = 0x2001, /* WSSID */203203+ WLP_ATTR_WSS_NAME = 0x2002, /* WSS Name */204204+ WLP_ATTR_WSS_SEC_STAT = 0x2003, /* WSS Secure Status */205205+ WLP_ATTR_WSS_BCAST = 0x2004, /* WSS Broadcast Address */206206+ WLP_ATTR_WSS_M_KEY = 0x2005, /* WSS Master Key */207207+ WLP_ATTR_ACC_ENRL = 0x2006, /* Accepting Enrollment */208208+ WLP_ATTR_WSS_INFO = 0x2007, /* WSS Information */209209+ WLP_ATTR_WSS_SEL_MTHD = 0x2008, /* WSS Selection Method */210210+ WLP_ATTR_ASSC_MTHD_LIST = 0x2009, /* Association Methods List */211211+ WLP_ATTR_SEL_ASSC_MTHD = 0x200A, /* Selected Association Method */212212+ WLP_ATTR_ENRL_HASH_COMM = 0x200B, /* Enrollee Hash Commitment */213213+ WLP_ATTR_WSS_TAG = 0x200C, /* WSS Tag */214214+ WLP_ATTR_WSS_VIRT = 0x200D, /* WSS Virtual EUI-48 */215215+ WLP_ATTR_WLP_ASSC_ERR = 0x200E, /* WLP Association Error */216216+ WLP_ATTR_VNDR_EXT = 0x200F, /* Vendor Extension */217217+};218218+219219+/**220220+ * WLP Category ID of primary/secondary device221221+ * WLP Draft 0.99 [6.6.1.8 Table 12]222222+ */223223+enum wlp_dev_category_id {224224+ WLP_DEV_CAT_COMPUTER = 1,225225+ WLP_DEV_CAT_INPUT,226226+ WLP_DEV_CAT_PRINT_SCAN_FAX_COPIER,227227+ WLP_DEV_CAT_CAMERA,228228+ WLP_DEV_CAT_STORAGE,229229+ WLP_DEV_CAT_INFRASTRUCTURE,230230+ WLP_DEV_CAT_DISPLAY,231231+ WLP_DEV_CAT_MULTIM,232232+ WLP_DEV_CAT_GAMING,233233+ WLP_DEV_CAT_TELEPHONE,234234+ WLP_DEV_CAT_OTHER = 65535,235235+};236236+237237+/**238238+ * WLP WSS selection method239239+ * WLP Draft 0.99 [6.6.1.6 Table 10]240240+ */241241+enum wlp_wss_sel_mthd {242242+ WLP_WSS_ENRL_SELECT = 1, /* Enrollee selects */243243+ WLP_WSS_REG_SELECT, /* Registrar selects */244244+};245245+246246+/**247247+ * WLP association error values248248+ * WLP Draft 0.99 [6.6.1.5 Table 9]249249+ */250250+enum wlp_assc_error {251251+ WLP_ASSOC_ERROR_NONE,252252+ WLP_ASSOC_ERROR_AUTH, /* Authenticator Failure */253253+ WLP_ASSOC_ERROR_ROGUE, /* Rogue activity suspected */254254+ WLP_ASSOC_ERROR_BUSY, /* Device busy */255255+ WLP_ASSOC_ERROR_LOCK, /* Setup Locked */256256+ WLP_ASSOC_ERROR_NOT_READY, /* Registrar not ready */257257+ WLP_ASSOC_ERROR_INV, /* Invalid WSS selection */258258+ WLP_ASSOC_ERROR_MSG_TIME, /* Message timeout */259259+ WLP_ASSOC_ERROR_ENR_TIME, /* Enrollment session timeout */260260+ WLP_ASSOC_ERROR_PW, /* Device password invalid */261261+ WLP_ASSOC_ERROR_VER, /* Unsupported version */262262+ WLP_ASSOC_ERROR_INT, /* Internal error */263263+ WLP_ASSOC_ERROR_UNDEF, /* Undefined error */264264+ WLP_ASSOC_ERROR_NUM, /* Numeric comparison failure */265265+ WLP_ASSOC_ERROR_WAIT, /* Waiting for user input */266266+};267267+268268+/**269269+ * WLP Parameters270270+ * WLP 0.99 [7.7]271271+ */272272+enum wlp_parameters {273273+ WLP_PER_MSG_TIMEOUT = 15, /* Seconds to wait for response to274274+ association message. */275275+};276276+277277+/**278278+ * WLP IE279279+ *280280+ * The WLP IE should be included in beacons by all devices.281281+ *282282+ * The driver can set only a few of the fields in this information element,283283+ * most fields are managed by the device self. When the driver needs to set284284+ * a field it will only provide values for the fields of interest, the rest285285+ * will be filled with zeroes. The fields of interest are:286286+ *287287+ * Element ID288288+ * Length289289+ * Capabilities (only to include WSSID Hash list length)290290+ * WSSID Hash List fields291291+ *292292+ * WLP 0.99 [6.7]293293+ *294294+ * Only the fields that will be used are detailed in this structure, rest295295+ * are not detailed or marked as "notused".296296+ */297297+struct wlp_ie {298298+ struct uwb_ie_hdr hdr;299299+ __le16 capabilities;300300+ __le16 cycle_param;301301+ __le16 acw_anchor_addr;302302+ u8 wssid_hash_list[];303303+} __attribute__((packed));304304+305305+static inline int wlp_ie_hash_length(struct wlp_ie *ie)306306+{307307+ return (le16_to_cpu(ie->capabilities) >> 12) & 0xf;308308+}309309+310310+static inline void wlp_ie_set_hash_length(struct wlp_ie *ie, int hash_length)311311+{312312+ u16 caps = le16_to_cpu(ie->capabilities);313313+ caps = (caps & ~(0xf << 12)) | (hash_length << 12);314314+ ie->capabilities = cpu_to_le16(caps);315315+}316316+317317+/**318318+ * WLP nonce319319+ * WLP Draft 0.99 [6.6.1 Table 6]320320+ *321321+ * A 128-bit random number often used (E-SNonce1, E-SNonce2, Enrollee322322+ * Nonce, Registrar Nonce, R-SNonce1, R-SNonce2). It is passed to HW so323323+ * it is packed.324324+ */325325+struct wlp_nonce {326326+ u8 data[16];327327+} __attribute__((packed));328328+329329+/**330330+ * WLP UUID331331+ * WLP Draft 0.99 [6.6.1 Table 6]332332+ *333333+ * Universally Unique Identifier (UUID) encoded as an octet string in the334334+ * order the octets are shown in string representation in RFC4122. A UUID335335+ * is often used (UUID-E, UUID-R, WSSID). It is passed to HW so it is packed.336336+ */337337+struct wlp_uuid {338338+ u8 data[16];339339+} __attribute__((packed));340340+341341+342342+/**343343+ * Primary and secondary device type attributes344344+ * WLP Draft 0.99 [6.6.1.8]345345+ */346346+struct wlp_dev_type {347347+ enum wlp_dev_category_id category:16;348348+ u8 OUI[3];349349+ u8 OUIsubdiv;350350+ __le16 subID;351351+} __attribute__((packed));352352+353353+/**354354+ * WLP frame header355355+ * WLP Draft 0.99 [6.2]356356+ */357357+struct wlp_frame_hdr {358358+ __le16 mux_hdr; /* WLP_PROTOCOL_ID */359359+ enum wlp_frame_type type:8;360360+} __attribute__((packed));361361+362362+/**363363+ * WLP attribute field header364364+ * WLP Draft 0.99 [6.6.1]365365+ *366366+ * Header of each attribute found in an association frame367367+ */368368+struct wlp_attr_hdr {369369+ __le16 type;370370+ __le16 length;371371+} __attribute__((packed));372372+373373+/**374374+ * Device information commonly used together375375+ *376376+ * Each of these device information elements has a specified range in which it377377+ * should fit (WLP 0.99 [Table 6]). This range provided in the spec does not378378+ * include the termination null '\0' character (when used in the379379+ * association protocol the attribute fields are accompanied380380+ * with a "length" field so the full range from the spec can be used for381381+ * the value). We thus allocate an extra byte to be able to store a string382382+ * of max length with a terminating '\0'.383383+ */384384+struct wlp_device_info {385385+ char name[33];386386+ char model_name[33];387387+ char manufacturer[65];388388+ char model_nr[33];389389+ char serial[33];390390+ struct wlp_dev_type prim_dev_type;391391+};392392+393393+/**394394+ * Macros for the WLP attributes395395+ *396396+ * There are quite a few attributes (total is 43). The attribute layout can be397397+ * in one of three categories: one value, an array, an enum forced to 8 bits.398398+ * These macros help with their definitions.399399+ */400400+#define wlp_attr(type, name) \401401+struct wlp_attr_##name { \402402+ struct wlp_attr_hdr hdr; \403403+ type name; \404404+} __attribute__((packed));405405+406406+#define wlp_attr_array(type, name) \407407+struct wlp_attr_##name { \408408+ struct wlp_attr_hdr hdr; \409409+ type name[]; \410410+} __attribute__((packed));411411+412412+/**413413+ * WLP association attribute fields414414+ * WLP Draft 0.99 [6.6.1 Table 6]415415+ *416416+ * Attributes appear in same order as the Table in the spec417417+ * FIXME Does not define all attributes yet418418+ */419419+420420+/* Device name: Friendly name of sending device */421421+wlp_attr_array(u8, dev_name)422422+423423+/* Enrollee Nonce: Random number generated by enrollee for an enrollment424424+ * session */425425+wlp_attr(struct wlp_nonce, enonce)426426+427427+/* Manufacturer name: Name of manufacturer of the sending device */428428+wlp_attr_array(u8, manufacturer)429429+430430+/* WLP Message Type */431431+wlp_attr(u8, msg_type)432432+433433+/* WLP Model name: Model name of sending device */434434+wlp_attr_array(u8, model_name)435435+436436+/* WLP Model number: Model number of sending device */437437+wlp_attr_array(u8, model_nr)438438+439439+/* Registrar Nonce: Random number generated by registrar for an enrollment440440+ * session */441441+wlp_attr(struct wlp_nonce, rnonce)442442+443443+/* Serial number of device */444444+wlp_attr_array(u8, serial)445445+446446+/* UUID of enrollee */447447+wlp_attr(struct wlp_uuid, uuid_e)448448+449449+/* UUID of registrar */450450+wlp_attr(struct wlp_uuid, uuid_r)451451+452452+/* WLP Primary device type */453453+wlp_attr(struct wlp_dev_type, prim_dev_type)454454+455455+/* WLP Secondary device type */456456+wlp_attr(struct wlp_dev_type, sec_dev_type)457457+458458+/* WLP protocol version */459459+wlp_attr(u8, version)460460+461461+/* WLP service set identifier */462462+wlp_attr(struct wlp_uuid, wssid)463463+464464+/* WLP WSS name */465465+wlp_attr_array(u8, wss_name)466466+467467+/* WLP WSS Secure Status */468468+wlp_attr(u8, wss_sec_status)469469+470470+/* WSS Broadcast Address */471471+wlp_attr(struct uwb_mac_addr, wss_bcast)472472+473473+/* WLP Accepting Enrollment */474474+wlp_attr(u8, accept_enrl)475475+476476+/**477477+ * WSS information attributes478478+ * WLP Draft 0.99 [6.6.3 Table 15]479479+ */480480+struct wlp_wss_info {481481+ struct wlp_attr_wssid wssid;482482+ struct wlp_attr_wss_name name;483483+ struct wlp_attr_accept_enrl accept;484484+ struct wlp_attr_wss_sec_status sec_stat;485485+ struct wlp_attr_wss_bcast bcast;486486+} __attribute__((packed));487487+488488+/* WLP WSS Information */489489+wlp_attr_array(struct wlp_wss_info, wss_info)490490+491491+/* WLP WSS Selection method */492492+wlp_attr(u8, wss_sel_mthd)493493+494494+/* WLP WSS tag */495495+wlp_attr(u8, wss_tag)496496+497497+/* WSS Virtual Address */498498+wlp_attr(struct uwb_mac_addr, wss_virt)499499+500500+/* WLP association error */501501+wlp_attr(u8, wlp_assc_err)502502+503503+/**504504+ * WLP standard and abbreviated frames505505+ *506506+ * WLP Draft 0.99 [6.3] and [6.4]507507+ *508508+ * The difference between the WLP standard frame and the WLP509509+ * abbreviated frame is that the standard frame includes the src510510+ * and dest addresses from the Ethernet header, the abbreviated frame does511511+ * not.512512+ * The src/dest (as well as the type/length and client data) are already513513+ * defined as part of the Ethernet header, we do not do this here.514514+ * From this perspective the standard and abbreviated frames appear the515515+ * same - they will be treated differently though.516516+ *517517+ * The size of this header is also captured in WLP_DATA_HLEN to enable518518+ * interfaces to prepare their headroom.519519+ */520520+struct wlp_frame_std_abbrv_hdr {521521+ struct wlp_frame_hdr hdr;522522+ u8 tag;523523+} __attribute__((packed));524524+525525+/**526526+ * WLP association frames527527+ *528528+ * WLP Draft 0.99 [6.6]529529+ */530530+struct wlp_frame_assoc {531531+ struct wlp_frame_hdr hdr;532532+ enum wlp_assoc_type type:8;533533+ struct wlp_attr_version version;534534+ struct wlp_attr_msg_type msg_type;535535+ u8 attr[];536536+} __attribute__((packed));537537+538538+/* Ethernet to dev address mapping */539539+struct wlp_eda {540540+ spinlock_t lock;541541+ struct list_head cache; /* Eth<->Dev Addr cache */542542+};543543+544544+/**545545+ * WSS information temporary storage546546+ *547547+ * This information is only stored temporarily during discovery. It should548548+ * not be stored unless the device is enrolled in the advertised WSS. This549549+ * is done mainly because we follow the letter of the spec in this regard.550550+ * See WLP 0.99 [7.2.3].551551+ * When the device does become enrolled in a WSS the WSS information will552552+ * be stored as part of the more comprehensive struct wlp_wss.553553+ */554554+struct wlp_wss_tmp_info {555555+ char name[WLP_WSS_NAME_SIZE];556556+ u8 accept_enroll;557557+ u8 sec_status;558558+ struct uwb_mac_addr bcast;559559+};560560+561561+struct wlp_wssid_e {562562+ struct list_head node;563563+ struct wlp_uuid wssid;564564+ struct wlp_wss_tmp_info *info;565565+};566566+567567+/**568568+ * A cache entry of WLP neighborhood569569+ *570570+ * @node: head of list is wlp->neighbors571571+ * @wssid: list of wssids of this neighbor, element is wlp_wssid_e572572+ * @info: temporary storage for information learned during discovery. This573573+ * storage is used together with the wssid_e temporary storage574574+ * during discovery.575575+ */576576+struct wlp_neighbor_e {577577+ struct list_head node;578578+ struct wlp_uuid uuid;579579+ struct uwb_dev *uwb_dev;580580+ struct list_head wssid; /* Elements are wlp_wssid_e */581581+ struct wlp_device_info *info;582582+};583583+584584+struct wlp;585585+/**586586+ * Information for an association session in progress.587587+ *588588+ * @exp_message: The type of the expected message. Both this message and a589589+ * F0 message (which can be sent in response to any590590+ * association frame) will be accepted as a valid message for591591+ * this session.592592+ * @cb: The function that will be called upon receipt of this593593+ * message.594594+ * @cb_priv: Private data of callback595595+ * @data: Data used in association process (always a sk_buff?)596596+ * @neighbor: Address of neighbor with which association session is in597597+ * progress.598598+ */599599+struct wlp_session {600600+ enum wlp_assoc_type exp_message;601601+ void (*cb)(struct wlp *);602602+ void *cb_priv;603603+ void *data;604604+ struct uwb_dev_addr neighbor_addr;605605+};606606+607607+/**608608+ * WLP Service Set609609+ *610610+ * @mutex: used to protect entire WSS structure.611611+ *612612+ * @name: The WSS name is set to 65 bytes, 1 byte larger than the maximum613613+ * allowed by the WLP spec. This is to have a null terminated string614614+ * for display to the user. A maximum of 64 bytes will still be used615615+ * when placing the WSS name field in association frames.616616+ *617617+ * @accept_enroll: Accepting enrollment: Set to one if registrar is618618+ * accepting enrollment in WSS, or zero otherwise.619619+ *620620+ * Global and local information for each WSS in which we are enrolled.621621+ * WLP 0.99 Section 7.2.1 and Section 7.2.2622622+ */623623+struct wlp_wss {624624+ struct mutex mutex;625625+ struct kobject kobj;626626+ /* Global properties. */627627+ struct wlp_uuid wssid;628628+ u8 hash;629629+ char name[WLP_WSS_NAME_SIZE];630630+ struct uwb_mac_addr bcast;631631+ u8 secure_status:1;632632+ u8 master_key[16];633633+ /* Local properties. */634634+ u8 tag;635635+ struct uwb_mac_addr virtual_addr;636636+ /* Extra */637637+ u8 accept_enroll:1;638638+ enum wlp_wss_state state;639639+};640640+641641+/**642642+ * WLP main structure643643+ * @mutex: protect changes to WLP structure. We only allow changes to the644644+ * uuid, so currently this mutex only protects this field.645645+ */646646+struct wlp {647647+ struct mutex mutex;648648+ struct uwb_rc *rc; /* UWB radio controller */649649+ struct uwb_pal pal;650650+ struct wlp_eda eda;651651+ struct wlp_uuid uuid;652652+ struct wlp_session *session;653653+ struct wlp_wss wss;654654+ struct mutex nbmutex; /* Neighbor mutex protects neighbors list */655655+ struct list_head neighbors; /* Elements are wlp_neighbor_e */656656+ struct uwb_notifs_handler uwb_notifs_handler;657657+ struct wlp_device_info *dev_info;658658+ void (*fill_device_info)(struct wlp *wlp, struct wlp_device_info *info);659659+ int (*xmit_frame)(struct wlp *, struct sk_buff *,660660+ struct uwb_dev_addr *);661661+ void (*stop_queue)(struct wlp *);662662+ void (*start_queue)(struct wlp *);663663+};664664+665665+/* sysfs */666666+667667+668668+struct wlp_wss_attribute {669669+ struct attribute attr;670670+ ssize_t (*show)(struct wlp_wss *wss, char *buf);671671+ ssize_t (*store)(struct wlp_wss *wss, const char *buf, size_t count);672672+};673673+674674+#define WSS_ATTR(_name, _mode, _show, _store) \675675+static struct wlp_wss_attribute wss_attr_##_name = __ATTR(_name, _mode, \676676+ _show, _store)677677+678678+extern int wlp_setup(struct wlp *, struct uwb_rc *);679679+extern void wlp_remove(struct wlp *);680680+extern ssize_t wlp_neighborhood_show(struct wlp *, char *);681681+extern int wlp_wss_setup(struct net_device *, struct wlp_wss *);682682+extern void wlp_wss_remove(struct wlp_wss *);683683+extern ssize_t wlp_wss_activate_show(struct wlp_wss *, char *);684684+extern ssize_t wlp_wss_activate_store(struct wlp_wss *, const char *, size_t);685685+extern ssize_t wlp_eda_show(struct wlp *, char *);686686+extern ssize_t wlp_eda_store(struct wlp *, const char *, size_t);687687+extern ssize_t wlp_uuid_show(struct wlp *, char *);688688+extern ssize_t wlp_uuid_store(struct wlp *, const char *, size_t);689689+extern ssize_t wlp_dev_name_show(struct wlp *, char *);690690+extern ssize_t wlp_dev_name_store(struct wlp *, const char *, size_t);691691+extern ssize_t wlp_dev_manufacturer_show(struct wlp *, char *);692692+extern ssize_t wlp_dev_manufacturer_store(struct wlp *, const char *, size_t);693693+extern ssize_t wlp_dev_model_name_show(struct wlp *, char *);694694+extern ssize_t wlp_dev_model_name_store(struct wlp *, const char *, size_t);695695+extern ssize_t wlp_dev_model_nr_show(struct wlp *, char *);696696+extern ssize_t wlp_dev_model_nr_store(struct wlp *, const char *, size_t);697697+extern ssize_t wlp_dev_serial_show(struct wlp *, char *);698698+extern ssize_t wlp_dev_serial_store(struct wlp *, const char *, size_t);699699+extern ssize_t wlp_dev_prim_category_show(struct wlp *, char *);700700+extern ssize_t wlp_dev_prim_category_store(struct wlp *, const char *,701701+ size_t);702702+extern ssize_t wlp_dev_prim_OUI_show(struct wlp *, char *);703703+extern ssize_t wlp_dev_prim_OUI_store(struct wlp *, const char *, size_t);704704+extern ssize_t wlp_dev_prim_OUI_sub_show(struct wlp *, char *);705705+extern ssize_t wlp_dev_prim_OUI_sub_store(struct wlp *, const char *,706706+ size_t);707707+extern ssize_t wlp_dev_prim_subcat_show(struct wlp *, char *);708708+extern ssize_t wlp_dev_prim_subcat_store(struct wlp *, const char *,709709+ size_t);710710+extern int wlp_receive_frame(struct device *, struct wlp *, struct sk_buff *,711711+ struct uwb_dev_addr *);712712+extern int wlp_prepare_tx_frame(struct device *, struct wlp *,713713+ struct sk_buff *, struct uwb_dev_addr *);714714+void wlp_reset_all(struct wlp *wlp);715715+716716+/**717717+ * Initialize WSS718718+ */719719+static inline720720+void wlp_wss_init(struct wlp_wss *wss)721721+{722722+ mutex_init(&wss->mutex);723723+}724724+725725+static inline726726+void wlp_init(struct wlp *wlp)727727+{728728+ INIT_LIST_HEAD(&wlp->neighbors);729729+ mutex_init(&wlp->mutex);730730+ mutex_init(&wlp->nbmutex);731731+ wlp_wss_init(&wlp->wss);732732+}733733+734734+735735+#endif /* #ifndef __LINUX__WLP_H_ */