diff options
author | James Ketrenos <jketreno@linux.intel.com> | 2005-07-28 17:25:55 -0400 |
---|---|---|
committer | James Ketrenos <jketreno@linux.intel.com> | 2005-11-07 18:50:27 -0500 |
commit | 227d2dc1f109e3348564320cf42fc56770428ed3 (patch) | |
tree | 0f3b2c85592e8ea4cdd998e10e9308d69b2d954d /drivers/net/wireless/ipw2200.c | |
parent | d2021cb4e28c512c395a439d65556c260b94e47e (diff) |
Updated to support ieee80211 callback to is_queue_full for 802.11e
support.
Signed-off-by: James Ketrenos <jketreno@linux.intel.com>
Diffstat (limited to 'drivers/net/wireless/ipw2200.c')
-rw-r--r-- | drivers/net/wireless/ipw2200.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 0923038ca788..3b3a4a077c0e 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c | |||
@@ -9654,8 +9654,8 @@ modify to send one tfd per fragment instead of using chunking. otherwise | |||
9654 | we need to heavily modify the ieee80211_skb_to_txb. | 9654 | we need to heavily modify the ieee80211_skb_to_txb. |
9655 | */ | 9655 | */ |
9656 | 9656 | ||
9657 | static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | 9657 | static inline int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, |
9658 | int pri) | 9658 | int pri) |
9659 | { | 9659 | { |
9660 | struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) | 9660 | struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *) |
9661 | txb->fragments[0]->data; | 9661 | txb->fragments[0]->data; |
@@ -9672,6 +9672,11 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
9672 | u16 remaining_bytes; | 9672 | u16 remaining_bytes; |
9673 | int fc; | 9673 | int fc; |
9674 | 9674 | ||
9675 | /* If there isn't room in the queue, we return busy and let the | ||
9676 | * network stack requeue the packet for us */ | ||
9677 | if (ipw_queue_space(q) < q->high_mark) | ||
9678 | return NETDEV_TX_BUSY; | ||
9679 | |||
9675 | switch (priv->ieee->iw_mode) { | 9680 | switch (priv->ieee->iw_mode) { |
9676 | case IW_MODE_ADHOC: | 9681 | case IW_MODE_ADHOC: |
9677 | hdr_len = IEEE80211_3ADDR_LEN; | 9682 | hdr_len = IEEE80211_3ADDR_LEN; |
@@ -9837,14 +9842,28 @@ static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb, | |||
9837 | q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd); | 9842 | q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd); |
9838 | ipw_write32(priv, q->reg_w, q->first_empty); | 9843 | ipw_write32(priv, q->reg_w, q->first_empty); |
9839 | 9844 | ||
9840 | if (ipw_queue_space(q) < q->high_mark) | 9845 | return NETDEV_TX_OK; |
9841 | netif_stop_queue(priv->net_dev); | ||
9842 | |||
9843 | return; | ||
9844 | 9846 | ||
9845 | drop: | 9847 | drop: |
9846 | IPW_DEBUG_DROP("Silently dropping Tx packet.\n"); | 9848 | IPW_DEBUG_DROP("Silently dropping Tx packet.\n"); |
9847 | ieee80211_txb_free(txb); | 9849 | ieee80211_txb_free(txb); |
9850 | return NETDEV_TX_OK; | ||
9851 | } | ||
9852 | |||
9853 | static int ipw_net_is_queue_full(struct net_device *dev, int pri) | ||
9854 | { | ||
9855 | struct ipw_priv *priv = ieee80211_priv(dev); | ||
9856 | #ifdef CONFIG_IPW_QOS | ||
9857 | int tx_id = ipw_get_tx_queue_number(priv, pri); | ||
9858 | struct clx2_tx_queue *txq = &priv->txq[tx_id]; | ||
9859 | #else | ||
9860 | struct clx2_tx_queue *txq = &priv->txq[0]; | ||
9861 | #endif /* CONFIG_IPW_QOS */ | ||
9862 | |||
9863 | if (ipw_queue_space(&txq->q) < txq->q.high_mark) | ||
9864 | return 1; | ||
9865 | |||
9866 | return 0; | ||
9848 | } | 9867 | } |
9849 | 9868 | ||
9850 | static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb, | 9869 | static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb, |
@@ -9852,6 +9871,7 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb, | |||
9852 | { | 9871 | { |
9853 | struct ipw_priv *priv = ieee80211_priv(dev); | 9872 | struct ipw_priv *priv = ieee80211_priv(dev); |
9854 | unsigned long flags; | 9873 | unsigned long flags; |
9874 | int ret; | ||
9855 | 9875 | ||
9856 | IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size); | 9876 | IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size); |
9857 | spin_lock_irqsave(&priv->lock, flags); | 9877 | spin_lock_irqsave(&priv->lock, flags); |
@@ -9863,11 +9883,12 @@ static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb, | |||
9863 | goto fail_unlock; | 9883 | goto fail_unlock; |
9864 | } | 9884 | } |
9865 | 9885 | ||
9866 | ipw_tx_skb(priv, txb, pri); | 9886 | ret = ipw_tx_skb(priv, txb, pri); |
9867 | __ipw_led_activity_on(priv); | 9887 | if (ret == NETDEV_TX_OK) |
9888 | __ipw_led_activity_on(priv); | ||
9868 | spin_unlock_irqrestore(&priv->lock, flags); | 9889 | spin_unlock_irqrestore(&priv->lock, flags); |
9869 | 9890 | ||
9870 | return 0; | 9891 | return ret; |
9871 | 9892 | ||
9872 | fail_unlock: | 9893 | fail_unlock: |
9873 | spin_unlock_irqrestore(&priv->lock, flags); | 9894 | spin_unlock_irqrestore(&priv->lock, flags); |
@@ -10706,6 +10727,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
10706 | 10727 | ||
10707 | priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit; | 10728 | priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit; |
10708 | priv->ieee->set_security = shim__set_security; | 10729 | priv->ieee->set_security = shim__set_security; |
10730 | priv->ieee->is_queue_full = ipw_net_is_queue_full; | ||
10709 | 10731 | ||
10710 | #ifdef CONFIG_IPW_QOS | 10732 | #ifdef CONFIG_IPW_QOS |
10711 | priv->ieee->handle_management_frame = ipw_handle_management_frame; | 10733 | priv->ieee->handle_management_frame = ipw_handle_management_frame; |