From 56f411f3c046b1a2a53739fd24b7fe7fb1b16e3b Mon Sep 17 00:00:00 2001 From: benoit Date: Thu, 10 Jan 2008 20:10:41 +0000 Subject: [PATCH] Fixed a kernel panic due to incorrect linux API use hard_start_xmit() functions must either return NETDEV_TX_OK or NETDEV_TX_BUSY (they might also return negative errno values as well, like -ENETDOWN) Correct a small missing static reported by sparse This revert part of r3075 git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@3123 0192ed92-7a03-0410-a25b-9323aeb14dbd --- ath/if_ath.c | 3 ++- net80211/ieee80211_input.c | 2 +- net80211/ieee80211_output.c | 21 +++++++++++++-------- net80211/ieee80211_power.c | 6 +++--- net80211/ieee80211_proto.h | 2 +- 5 files changed, 20 insertions(+), 14 deletions(-) diff --git a/ath/if_ath.c b/ath/if_ath.c index 357234e..372f59a 100644 --- a/ath/if_ath.c +++ b/ath/if_ath.c @@ -2958,6 +2958,7 @@ _take_txbuf(struct ath_softc *sc, int for_management) { * assumed to reclaim the resources. * * Context: process context with BHs disabled + * It mut return either NETDEV_TX_OK or NETDEV_TX_BUSY */ static int ath_hardstart(struct sk_buff *skb, struct net_device *dev) @@ -5873,7 +5874,7 @@ ath_rxbuf_init(struct ath_softc *sc, struct ath_buf *bf) * created, otherwise the same SKB is used. * * NB: MAY ALLOCATE */ -struct sk_buff * +static struct sk_buff * ath_skb_removepad(struct sk_buff *skb, unsigned int copy_skb) { struct sk_buff *tskb = skb; diff --git a/net80211/ieee80211_input.c b/net80211/ieee80211_input.c index 3ef89f2..c8e20ca 100644 --- a/net80211/ieee80211_input.c +++ b/net80211/ieee80211_input.c @@ -3736,7 +3736,7 @@ ieee80211_recv_pspoll(struct ieee80211_node *ni, struct sk_buff *skb0) } M_PWR_SAV_SET(skb); /* ensure MORE_DATA bit is set correctly */ - (void)ieee80211_parent_queue_xmit(skb); /* Submit to parent device, including updating stats */ + ieee80211_parent_queue_xmit(skb); /* Submit to parent device, including updating stats */ } #ifdef ATH_SUPERG_FF diff --git a/net80211/ieee80211_output.c b/net80211/ieee80211_output.c index 729a861..4ed6ae5 100644 --- a/net80211/ieee80211_output.c +++ b/net80211/ieee80211_output.c @@ -196,6 +196,7 @@ ieee80211_classify(struct ieee80211_node *ni, struct sk_buff *skb) /* * Context: process context (BHs disabled) + * It must return either NETDEV_TX_OK or NETDEV_TX_BUSY */ int ieee80211_hardstart(struct sk_buff *skb, struct net_device *dev) @@ -232,7 +233,8 @@ ieee80211_hardstart(struct sk_buff *skb, struct net_device *dev) if (vap->iv_opmode == IEEE80211_M_MONITOR) { ieee80211_monitor_encap(vap, skb); - return ieee80211_parent_queue_xmit(skb); + ieee80211_parent_queue_xmit(skb); + return NETDEV_TX_OK; } /* Cancel any running BG scan */ @@ -290,24 +292,28 @@ ieee80211_hardstart(struct sk_buff *skb, struct net_device *dev) SKB_CB(skb1)->ni = ieee80211_find_txnode(vap->iv_xrvap, eh->ether_dhost); /* Ignore this return code. */ - (void)ieee80211_parent_queue_xmit(skb1); + ieee80211_parent_queue_xmit(skb1); } } #endif ieee80211_unref_node(&ni); - return ieee80211_parent_queue_xmit(skb); + ieee80211_parent_queue_xmit(skb); + return NETDEV_TX_OK; bad: if (skb != NULL) ieee80211_dev_kfree_skb(&skb); if (ni != NULL) ieee80211_unref_node(&ni); - return 0; + return NETDEV_TX_OK; } -int ieee80211_parent_queue_xmit(struct sk_buff *skb) { +/* + * skb is consumed in all cases + */ + +void ieee80211_parent_queue_xmit(struct sk_buff *skb) { struct ieee80211vap *vap = skb->dev->priv; - int ret; vap->iv_devstats.tx_packets++; vap->iv_devstats.tx_bytes += skb->len; @@ -316,10 +322,9 @@ int ieee80211_parent_queue_xmit(struct sk_buff *skb) { /* Dispatch the packet to the parent device */ skb->dev = vap->iv_ic->ic_dev; - if ((ret = dev_queue_xmit(skb)) == NET_XMIT_DROP) + if (dev_queue_xmit(skb) == NET_XMIT_DROP) vap->iv_devstats.tx_dropped++; - return ret; } /* diff --git a/net80211/ieee80211_power.c b/net80211/ieee80211_power.c index 817ea6a..d51bfe3 100644 --- a/net80211/ieee80211_power.c +++ b/net80211/ieee80211_power.c @@ -209,6 +209,7 @@ ieee80211_set_tim(struct ieee80211_node *ni, int set) * Save an outbound packet for a node in power-save sleep state. * The new packet is placed on the node's saved queue, and the TIM * is changed, if necessary. + * It must return either NETDEV_TX_OK or NETDEV_TX_BUSY */ int ieee80211_pwrsave(struct sk_buff *skb) @@ -231,7 +232,6 @@ ieee80211_pwrsave(struct sk_buff *skb) ieee80211_dump_pkt(ni->ni_ic, skb->data, skb->len, -1, -1); #endif ieee80211_unref_node(&SKB_CB(skb)->ni); - ieee80211_dev_kfree_skb(&skb); return NETDEV_TX_BUSY; } @@ -339,7 +339,7 @@ ieee80211_node_pwrsave(struct ieee80211_node *ni, int enable) skb->dev = vap->iv_dev; /* XXX? unnecessary */ #endif - (void)ieee80211_parent_queue_xmit(skb); + ieee80211_parent_queue_xmit(skb); } vap->iv_set_tim(ni, 0); } @@ -380,7 +380,7 @@ ieee80211_sta_pwrsave(struct ieee80211vap *vap, int enable) IEEE80211_NODE_SAVEQ_UNLOCK_IRQ(ni); if (skb == NULL) break; - (void)ieee80211_parent_queue_xmit(skb); + ieee80211_parent_queue_xmit(skb); } } } else { diff --git a/net80211/ieee80211_proto.h b/net80211/ieee80211_proto.h index eae3564..23e2f49 100644 --- a/net80211/ieee80211_proto.h +++ b/net80211/ieee80211_proto.h @@ -72,7 +72,7 @@ void ieee80211_saveath(struct ieee80211_node *, u_int8_t *); void ieee80211_recv_mgmt(struct ieee80211_node *, struct sk_buff *, int, int, u_int64_t); int ieee80211_hardstart(struct sk_buff *, struct net_device *); -int ieee80211_parent_queue_xmit(struct sk_buff *); +void ieee80211_parent_queue_xmit(struct sk_buff *); int ieee80211_send_nulldata(struct ieee80211_node *); int ieee80211_send_qosnulldata(struct ieee80211_node *, int); int ieee80211_send_mgmt(struct ieee80211_node *, int, int); -- 2.35.1