aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54/p54common.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-05-15 06:55:29 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-21 21:48:11 -0400
commite039fa4a4195ac4ee895e6f3d1334beed63256fe (patch)
treecfd0762d73df96b73052378be7b157c4ac6e7035 /drivers/net/wireless/p54/p54common.c
parente24549485f859be6518929bb1c9c0257d79f033d (diff)
mac80211: move TX info into skb->cb
This patch converts mac80211 and all drivers to have transmit information and status in skb->cb rather than allocating extra memory for it and copying all the data around. To make it fit, a union is used where only data that is necessary for all steps is kept outside of the union. A number of fixes were done by Ivo, as well as the rt2x00 part of this patch. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Acked-by: David S. Miller <davem@davemloft.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54/p54common.c')
-rw-r--r--drivers/net/wireless/p54/p54common.c90
1 files changed, 38 insertions, 52 deletions
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 3ca9386561ff..850857932e29 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -394,7 +394,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
394 while (entry != (struct sk_buff *)&priv->tx_queue) { 394 while (entry != (struct sk_buff *)&priv->tx_queue) {
395 range = (struct memrecord *)&entry->cb; 395 range = (struct memrecord *)&entry->cb;
396 if (range->start_addr == addr) { 396 if (range->start_addr == addr) {
397 struct ieee80211_tx_status status; 397 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
398 struct p54_control_hdr *entry_hdr; 398 struct p54_control_hdr *entry_hdr;
399 struct p54_tx_control_allocdata *entry_data; 399 struct p54_tx_control_allocdata *entry_data;
400 int pad = 0; 400 int pad = 0;
@@ -406,30 +406,23 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
406 406
407 last_addr = range->end_addr; 407 last_addr = range->end_addr;
408 __skb_unlink(entry, &priv->tx_queue); 408 __skb_unlink(entry, &priv->tx_queue);
409 if (!range->control) { 409 memset(&info->status, 0, sizeof(info->status));
410 kfree_skb(entry); 410 priv->tx_stats[info->queue].len--;
411 break;
412 }
413 memset(&status, 0, sizeof(status));
414 memcpy(&status.control, range->control,
415 sizeof(status.control));
416 kfree(range->control);
417 priv->tx_stats[status.control.queue].len--;
418 entry_hdr = (struct p54_control_hdr *) entry->data; 411 entry_hdr = (struct p54_control_hdr *) entry->data;
419 entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data; 412 entry_data = (struct p54_tx_control_allocdata *) entry_hdr->data;
420 if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0) 413 if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
421 pad = entry_data->align[0]; 414 pad = entry_data->align[0];
422 415
423 if (!(status.control.flags & IEEE80211_TXCTL_NO_ACK)) { 416 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
424 if (!(payload->status & 0x01)) 417 if (!(payload->status & 0x01))
425 status.flags |= IEEE80211_TX_STATUS_ACK; 418 info->flags |= IEEE80211_TX_STAT_ACK;
426 else 419 else
427 status.excessive_retries = 1; 420 info->status.excessive_retries = 1;
428 } 421 }
429 status.retry_count = payload->retries - 1; 422 info->status.retry_count = payload->retries - 1;
430 status.ack_signal = le16_to_cpu(payload->ack_rssi); 423 info->status.ack_signal = le16_to_cpu(payload->ack_rssi);
431 skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data)); 424 skb_pull(entry, sizeof(*hdr) + pad + sizeof(*entry_data));
432 ieee80211_tx_status_irqsafe(dev, entry, &status); 425 ieee80211_tx_status_irqsafe(dev, entry);
433 break; 426 break;
434 } else 427 } else
435 last_addr = range->end_addr; 428 last_addr = range->end_addr;
@@ -494,13 +487,11 @@ EXPORT_SYMBOL_GPL(p54_rx);
494 * allocated areas. 487 * allocated areas.
495 */ 488 */
496static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, 489static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
497 struct p54_control_hdr *data, u32 len, 490 struct p54_control_hdr *data, u32 len)
498 struct ieee80211_tx_control *control)
499{ 491{
500 struct p54_common *priv = dev->priv; 492 struct p54_common *priv = dev->priv;
501 struct sk_buff *entry = priv->tx_queue.next; 493 struct sk_buff *entry = priv->tx_queue.next;
502 struct sk_buff *target_skb = NULL; 494 struct sk_buff *target_skb = NULL;
503 struct memrecord *range;
504 u32 last_addr = priv->rx_start; 495 u32 last_addr = priv->rx_start;
505 u32 largest_hole = 0; 496 u32 largest_hole = 0;
506 u32 target_addr = priv->rx_start; 497 u32 target_addr = priv->rx_start;
@@ -512,7 +503,8 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
512 left = skb_queue_len(&priv->tx_queue); 503 left = skb_queue_len(&priv->tx_queue);
513 while (left--) { 504 while (left--) {
514 u32 hole_size; 505 u32 hole_size;
515 range = (struct memrecord *)&entry->cb; 506 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry);
507 struct memrecord *range = (void *)info->driver_data;
516 hole_size = range->start_addr - last_addr; 508 hole_size = range->start_addr - last_addr;
517 if (!target_skb && hole_size >= len) { 509 if (!target_skb && hole_size >= len) {
518 target_skb = entry->prev; 510 target_skb = entry->prev;
@@ -527,17 +519,18 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
527 target_skb = priv->tx_queue.prev; 519 target_skb = priv->tx_queue.prev;
528 largest_hole = max(largest_hole, priv->rx_end - last_addr - len); 520 largest_hole = max(largest_hole, priv->rx_end - last_addr - len);
529 if (!skb_queue_empty(&priv->tx_queue)) { 521 if (!skb_queue_empty(&priv->tx_queue)) {
530 range = (struct memrecord *)&target_skb->cb; 522 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(target_skb);
523 struct memrecord *range = (void *)info->driver_data;
531 target_addr = range->end_addr; 524 target_addr = range->end_addr;
532 } 525 }
533 } else 526 } else
534 largest_hole = max(largest_hole, priv->rx_end - last_addr); 527 largest_hole = max(largest_hole, priv->rx_end - last_addr);
535 528
536 if (skb) { 529 if (skb) {
537 range = (struct memrecord *)&skb->cb; 530 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
531 struct memrecord *range = (void *)info->driver_data;
538 range->start_addr = target_addr; 532 range->start_addr = target_addr;
539 range->end_addr = target_addr + len; 533 range->end_addr = target_addr + len;
540 range->control = control;
541 __skb_queue_after(&priv->tx_queue, target_skb, skb); 534 __skb_queue_after(&priv->tx_queue, target_skb, skb);
542 if (largest_hole < IEEE80211_MAX_RTS_THRESHOLD + 0x170 + 535 if (largest_hole < IEEE80211_MAX_RTS_THRESHOLD + 0x170 +
543 sizeof(struct p54_control_hdr)) 536 sizeof(struct p54_control_hdr))
@@ -548,32 +541,27 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
548 data->req_id = cpu_to_le32(target_addr + 0x70); 541 data->req_id = cpu_to_le32(target_addr + 0x70);
549} 542}
550 543
551static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb, 544static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
552 struct ieee80211_tx_control *control)
553{ 545{
546 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
554 struct ieee80211_tx_queue_stats *current_queue; 547 struct ieee80211_tx_queue_stats *current_queue;
555 struct p54_common *priv = dev->priv; 548 struct p54_common *priv = dev->priv;
556 struct p54_control_hdr *hdr; 549 struct p54_control_hdr *hdr;
557 struct p54_tx_control_allocdata *txhdr; 550 struct p54_tx_control_allocdata *txhdr;
558 struct ieee80211_tx_control *control_copy;
559 size_t padding, len; 551 size_t padding, len;
560 u8 rate; 552 u8 rate;
561 553
562 current_queue = &priv->tx_stats[control->queue]; 554 current_queue = &priv->tx_stats[info->queue];
563 if (unlikely(current_queue->len > current_queue->limit)) 555 if (unlikely(current_queue->len > current_queue->limit))
564 return NETDEV_TX_BUSY; 556 return NETDEV_TX_BUSY;
565 current_queue->len++; 557 current_queue->len++;
566 current_queue->count++; 558 current_queue->count++;
567 if (current_queue->len == current_queue->limit) 559 if (current_queue->len == current_queue->limit)
568 ieee80211_stop_queue(dev, control->queue); 560 ieee80211_stop_queue(dev, info->queue);
569 561
570 padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3; 562 padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3;
571 len = skb->len; 563 len = skb->len;
572 564
573 control_copy = kmalloc(sizeof(*control), GFP_ATOMIC);
574 if (control_copy)
575 memcpy(control_copy, control, sizeof(*control));
576
577 txhdr = (struct p54_tx_control_allocdata *) 565 txhdr = (struct p54_tx_control_allocdata *)
578 skb_push(skb, sizeof(*txhdr) + padding); 566 skb_push(skb, sizeof(*txhdr) + padding);
579 hdr = (struct p54_control_hdr *) skb_push(skb, sizeof(*hdr)); 567 hdr = (struct p54_control_hdr *) skb_push(skb, sizeof(*hdr));
@@ -583,35 +571,37 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb,
583 else 571 else
584 hdr->magic1 = cpu_to_le16(0x0010); 572 hdr->magic1 = cpu_to_le16(0x0010);
585 hdr->len = cpu_to_le16(len); 573 hdr->len = cpu_to_le16(len);
586 hdr->type = (control->flags & IEEE80211_TXCTL_NO_ACK) ? 0 : cpu_to_le16(1); 574 hdr->type = (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 0 : cpu_to_le16(1);
587 hdr->retry1 = hdr->retry2 = control->retry_limit; 575 hdr->retry1 = hdr->retry2 = info->control.retry_limit;
588 p54_assign_address(dev, skb, hdr, skb->len, control_copy);
589 576
590 memset(txhdr->wep_key, 0x0, 16); 577 memset(txhdr->wep_key, 0x0, 16);
591 txhdr->padding = 0; 578 txhdr->padding = 0;
592 txhdr->padding2 = 0; 579 txhdr->padding2 = 0;
593 580
594 /* TODO: add support for alternate retry TX rates */ 581 /* TODO: add support for alternate retry TX rates */
595 rate = ieee80211_get_tx_rate(dev, control)->hw_value; 582 rate = ieee80211_get_tx_rate(dev, info)->hw_value;
596 if (control->flags & IEEE80211_TXCTL_SHORT_PREAMBLE) 583 if (info->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE)
597 rate |= 0x10; 584 rate |= 0x10;
598 if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) 585 if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
599 rate |= 0x40; 586 rate |= 0x40;
600 else if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) 587 else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
601 rate |= 0x20; 588 rate |= 0x20;
602 memset(txhdr->rateset, rate, 8); 589 memset(txhdr->rateset, rate, 8);
603 txhdr->wep_key_present = 0; 590 txhdr->wep_key_present = 0;
604 txhdr->wep_key_len = 0; 591 txhdr->wep_key_len = 0;
605 txhdr->frame_type = cpu_to_le32(control->queue + 4); 592 txhdr->frame_type = cpu_to_le32(info->queue + 4);
606 txhdr->magic4 = 0; 593 txhdr->magic4 = 0;
607 txhdr->antenna = (control->antenna_sel_tx == 0) ? 594 txhdr->antenna = (info->antenna_sel_tx == 0) ?
608 2 : control->antenna_sel_tx - 1; 595 2 : info->antenna_sel_tx - 1;
609 txhdr->output_power = 0x7f; // HW Maximum 596 txhdr->output_power = 0x7f; // HW Maximum
610 txhdr->magic5 = (control->flags & IEEE80211_TXCTL_NO_ACK) ? 597 txhdr->magic5 = (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
611 0 : ((rate > 0x3) ? cpu_to_le32(0x33) : cpu_to_le32(0x23)); 598 0 : ((rate > 0x3) ? cpu_to_le32(0x33) : cpu_to_le32(0x23));
612 if (padding) 599 if (padding)
613 txhdr->align[0] = padding; 600 txhdr->align[0] = padding;
614 601
602 /* modifies skb->cb and with it info, so must be last! */
603 p54_assign_address(dev, skb, hdr, skb->len);
604
615 priv->tx(dev, hdr, skb->len, 0); 605 priv->tx(dev, hdr, skb->len, 0);
616 return 0; 606 return 0;
617} 607}
@@ -634,7 +624,7 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
634 filter = (struct p54_tx_control_filter *) hdr->data; 624 filter = (struct p54_tx_control_filter *) hdr->data;
635 hdr->magic1 = cpu_to_le16(0x8001); 625 hdr->magic1 = cpu_to_le16(0x8001);
636 hdr->len = cpu_to_le16(sizeof(*filter)); 626 hdr->len = cpu_to_le16(sizeof(*filter));
637 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*filter), NULL); 627 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*filter));
638 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_FILTER_SET); 628 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_FILTER_SET);
639 629
640 filter->filter_type = cpu_to_le16(filter_type); 630 filter->filter_type = cpu_to_le16(filter_type);
@@ -678,7 +668,7 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
678 hdr->magic1 = cpu_to_le16(0x8001); 668 hdr->magic1 = cpu_to_le16(0x8001);
679 hdr->len = cpu_to_le16(sizeof(*chan)); 669 hdr->len = cpu_to_le16(sizeof(*chan));
680 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE); 670 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE);
681 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + payload_len, NULL); 671 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + payload_len);
682 672
683 chan->magic1 = cpu_to_le16(0x1); 673 chan->magic1 = cpu_to_le16(0x1);
684 chan->magic2 = cpu_to_le16(0x0); 674 chan->magic2 = cpu_to_le16(0x0);
@@ -751,7 +741,7 @@ static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
751 hdr->magic1 = cpu_to_le16(0x8001); 741 hdr->magic1 = cpu_to_le16(0x8001);
752 hdr->len = cpu_to_le16(sizeof(*led)); 742 hdr->len = cpu_to_le16(sizeof(*led));
753 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_LED); 743 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_LED);
754 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*led), NULL); 744 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*led));
755 745
756 led = (struct p54_tx_control_led *) hdr->data; 746 led = (struct p54_tx_control_led *) hdr->data;
757 led->mode = cpu_to_le16(mode); 747 led->mode = cpu_to_le16(mode);
@@ -801,7 +791,7 @@ static void p54_set_vdcf(struct ieee80211_hw *dev)
801 791
802 hdr = (void *)priv->cached_vdcf + priv->tx_hdr_len; 792 hdr = (void *)priv->cached_vdcf + priv->tx_hdr_len;
803 793
804 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*vdcf), NULL); 794 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*vdcf));
805 795
806 vdcf = (struct p54_tx_control_vdcf *) hdr->data; 796 vdcf = (struct p54_tx_control_vdcf *) hdr->data;
807 797
@@ -837,12 +827,8 @@ static void p54_stop(struct ieee80211_hw *dev)
837{ 827{
838 struct p54_common *priv = dev->priv; 828 struct p54_common *priv = dev->priv;
839 struct sk_buff *skb; 829 struct sk_buff *skb;
840 while ((skb = skb_dequeue(&priv->tx_queue))) { 830 while ((skb = skb_dequeue(&priv->tx_queue)))
841 struct memrecord *range = (struct memrecord *)&skb->cb;
842 if (range->control)
843 kfree(range->control);
844 kfree_skb(skb); 831 kfree_skb(skb);
845 }
846 priv->stop(dev); 832 priv->stop(dev);
847 priv->mode = IEEE80211_IF_TYPE_INVALID; 833 priv->mode = IEEE80211_IF_TYPE_INVALID;
848} 834}