diff options
-rw-r--r-- | drivers/net/wireless/ipw2200.c | 71 |
1 files changed, 33 insertions, 38 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index a879edba5fac..0500e8006a14 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -6859,61 +6859,55 @@ static int ipw_get_tx_queue_number(struct ipw_priv *priv, u16 priority) | |||
6859 | return from_priority_to_tx_queue[priority] - 1; | 6859 | return from_priority_to_tx_queue[priority] - 1; |
6860 | } | 6860 | } |
6861 | 6861 | ||
6862 | /* | 6862 | static int ipw_is_qos_active(struct net_device *dev, |
6863 | * add QoS parameter to the TX command | 6863 | struct sk_buff *skb) |
6864 | */ | ||
6865 | static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv, | ||
6866 | u16 priority, | ||
6867 | struct tfd_data *tfd, u8 unicast) | ||
6868 | { | 6864 | { |
6869 | int ret = 0; | 6865 | struct ipw_priv *priv = ieee80211_priv(dev); |
6870 | int tx_queue_id = 0; | ||
6871 | struct ieee80211_qos_data *qos_data = NULL; | 6866 | struct ieee80211_qos_data *qos_data = NULL; |
6872 | int active, supported; | 6867 | int active, supported; |
6873 | unsigned long flags; | 6868 | u8 *daddr = skb->data + ETH_ALEN; |
6869 | int unicast = !is_multicast_ether_addr(daddr); | ||
6874 | 6870 | ||
6875 | if (!(priv->status & STATUS_ASSOCIATED)) | 6871 | if (!(priv->status & STATUS_ASSOCIATED)) |
6876 | return 0; | 6872 | return 0; |
6877 | 6873 | ||
6878 | qos_data = &priv->assoc_network->qos_data; | 6874 | qos_data = &priv->assoc_network->qos_data; |
6879 | 6875 | ||
6880 | spin_lock_irqsave(&priv->ieee->lock, flags); | ||
6881 | |||
6882 | if (priv->ieee->iw_mode == IW_MODE_ADHOC) { | 6876 | if (priv->ieee->iw_mode == IW_MODE_ADHOC) { |
6883 | if (unicast == 0) | 6877 | if (unicast == 0) |
6884 | qos_data->active = 0; | 6878 | qos_data->active = 0; |
6885 | else | 6879 | else |
6886 | qos_data->active = qos_data->supported; | 6880 | qos_data->active = qos_data->supported; |
6887 | } | 6881 | } |
6888 | |||
6889 | active = qos_data->active; | 6882 | active = qos_data->active; |
6890 | supported = qos_data->supported; | 6883 | supported = qos_data->supported; |
6891 | |||
6892 | spin_unlock_irqrestore(&priv->ieee->lock, flags); | ||
6893 | |||
6894 | IPW_DEBUG_QOS("QoS %d network is QoS active %d supported %d " | 6884 | IPW_DEBUG_QOS("QoS %d network is QoS active %d supported %d " |
6895 | "unicast %d\n", | 6885 | "unicast %d\n", |
6896 | priv->qos_data.qos_enable, active, supported, unicast); | 6886 | priv->qos_data.qos_enable, active, supported, unicast); |
6897 | if (active && priv->qos_data.qos_enable) { | 6887 | if (active && priv->qos_data.qos_enable) |
6898 | ret = from_priority_to_tx_queue[priority]; | 6888 | return 1; |
6899 | tx_queue_id = ret - 1; | ||
6900 | IPW_DEBUG_QOS("QoS packet priority is %d \n", priority); | ||
6901 | if (priority <= 7) { | ||
6902 | tfd->tx_flags_ext |= DCT_FLAG_EXT_QOS_ENABLED; | ||
6903 | tfd->tfd.tfd_26.mchdr.qos_ctrl = priority; | ||
6904 | tfd->tfd.tfd_26.mchdr.frame_ctl |= | ||
6905 | IEEE80211_STYPE_QOS_DATA; | ||
6906 | |||
6907 | if (priv->qos_data.qos_no_ack_mask & | ||
6908 | (1UL << tx_queue_id)) { | ||
6909 | tfd->tx_flags &= ~DCT_FLAG_ACK_REQD; | ||
6910 | tfd->tfd.tfd_26.mchdr.qos_ctrl |= | ||
6911 | CTRL_QOS_NO_ACK; | ||
6912 | } | ||
6913 | } | ||
6914 | } | ||
6915 | 6889 | ||
6916 | return ret; | 6890 | return 0; |
6891 | |||
6892 | } | ||
6893 | /* | ||
6894 | * add QoS parameter to the TX command | ||
6895 | */ | ||
6896 | static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv, | ||
6897 | u16 priority, | ||
6898 | struct tfd_data *tfd) | ||
6899 | { | ||
6900 | int tx_queue_id = 0; | ||
6901 | |||
6902 | |||
6903 | tx_queue_id = from_priority_to_tx_queue[priority] - 1; | ||
6904 | tfd->tx_flags_ext |= DCT_FLAG_EXT_QOS_ENABLED; | ||
6905 | |||
6906 | if (priv->qos_data.qos_no_ack_mask & (1UL << tx_queue_id)) { | ||
6907 | tfd->tx_flags &= ~DCT_FLAG_ACK_REQD; | ||
6908 | tfd->tfd.tfd_26.mchdr.qos_ctrl |= CTRL_QOS_NO_ACK; | ||
6909 | } | ||
6910 | return 0; | ||
6917 | } | 6911 | } |
6918 | 6912 | ||
6919 | /* | 6913 | /* |
@@ -9653,7 +9647,7 @@ we need to heavily modify the ieee80211_skb_to_txb. | |||
9653 | static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | 9647 | static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, |
9654 | int pri) | 9648 | int pri) |
9655 | { | 9649 | { |
9656 | struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) | 9650 | struct ieee80211_hdr_3addrqos *hdr = (struct ieee80211_hdr_3addrqos *) |
9657 | txb->fragments[0]->data; | 9651 | txb->fragments[0]->data; |
9658 | int i = 0; | 9652 | int i = 0; |
9659 | struct tfd_frame *tfd; | 9653 | struct tfd_frame *tfd; |
@@ -9668,9 +9662,9 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
9668 | u16 remaining_bytes; | 9662 | u16 remaining_bytes; |
9669 | int fc; | 9663 | int fc; |
9670 | 9664 | ||
9665 | hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); | ||
9671 | switch (priv->ieee->iw_mode) { | 9666 | switch (priv->ieee->iw_mode) { |
9672 | case IW_MODE_ADHOC: | 9667 | case IW_MODE_ADHOC: |
9673 | hdr_len = IEEE80211_3ADDR_LEN; | ||
9674 | unicast = !is_multicast_ether_addr(hdr->addr1); | 9668 | unicast = !is_multicast_ether_addr(hdr->addr1); |
9675 | id = ipw_find_station(priv, hdr->addr1); | 9669 | id = ipw_find_station(priv, hdr->addr1); |
9676 | if (id == IPW_INVALID_STATION) { | 9670 | if (id == IPW_INVALID_STATION) { |
@@ -9687,7 +9681,6 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
9687 | case IW_MODE_INFRA: | 9681 | case IW_MODE_INFRA: |
9688 | default: | 9682 | default: |
9689 | unicast = !is_multicast_ether_addr(hdr->addr3); | 9683 | unicast = !is_multicast_ether_addr(hdr->addr3); |
9690 | hdr_len = IEEE80211_3ADDR_LEN; | ||
9691 | id = 0; | 9684 | id = 0; |
9692 | break; | 9685 | break; |
9693 | } | 9686 | } |
@@ -9766,7 +9759,8 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
9766 | tfd->u.data.tx_flags |= DCT_FLAG_NO_WEP; | 9759 | tfd->u.data.tx_flags |= DCT_FLAG_NO_WEP; |
9767 | 9760 | ||
9768 | #ifdef CONFIG_IPW_QOS | 9761 | #ifdef CONFIG_IPW_QOS |
9769 | ipw_qos_set_tx_queue_command(priv, pri, &(tfd->u.data), unicast); | 9762 | if (fc & IEEE80211_STYPE_QOS_DATA) |
9763 | ipw_qos_set_tx_queue_command(priv, pri, &(tfd->u.data)); | ||
9770 | #endif /* CONFIG_IPW_QOS */ | 9764 | #endif /* CONFIG_IPW_QOS */ |
9771 | 9765 | ||
9772 | /* payload */ | 9766 | /* payload */ |
@@ -10966,6 +10960,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
10966 | priv->ieee->is_queue_full = ipw_net_is_queue_full; | 10960 | priv->ieee->is_queue_full = ipw_net_is_queue_full; |
10967 | 10961 | ||
10968 | #ifdef CONFIG_IPW_QOS | 10962 | #ifdef CONFIG_IPW_QOS |
10963 | priv->ieee->is_qos_active = ipw_is_qos_active; | ||
10969 | priv->ieee->handle_probe_response = ipw_handle_beacon; | 10964 | priv->ieee->handle_probe_response = ipw_handle_beacon; |
10970 | priv->ieee->handle_beacon = ipw_handle_probe_response; | 10965 | priv->ieee->handle_beacon = ipw_handle_probe_response; |
10971 | priv->ieee->handle_assoc_response = ipw_handle_assoc_response; | 10966 | priv->ieee->handle_assoc_response = ipw_handle_assoc_response; |