1/* 2 * WiMedia Logical Link Control Protocol (WLP) 3 * Internal API 4 * 5 * Copyright (C) 2007 Intel Corporation 6 * Reinette Chatre <reinette.chatre@intel.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License version 10 * 2 as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20 * 02110-1301, USA. 21 * 22 */ 23 24#ifndef __WLP_INTERNAL_H__ 25#define __WLP_INTERNAL_H__ 26 27/** 28 * State of WSS connection 29 * 30 * A device needs to connect to a neighbor in an activated WSS before data 31 * can be transmitted. The spec also distinguishes between a new connection 32 * attempt and a connection attempt after previous connection attempts. The 33 * state WLP_WSS_CONNECT_FAILED is used for this scenario. See WLP 0.99 34 * [7.2.6] 35 */ 36enum wlp_wss_connect { 37 WLP_WSS_UNCONNECTED = 0, 38 WLP_WSS_CONNECTED, 39 WLP_WSS_CONNECT_FAILED, 40}; 41 42extern struct kobj_type wss_ktype; 43extern struct attribute_group wss_attr_group; 44 45/* This should be changed to a dynamic array where entries are sorted 46 * by eth_addr and search is done in a binary form 47 * 48 * Although thinking twice about it: this technologie's maximum reach 49 * is 10 meters...unless you want to pack too much stuff in around 50 * your radio controller/WLP device, the list will probably not be 51 * too big. 52 * 53 * In any case, there is probably some data structure in the kernel 54 * than we could reused for that already. 55 * 56 * The below structure is really just good while we support one WSS per 57 * host. 58 */ 59struct wlp_eda_node { 60 struct list_head list_node; 61 unsigned char eth_addr[ETH_ALEN]; 62 struct uwb_dev_addr dev_addr; 63 struct wlp_wss *wss; 64 unsigned char virt_addr[ETH_ALEN]; 65 u8 tag; 66 enum wlp_wss_connect state; 67}; 68 69typedef int (*wlp_eda_for_each_f)(struct wlp *, struct wlp_eda_node *, void *); 70 71extern void wlp_eda_init(struct wlp_eda *); 72extern void wlp_eda_release(struct wlp_eda *); 73extern int wlp_eda_create_node(struct wlp_eda *, 74 const unsigned char eth_addr[ETH_ALEN], 75 const struct uwb_dev_addr *); 76extern void wlp_eda_rm_node(struct wlp_eda *, const struct uwb_dev_addr *); 77extern int wlp_eda_update_node(struct wlp_eda *, 78 const struct uwb_dev_addr *, 79 struct wlp_wss *, 80 const unsigned char virt_addr[ETH_ALEN], 81 const u8, const enum wlp_wss_connect); 82extern int wlp_eda_update_node_state(struct wlp_eda *, 83 const struct uwb_dev_addr *, 84 const enum wlp_wss_connect); 85 86extern int wlp_copy_eda_node(struct wlp_eda *, struct uwb_dev_addr *, 87 struct wlp_eda_node *); 88extern int wlp_eda_for_each(struct wlp_eda *, wlp_eda_for_each_f , void *); 89extern int wlp_eda_for_virtual(struct wlp_eda *, 90 const unsigned char eth_addr[ETH_ALEN], 91 struct uwb_dev_addr *, 92 wlp_eda_for_each_f , void *); 93 94 95extern void wlp_remove_neighbor_tmp_info(struct wlp_neighbor_e *); 96 97extern size_t wlp_wss_key_print(char *, size_t, u8 *); 98 99/* Function called when no more references to WSS exists */ 100extern void wlp_wss_release(struct kobject *); 101 102extern void wlp_wss_reset(struct wlp_wss *); 103extern int wlp_wss_create_activate(struct wlp_wss *, struct wlp_uuid *, 104 char *, unsigned, unsigned); 105extern int wlp_wss_enroll_activate(struct wlp_wss *, struct wlp_uuid *, 106 struct uwb_dev_addr *); 107extern ssize_t wlp_discover(struct wlp *); 108 109extern int wlp_enroll_neighbor(struct wlp *, struct wlp_neighbor_e *, 110 struct wlp_wss *, struct wlp_uuid *); 111extern int wlp_wss_is_active(struct wlp *, struct wlp_wss *, 112 struct uwb_dev_addr *); 113 114struct wlp_assoc_conn_ctx { 115 struct work_struct ws; 116 struct wlp *wlp; 117 struct sk_buff *skb; 118 struct wlp_eda_node eda_entry; 119}; 120 121 122extern int wlp_wss_connect_prep(struct wlp *, struct wlp_eda_node *, void *); 123extern int wlp_wss_send_copy(struct wlp *, struct wlp_eda_node *, void *); 124 125 126/* Message handling */ 127struct wlp_assoc_frame_ctx { 128 struct work_struct ws; 129 struct wlp *wlp; 130 struct sk_buff *skb; 131 struct uwb_dev_addr src; 132}; 133 134extern int wlp_wss_prep_hdr(struct wlp *, struct wlp_eda_node *, void *); 135extern void wlp_handle_d1_frame(struct work_struct *); 136extern int wlp_parse_d2_frame_to_cache(struct wlp *, struct sk_buff *, 137 struct wlp_neighbor_e *); 138extern int wlp_parse_d2_frame_to_enroll(struct wlp_wss *, struct sk_buff *, 139 struct wlp_neighbor_e *, 140 struct wlp_uuid *); 141extern void wlp_handle_c1_frame(struct work_struct *); 142extern void wlp_handle_c3_frame(struct work_struct *); 143extern int wlp_parse_c3c4_frame(struct wlp *, struct sk_buff *, 144 struct wlp_uuid *, u8 *, 145 struct uwb_mac_addr *); 146extern int wlp_parse_f0(struct wlp *, struct sk_buff *); 147extern int wlp_send_assoc_frame(struct wlp *, struct wlp_wss *, 148 struct uwb_dev_addr *, enum wlp_assoc_type); 149extern ssize_t wlp_get_version(struct wlp *, struct wlp_attr_version *, 150 u8 *, ssize_t); 151extern ssize_t wlp_get_wssid(struct wlp *, struct wlp_attr_wssid *, 152 struct wlp_uuid *, ssize_t); 153extern int __wlp_alloc_device_info(struct wlp *); 154extern int __wlp_setup_device_info(struct wlp *); 155 156extern struct wlp_wss_attribute wss_attribute_properties; 157extern struct wlp_wss_attribute wss_attribute_members; 158extern struct wlp_wss_attribute wss_attribute_state; 159 160static inline 161size_t wlp_wss_uuid_print(char *buf, size_t bufsize, struct wlp_uuid *uuid) 162{ 163 size_t result; 164 165 result = scnprintf(buf, bufsize, 166 "%02x:%02x:%02x:%02x:%02x:%02x:" 167 "%02x:%02x:%02x:%02x:%02x:%02x:" 168 "%02x:%02x:%02x:%02x", 169 uuid->data[0], uuid->data[1], 170 uuid->data[2], uuid->data[3], 171 uuid->data[4], uuid->data[5], 172 uuid->data[6], uuid->data[7], 173 uuid->data[8], uuid->data[9], 174 uuid->data[10], uuid->data[11], 175 uuid->data[12], uuid->data[13], 176 uuid->data[14], uuid->data[15]); 177 return result; 178} 179 180static inline 181size_t wlp_wss_nonce_print(char *buf, size_t bufsize, struct wlp_nonce *nonce) 182{ 183 size_t result; 184 185 result = scnprintf(buf, bufsize, 186 "%02x %02x %02x %02x %02x %02x " 187 "%02x %02x %02x %02x %02x %02x " 188 "%02x %02x %02x %02x", 189 nonce->data[0], nonce->data[1], 190 nonce->data[2], nonce->data[3], 191 nonce->data[4], nonce->data[5], 192 nonce->data[6], nonce->data[7], 193 nonce->data[8], nonce->data[9], 194 nonce->data[10], nonce->data[11], 195 nonce->data[12], nonce->data[13], 196 nonce->data[14], nonce->data[15]); 197 return result; 198} 199 200 201static inline 202void wlp_session_cb(struct wlp *wlp) 203{ 204 struct completion *completion = wlp->session->cb_priv; 205 complete(completion); 206} 207 208static inline 209int wlp_uuid_is_set(struct wlp_uuid *uuid) 210{ 211 struct wlp_uuid zero_uuid = { .data = { 0x00, 0x00, 0x00, 0x00, 212 0x00, 0x00, 0x00, 0x00, 213 0x00, 0x00, 0x00, 0x00, 214 0x00, 0x00, 0x00, 0x00} }; 215 216 if (!memcmp(uuid, &zero_uuid, sizeof(*uuid))) 217 return 0; 218 return 1; 219} 220 221#endif /* __WLP_INTERNAL_H__ */ 222