Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.34 354 lines 11 kB view raw
1/* 2 * WiMedia Logical Link Control Protocol (WLP) 3 * Message exchange infrastructure 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 * FIXME: Docs 24 * 25 */ 26 27#include <linux/etherdevice.h> 28#include <linux/slab.h> 29#include <linux/wlp.h> 30 31#include "wlp-internal.h" 32 33/* 34 * Direct incoming association msg to correct parsing routine 35 * 36 * We only expect D1, E1, C1, C3 messages as new. All other incoming 37 * association messages should form part of an established session that is 38 * handled elsewhere. 39 * The handling of these messages often require calling sleeping functions 40 * - this cannot be done in interrupt context. We use the kernel's 41 * workqueue to handle these messages. 42 */ 43static 44void wlp_direct_assoc_frame(struct wlp *wlp, struct sk_buff *skb, 45 struct uwb_dev_addr *src) 46{ 47 struct device *dev = &wlp->rc->uwb_dev.dev; 48 struct wlp_frame_assoc *assoc = (void *) skb->data; 49 struct wlp_assoc_frame_ctx *frame_ctx; 50 51 frame_ctx = kmalloc(sizeof(*frame_ctx), GFP_ATOMIC); 52 if (frame_ctx == NULL) { 53 dev_err(dev, "WLP: Unable to allocate memory for association " 54 "frame handling.\n"); 55 kfree_skb(skb); 56 return; 57 } 58 frame_ctx->wlp = wlp; 59 frame_ctx->skb = skb; 60 frame_ctx->src = *src; 61 switch (assoc->type) { 62 case WLP_ASSOC_D1: 63 INIT_WORK(&frame_ctx->ws, wlp_handle_d1_frame); 64 schedule_work(&frame_ctx->ws); 65 break; 66 case WLP_ASSOC_E1: 67 kfree_skb(skb); /* Temporary until we handle it */ 68 kfree(frame_ctx); /* Temporary until we handle it */ 69 break; 70 case WLP_ASSOC_C1: 71 INIT_WORK(&frame_ctx->ws, wlp_handle_c1_frame); 72 schedule_work(&frame_ctx->ws); 73 break; 74 case WLP_ASSOC_C3: 75 INIT_WORK(&frame_ctx->ws, wlp_handle_c3_frame); 76 schedule_work(&frame_ctx->ws); 77 break; 78 default: 79 dev_err(dev, "Received unexpected association frame. " 80 "Type = %d \n", assoc->type); 81 kfree_skb(skb); 82 kfree(frame_ctx); 83 break; 84 } 85} 86 87/* 88 * Process incoming association frame 89 * 90 * Although it could be possible to deal with some incoming association 91 * messages without creating a new session we are keeping things simple. We 92 * do not accept new association messages if there is a session in progress 93 * and the messages do not belong to that session. 94 * 95 * If an association message arrives that causes the creation of a session 96 * (WLP_ASSOC_E1) while we are in the process of creating a session then we 97 * rely on the neighbor mutex to protect the data. That is, the new session 98 * will not be started until the previous is completed. 99 */ 100static 101void wlp_receive_assoc_frame(struct wlp *wlp, struct sk_buff *skb, 102 struct uwb_dev_addr *src) 103{ 104 struct device *dev = &wlp->rc->uwb_dev.dev; 105 struct wlp_frame_assoc *assoc = (void *) skb->data; 106 struct wlp_session *session = wlp->session; 107 u8 version; 108 109 if (wlp_get_version(wlp, &assoc->version, &version, 110 sizeof(assoc->version)) < 0) 111 goto error; 112 if (version != WLP_VERSION) { 113 dev_err(dev, "Unsupported WLP version in association " 114 "message.\n"); 115 goto error; 116 } 117 if (session != NULL) { 118 /* Function that created this session is still holding the 119 * &wlp->mutex to protect this session. */ 120 if (assoc->type == session->exp_message || 121 assoc->type == WLP_ASSOC_F0) { 122 if (!memcmp(&session->neighbor_addr, src, 123 sizeof(*src))) { 124 session->data = skb; 125 (session->cb)(wlp); 126 } else { 127 dev_err(dev, "Received expected message from " 128 "unexpected source. Expected message " 129 "%d or F0 from %02x:%02x, but received " 130 "it from %02x:%02x. Dropping.\n", 131 session->exp_message, 132 session->neighbor_addr.data[1], 133 session->neighbor_addr.data[0], 134 src->data[1], src->data[0]); 135 goto error; 136 } 137 } else { 138 dev_err(dev, "Association already in progress. " 139 "Dropping.\n"); 140 goto error; 141 } 142 } else { 143 wlp_direct_assoc_frame(wlp, skb, src); 144 } 145 return; 146error: 147 kfree_skb(skb); 148} 149 150/* 151 * Verify incoming frame is from connected neighbor, prep to pass to WLP client 152 * 153 * Verification proceeds according to WLP 0.99 [7.3.1]. The source address 154 * is used to determine which neighbor is sending the frame and the WSS tag 155 * is used to know to which WSS the frame belongs (we only support one WSS 156 * so this test is straight forward). 157 * With the WSS found we need to ensure that we are connected before 158 * allowing the exchange of data frames. 159 */ 160static 161int wlp_verify_prep_rx_frame(struct wlp *wlp, struct sk_buff *skb, 162 struct uwb_dev_addr *src) 163{ 164 struct device *dev = &wlp->rc->uwb_dev.dev; 165 int result = -EINVAL; 166 struct wlp_eda_node eda_entry; 167 struct wlp_frame_std_abbrv_hdr *hdr = (void *) skb->data; 168 169 /*verify*/ 170 result = wlp_copy_eda_node(&wlp->eda, src, &eda_entry); 171 if (result < 0) { 172 if (printk_ratelimit()) 173 dev_err(dev, "WLP: Incoming frame is from unknown " 174 "neighbor %02x:%02x.\n", src->data[1], 175 src->data[0]); 176 goto out; 177 } 178 if (hdr->tag != eda_entry.tag) { 179 if (printk_ratelimit()) 180 dev_err(dev, "WLP: Tag of incoming frame from " 181 "%02x:%02x does not match expected tag. " 182 "Received 0x%02x, expected 0x%02x. \n", 183 src->data[1], src->data[0], hdr->tag, 184 eda_entry.tag); 185 result = -EINVAL; 186 goto out; 187 } 188 if (eda_entry.state != WLP_WSS_CONNECTED) { 189 if (printk_ratelimit()) 190 dev_err(dev, "WLP: Incoming frame from " 191 "%02x:%02x does is not from connected WSS.\n", 192 src->data[1], src->data[0]); 193 result = -EINVAL; 194 goto out; 195 } 196 /*prep*/ 197 skb_pull(skb, sizeof(*hdr)); 198out: 199 return result; 200} 201 202/* 203 * Receive a WLP frame from device 204 * 205 * @returns: 1 if calling function should free the skb 206 * 0 if it successfully handled skb and freed it 207 * 0 if error occured, will free skb in this case 208 */ 209int wlp_receive_frame(struct device *dev, struct wlp *wlp, struct sk_buff *skb, 210 struct uwb_dev_addr *src) 211{ 212 unsigned len = skb->len; 213 void *ptr = skb->data; 214 struct wlp_frame_hdr *hdr; 215 int result = 0; 216 217 if (len < sizeof(*hdr)) { 218 dev_err(dev, "Not enough data to parse WLP header.\n"); 219 result = -EINVAL; 220 goto out; 221 } 222 hdr = ptr; 223 if (le16_to_cpu(hdr->mux_hdr) != WLP_PROTOCOL_ID) { 224 dev_err(dev, "Not a WLP frame type.\n"); 225 result = -EINVAL; 226 goto out; 227 } 228 switch (hdr->type) { 229 case WLP_FRAME_STANDARD: 230 if (len < sizeof(struct wlp_frame_std_abbrv_hdr)) { 231 dev_err(dev, "Not enough data to parse Standard " 232 "WLP header.\n"); 233 goto out; 234 } 235 result = wlp_verify_prep_rx_frame(wlp, skb, src); 236 if (result < 0) { 237 if (printk_ratelimit()) 238 dev_err(dev, "WLP: Verification of frame " 239 "from neighbor %02x:%02x failed.\n", 240 src->data[1], src->data[0]); 241 goto out; 242 } 243 result = 1; 244 break; 245 case WLP_FRAME_ABBREVIATED: 246 dev_err(dev, "Abbreviated frame received. FIXME?\n"); 247 kfree_skb(skb); 248 break; 249 case WLP_FRAME_CONTROL: 250 dev_err(dev, "Control frame received. FIXME?\n"); 251 kfree_skb(skb); 252 break; 253 case WLP_FRAME_ASSOCIATION: 254 if (len < sizeof(struct wlp_frame_assoc)) { 255 dev_err(dev, "Not enough data to parse Association " 256 "WLP header.\n"); 257 goto out; 258 } 259 wlp_receive_assoc_frame(wlp, skb, src); 260 break; 261 default: 262 dev_err(dev, "Invalid frame received.\n"); 263 result = -EINVAL; 264 break; 265 } 266out: 267 if (result < 0) { 268 kfree_skb(skb); 269 result = 0; 270 } 271 return result; 272} 273EXPORT_SYMBOL_GPL(wlp_receive_frame); 274 275 276/* 277 * Verify frame from network stack, prepare for further transmission 278 * 279 * @skb: the socket buffer that needs to be prepared for transmission (it 280 * is in need of a WLP header). If this is a broadcast frame we take 281 * over the entire transmission. 282 * If it is a unicast the WSS connection should already be established 283 * and transmission will be done by the calling function. 284 * @dst: On return this will contain the device address to which the 285 * frame is destined. 286 * @returns: 0 on success no tx : WLP header successfully applied to skb buffer, 287 * calling function can proceed with tx 288 * 1 on success with tx : WLP will take over transmission of this 289 * frame 290 * <0 on error 291 * 292 * The network stack (WLP client) is attempting to transmit a frame. We can 293 * only transmit data if a local WSS is at least active (connection will be 294 * done here if this is a broadcast frame and neighbor also has the WSS 295 * active). 296 * 297 * The frame can be either broadcast or unicast. Broadcast in a WSS is 298 * supported via multicast, but we don't support multicast yet (until 299 * devices start to support MAB IEs). If a broadcast frame needs to be 300 * transmitted it is treated as a unicast frame to each neighbor. In this 301 * case the WLP takes over transmission of the skb and returns 1 302 * to the caller to indicate so. Also, in this case, if a neighbor has the 303 * same WSS activated but is not connected then the WSS connection will be 304 * done at this time. The neighbor's virtual address will be learned at 305 * this time. 306 * 307 * The destination address in a unicast frame is the virtual address of the 308 * neighbor. This address only becomes known when a WSS connection is 309 * established. We thus rely on a broadcast frame to trigger the setup of 310 * WSS connections to all neighbors before we are able to send unicast 311 * frames to them. This seems reasonable as IP would usually use ARP first 312 * before any unicast frames are sent. 313 * 314 * If we are already connected to the neighbor (neighbor's virtual address 315 * is known) we just prepare the WLP header and the caller will continue to 316 * send the frame. 317 * 318 * A failure in this function usually indicates something that cannot be 319 * fixed automatically. So, if this function fails (@return < 0) the calling 320 * function should not retry to send the frame as it will very likely keep 321 * failing. 322 * 323 */ 324int wlp_prepare_tx_frame(struct device *dev, struct wlp *wlp, 325 struct sk_buff *skb, struct uwb_dev_addr *dst) 326{ 327 int result = -EINVAL; 328 struct ethhdr *eth_hdr = (void *) skb->data; 329 330 if (is_multicast_ether_addr(eth_hdr->h_dest)) { 331 result = wlp_eda_for_each(&wlp->eda, wlp_wss_send_copy, skb); 332 if (result < 0) { 333 if (printk_ratelimit()) 334 dev_err(dev, "Unable to handle broadcast " 335 "frame from WLP client.\n"); 336 goto out; 337 } 338 dev_kfree_skb_irq(skb); 339 result = 1; 340 /* Frame will be transmitted by WLP. */ 341 } else { 342 result = wlp_eda_for_virtual(&wlp->eda, eth_hdr->h_dest, dst, 343 wlp_wss_prep_hdr, skb); 344 if (unlikely(result < 0)) { 345 if (printk_ratelimit()) 346 dev_err(dev, "Unable to prepare " 347 "skb for transmission. \n"); 348 goto out; 349 } 350 } 351out: 352 return result; 353} 354EXPORT_SYMBOL_GPL(wlp_prepare_tx_frame);