aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/adm8211.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/adm8211.c')
-rw-r--r--drivers/net/wireless/adm8211.c58
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) */
1640static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, 1638static 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 */
1689static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb, 1685static 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;