2007-09-24 22:13:18

by Michael Wu

[permalink] [raw]
Subject: [PATCH 1/6] adm8211: kill interrupt loop

From: Michael Wu <[email protected]>

Looping in the interrupt handler is unnecessary.

Signed-off-by: Michael Wu <[email protected]>
---

drivers/net/wireless/adm8211.c | 84 +++++++++++++++++++---------------------
1 files changed, 39 insertions(+), 45 deletions(-)

diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 49a6b9e..0893d0d 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -458,51 +458,45 @@ do { \

struct ieee80211_hw *dev = dev_id;
struct adm8211_priv *priv = dev->priv;
- unsigned int count = 0;
- u32 stsr;
-
- do {
- stsr = ADM8211_CSR_READ(STSR);
- ADM8211_CSR_WRITE(STSR, stsr);
- if (stsr == 0xffffffff)
- return IRQ_HANDLED;
-
- if (!(stsr & (ADM8211_STSR_NISS | ADM8211_STSR_AISS)))
- break;
-
- if (stsr & ADM8211_STSR_RCI)
- adm8211_interrupt_rci(dev);
- if (stsr & ADM8211_STSR_TCI)
- adm8211_interrupt_tci(dev);
-
- /*ADM8211_INT(LinkOn);*/
- /*ADM8211_INT(LinkOff);*/
-
- ADM8211_INT(PCF);
- ADM8211_INT(BCNTC);
- ADM8211_INT(GPINT);
- ADM8211_INT(ATIMTC);
- ADM8211_INT(TSFTF);
- ADM8211_INT(TSCZ);
- ADM8211_INT(SQL);
- ADM8211_INT(WEPTD);
- ADM8211_INT(ATIME);
- /*ADM8211_INT(TBTT);*/
- ADM8211_INT(TEIS);
- ADM8211_INT(FBE);
- ADM8211_INT(REIS);
- ADM8211_INT(GPTT);
- ADM8211_INT(RPS);
- ADM8211_INT(RDU);
- ADM8211_INT(TUF);
- /*ADM8211_INT(TRT);*/
- /*ADM8211_INT(TLT);*/
- /*ADM8211_INT(TDU);*/
- ADM8211_INT(TPS);
-
- } while (count++ < 20);
-
- return IRQ_RETVAL(count);
+ u32 stsr = ADM8211_CSR_READ(STSR);
+ ADM8211_CSR_WRITE(STSR, stsr);
+ if (stsr == 0xffffffff)
+ return IRQ_HANDLED;
+
+ if (!(stsr & (ADM8211_STSR_NISS | ADM8211_STSR_AISS)))
+ return IRQ_HANDLED;
+
+ if (stsr & ADM8211_STSR_RCI)
+ adm8211_interrupt_rci(dev);
+ if (stsr & ADM8211_STSR_TCI)
+ adm8211_interrupt_tci(dev);
+
+ /*ADM8211_INT(LinkOn);*/
+ /*ADM8211_INT(LinkOff);*/
+
+ ADM8211_INT(PCF);
+ ADM8211_INT(BCNTC);
+ ADM8211_INT(GPINT);
+ ADM8211_INT(ATIMTC);
+ ADM8211_INT(TSFTF);
+ ADM8211_INT(TSCZ);
+ ADM8211_INT(SQL);
+ ADM8211_INT(WEPTD);
+ ADM8211_INT(ATIME);
+ /*ADM8211_INT(TBTT);*/
+ ADM8211_INT(TEIS);
+ ADM8211_INT(FBE);
+ ADM8211_INT(REIS);
+ ADM8211_INT(GPTT);
+ ADM8211_INT(RPS);
+ ADM8211_INT(RDU);
+ ADM8211_INT(TUF);
+ /*ADM8211_INT(TRT);*/
+ /*ADM8211_INT(TLT);*/
+ /*ADM8211_INT(TDU);*/
+ ADM8211_INT(TPS);
+
+ return IRQ_HANDLED;

#undef ADM8211_INT
}



2007-09-24 22:37:59

by Michael Wu

[permalink] [raw]
Subject: Re: [PATCH 6/6] adm8211: Detect interface up/down in suspend/resume hooks correctly

On Monday 24 September 2007 18:10, Michael Wu wrote:
> From: Michael Wu <[email protected]>
>
> Interface up/down detection was incorrectly changed during the filter API
> update.
>
> Signed-off-by: Michael Wu <[email protected]>
Opps. This patch is missing one part that's needed to make it actually work.
Working patch attached. Please use this instead.

Thanks,
-Michael Wu


Attachments:
(No filename) (0.00 B)
(No filename) (189.00 B)
Download all attachments

2007-09-24 22:13:18

by Michael Wu

[permalink] [raw]
Subject: [PATCH 4/6] adm8211: Use revision from pci_dev

From: Michael Wu <[email protected]>

No need to load the revision ourselves anymore.

Signed-off-by: Michael Wu <[email protected]>
---

drivers/net/wireless/adm8211.c | 44 +++++++++++++++++++---------------------
drivers/net/wireless/adm8211.h | 4 +---
2 files changed, 22 insertions(+), 26 deletions(-)

diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index ce1f8e3..e950a7d 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -117,7 +117,7 @@ static int adm8211_read_eeprom(struct ieee80211_hw *dev)
break;

default:
- if (priv->revid < ADM8211_REV_CA)
+ if (priv->pdev->revision < ADM8211_REV_CA)
priv->rf_type = ADM8211_TYPE_RFMD;
else
priv->rf_type = ADM8211_TYPE_AIROHA;
@@ -135,7 +135,7 @@ static int adm8211_read_eeprom(struct ieee80211_hw *dev)
case ADM8211_TYPE_ADMTEK:
break;
default:
- if (priv->revid < ADM8211_REV_CA)
+ if (priv->pdev->revision < ADM8211_REV_CA)
priv->bbp_type = ADM8211_TYPE_RFMD;
else
priv->bbp_type = ADM8211_TYPE_ADMTEK;
@@ -175,7 +175,7 @@ static int adm8211_read_eeprom(struct ieee80211_hw *dev)
break;

default:
- if (priv->revid < ADM8211_REV_CA)
+ if (priv->pdev->revision < ADM8211_REV_CA)
priv->specific_bbptype = ADM8211_BBP_RFMD3000;
else
priv->specific_bbptype = ADM8211_BBP_ADM8011;
@@ -194,11 +194,11 @@ static int adm8211_read_eeprom(struct ieee80211_hw *dev)
break;

default:
- if (priv->revid == ADM8211_REV_BA)
+ if (priv->pdev->revision == ADM8211_REV_BA)
priv->transceiver_type = ADM8211_RFMD2958_RF3000_CONTROL_POWER;
- else if (priv->revid == ADM8211_REV_CA)
+ else if (priv->pdev->revision == ADM8211_REV_CA)
priv->transceiver_type = ADM8211_AL2210L;
- else if (priv->revid == ADM8211_REV_AB)
+ else if (priv->pdev->revision == ADM8211_REV_AB)
priv->transceiver_type = ADM8211_RFMD2948;

printk(KERN_WARNING "%s (adm8211): Unknown transceiver: %d\n",
@@ -220,7 +220,7 @@ static inline void adm8211_write_sram(struct ieee80211_hw *dev,
struct adm8211_priv *priv = dev->priv;

ADM8211_CSR_WRITE(WEPCTL, addr | ADM8211_WEPCTL_TABLE_WR |
- (priv->revid < ADM8211_REV_BA ?
+ (priv->pdev->revision < ADM8211_REV_BA ?
0 : ADM8211_WEPCTL_SEL_WEPTABLE ));
ADM8211_CSR_READ(WEPCTL);
msleep(1);
@@ -238,7 +238,7 @@ static void adm8211_write_sram_bytes(struct ieee80211_hw *dev,
u32 reg = ADM8211_CSR_READ(WEPCTL);
unsigned int i;

- if (priv->revid < ADM8211_REV_BA) {
+ if (priv->pdev->revision < ADM8211_REV_BA) {
for (i = 0; i < len; i += 2) {
u16 val = buf[i] | (buf[i + 1] << 8);
adm8211_write_sram(dev, addr + i / 2, val);
@@ -421,7 +421,7 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
if (skb) {
struct ieee80211_rx_status rx_status = {0};

- if (priv->revid < ADM8211_REV_CA)
+ if (priv->pdev->revision < ADM8211_REV_CA)
rx_status.ssi = rssi;
else
rx_status.ssi = 100 - rssi;
@@ -703,7 +703,7 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan)
adm8211_rf_write_syn_rfmd2958(dev, 0x0A, reg);
/* set TXRX TX_GAIN */
adm8211_rf_write_syn_rfmd2958(dev, 0x09, 0x00050 |
- (priv->revid < ADM8211_REV_CA ? tx_power : 0));
+ (priv->pdev->revision < ADM8211_REV_CA ? tx_power : 0));
} else {
reg = ADM8211_CSR_READ(PLCPHD);
reg &= 0xff00ffff;
@@ -722,7 +722,7 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan)
tx_power<<2);
adm8211_write_bbp(dev, RF3000_LOW_GAIN_CALIB, lpf_cutoff);
adm8211_write_bbp(dev, RF3000_HIGH_GAIN_CALIB, lnags_thresh);
- adm8211_write_bbp(dev, 0x1c, priv->revid == ADM8211_REV_BA ?
+ adm8211_write_bbp(dev, 0x1c, priv->pdev->revision == ADM8211_REV_BA ?
priv->eeprom->cr28 : 0);
adm8211_write_bbp(dev, 0x1d, priv->eeprom->cr29);

@@ -761,7 +761,7 @@ static void adm8211_update_mode(struct ieee80211_hw *dev)
priv->nar |= ADM8211_NAR_EA | ADM8211_NAR_ST | ADM8211_NAR_SR;

/* don't trust the error bits on rev 0x20 and up in adhoc */
- if (priv->revid >= ADM8211_REV_BA)
+ if (priv->pdev->revision >= ADM8211_REV_BA)
priv->soft_rx_crc = 1;
break;
case IEEE80211_IF_TYPE_MNTR:
@@ -862,7 +862,7 @@ static int adm8211_hw_init_bbp(struct ieee80211_hw *dev)
break;
}

- switch (priv->revid) {
+ switch (priv->pdev->revision) {
case ADM8211_REV_CA:
if (priv->transceiver_type == ADM8211_RFMD2958 ||
priv->transceiver_type == ADM8211_RFMD2958_RF3000_CONTROL_POWER ||
@@ -920,7 +920,7 @@ static int adm8211_hw_init_bbp(struct ieee80211_hw *dev)
adm8211_write_bbp(dev, 0x1c, 0x00);
adm8211_write_bbp(dev, 0x1d, 0x80);
} else {
- if (priv->revid == ADM8211_REV_BA)
+ if (priv->pdev->revision == ADM8211_REV_BA)
adm8211_write_bbp(dev, 0x1c, priv->eeprom->cr28);
else
adm8211_write_bbp(dev, 0x1c, 0x00);
@@ -1052,7 +1052,7 @@ static int adm8211_set_rate(struct ieee80211_hw *dev)
u8 rate_buf[12] = {0};

/* write supported rates */
- if (priv->revid != ADM8211_REV_BA) {
+ if (priv->pdev->revision != ADM8211_REV_BA) {
rate_buf[0] = ARRAY_SIZE(adm8211_rates);
for (i = 0; i < ARRAY_SIZE(adm8211_rates); i++)
rate_buf[i + 1] = (adm8211_rates[i].rate / 5) | 0x80;
@@ -1136,7 +1136,7 @@ static void adm8211_hw_init(struct ieee80211_hw *dev)
* PWR0PE2 = 13 us
* PWR1PE2 = 1 us
* PWR0TXPE = 8 or 6 */
- if (priv->revid < ADM8211_REV_CA)
+ if (priv->pdev->revision < ADM8211_REV_CA)
ADM8211_CSR_WRITE(TOFS2, 0x8815cd18);
else
ADM8211_CSR_WRITE(TOFS2, 0x8535cd16);
@@ -1165,7 +1165,7 @@ static void adm8211_hw_init(struct ieee80211_hw *dev)

/* SLOT=20 us, SIFS=110 cycles of 22 MHz (5 us),
* DIFS=50 us, EIFS=100 us */
- if (priv->revid < ADM8211_REV_CA)
+ if (priv->pdev->revision < ADM8211_REV_CA)
ADM8211_CSR_WRITE(IFST, (20 << 23) | (110 << 15) |
(50 << 9) | 100);
else
@@ -1224,13 +1224,13 @@ static int adm8211_hw_reset(struct ieee80211_hw *dev)

ADM8211_CSR_WRITE(PAR, tmp);

- if (priv->revid == ADM8211_REV_BA &&
+ if (priv->pdev->revision == ADM8211_REV_BA &&
(priv->transceiver_type == ADM8211_RFMD2958_RF3000_CONTROL_POWER ||
priv->transceiver_type == ADM8211_RFMD2958)) {
reg = ADM8211_CSR_READ(CSR_TEST1);
reg |= (1 << 4) | (1 << 5);
ADM8211_CSR_WRITE(CSR_TEST1, reg);
- } else if (priv->revid == ADM8211_REV_CA) {
+ } else if (priv->pdev->revision == ADM8211_REV_CA) {
reg = ADM8211_CSR_READ(CSR_TEST1);
reg &= ~((1 << 4) | (1 << 5));
ADM8211_CSR_WRITE(CSR_TEST1, reg);
@@ -1866,8 +1866,6 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
goto err_iounmap;
}

- pci_read_config_byte(pdev, PCI_CLASS_REVISION, &priv->revid);
-
*(u32 *)perm_addr = le32_to_cpu((__force __le32)ADM8211_CSR_READ(PAR0));
*(u16 *)&perm_addr[4] =
le16_to_cpu((__force __le16)ADM8211_CSR_READ(PAR1) & 0xFFFF);
@@ -1902,7 +1900,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
priv->mode = IEEE80211_IF_TYPE_MNTR;

/* Power-on issue. EEPROM won't read correctly without */
- if (priv->revid >= ADM8211_REV_BA) {
+ if (pdev->revision >= ADM8211_REV_BA) {
ADM8211_CSR_WRITE(FRCTL, 0);
ADM8211_CSR_READ(FRCTL);
ADM8211_CSR_WRITE(FRCTL, 1);
@@ -1935,7 +1933,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,

printk(KERN_INFO "%s: hwaddr %s, Rev 0x%02x\n",
wiphy_name(dev->wiphy), print_mac(mac, dev->wiphy->perm_addr),
- priv->revid);
+ pdev->revision);

return 0;

diff --git a/drivers/net/wireless/adm8211.h b/drivers/net/wireless/adm8211.h
index 5991b17..ef326fe 100644
--- a/drivers/net/wireless/adm8211.h
+++ b/drivers/net/wireless/adm8211.h
@@ -416,7 +416,7 @@ struct adm8211_desc {
#define TDES1_CONTROL_RBS1 (0x00000fff)

/* SRAM offsets */
-#define ADM8211_SRAM(x) (priv->revid < ADM8211_REV_BA ? \
+#define ADM8211_SRAM(x) (priv->pdev->revision < ADM8211_REV_BA ? \
ADM8211_SRAM_A_ ## x : ADM8211_SRAM_B_ ## x)

#define ADM8211_SRAM_INDIV_KEY 0x0000
@@ -623,8 +623,6 @@ struct adm8211_priv {
struct adm8211_eeprom *eeprom;
size_t eeprom_len;

- u8 revid;
-
u32 nar;

#define ADM8211_TYPE_INTERSIL 0x00


2007-09-24 22:13:18

by Michael Wu

[permalink] [raw]
Subject: [PATCH 6/6] adm8211: Detect interface up/down in suspend/resume hooks correctly

From: Michael Wu <[email protected]>

Interface up/down detection was incorrectly changed during the filter API
update.

Signed-off-by: Michael Wu <[email protected]>
---

drivers/net/wireless/adm8211.c | 7 ++++---
1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 95c8315..94f061c 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1554,6 +1554,7 @@ static void adm8211_stop(struct ieee80211_hw *dev)
{
struct adm8211_priv *priv = dev->priv;

+ priv->mode = IEEE80211_IF_TYPE_MGMT;
priv->nar = 0;
ADM8211_CSR_WRITE(NAR, 0);
ADM8211_CSR_WRITE(IER, 0);
@@ -1896,7 +1897,7 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
priv->tx_power = 0x40;
priv->lpf_cutoff = 0xFF;
priv->lnags_threshold = 0xFF;
- priv->mode = IEEE80211_IF_TYPE_MNTR;
+ priv->mode = IEEE80211_IF_TYPE_MGMT;

/* Power-on issue. EEPROM won't read correctly without */
if (pdev->revision >= ADM8211_REV_BA) {
@@ -1991,7 +1992,7 @@ static int adm8211_suspend(struct pci_dev *pdev, pm_message_t state)
struct ieee80211_hw *dev = pci_get_drvdata(pdev);
struct adm8211_priv *priv = dev->priv;

- if (priv->mode != IEEE80211_IF_TYPE_MNTR) {
+ if (priv->mode != IEEE80211_IF_TYPE_MGMT) {
ieee80211_stop_queues(dev);
adm8211_stop(dev);
}
@@ -2009,7 +2010,7 @@ static int adm8211_resume(struct pci_dev *pdev)
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);

- if (priv->mode != IEEE80211_IF_TYPE_MNTR) {
+ if (priv->mode != IEEE80211_IF_TYPE_MGMT) {
adm8211_start(dev);
ieee80211_start_queues(dev);
}


2007-09-24 22:13:18

by Michael Wu

[permalink] [raw]
Subject: [PATCH 5/6] adm8211: Pass all TXed frames to tx_status_irqsafe

From: Michael Wu <[email protected]>

ieee80211_tx_status_irqsafe can handle the freeing of all TXed frames.

Also, set excessive_retries for failed frames.

Signed-off-by: Michael Wu <[email protected]>
---

drivers/net/wireless/adm8211.c | 27 +++++++++++++--------------
1 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index e950a7d..95c8315 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -299,6 +299,7 @@ static void adm8211_interrupt_tci(struct ieee80211_hw *dev)
for (dirty_tx = priv->dirty_tx; priv->cur_tx - dirty_tx; dirty_tx++) {
unsigned int entry = dirty_tx % priv->tx_ring_size;
u32 status = le32_to_cpu(priv->tx_ring[entry].status);
+ struct ieee80211_tx_status tx_status;
struct adm8211_tx_ring_info *info;
struct sk_buff *skb;

@@ -314,21 +315,19 @@ static void adm8211_interrupt_tci(struct ieee80211_hw *dev)
pci_unmap_single(priv->pdev, info->mapping,
info->skb->len, PCI_DMA_TODEVICE);

- if (info->tx_control.flags & IEEE80211_TXCTL_REQ_TX_STATUS) {
- struct ieee80211_tx_status tx_status = {{0}};
- struct ieee80211_hdr *hdr;
- size_t hdrlen = info->hdrlen;
-
- skb_pull(skb, sizeof(struct adm8211_tx_hdr));
- hdr = (struct ieee80211_hdr *)skb_push(skb, hdrlen);
- memcpy(hdr, skb->cb, hdrlen);
- memcpy(&tx_status.control, &info->tx_control,
- sizeof(tx_status.control));
- if (!(status & TDES0_STATUS_ES))
+ memset(&tx_status, 0, sizeof(tx_status));
+ skb_pull(skb, sizeof(struct adm8211_tx_hdr));
+ memcpy(skb_push(skb, info->hdrlen), skb->cb, info->hdrlen);
+ memcpy(&tx_status.control, &info->tx_control,
+ sizeof(tx_status.control));
+ if (!(tx_status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
+ if (status & TDES0_STATUS_ES)
+ tx_status.excessive_retries = 1;
+ else
tx_status.flags |= IEEE80211_TX_STATUS_ACK;
- ieee80211_tx_status_irqsafe(dev, skb, &tx_status);
- } else
- dev_kfree_skb_irq(skb);
+ }
+ ieee80211_tx_status_irqsafe(dev, skb, &tx_status);
+
info->skb = NULL;
}



2007-09-24 22:13:17

by Michael Wu

[permalink] [raw]
Subject: [PATCH 3/6] adm8211: kill version printks

From: Michael Wu <[email protected]>

No need to pollute dmesg with copyright info.

Signed-off-by: Michael Wu <[email protected]>
---

drivers/net/wireless/adm8211.c | 15 ---------------
1 files changed, 0 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 4c43cdb..ce1f8e3 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -39,11 +39,6 @@ static unsigned int rx_ring_size __read_mostly = 16;
module_param(tx_ring_size, uint, 0);
module_param(rx_ring_size, uint, 0);

-static const char version[] = KERN_INFO "adm8211: "
-"Copyright 2003, Jouni Malinen <[email protected]>; "
-"Copyright 2004-2007, Michael Wu <[email protected]>\n";
-
-
static struct pci_device_id adm8211_pci_id_table[] __devinitdata = {
/* ADMtek ADM8211 */
{ PCI_DEVICE(0x10B7, 0x6000) }, /* 3Com 3CRSHPW796 */
@@ -1794,12 +1789,6 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
u8 perm_addr[ETH_ALEN];
DECLARE_MAC_BUF(mac);

-#ifndef MODULE
- static unsigned int cardidx;
- if (!cardidx++)
- printk(version);
-#endif
-
err = pci_enable_device(pdev);
if (err) {
printk(KERN_ERR "%s (adm8211): Cannot enable new PCI device\n",
@@ -2051,10 +2040,6 @@ static struct pci_driver adm8211_driver = {

static int __init adm8211_init(void)
{
-#ifdef MODULE
- printk(version);
-#endif
-
return pci_register_driver(&adm8211_driver);
}



2007-09-24 22:13:17

by Michael Wu

[permalink] [raw]
Subject: [PATCH 2/6] adm8211: Improve writing of mac addrs to registers

From: Michael Wu <[email protected]>

The mac address write is broken for big endian and the bssid write can be
simplified. This patch does both.

Signed-off-by: Michael Wu <[email protected]>
---

drivers/net/wireless/adm8211.c | 7 +++----
1 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index 0893d0d..4c43cdb 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1283,8 +1283,7 @@ static void adm8211_set_bssid(struct ieee80211_hw *dev, const u8 *bssid)
struct adm8211_priv *priv = dev->priv;
u32 reg;

- reg = bssid[0] | (bssid[1] << 8) | (bssid[2] << 16) | (bssid[3] << 24);
- ADM8211_CSR_WRITE(BSSID0, reg);
+ ADM8211_CSR_WRITE(BSSID0, le32_to_cpu(*(__le32 *)bssid));
reg = ADM8211_CSR_READ(ABDA1);
reg &= 0x0000ffff;
reg |= (bssid[4] << 16) | (bssid[5] << 24);
@@ -1414,8 +1413,8 @@ static int adm8211_add_interface(struct ieee80211_hw *dev,

ADM8211_IDLE();

- ADM8211_CSR_WRITE(PAR0, *(u32 *)conf->mac_addr);
- ADM8211_CSR_WRITE(PAR1, *(u16 *)(conf->mac_addr + 4));
+ ADM8211_CSR_WRITE(PAR0, le32_to_cpu(*(__le32 *)conf->mac_addr));
+ ADM8211_CSR_WRITE(PAR1, le16_to_cpu(*(__le16 *)(conf->mac_addr + 4)));

adm8211_update_mode(dev);