rxtx.c (19375B)
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc. 4 * All rights reserved. 5 * 6 * Purpose: handle WMAC/802.3/802.11 rx & tx functions 7 * 8 * Author: Lyndon Chen 9 * 10 * Date: May 20, 2003 11 * 12 * Functions: 13 * vnt_generate_tx_parameter - Generate tx dma required parameter. 14 * vnt_get_rsvtime- get frame reserved time 15 * vnt_fill_cts_head- fulfill CTS ctl header 16 * 17 * Revision History: 18 * 19 */ 20 21#include <linux/etherdevice.h> 22#include "device.h" 23#include "rxtx.h" 24#include "card.h" 25#include "mac.h" 26#include "rf.h" 27#include "usbpipe.h" 28 29static const u16 vnt_time_stampoff[2][MAX_RATE] = { 30 /* Long Preamble */ 31 {384, 288, 226, 209, 54, 43, 37, 31, 28, 25, 24, 23}, 32 33 /* Short Preamble */ 34 {384, 192, 130, 113, 54, 43, 37, 31, 28, 25, 24, 23}, 35}; 36 37#define DATADUR_B 10 38#define DATADUR_A 11 39 40static const u8 vnt_phy_signal[] = { 41 0x00, /* RATE_1M */ 42 0x01, /* RATE_2M */ 43 0x02, /* RATE_5M */ 44 0x03, /* RATE_11M */ 45 0x8b, /* RATE_6M */ 46 0x8f, /* RATE_9M */ 47 0x8a, /* RATE_12M */ 48 0x8e, /* RATE_18M */ 49 0x89, /* RATE_24M */ 50 0x8d, /* RATE_36M */ 51 0x88, /* RATE_48M */ 52 0x8c /* RATE_54M */ 53}; 54 55static struct vnt_usb_send_context 56 *vnt_get_free_context(struct vnt_private *priv) 57{ 58 struct vnt_usb_send_context *context = NULL; 59 int ii; 60 61 for (ii = 0; ii < priv->num_tx_context; ii++) { 62 if (!priv->tx_context[ii]) 63 return NULL; 64 65 context = priv->tx_context[ii]; 66 if (!context->in_use) { 67 context->in_use = true; 68 return context; 69 } 70 } 71 72 if (ii == priv->num_tx_context) { 73 dev_dbg(&priv->usb->dev, "%s No Free Tx Context\n", __func__); 74 75 ieee80211_stop_queues(priv->hw); 76 } 77 78 return NULL; 79} 80 81/* Get Length, Service, and Signal fields of Phy for Tx */ 82static void vnt_get_phy_field(struct vnt_private *priv, u32 frame_length, 83 u16 tx_rate, u8 pkt_type, 84 struct vnt_phy_field *phy) 85{ 86 u32 bit_count; 87 u32 count = 0; 88 u32 tmp; 89 int ext_bit; 90 int i; 91 u8 mask = 0; 92 u8 preamble_type = priv->preamble_type; 93 94 bit_count = frame_length * 8; 95 ext_bit = false; 96 97 switch (tx_rate) { 98 case RATE_1M: 99 count = bit_count; 100 break; 101 case RATE_2M: 102 count = bit_count / 2; 103 break; 104 case RATE_5M: 105 count = DIV_ROUND_UP(bit_count * 10, 55); 106 break; 107 case RATE_11M: 108 count = bit_count / 11; 109 tmp = count * 11; 110 111 if (tmp != bit_count) { 112 count++; 113 114 if ((bit_count - tmp) <= 3) 115 ext_bit = true; 116 } 117 118 break; 119 } 120 121 if (tx_rate > RATE_11M) { 122 if (pkt_type == PK_TYPE_11A) 123 mask = BIT(4); 124 } else if (tx_rate > RATE_1M) { 125 if (preamble_type == PREAMBLE_SHORT) 126 mask = BIT(3); 127 } 128 129 i = tx_rate > RATE_54M ? RATE_54M : tx_rate; 130 phy->signal = vnt_phy_signal[i] | mask; 131 phy->service = 0x00; 132 133 if (pkt_type == PK_TYPE_11B) { 134 if (ext_bit) 135 phy->service |= 0x80; 136 phy->len = cpu_to_le16((u16)count); 137 } else { 138 phy->len = cpu_to_le16((u16)frame_length); 139 } 140} 141 142static __le16 vnt_time_stamp_off(struct vnt_private *priv, u16 rate) 143{ 144 return cpu_to_le16(vnt_time_stampoff[priv->preamble_type % 2] 145 [rate % MAX_RATE]); 146} 147 148static __le16 vnt_rxtx_rsvtime_le16(struct vnt_usb_send_context *context) 149{ 150 struct vnt_private *priv = context->priv; 151 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(context->skb); 152 struct ieee80211_rate *rate = ieee80211_get_tx_rate(priv->hw, info); 153 154 return ieee80211_generic_frame_duration(priv->hw, 155 info->control.vif, info->band, 156 context->frame_len, 157 rate); 158} 159 160static __le16 vnt_get_rts_duration(struct vnt_usb_send_context *context) 161{ 162 struct vnt_private *priv = context->priv; 163 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(context->skb); 164 165 return ieee80211_rts_duration(priv->hw, priv->vif, 166 context->frame_len, info); 167} 168 169static __le16 vnt_get_cts_duration(struct vnt_usb_send_context *context) 170{ 171 struct vnt_private *priv = context->priv; 172 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(context->skb); 173 174 return ieee80211_ctstoself_duration(priv->hw, priv->vif, 175 context->frame_len, info); 176} 177 178static void vnt_rxtx_datahead_g(struct vnt_usb_send_context *tx_context, 179 struct vnt_tx_datahead_g *buf) 180{ 181 struct vnt_private *priv = tx_context->priv; 182 struct ieee80211_hdr *hdr = 183 (struct ieee80211_hdr *)tx_context->skb->data; 184 u32 frame_len = tx_context->frame_len; 185 u16 rate = tx_context->tx_rate; 186 187 /* Get SignalField,ServiceField,Length */ 188 vnt_get_phy_field(priv, frame_len, rate, tx_context->pkt_type, &buf->a); 189 vnt_get_phy_field(priv, frame_len, priv->top_cck_basic_rate, 190 PK_TYPE_11B, &buf->b); 191 192 /* Get Duration and TimeStamp */ 193 buf->duration_a = hdr->duration_id; 194 buf->duration_b = hdr->duration_id; 195 buf->time_stamp_off_a = vnt_time_stamp_off(priv, rate); 196 buf->time_stamp_off_b = vnt_time_stamp_off(priv, 197 priv->top_cck_basic_rate); 198} 199 200static void vnt_rxtx_datahead_ab(struct vnt_usb_send_context *tx_context, 201 struct vnt_tx_datahead_ab *buf) 202{ 203 struct vnt_private *priv = tx_context->priv; 204 struct ieee80211_hdr *hdr = 205 (struct ieee80211_hdr *)tx_context->skb->data; 206 u32 frame_len = tx_context->frame_len; 207 u16 rate = tx_context->tx_rate; 208 209 /* Get SignalField,ServiceField,Length */ 210 vnt_get_phy_field(priv, frame_len, rate, 211 tx_context->pkt_type, &buf->ab); 212 213 /* Get Duration and TimeStampOff */ 214 buf->duration = hdr->duration_id; 215 buf->time_stamp_off = vnt_time_stamp_off(priv, rate); 216} 217 218static void vnt_fill_ieee80211_rts(struct vnt_usb_send_context *tx_context, 219 struct ieee80211_rts *rts, __le16 duration) 220{ 221 struct ieee80211_hdr *hdr = 222 (struct ieee80211_hdr *)tx_context->skb->data; 223 224 rts->duration = duration; 225 rts->frame_control = 226 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); 227 228 ether_addr_copy(rts->ra, hdr->addr1); 229 ether_addr_copy(rts->ta, hdr->addr2); 230} 231 232static void vnt_rxtx_rts_g_head(struct vnt_usb_send_context *tx_context, 233 struct vnt_rts_g *buf) 234{ 235 struct vnt_private *priv = tx_context->priv; 236 u16 rts_frame_len = 20; 237 238 vnt_get_phy_field(priv, rts_frame_len, priv->top_cck_basic_rate, 239 PK_TYPE_11B, &buf->b); 240 vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate, 241 tx_context->pkt_type, &buf->a); 242 243 buf->duration_bb = vnt_get_rts_duration(tx_context); 244 buf->duration_aa = buf->duration_bb; 245 buf->duration_ba = buf->duration_bb; 246 247 vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration_aa); 248 249 vnt_rxtx_datahead_g(tx_context, &buf->data_head); 250} 251 252static void vnt_rxtx_rts_ab_head(struct vnt_usb_send_context *tx_context, 253 struct vnt_rts_ab *buf) 254{ 255 struct vnt_private *priv = tx_context->priv; 256 u16 rts_frame_len = 20; 257 258 vnt_get_phy_field(priv, rts_frame_len, priv->top_ofdm_basic_rate, 259 tx_context->pkt_type, &buf->ab); 260 261 buf->duration = vnt_get_rts_duration(tx_context); 262 263 vnt_fill_ieee80211_rts(tx_context, &buf->data, buf->duration); 264 265 vnt_rxtx_datahead_ab(tx_context, &buf->data_head); 266} 267 268static void vnt_fill_cts_head(struct vnt_usb_send_context *tx_context, 269 union vnt_tx_data_head *head) 270{ 271 struct vnt_private *priv = tx_context->priv; 272 struct vnt_cts *buf = &head->cts_g; 273 u32 cts_frame_len = 14; 274 275 /* Get SignalField,ServiceField,Length */ 276 vnt_get_phy_field(priv, cts_frame_len, priv->top_cck_basic_rate, 277 PK_TYPE_11B, &buf->b); 278 /* Get CTSDuration_ba */ 279 buf->duration_ba = vnt_get_cts_duration(tx_context); 280 /*Get CTS Frame body*/ 281 buf->data.duration = buf->duration_ba; 282 buf->data.frame_control = 283 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); 284 285 ether_addr_copy(buf->data.ra, priv->current_net_addr); 286 287 vnt_rxtx_datahead_g(tx_context, &buf->data_head); 288} 289 290/* returns true if mic_hdr is needed */ 291static bool vnt_fill_txkey(struct vnt_tx_buffer *tx_buffer, struct sk_buff *skb) 292{ 293 struct vnt_tx_fifo_head *fifo = &tx_buffer->fifo_head; 294 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 295 struct ieee80211_key_conf *tx_key = info->control.hw_key; 296 struct vnt_mic_hdr *mic_hdr; 297 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 298 u64 pn64; 299 u16 payload_len = skb->len; 300 u8 *iv = ((u8 *)hdr + ieee80211_get_hdrlen_from_skb(skb)); 301 302 /* strip header and icv len from payload */ 303 payload_len -= ieee80211_get_hdrlen_from_skb(skb); 304 payload_len -= tx_key->icv_len; 305 306 switch (tx_key->cipher) { 307 case WLAN_CIPHER_SUITE_WEP40: 308 case WLAN_CIPHER_SUITE_WEP104: 309 memcpy(fifo->tx_key, iv, 3); 310 memcpy(fifo->tx_key + 3, tx_key->key, tx_key->keylen); 311 312 if (tx_key->keylen == WLAN_KEY_LEN_WEP40) { 313 memcpy(fifo->tx_key + 8, iv, 3); 314 memcpy(fifo->tx_key + 11, 315 tx_key->key, WLAN_KEY_LEN_WEP40); 316 } 317 318 fifo->frag_ctl |= cpu_to_le16(FRAGCTL_LEGACY); 319 break; 320 case WLAN_CIPHER_SUITE_TKIP: 321 ieee80211_get_tkip_p2k(tx_key, skb, fifo->tx_key); 322 323 fifo->frag_ctl |= cpu_to_le16(FRAGCTL_TKIP); 324 break; 325 case WLAN_CIPHER_SUITE_CCMP: 326 if (info->control.use_cts_prot) { 327 if (info->control.use_rts) 328 mic_hdr = &tx_buffer->tx_head.tx_rts.tx.mic.hdr; 329 else 330 mic_hdr = &tx_buffer->tx_head.tx_cts.tx.mic.hdr; 331 } else { 332 mic_hdr = &tx_buffer->tx_head.tx_ab.tx.mic.hdr; 333 } 334 335 mic_hdr->id = 0x59; 336 mic_hdr->payload_len = cpu_to_be16(payload_len); 337 ether_addr_copy(mic_hdr->mic_addr2, hdr->addr2); 338 339 pn64 = atomic64_read(&tx_key->tx_pn); 340 mic_hdr->ccmp_pn[5] = pn64; 341 mic_hdr->ccmp_pn[4] = pn64 >> 8; 342 mic_hdr->ccmp_pn[3] = pn64 >> 16; 343 mic_hdr->ccmp_pn[2] = pn64 >> 24; 344 mic_hdr->ccmp_pn[1] = pn64 >> 32; 345 mic_hdr->ccmp_pn[0] = pn64 >> 40; 346 347 if (ieee80211_has_a4(hdr->frame_control)) 348 mic_hdr->hlen = cpu_to_be16(28); 349 else 350 mic_hdr->hlen = cpu_to_be16(22); 351 352 ether_addr_copy(mic_hdr->addr1, hdr->addr1); 353 ether_addr_copy(mic_hdr->addr2, hdr->addr2); 354 ether_addr_copy(mic_hdr->addr3, hdr->addr3); 355 356 mic_hdr->frame_control = cpu_to_le16(le16_to_cpu(hdr->frame_control) & 0xc78f); 357 mic_hdr->seq_ctrl = cpu_to_le16(le16_to_cpu(hdr->seq_ctrl) & 0xf); 358 359 if (ieee80211_has_a4(hdr->frame_control)) 360 ether_addr_copy(mic_hdr->addr4, hdr->addr4); 361 362 memcpy(fifo->tx_key, tx_key->key, WLAN_KEY_LEN_CCMP); 363 364 fifo->frag_ctl |= cpu_to_le16(FRAGCTL_AES); 365 return true; 366 default: 367 break; 368 } 369 370 return false; 371} 372 373static void vnt_rxtx_rts(struct vnt_usb_send_context *tx_context) 374{ 375 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb); 376 struct vnt_tx_buffer *tx_buffer = tx_context->tx_buffer; 377 union vnt_tx_head *tx_head = &tx_buffer->tx_head; 378 struct vnt_rrv_time_rts *buf = &tx_head->tx_rts.rts; 379 union vnt_tx_data_head *head = &tx_head->tx_rts.tx.head; 380 381 buf->rts_rrv_time_aa = vnt_get_rts_duration(tx_context); 382 buf->rts_rrv_time_ba = buf->rts_rrv_time_aa; 383 buf->rts_rrv_time_bb = buf->rts_rrv_time_aa; 384 385 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(tx_context); 386 buf->rrv_time_b = buf->rrv_time_a; 387 388 if (info->control.hw_key) { 389 if (vnt_fill_txkey(tx_buffer, tx_context->skb)) 390 head = &tx_head->tx_rts.tx.mic.head; 391 } 392 393 vnt_rxtx_rts_g_head(tx_context, &head->rts_g); 394} 395 396static void vnt_rxtx_cts(struct vnt_usb_send_context *tx_context) 397{ 398 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb); 399 struct vnt_tx_buffer *tx_buffer = tx_context->tx_buffer; 400 union vnt_tx_head *tx_head = &tx_buffer->tx_head; 401 struct vnt_rrv_time_cts *buf = &tx_head->tx_cts.cts; 402 union vnt_tx_data_head *head = &tx_head->tx_cts.tx.head; 403 404 buf->rrv_time_a = vnt_rxtx_rsvtime_le16(tx_context); 405 buf->rrv_time_b = buf->rrv_time_a; 406 407 buf->cts_rrv_time_ba = vnt_get_cts_duration(tx_context); 408 409 if (info->control.hw_key) { 410 if (vnt_fill_txkey(tx_buffer, tx_context->skb)) 411 head = &tx_head->tx_cts.tx.mic.head; 412 } 413 414 vnt_fill_cts_head(tx_context, head); 415} 416 417static void vnt_rxtx_ab(struct vnt_usb_send_context *tx_context) 418{ 419 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb); 420 struct vnt_tx_buffer *tx_buffer = tx_context->tx_buffer; 421 union vnt_tx_head *tx_head = &tx_buffer->tx_head; 422 struct vnt_rrv_time_ab *buf = &tx_head->tx_ab.ab; 423 union vnt_tx_data_head *head = &tx_head->tx_ab.tx.head; 424 425 buf->rrv_time = vnt_rxtx_rsvtime_le16(tx_context); 426 427 if (info->control.hw_key) { 428 if (vnt_fill_txkey(tx_buffer, tx_context->skb)) 429 head = &tx_head->tx_ab.tx.mic.head; 430 } 431 432 if (info->control.use_rts) { 433 buf->rts_rrv_time = vnt_get_rts_duration(tx_context); 434 435 vnt_rxtx_rts_ab_head(tx_context, &head->rts_ab); 436 437 return; 438 } 439 440 vnt_rxtx_datahead_ab(tx_context, &head->data_head_ab); 441} 442 443static void vnt_generate_tx_parameter(struct vnt_usb_send_context *tx_context) 444{ 445 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx_context->skb); 446 447 if (info->control.use_cts_prot) { 448 if (info->control.use_rts) { 449 vnt_rxtx_rts(tx_context); 450 451 return; 452 } 453 454 vnt_rxtx_cts(tx_context); 455 456 return; 457 } 458 459 vnt_rxtx_ab(tx_context); 460} 461 462static u16 vnt_get_hdr_size(struct ieee80211_tx_info *info) 463{ 464 u16 size = sizeof(struct vnt_tx_datahead_ab); 465 466 if (info->control.use_cts_prot) { 467 if (info->control.use_rts) 468 size = sizeof(struct vnt_rts_g); 469 else 470 size = sizeof(struct vnt_cts); 471 } else if (info->control.use_rts) { 472 size = sizeof(struct vnt_rts_ab); 473 } 474 475 if (info->control.hw_key) { 476 if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_CCMP) 477 size += sizeof(struct vnt_mic_hdr); 478 } 479 480 /* Get rrv_time header */ 481 if (info->control.use_cts_prot) { 482 if (info->control.use_rts) 483 size += sizeof(struct vnt_rrv_time_rts); 484 else 485 size += sizeof(struct vnt_rrv_time_cts); 486 } else { 487 size += sizeof(struct vnt_rrv_time_ab); 488 } 489 490 size += sizeof(struct vnt_tx_fifo_head); 491 492 return size; 493} 494 495int vnt_tx_packet(struct vnt_private *priv, struct sk_buff *skb) 496{ 497 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 498 struct ieee80211_tx_rate *tx_rate = &info->control.rates[0]; 499 struct ieee80211_rate *rate; 500 struct ieee80211_hdr *hdr; 501 struct vnt_tx_buffer *tx_buffer; 502 struct vnt_tx_fifo_head *tx_buffer_head; 503 struct vnt_usb_send_context *tx_context; 504 unsigned long flags; 505 u8 pkt_type; 506 507 hdr = (struct ieee80211_hdr *)(skb->data); 508 509 rate = ieee80211_get_tx_rate(priv->hw, info); 510 511 if (rate->hw_value > RATE_11M) { 512 if (info->band == NL80211_BAND_5GHZ) { 513 pkt_type = PK_TYPE_11A; 514 } else { 515 if (tx_rate->flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { 516 if (priv->basic_rates & VNT_B_RATES) 517 pkt_type = PK_TYPE_11GB; 518 else 519 pkt_type = PK_TYPE_11GA; 520 } else { 521 pkt_type = PK_TYPE_11A; 522 } 523 } 524 } else { 525 pkt_type = PK_TYPE_11B; 526 } 527 528 spin_lock_irqsave(&priv->lock, flags); 529 530 tx_context = vnt_get_free_context(priv); 531 if (!tx_context) { 532 dev_dbg(&priv->usb->dev, "%s No free context\n", __func__); 533 spin_unlock_irqrestore(&priv->lock, flags); 534 return -ENOMEM; 535 } 536 537 tx_context->pkt_type = pkt_type; 538 tx_context->frame_len = skb->len + 4; 539 tx_context->tx_rate = rate->hw_value; 540 541 spin_unlock_irqrestore(&priv->lock, flags); 542 543 tx_context->skb = skb_clone(skb, GFP_ATOMIC); 544 if (!tx_context->skb) { 545 tx_context->in_use = false; 546 return -ENOMEM; 547 } 548 549 tx_buffer = skb_push(skb, vnt_get_hdr_size(info)); 550 tx_context->tx_buffer = tx_buffer; 551 tx_buffer_head = &tx_buffer->fifo_head; 552 553 tx_context->type = CONTEXT_DATA_PACKET; 554 555 /*Set fifo controls */ 556 if (pkt_type == PK_TYPE_11A) 557 tx_buffer_head->fifo_ctl = 0; 558 else if (pkt_type == PK_TYPE_11B) 559 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11B); 560 else if (pkt_type == PK_TYPE_11GB) 561 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GB); 562 else if (pkt_type == PK_TYPE_11GA) 563 tx_buffer_head->fifo_ctl = cpu_to_le16(FIFOCTL_11GA); 564 565 if (!ieee80211_is_data(hdr->frame_control)) { 566 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT | 567 FIFOCTL_ISDMA0); 568 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_TMOEN); 569 570 tx_buffer_head->time_stamp = 571 cpu_to_le16(DEFAULT_MGN_LIFETIME_RES_64us); 572 } else { 573 tx_buffer_head->time_stamp = 574 cpu_to_le16(DEFAULT_MSDU_LIFETIME_RES_64us); 575 } 576 577 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) 578 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_NEEDACK); 579 580 if (ieee80211_has_retry(hdr->frame_control)) 581 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LRETRY); 582 583 if (info->control.use_rts) 584 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_RTS); 585 586 if (ieee80211_has_a4(hdr->frame_control)) 587 tx_buffer_head->fifo_ctl |= cpu_to_le16(FIFOCTL_LHEAD); 588 589 tx_buffer_head->frag_ctl = 590 cpu_to_le16(ieee80211_hdrlen(hdr->frame_control) << 10); 591 592 if (info->control.hw_key) 593 tx_context->frame_len += info->control.hw_key->icv_len; 594 595 tx_buffer_head->current_rate = cpu_to_le16(rate->hw_value); 596 597 vnt_generate_tx_parameter(tx_context); 598 599 tx_buffer_head->frag_ctl |= cpu_to_le16(FRAGCTL_NONFRAG); 600 601 priv->seq_counter = (le16_to_cpu(hdr->seq_ctrl) & 602 IEEE80211_SCTL_SEQ) >> 4; 603 604 spin_lock_irqsave(&priv->lock, flags); 605 606 if (vnt_tx_context(priv, tx_context, skb)) { 607 dev_kfree_skb(tx_context->skb); 608 spin_unlock_irqrestore(&priv->lock, flags); 609 return -EIO; 610 } 611 612 dev_kfree_skb(skb); 613 614 spin_unlock_irqrestore(&priv->lock, flags); 615 616 return 0; 617} 618 619static int vnt_beacon_xmit(struct vnt_private *priv, struct sk_buff *skb) 620{ 621 struct vnt_tx_short_buf_head *short_head; 622 struct ieee80211_tx_info *info; 623 struct vnt_usb_send_context *context; 624 struct ieee80211_mgmt *mgmt_hdr; 625 unsigned long flags; 626 u32 frame_size = skb->len + 4; 627 u16 current_rate; 628 629 spin_lock_irqsave(&priv->lock, flags); 630 631 context = vnt_get_free_context(priv); 632 if (!context) { 633 dev_dbg(&priv->usb->dev, "%s No free context!\n", __func__); 634 spin_unlock_irqrestore(&priv->lock, flags); 635 return -ENOMEM; 636 } 637 638 context->skb = skb; 639 640 spin_unlock_irqrestore(&priv->lock, flags); 641 642 mgmt_hdr = (struct ieee80211_mgmt *)skb->data; 643 short_head = skb_push(skb, sizeof(*short_head)); 644 645 if (priv->bb_type == BB_TYPE_11A) { 646 current_rate = RATE_6M; 647 648 /* Get SignalField,ServiceField,Length */ 649 vnt_get_phy_field(priv, frame_size, current_rate, 650 PK_TYPE_11A, &short_head->ab); 651 652 /* Get TimeStampOff */ 653 short_head->time_stamp_off = 654 vnt_time_stamp_off(priv, current_rate); 655 } else { 656 current_rate = RATE_1M; 657 short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B); 658 659 /* Get SignalField,ServiceField,Length */ 660 vnt_get_phy_field(priv, frame_size, current_rate, 661 PK_TYPE_11B, &short_head->ab); 662 663 /* Get TimeStampOff */ 664 short_head->time_stamp_off = 665 vnt_time_stamp_off(priv, current_rate); 666 } 667 668 /* Get Duration */ 669 short_head->duration = mgmt_hdr->duration; 670 671 /* time stamp always 0 */ 672 mgmt_hdr->u.beacon.timestamp = 0; 673 674 info = IEEE80211_SKB_CB(skb); 675 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 676 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr; 677 678 hdr->duration_id = 0; 679 hdr->seq_ctrl = cpu_to_le16(priv->seq_counter << 4); 680 } 681 682 priv->seq_counter++; 683 if (priv->seq_counter > 0x0fff) 684 priv->seq_counter = 0; 685 686 context->type = CONTEXT_BEACON_PACKET; 687 688 spin_lock_irqsave(&priv->lock, flags); 689 690 if (vnt_tx_context(priv, context, skb)) 691 ieee80211_free_txskb(priv->hw, context->skb); 692 693 spin_unlock_irqrestore(&priv->lock, flags); 694 695 return 0; 696} 697 698int vnt_beacon_make(struct vnt_private *priv, struct ieee80211_vif *vif) 699{ 700 struct sk_buff *beacon; 701 702 beacon = ieee80211_beacon_get(priv->hw, vif); 703 if (!beacon) 704 return -ENOMEM; 705 706 if (vnt_beacon_xmit(priv, beacon)) { 707 ieee80211_free_txskb(priv->hw, beacon); 708 return -ENODEV; 709 } 710 711 return 0; 712} 713 714int vnt_beacon_enable(struct vnt_private *priv, struct ieee80211_vif *vif, 715 struct ieee80211_bss_conf *conf) 716{ 717 vnt_mac_reg_bits_off(priv, MAC_REG_TCR, TCR_AUTOBCNTX); 718 719 vnt_mac_reg_bits_off(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); 720 721 vnt_mac_set_beacon_interval(priv, conf->beacon_int); 722 723 vnt_clear_current_tsf(priv); 724 725 vnt_mac_reg_bits_on(priv, MAC_REG_TFTCTL, TFTCTL_TSFCNTREN); 726 727 vnt_reset_next_tbtt(priv, conf->beacon_int); 728 729 return vnt_beacon_make(priv, vif); 730}