On Thursday 05 December 2013 22:56:01 you wrote:
> On 2013-12-05 22:41, Tijs Van Buggenhout wrote:
> > Hi Felix,
> > 
> > I have a question about https://dev.openwrt.org/changeset/38486. While
> > backporting the aforementioned patch from trunk to attitude adjustment, I
> > noticed that the patch does not include a gettor function for the adc
> > entropy of the ar9002 chip, only those of ar5008 and ar9003.
> > 
> > static void ar9003_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t
> > len) static void ar5008_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf,
> > size_t len)
> > 
> > but no
> > 
> > static void ar9002_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t
> > len)
> > 
> > Furthermore, when the phy_ops are constructed in ar9002_hw_attach_phy_ops,
> > the get_adc_entropy function pointer is never assigned.
> > 
> > I can be wrong ofcourse, but am under the impression this will create a
> > problem when the driver is probed for an ar9002 chip and possibly result
> > in a kernel oops, because "ath9k_hw_get_adc_entropy" expects the ath_hw
> > struct to have a valid (non-NULL) function pointer for get_adc_entropy.
> > See below:
> > 
> > static inline void ath9k_hw_get_adc_entropy(struct ath_hw *ah,
> > 
> >                u8 *buf, size_t len)
> > 
> > {
> > 
> >        ath9k_hw_ops(ah)->get_adc_entropy(ah, buf, len);
> > 
> > }
> > 
> > Did changes in ar9002_phy.c somehow miss inclusion in the patch?
> 
> ar5008_hw_attach_phy_ops is called for all chips older than AR9003, and
> it is generic enough to work across that range of chips.

Ah yes, I see what you mean in ar9002_hw_attach_ops

        ret = ar5008_hw_attach_phy_ops(ah);
        if (ret)
                return ret;

        if (AR_SREV_9280_20_OR_LATER(ah))
                ar9002_hw_attach_phy_ops(ah);

Missed that.. I assumed hw_attach_phy_ops was specific for every chip.

> > When testing the backported patch for my ar9003 chip, I was confronted
> > with a kernel oops at initialisation, which I narrowed down to
> > ath9k_hw_reset function, called from ath_get_initial_entropy, where the
> > channels in ieee80211_conf data field in common hardware config are not
> > yet initialised it seems. I changed the condition to verify for a valid
> > pointer before dereferencing it, which seems to solve the problem.
> > This is different in the mac82011 version from trunk (compat-
> > wireless-2013-11-05), where channelFlags from channel are used in the
> > condition, which is an u32, and thus can not result in a null pointer
> > dereference. My question now is, although the fix seems sufficient, is it
> > also correct/expected behaviour?
> 
> The patch assumes that ah->curchan is left initializes after the tx
> power limit test.
> In ath9k_init_txpower_limits, the new version has this code:
> 
>     if (curchan)
>         ah->curchan = curchan;
> 
> I think the old version probably overwrites ah->curchan without checking
> for NULL.

This is part of the entropy patch, which I included in the backport aswell..

diff -u -Naur a/drivers/net/wireless/ath/ath9k/init.c 
b/drivers/net/wireless/ath/ath9k/init.c
--- a/drivers/net/wireless/ath/ath9k/init.c     2013-10-28 18:00:58.000000000 
+0100
+++ b/drivers/net/wireless/ath/ath9k/init.c     2013-12-05 21:09:55.000000000 
+0100
@@ -735,7 +735,8 @@
        if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
                ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);

-       ah->curchan = curchan;
+       if (curchan)
+               ah->curchan = curchan;
 }

 void ath9k_reload_chainmask_settings(struct ath_softc *sc)
@@ -880,6 +881,19 @@

but the problem is in struct ieee80211_conf, part of hw common config, which 
is not yet initialised when ath_get_initial_entropy is called from 
ath9k_init_device..

--- a/drivers/net/wireless/ath/ath9k/hw.c       2013-10-28 18:00:58.000000000 
+0100
+++ b/drivers/net/wireless/ath/ath9k/hw.c       2013-12-05 21:05:25.000000000 
+0100
@@ -131,8 +131,8 @@

 static void ath9k_hw_set_clockrate(struct ath_hw *ah)
 {
-       struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
        struct ath_common *common = ath9k_hw_common(ah);
+       struct ieee80211_conf *conf = &common->hw->conf;
        unsigned int clockrate;

        /* AR9287 v1.3+ uses async FIFO and runs the MAC at 117 MHz */
@@ -140,7 +140,7 @@
                clockrate = 117;
        else if (!ah->curchan) /* should really check for CCK instead */
                clockrate = ATH9K_CLOCK_RATE_CCK;
-       else if (conf->chandef.chan->band == IEEE80211_BAND_2GHZ)
+       else if (conf->chandef.chan && conf->chandef.chan->band == 
IEEE80211_BAND_2GHZ)

In ath9k_hw_reset, I experienced the problem with ath9k_hw_set_clockrate(ah) 
at line 1998, a few lines later (2008) in ath9k_hw_init_global_settings(ah) I 
see the same kind of null condition check I introduced in 
ath9k_hw_set_clockrate:

        /*
         * Workaround for early ACK timeouts, add an offset to match the
         * initval's 64us ack timeout value. Use 48us for the CTS timeout.
         * This was initially only meant to work around an issue with delayed
         * BA frames in some implementations, but it has been found to fix ACK
         * timeout issues in other cases as well.
         */
        if (conf->chandef.chan &&
            conf->chandef.chan->band == IEEE80211_BAND_2GHZ &&
            !IS_CHAN_HALF_RATE(chan) && !IS_CHAN_QUARTER_RATE(chan)) {
                acktimeout += 64 - sifstime - ah->slottime;
                ctstimeout += 48 - sifstime - ah->slottime;
        }

So it is probably safe to assume this can happen.

When I move the call to ath_get_initial_entropy in ath9k_init_device, which is 
in between ath9k_init_txpower_limits and ieee80211_register_hw, down a bit 
until after ieee80211_register_hw, the kernel oops is no more, like so:

@@ -918,30 +932,32 @@ int ath9k_init_device(u16 devid, struct
 
        ath9k_init_txpower_limits(sc);
 
 #ifdef CPTCFG_MAC80211_LEDS
        /* must be initialized before ieee80211_register_hw */
        sc->led_default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
                IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
                ARRAY_SIZE(ath9k_tpt_blink));
 #endif
 
        /* Register with mac80211 */
        error = ieee80211_register_hw(hw);
        if (error)
                goto rx_cleanup;
 
+       ath_get_initial_entropy(sc);
+
        error = ath9k_init_debug(ah);
        if (error) {
                ath_err(common, "Unable to create debugfs files\n");
                goto unregister;
        }

Is there anything opposed this change?

> - Felix

Thanks,
Tijs
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to