/* * HD-Audio helpers to sync with i915 driver */ #ifndef __SOUND_HDA_I915_H #define __SOUND_HDA_I915_H #include #ifdef CONFIG_SND_HDA_I915 int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable); int snd_hdac_display_power(struct hdac_bus *bus, bool enable); void snd_hdac_i915_set_bclk(struct hdac_bus *bus); int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int dev_id, int rate); int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id, bool *audio_enabled, char *buffer, int max_bytes); int snd_hdac_i915_init(struct hdac_bus *bus); int snd_hdac_i915_exit(struct hdac_bus *bus); int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *); #else static inline int snd_hdac_set_codec_wakeup(struct hdac_bus *bus, bool enable) { return 0; } static inline int snd_hdac_display_power(struct hdac_bus *bus, bool enable) { return 0; } static inline void snd_hdac_i915_set_bclk(struct hdac_bus *bus) { } static inline int snd_hdac_sync_audio_rate(struct hdac_device *codec, hda_nid_t nid, int dev_id, int rate) { return 0; } static inline int snd_hdac_acomp_get_eld(struct hdac_device *codec, hda_nid_t nid, int dev_id, bool *audio_enabled, char *buffer, int max_bytes) { return -ENODEV; } static inline int snd_hdac_i915_init(struct hdac_bus *bus) { return -ENODEV; } static inline int snd_hdac_i915_exit(struct hdac_bus *bus) { return 0; } static inline int snd_hdac_i915_register_notifier(const struct i915_audio_component_audio_ops *ops) { return -ENODEV; } #endif #endif /* __SOUND_HDA_I915_H */ 342e60'>refslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2011-11-27 15:29:44 +0200
committerJohn W. Linville <linville@tuxdriver.com>2011-11-28 13:46:41 -0500
commit2a1e0fd175dcfd72096ba9291d31e3b1b5342e60 (patch)
tree75d1125cffd90d1af3213aa089049139a04b5536 /net
parentd305a6557b2c4dca0110f05ffe745b1ef94adb80 (diff)
mac80211: fix race between the AGG SM and the Tx data path
When a packet is supposed to sent be as an a-MPDU, mac80211 sets IEEE80211_TX_CTL_AMPDU to let the driver know. On the other hand, mac80211 configures the driver for aggregration with the ampdu_action callback. There is race between these two mechanisms since the following scenario can occur when the BA agreement is torn down: Tx softIRQ drv configuration ========== ================= check OPERATIONAL bit Set the TX_CTL_AMPDU bit in the packet clear OPERATIONAL bit stop Tx AGG Pass Tx packet to the driver. In that case the driver would get a packet with TX_CTL_AMPDU set although it has already been notified that the BA session has been torn down. To fix this, we need to synchronize all the Qdisc activity after we cleared the OPERATIONAL bit. After that step, all the following packets will be buffered until the driver reports it is ready to get new packets for this RA / TID. This buffering allows not to run into another race that would send packets with TX_CTL_AMPDU unset while the driver hasn't been requested to tear down the BA session yet. This race occurs in practice and iwlwifi complains with a WARN_ON when it happens. Cc: stable@kernel.org Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Reviewed-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')