diff -urN linux-2.6.24/drivers/net/wireless/rtl8187_dev.c wireless-2.6/drivers/net/wireless/rtl8187_dev.c --- linux-2.6.24/drivers/net/wireless/rtl8187_dev.c 2008-01-25 02:20:42.000000000 +0100 +++ wireless-2.6/drivers/net/wireless/rtl8187_dev.c 2008-04-01 02:09:41.000000000 +0200 @@ -113,10 +113,12 @@ static void rtl8187_tx_cb(struct urb *urb) { - struct ieee80211_tx_status status = { {0} }; + struct ieee80211_tx_status status; struct sk_buff *skb = (struct sk_buff *)urb->context; struct rtl8187_tx_info *info = (struct rtl8187_tx_info *)skb->cb; + memset(&status, 0, sizeof(status)); + usb_free_urb(info->urb); if (info->control) memcpy(&status.control, info->control, sizeof(status.control)); @@ -150,7 +152,8 @@ flags |= RTL8187_TX_FLAG_MORE_FRAG; if (control->flags & IEEE80211_TXCTL_USE_RTS_CTS) { flags |= RTL8187_TX_FLAG_RTS; - rts_dur = ieee80211_rts_duration(dev, priv->if_id, skb->len, control); + rts_dur = ieee80211_rts_duration(dev, priv->vif, + skb->len, control); } if (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) flags |= RTL8187_TX_FLAG_CTS; @@ -227,6 +230,7 @@ rx_status.channel = dev->conf.channel; rx_status.phymode = dev->conf.phymode; rx_status.mactime = le64_to_cpu(hdr->mac_time); + rx_status.flag |= RX_FLAG_TSFT; if (flags & (1 << 13)) rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; ieee80211_rx_irqsafe(dev, skb, &rx_status); @@ -392,37 +396,19 @@ rtl818x_iowrite16(priv, &priv->map->RFPinsEnable, 0x1FF7); msleep(100); - priv->rf_init(dev); + priv->rf->init(dev); rtl818x_iowrite16(priv, &priv->map->BRSR, 0x01F3); - reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & 0xfffe; - rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 0x1); + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1; + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1); rtl818x_iowrite16(priv, (__le16 *)0xFFFE, 0x10); rtl818x_iowrite8(priv, &priv->map->TALLY_SEL, 0x80); rtl818x_iowrite8(priv, (u8 *)0xFFFF, 0x60); - rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); return 0; } -static void rtl8187_set_channel(struct ieee80211_hw *dev, int channel) -{ - u32 reg; - struct rtl8187_priv *priv = dev->priv; - - reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); - /* Enable TX loopback on MAC level to avoid TX during channel - * changes, as this has be seen to causes problems and the - * card will stop work until next reset - */ - rtl818x_iowrite32(priv, &priv->map->TX_CONF, - reg | RTL818X_TX_CONF_LOOPBACK_MAC); - msleep(10); - rtl8225_rf_set_channel(dev, channel); - msleep(10); - rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); -} - static int rtl8187_start(struct ieee80211_hw *dev) { struct rtl8187_priv *priv = dev->priv; @@ -491,7 +477,7 @@ reg &= ~RTL818X_CMD_RX_ENABLE; rtl818x_iowrite8(priv, &priv->map->CMD, reg); - rtl8225_rf_stop(dev); + priv->rf->stop(dev); rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG); reg = rtl818x_ioread8(priv, &priv->map->CONFIG4); @@ -542,7 +528,19 @@ static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf) { struct rtl8187_priv *priv = dev->priv; - rtl8187_set_channel(dev, conf->channel); + u32 reg; + + reg = rtl818x_ioread32(priv, &priv->map->TX_CONF); + /* Enable TX loopback on MAC level to avoid TX during channel + * changes, as this has be seen to causes problems and the + * card will stop work until next reset + */ + rtl818x_iowrite32(priv, &priv->map->TX_CONF, + reg | RTL818X_TX_CONF_LOOPBACK_MAC); + msleep(10); + priv->rf->set_chan(dev, conf); + msleep(10); + rtl818x_iowrite32(priv, &priv->map->TX_CONF, reg); rtl818x_iowrite8(priv, &priv->map->SIFS, 0x22); @@ -565,14 +563,13 @@ return 0; } -static int rtl8187_config_interface(struct ieee80211_hw *dev, int if_id, +static int rtl8187_config_interface(struct ieee80211_hw *dev, + struct ieee80211_vif *vif, struct ieee80211_if_conf *conf) { struct rtl8187_priv *priv = dev->priv; int i; - priv->if_id = if_id; - for (i = 0; i < ETH_ALEN; i++) rtl818x_iowrite8(priv, &priv->map->BSSID[i], conf->bssid[i]); @@ -752,23 +749,16 @@ eeprom_93cx6_read(&eeprom, RTL8187_EEPROM_TXPWR_BASE, &priv->txpwr_base); - reg = rtl818x_ioread16(priv, &priv->map->PGSELECT) & ~1; - rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg | 1); + reg = rtl818x_ioread8(priv, &priv->map->PGSELECT) & ~1; + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg | 1); /* 0 means asic B-cut, we should use SW 3 wire * bit-by-bit banging for radio. 1 means we can use * USB specific request to write radio registers */ priv->asic_rev = rtl818x_ioread8(priv, (u8 *)0xFFFE) & 0x3; - rtl818x_iowrite16(priv, &priv->map->PGSELECT, reg); + rtl818x_iowrite8(priv, &priv->map->PGSELECT, reg); rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); - rtl8225_write(dev, 0, 0x1B7); - - if (rtl8225_read(dev, 8) != 0x588 || rtl8225_read(dev, 9) != 0x700) - priv->rf_init = rtl8225_rf_init; - else - priv->rf_init = rtl8225z2_rf_init; - - rtl8225_write(dev, 0, 0x0B7); + priv->rf = rtl8187_detect_rf(dev); err = ieee80211_register_hw(dev); if (err) { @@ -778,8 +768,7 @@ printk(KERN_INFO "%s: hwaddr %s, rtl8187 V%d + %s\n", wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr), - priv->asic_rev, priv->rf_init == rtl8225_rf_init ? - "rtl8225" : "rtl8225z2"); + priv->asic_rev, priv->rf->name); return 0; diff -urN linux-2.6.24/drivers/net/wireless/rtl8187.h wireless-2.6/drivers/net/wireless/rtl8187.h --- linux-2.6.24/drivers/net/wireless/rtl8187.h 2008-01-25 02:20:42.000000000 +0100 +++ wireless-2.6/drivers/net/wireless/rtl8187.h 2008-02-21 01:38:42.000000000 +0100 @@ -64,9 +64,9 @@ struct rtl8187_priv { /* common between rtl818x drivers */ struct rtl818x_csr *map; - void (*rf_init)(struct ieee80211_hw *); + const struct rtl818x_rf_ops *rf; + struct ieee80211_vif *vif; int mode; - int if_id; /* rtl8187 specific */ struct ieee80211_channel channels[14]; I file binari linux-2.6.24/drivers/net/wireless/rtl8187.ko e wireless-2.6/drivers/net/wireless/rtl8187.ko differiscono diff -urN linux-2.6.24/drivers/net/wireless/rtl8187_rtl8225.c wireless-2.6/drivers/net/wireless/rtl8187_rtl8225.c --- linux-2.6.24/drivers/net/wireless/rtl8187_rtl8225.c 2007-10-09 22:31:38.000000000 +0200 +++ wireless-2.6/drivers/net/wireless/rtl8187_rtl8225.c 2008-02-21 01:38:42.000000000 +0100 @@ -101,7 +101,7 @@ msleep(2); } -void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) +static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data) { struct rtl8187_priv *priv = dev->priv; @@ -111,7 +111,7 @@ rtl8225_write_bitbang(dev, addr, data); } -u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) +static u16 rtl8225_read(struct ieee80211_hw *dev, u8 addr) { struct rtl8187_priv *priv = dev->priv; u16 reg80, reg82, reg84, out; @@ -325,7 +325,7 @@ msleep(1); } -void rtl8225_rf_init(struct ieee80211_hw *dev) +static void rtl8225_rf_init(struct ieee80211_hw *dev) { struct rtl8187_priv *priv = dev->priv; int i; @@ -567,7 +567,7 @@ 0x63, 0x15, 0xc5 /* -66dBm */ }; -void rtl8225z2_rf_init(struct ieee80211_hw *dev) +static void rtl8225z2_rf_init(struct ieee80211_hw *dev) { struct rtl8187_priv *priv = dev->priv; int i; @@ -715,7 +715,7 @@ rtl818x_iowrite32(priv, (__le32 *)0xFF94, 0x3dc00002); } -void rtl8225_rf_stop(struct ieee80211_hw *dev) +static void rtl8225_rf_stop(struct ieee80211_hw *dev) { u8 reg; struct rtl8187_priv *priv = dev->priv; @@ -731,15 +731,47 @@ rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL); } -void rtl8225_rf_set_channel(struct ieee80211_hw *dev, int channel) +static void rtl8225_rf_set_channel(struct ieee80211_hw *dev, + struct ieee80211_conf *conf) { struct rtl8187_priv *priv = dev->priv; - if (priv->rf_init == rtl8225_rf_init) - rtl8225_rf_set_tx_power(dev, channel); + if (priv->rf->init == rtl8225_rf_init) + rtl8225_rf_set_tx_power(dev, conf->channel); else - rtl8225z2_rf_set_tx_power(dev, channel); + rtl8225z2_rf_set_tx_power(dev, conf->channel); - rtl8225_write(dev, 0x7, rtl8225_chan[channel - 1]); + rtl8225_write(dev, 0x7, rtl8225_chan[conf->channel - 1]); msleep(10); } + +static const struct rtl818x_rf_ops rtl8225_ops = { + .name = "rtl8225", + .init = rtl8225_rf_init, + .stop = rtl8225_rf_stop, + .set_chan = rtl8225_rf_set_channel +}; + +static const struct rtl818x_rf_ops rtl8225z2_ops = { + .name = "rtl8225z2", + .init = rtl8225z2_rf_init, + .stop = rtl8225_rf_stop, + .set_chan = rtl8225_rf_set_channel +}; + +const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *dev) +{ + u16 reg8, reg9; + + rtl8225_write(dev, 0, 0x1B7); + + reg8 = rtl8225_read(dev, 8); + reg9 = rtl8225_read(dev, 9); + + rtl8225_write(dev, 0, 0x0B7); + + if (reg8 != 0x588 || reg9 != 0x700) + return &rtl8225_ops; + + return &rtl8225z2_ops; +} diff -urN linux-2.6.24/drivers/net/wireless/rtl8187_rtl8225.h wireless-2.6/drivers/net/wireless/rtl8187_rtl8225.h --- linux-2.6.24/drivers/net/wireless/rtl8187_rtl8225.h 2007-10-09 22:31:38.000000000 +0200 +++ wireless-2.6/drivers/net/wireless/rtl8187_rtl8225.h 2008-02-21 01:38:42.000000000 +0100 @@ -20,14 +20,7 @@ #define RTL8225_ANAPARAM_OFF 0xa00beb59 #define RTL8225_ANAPARAM2_OFF 0x840dec11 -void rtl8225_write(struct ieee80211_hw *, u8 addr, u16 data); -u16 rtl8225_read(struct ieee80211_hw *, u8 addr); - -void rtl8225_rf_init(struct ieee80211_hw *); -void rtl8225z2_rf_init(struct ieee80211_hw *); -void rtl8225_rf_stop(struct ieee80211_hw *); -void rtl8225_rf_set_channel(struct ieee80211_hw *, int); - +const struct rtl818x_rf_ops * rtl8187_detect_rf(struct ieee80211_hw *); static inline void rtl8225_write_phy_ofdm(struct ieee80211_hw *dev, u8 addr, u32 data)