diff options
Diffstat (limited to 'drivers/net/wireless/adm8211.c')
-rw-r--r-- | drivers/net/wireless/adm8211.c | 58 |
1 files changed, 24 insertions, 34 deletions
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 5c0d2b082750..3333d4596b8d 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
@@ -306,11 +306,10 @@ static int adm8211_get_tx_stats(struct ieee80211_hw *dev, | |||
306 | struct ieee80211_tx_queue_stats *stats) | 306 | struct ieee80211_tx_queue_stats *stats) |
307 | { | 307 | { |
308 | struct adm8211_priv *priv = dev->priv; | 308 | struct adm8211_priv *priv = dev->priv; |
309 | struct ieee80211_tx_queue_stats_data *data = &stats->data[0]; | ||
310 | 309 | ||
311 | data->len = priv->cur_tx - priv->dirty_tx; | 310 | stats[0].len = priv->cur_tx - priv->dirty_tx; |
312 | data->limit = priv->tx_ring_size - 2; | 311 | stats[0].limit = priv->tx_ring_size - 2; |
313 | data->count = priv->dirty_tx; | 312 | stats[0].count = priv->dirty_tx; |
314 | 313 | ||
315 | return 0; | 314 | return 0; |
316 | } | 315 | } |
@@ -325,7 +324,7 @@ static void adm8211_interrupt_tci(struct ieee80211_hw *dev) | |||
325 | for (dirty_tx = priv->dirty_tx; priv->cur_tx - dirty_tx; dirty_tx++) { | 324 | for (dirty_tx = priv->dirty_tx; priv->cur_tx - dirty_tx; dirty_tx++) { |
326 | unsigned int entry = dirty_tx % priv->tx_ring_size; | 325 | unsigned int entry = dirty_tx % priv->tx_ring_size; |
327 | u32 status = le32_to_cpu(priv->tx_ring[entry].status); | 326 | u32 status = le32_to_cpu(priv->tx_ring[entry].status); |
328 | struct ieee80211_tx_status tx_status; | 327 | struct ieee80211_tx_info *txi; |
329 | struct adm8211_tx_ring_info *info; | 328 | struct adm8211_tx_ring_info *info; |
330 | struct sk_buff *skb; | 329 | struct sk_buff *skb; |
331 | 330 | ||
@@ -335,24 +334,23 @@ static void adm8211_interrupt_tci(struct ieee80211_hw *dev) | |||
335 | 334 | ||
336 | info = &priv->tx_buffers[entry]; | 335 | info = &priv->tx_buffers[entry]; |
337 | skb = info->skb; | 336 | skb = info->skb; |
337 | txi = IEEE80211_SKB_CB(skb); | ||
338 | 338 | ||
339 | /* TODO: check TDES0_STATUS_TUF and TDES0_STATUS_TRO */ | 339 | /* TODO: check TDES0_STATUS_TUF and TDES0_STATUS_TRO */ |
340 | 340 | ||
341 | pci_unmap_single(priv->pdev, info->mapping, | 341 | pci_unmap_single(priv->pdev, info->mapping, |
342 | info->skb->len, PCI_DMA_TODEVICE); | 342 | info->skb->len, PCI_DMA_TODEVICE); |
343 | 343 | ||
344 | memset(&tx_status, 0, sizeof(tx_status)); | 344 | memset(&txi->status, 0, sizeof(txi->status)); |
345 | skb_pull(skb, sizeof(struct adm8211_tx_hdr)); | 345 | skb_pull(skb, sizeof(struct adm8211_tx_hdr)); |
346 | memcpy(skb_push(skb, info->hdrlen), skb->cb, info->hdrlen); | 346 | memcpy(skb_push(skb, info->hdrlen), skb->cb, info->hdrlen); |
347 | memcpy(&tx_status.control, &info->tx_control, | 347 | if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK)) { |
348 | sizeof(tx_status.control)); | ||
349 | if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) { | ||
350 | if (status & TDES0_STATUS_ES) | 348 | if (status & TDES0_STATUS_ES) |
351 | tx_status.excessive_retries = 1; | 349 | txi->status.excessive_retries = 1; |
352 | else | 350 | else |
353 | tx_status.flags |= IEEE80211_TX_STATUS_ACK; | 351 | txi->flags |= IEEE80211_TX_STAT_ACK; |
354 | } | 352 | } |
355 | ieee80211_tx_status_irqsafe(dev, skb, &tx_status); | 353 | ieee80211_tx_status_irqsafe(dev, skb); |
356 | 354 | ||
357 | info->skb = NULL; | 355 | info->skb = NULL; |
358 | } | 356 | } |
@@ -446,9 +444,9 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev) | |||
446 | struct ieee80211_rx_status rx_status = {0}; | 444 | struct ieee80211_rx_status rx_status = {0}; |
447 | 445 | ||
448 | if (priv->pdev->revision < ADM8211_REV_CA) | 446 | if (priv->pdev->revision < ADM8211_REV_CA) |
449 | rx_status.ssi = rssi; | 447 | rx_status.signal = rssi; |
450 | else | 448 | else |
451 | rx_status.ssi = 100 - rssi; | 449 | rx_status.signal = 100 - rssi; |
452 | 450 | ||
453 | rx_status.rate_idx = rate; | 451 | rx_status.rate_idx = rate; |
454 | 452 | ||
@@ -1639,7 +1637,6 @@ static void adm8211_calc_durations(int *dur, int *plcp, size_t payload_len, int | |||
1639 | /* Transmit skb w/adm8211_tx_hdr (802.11 header created by hardware) */ | 1637 | /* Transmit skb w/adm8211_tx_hdr (802.11 header created by hardware) */ |
1640 | static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, | 1638 | static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, |
1641 | u16 plcp_signal, | 1639 | u16 plcp_signal, |
1642 | struct ieee80211_tx_control *control, | ||
1643 | size_t hdrlen) | 1640 | size_t hdrlen) |
1644 | { | 1641 | { |
1645 | struct adm8211_priv *priv = dev->priv; | 1642 | struct adm8211_priv *priv = dev->priv; |
@@ -1665,7 +1662,6 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1665 | 1662 | ||
1666 | priv->tx_buffers[entry].skb = skb; | 1663 | priv->tx_buffers[entry].skb = skb; |
1667 | priv->tx_buffers[entry].mapping = mapping; | 1664 | priv->tx_buffers[entry].mapping = mapping; |
1668 | memcpy(&priv->tx_buffers[entry].tx_control, control, sizeof(*control)); | ||
1669 | priv->tx_buffers[entry].hdrlen = hdrlen; | 1665 | priv->tx_buffers[entry].hdrlen = hdrlen; |
1670 | priv->tx_ring[entry].buffer1 = cpu_to_le32(mapping); | 1666 | priv->tx_ring[entry].buffer1 = cpu_to_le32(mapping); |
1671 | 1667 | ||
@@ -1686,22 +1682,20 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1686 | } | 1682 | } |
1687 | 1683 | ||
1688 | /* Put adm8211_tx_hdr on skb and transmit */ | 1684 | /* Put adm8211_tx_hdr on skb and transmit */ |
1689 | static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | 1685 | static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) |
1690 | struct ieee80211_tx_control *control) | ||
1691 | { | 1686 | { |
1692 | struct adm8211_tx_hdr *txhdr; | 1687 | struct adm8211_tx_hdr *txhdr; |
1693 | u16 fc; | ||
1694 | size_t payload_len, hdrlen; | 1688 | size_t payload_len, hdrlen; |
1695 | int plcp, dur, len, plcp_signal, short_preamble; | 1689 | int plcp, dur, len, plcp_signal, short_preamble; |
1696 | struct ieee80211_hdr *hdr; | 1690 | struct ieee80211_hdr *hdr; |
1691 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1692 | struct ieee80211_rate *txrate = ieee80211_get_tx_rate(dev, info); | ||
1697 | 1693 | ||
1698 | short_preamble = !!(control->tx_rate->flags & | 1694 | short_preamble = !!(txrate->flags & IEEE80211_TX_CTL_SHORT_PREAMBLE); |
1699 | IEEE80211_TXCTL_SHORT_PREAMBLE); | 1695 | plcp_signal = txrate->bitrate; |
1700 | plcp_signal = control->tx_rate->bitrate; | ||
1701 | 1696 | ||
1702 | hdr = (struct ieee80211_hdr *)skb->data; | 1697 | hdr = (struct ieee80211_hdr *)skb->data; |
1703 | fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED; | 1698 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1704 | hdrlen = ieee80211_get_hdrlen(fc); | ||
1705 | memcpy(skb->cb, skb->data, hdrlen); | 1699 | memcpy(skb->cb, skb->data, hdrlen); |
1706 | hdr = (struct ieee80211_hdr *)skb->cb; | 1700 | hdr = (struct ieee80211_hdr *)skb->cb; |
1707 | skb_pull(skb, hdrlen); | 1701 | skb_pull(skb, hdrlen); |
@@ -1715,8 +1709,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1715 | txhdr->frame_control = hdr->frame_control; | 1709 | txhdr->frame_control = hdr->frame_control; |
1716 | 1710 | ||
1717 | len = hdrlen + payload_len + FCS_LEN; | 1711 | len = hdrlen + payload_len + FCS_LEN; |
1718 | if (fc & IEEE80211_FCTL_PROTECTED) | ||
1719 | len += 8; | ||
1720 | 1712 | ||
1721 | txhdr->frag = cpu_to_le16(0x0FFF); | 1713 | txhdr->frag = cpu_to_le16(0x0FFF); |
1722 | adm8211_calc_durations(&dur, &plcp, payload_len, | 1714 | adm8211_calc_durations(&dur, &plcp, payload_len, |
@@ -1731,15 +1723,12 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1731 | if (short_preamble) | 1723 | if (short_preamble) |
1732 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_SHORT_PREAMBLE); | 1724 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_SHORT_PREAMBLE); |
1733 | 1725 | ||
1734 | if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) | 1726 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) |
1735 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS); | 1727 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS); |
1736 | 1728 | ||
1737 | if (fc & IEEE80211_FCTL_PROTECTED) | 1729 | txhdr->retry_limit = info->control.retry_limit; |
1738 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_WEP_ENGINE); | ||
1739 | 1730 | ||
1740 | txhdr->retry_limit = control->retry_limit; | 1731 | adm8211_tx_raw(dev, skb, plcp_signal, hdrlen); |
1741 | |||
1742 | adm8211_tx_raw(dev, skb, plcp_signal, control, hdrlen); | ||
1743 | 1732 | ||
1744 | return NETDEV_TX_OK; | 1733 | return NETDEV_TX_OK; |
1745 | } | 1734 | } |
@@ -1894,9 +1883,10 @@ static int __devinit adm8211_probe(struct pci_dev *pdev, | |||
1894 | 1883 | ||
1895 | dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); | 1884 | dev->extra_tx_headroom = sizeof(struct adm8211_tx_hdr); |
1896 | /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ | 1885 | /* dev->flags = IEEE80211_HW_RX_INCLUDES_FCS in promisc mode */ |
1886 | dev->flags = IEEE80211_HW_SIGNAL_UNSPEC; | ||
1897 | 1887 | ||
1898 | dev->channel_change_time = 1000; | 1888 | dev->channel_change_time = 1000; |
1899 | dev->max_rssi = 100; /* FIXME: find better value */ | 1889 | dev->max_signal = 100; /* FIXME: find better value */ |
1900 | 1890 | ||
1901 | dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */ | 1891 | dev->queues = 1; /* ADM8211C supports more, maybe ADM8211B too */ |
1902 | 1892 | ||
@@ -2015,7 +2005,7 @@ static int adm8211_resume(struct pci_dev *pdev) | |||
2015 | 2005 | ||
2016 | if (priv->mode != IEEE80211_IF_TYPE_INVALID) { | 2006 | if (priv->mode != IEEE80211_IF_TYPE_INVALID) { |
2017 | adm8211_start(dev); | 2007 | adm8211_start(dev); |
2018 | ieee80211_start_queues(dev); | 2008 | ieee80211_wake_queues(dev); |
2019 | } | 2009 | } |
2020 | 2010 | ||
2021 | return 0; | 2011 | return 0; |