Search Linux Wireless

Re: [PATCH 5/5] ath5k: Fix and clean mode initialization, prefer G for AR5212

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



You can also check card capabilities before initializing the modes
instead of ah_version since you have access on cap.mode ;-)

2007/10/13, Luis R. Rodriguez <mcgrof@xxxxxxxxx>:
> On Fri, Oct 12, 2007 at 11:33:05PM +0200, Jiri Slaby wrote:
> > I didn't sleep too much due to travelling, maybe I'm wrong in some
> > cases, some comments follows.
>
> Seems it was me that didn't get the sleep ;)
>
> > On 10/12/07, Luis R. Rodriguez <mcgrof@xxxxxxxxx> wrote:
> > > +       modes[0].mode = MODE_IEEE80211G;
> > > +       modes[1].mode = MODE_IEEE80211B;
> > > +       modes[2].mode = MODE_IEEE80211A;
> > > +
> > > +       max_r = ARRAY_SIZE(sc->rates);
> > > +       max_c = ARRAY_SIZE(sc->channels);
> > > +       modes[0].rates = sc->rates;
>
> I'll delete this line above.
>
> > > +
> > > +       for (i = 0; i <= 2; i++) {
> > > +               struct ieee80211_hw_mode *mode = &modes[i];
> > > +               const struct ath5k_rate_table *hw_rates;
> > > +
> > > +               if (i == 0) {
> > > +                       mode->rates     = sc->rates;
> > > +                       modes->channels = sc->channels;
> >
> > mode/modes, it's doesn't matter here, but it doesn't look well
>
> And put it above as modes[0].rates = sc->rates then.
>
> > > +               } else {
> > > +                       struct ieee80211_hw_mode *prev_mode = &modes[i-1];
> > > +                       int prev_num_r  = prev_mode->num_rates;
> > > +                       int prev_num_c  = prev_mode->num_channels;
> > > +                       mode->rates     = &prev_mode->rates[prev_num_r];
> > > +                       mode->channels  = &prev_mode->channels[prev_num_c];
> > >                 }
> > > +
> > > +               hw_rates = ath5k_hw_get_rate_table(ah, mode->mode);
> > > +               mode->num_rates    = ath_copy_rates(mode->rates, hw_rates,
> > > +                       max_r);
> > > +               mode->num_channels = ath_copy_channels(ah, mode->channels,
> > > +                       mode->mode, max_c);
> > > +               max_r -= modes->num_rates;
> >
> > modes? but here it matters...
>
> Good catch.
>
> > > +               max_c -= mode->num_channels;
> > > +       }
> > > +
> > > +       switch (ah->ah_version) {
> > > +       case AR5K_AR5210:
> > > +               REGISTER_MODE(MODE_IEEE80211A);
> > > +               break;
> > > +       case AR5K_AR5211:
> > > +               REGISTER_MODE(MODE_IEEE80211B);
> > > +               break;
> > > +       case AR5K_AR5212:
> > > +               if (!ah->ah_single_chip)
> > > +                       REGISTER_MODE(MODE_IEEE80211A);
> > > +               REGISTER_MODE(MODE_IEEE80211G);
> >
> > And this seems totally wrong. you use 0, 1, 2 indexes above and here
> > you index it by mac80211 integers. That's exactly why the enum was
> > there (a shortcut like in intel drivers) -- to not get into it.
>
> Actually you are right, that was not what I intended though. The A, B,
> and G enums seemed to add confusion so I just got rid of them. What I
> really *intended* on doing was:
>
> #define REGISTER_MODE(m) do { \
>         for (i=0; i<2; i++) { \
>                 if (modes[i].mode != m || !modes[i].num_channels) \
>                         continue; \
>                 ret = ieee80211_register_hwmode(hw, &modes[i]); \
>                 if (ret) { \
>                         printk(KERN_ERR "can't register hwmode %u\n",m); \
>                         goto err; \
>                 } \
>         } \
> } while (0)
>
> Also, you forgot to catch I wasn't registering MODE_IEEE80211A for
> AR5211, I've added it now :). BTW with johill's patch,
> [PATCH v2] mac80211: fix set_channel regression
> the mode that is used first changes now is reversed again depending on
> the order in which you registered it so I've moved things around to assure
> we prefer keep preferring G for AR5212s and B for AR5211s.
>
> Below you'll find the new revised patch. This was tested with AR5212
> and AR5211. Checkpatch was run too ;)
>
>         Luis
>
> [PATCH 5/5] ath5k: Fix and clean mode initialization, prefer G for AR5212
>
> Currently you get locked on B mode with AR5212s. This could be partly
> mac80211's fault with a recent regression introduced but ath5k mode
> initialization right now is pretty sloppy. For AR5212s we also currently
> start scanning in 5GHz. I've made the mode initialization on ath5k a bit
> clearer and only am registering G mode now instead of both B and G for
> AR5212s. 11Mbps is still the only stable rate but at least now we can
> work and test the other rates again.
>
> Note: mac80211 simple rate algo throws us to 1Mbps after assoc, this is by
>         design. I recommend users to set rate to 11M for now after assoc.
>
> Changes-licensed-under: 3-clause-BSD
> Signed-off-by: Luis R. Rodriguez <mcgrof@xxxxxxxxx>
> ---
>  drivers/net/wireless/ath5k/base.c |  106 ++++++++++++++++++++-----------------
>  net/mac80211/ieee80211_ioctl.c    |    5 ++-
>  2 files changed, 61 insertions(+), 50 deletions(-)
>
> diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
> index 18ee995..8413950 100644
> --- a/drivers/net/wireless/ath5k/base.c
> +++ b/drivers/net/wireless/ath5k/base.c
> @@ -1919,67 +1919,75 @@ static void ath_dump_modes(struct ieee80211_hw_mode *modes)
>  static inline void ath_dump_modes(struct ieee80211_hw_mode *modes) {}
>  #endif
>
> +#define REGISTER_MODE(m) do { \
> +       for (i = 0; i <= 2; i++) { \
> +               if (modes[i].mode != m || !modes[i].num_channels) \
> +                       continue; \
> +               ret = ieee80211_register_hwmode(hw, &modes[i]); \
> +               if (ret) { \
> +                       printk(KERN_ERR "can't register hwmode %u\n", m); \
> +                       goto err; \
> +               } \
> +       } \
> +} while (0)
> +
>  static int ath_getchannels(struct ieee80211_hw *hw)
>  {
>         struct ath_softc *sc = hw->priv;
>         struct ath_hw *ah = sc->ah;
>         struct ieee80211_hw_mode *modes = sc->modes;
> -       unsigned int i, max;
> +       unsigned int i, max_r, max_c;
>         int ret;
> -       enum {
> -               A = MODE_IEEE80211A,
> -               B = MODE_IEEE80211G, /* this is not a typo, but workaround */
> -               G = MODE_IEEE80211B, /* to prefer g over b */
> -               T = MODE_ATHEROS_TURBO,
> -               TG = MODE_ATHEROS_TURBOG,
> -       };
>
>         BUILD_BUG_ON(ARRAY_SIZE(sc->modes) < 3);
>
>         ah->ah_country_code = countrycode;
>
> -       modes[A].mode = MODE_IEEE80211A;
> -       modes[B].mode = MODE_IEEE80211B;
> -       modes[G].mode = MODE_IEEE80211G;
> -
> -       max = ARRAY_SIZE(sc->rates);
> -       modes[A].rates = sc->rates;
> -       max -= modes[A].num_rates = ath_copy_rates(modes[A].rates,
> -                       ath5k_hw_get_rate_table(ah, MODE_IEEE80211A), max);
> -       modes[B].rates = &modes[A].rates[modes[A].num_rates];
> -       max -= modes[B].num_rates = ath_copy_rates(modes[B].rates,
> -                       ath5k_hw_get_rate_table(ah, MODE_IEEE80211B), max);
> -       modes[G].rates = &modes[B].rates[modes[B].num_rates];
> -       max -= modes[G].num_rates = ath_copy_rates(modes[G].rates,
> -                       ath5k_hw_get_rate_table(ah, MODE_IEEE80211G), max);
> -
> -       if (!max)
> -               printk(KERN_WARNING "yet another rates found, but there is not "
> -                               "sufficient space to store them\n");
> -
> -       max = ARRAY_SIZE(sc->channels);
> -       modes[A].channels = sc->channels;
> -       max -= modes[A].num_channels = ath_copy_channels(ah, modes[A].channels,
> -                       MODE_IEEE80211A, max);
> -       modes[B].channels = &modes[A].channels[modes[A].num_channels];
> -       max -= modes[B].num_channels = ath_copy_channels(ah, modes[B].channels,
> -                       MODE_IEEE80211B, max);
> -       modes[G].channels = &modes[B].channels[modes[B].num_channels];
> -       max -= modes[G].num_channels = ath_copy_channels(ah, modes[G].channels,
> -                       MODE_IEEE80211G, max);
> -
> -       if (!max)
> -               printk(KERN_WARNING "yet another modes found, but there is not "
> -                               "sufficient space to store them\n");
> -
> -       for (i = 0; i < ARRAY_SIZE(sc->modes); i++)
> -               if (modes[i].num_channels) {
> -                       ret = ieee80211_register_hwmode(hw, &modes[i]);
> -                       if (ret) {
> -                               printk(KERN_ERR "can't register hwmode %u\n",i);
> -                               goto err;
> -                       }
> +       modes[0].mode = MODE_IEEE80211G;
> +       modes[1].mode = MODE_IEEE80211B;
> +       modes[2].mode = MODE_IEEE80211A;
> +
> +       max_r = ARRAY_SIZE(sc->rates);
> +       max_c = ARRAY_SIZE(sc->channels);
> +
> +       for (i = 0; i <= 2; i++) {
> +               struct ieee80211_hw_mode *mode = &modes[i];
> +               const struct ath5k_rate_table *hw_rates;
> +
> +               if (i == 0) {
> +                       modes[0].rates  = sc->rates;
> +                       modes->channels = sc->channels;
> +               } else {
> +                       struct ieee80211_hw_mode *prev_mode = &modes[i-1];
> +                       int prev_num_r  = prev_mode->num_rates;
> +                       int prev_num_c  = prev_mode->num_channels;
> +                       mode->rates     = &prev_mode->rates[prev_num_r];
> +                       mode->channels  = &prev_mode->channels[prev_num_c];
>                 }
> +
> +               hw_rates = ath5k_hw_get_rate_table(ah, mode->mode);
> +               mode->num_rates    = ath_copy_rates(mode->rates, hw_rates,
> +                       max_r);
> +               mode->num_channels = ath_copy_channels(ah, mode->channels,
> +                       mode->mode, max_c);
> +               max_r -= mode->num_rates;
> +               max_c -= mode->num_channels;
> +       }
> +
> +       switch (ah->ah_version) {
> +       case AR5K_AR5210:
> +               REGISTER_MODE(MODE_IEEE80211A);
> +               break;
> +       case AR5K_AR5211:
> +               REGISTER_MODE(MODE_IEEE80211B);
> +               REGISTER_MODE(MODE_IEEE80211A);
> +               break;
> +       case AR5K_AR5212:
> +               REGISTER_MODE(MODE_IEEE80211G);
> +               if (!ah->ah_single_chip)
> +                       REGISTER_MODE(MODE_IEEE80211A);
> +               break;
> +       }
>         ath_dump_modes(modes);
>
>         return 0;
>


-- 
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick
-
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux