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; |
