Skip to content

Commit

Permalink
Merge branch 'upstream' of master.kernel.org:/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/linville/wireless-2.6 into upstream
  • Loading branch information
Jeff Garzik committed Feb 9, 2007
2 parents e45d9ab + 46b8c85 commit a3cc2de
Show file tree
Hide file tree
Showing 9 changed files with 210 additions and 94 deletions.
1 change: 1 addition & 0 deletions drivers/net/wireless/bcm43xx/bcm43xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,7 @@ struct bcm43xx_private {
* This is currently always BCM43xx_BUSTYPE_PCI
*/
u8 bustype;
u64 dma_mask;

u16 board_vendor;
u16 board_type;
Expand Down
171 changes: 124 additions & 47 deletions drivers/net/wireless/bcm43xx/bcm43xx_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,16 +145,14 @@ dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,
int tx)
{
dma_addr_t dmaaddr;
int direction = PCI_DMA_FROMDEVICE;

if (tx) {
dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
buf, len,
DMA_TO_DEVICE);
} else {
dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
if (tx)
direction = PCI_DMA_TODEVICE;

dmaaddr = pci_map_single(ring->bcm->pci_dev,
buf, len,
DMA_FROM_DEVICE);
}
direction);

return dmaaddr;
}
Expand All @@ -166,13 +164,13 @@ void unmap_descbuffer(struct bcm43xx_dmaring *ring,
int tx)
{
if (tx) {
dma_unmap_single(&ring->bcm->pci_dev->dev,
pci_unmap_single(ring->bcm->pci_dev,
addr, len,
DMA_TO_DEVICE);
PCI_DMA_TODEVICE);
} else {
dma_unmap_single(&ring->bcm->pci_dev->dev,
pci_unmap_single(ring->bcm->pci_dev,
addr, len,
DMA_FROM_DEVICE);
PCI_DMA_FROMDEVICE);
}
}

Expand All @@ -183,8 +181,8 @@ void sync_descbuffer_for_cpu(struct bcm43xx_dmaring *ring,
{
assert(!ring->tx);

dma_sync_single_for_cpu(&ring->bcm->pci_dev->dev,
addr, len, DMA_FROM_DEVICE);
pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,
addr, len, PCI_DMA_FROMDEVICE);
}

static inline
Expand All @@ -194,8 +192,8 @@ void sync_descbuffer_for_device(struct bcm43xx_dmaring *ring,
{
assert(!ring->tx);

dma_sync_single_for_device(&ring->bcm->pci_dev->dev,
addr, len, DMA_FROM_DEVICE);
pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,
addr, len, PCI_DMA_TODEVICE);
}

/* Unmap and free a descriptor buffer. */
Expand All @@ -214,17 +212,53 @@ void free_descriptor_buffer(struct bcm43xx_dmaring *ring,

static int alloc_ringmemory(struct bcm43xx_dmaring *ring)
{
struct device *dev = &(ring->bcm->pci_dev->dev);

ring->descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
&(ring->dmabase), GFP_KERNEL);
ring->descbase = pci_alloc_consistent(ring->bcm->pci_dev, BCM43xx_DMA_RINGMEMSIZE,
&(ring->dmabase));
if (!ring->descbase) {
printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
return -ENOMEM;
/* Allocation may have failed due to pci_alloc_consistent
insisting on use of GFP_DMA, which is more restrictive
than necessary... */
struct dma_desc *rx_ring;
dma_addr_t rx_ring_dma;

rx_ring = kzalloc(BCM43xx_DMA_RINGMEMSIZE, GFP_KERNEL);
if (!rx_ring)
goto out_err;

rx_ring_dma = pci_map_single(ring->bcm->pci_dev, rx_ring,
BCM43xx_DMA_RINGMEMSIZE,
PCI_DMA_BIDIRECTIONAL);

if (pci_dma_mapping_error(rx_ring_dma) ||
rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > ring->bcm->dma_mask) {
/* Sigh... */
if (!pci_dma_mapping_error(rx_ring_dma))
pci_unmap_single(ring->bcm->pci_dev,
rx_ring_dma, BCM43xx_DMA_RINGMEMSIZE,
PCI_DMA_BIDIRECTIONAL);
rx_ring_dma = pci_map_single(ring->bcm->pci_dev,
rx_ring, BCM43xx_DMA_RINGMEMSIZE,
PCI_DMA_BIDIRECTIONAL);
if (pci_dma_mapping_error(rx_ring_dma) ||
rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > ring->bcm->dma_mask) {
assert(0);
if (!pci_dma_mapping_error(rx_ring_dma))
pci_unmap_single(ring->bcm->pci_dev,
rx_ring_dma, BCM43xx_DMA_RINGMEMSIZE,
PCI_DMA_BIDIRECTIONAL);
goto out_err;
}
}

ring->descbase = rx_ring;
ring->dmabase = rx_ring_dma;
}
memset(ring->descbase, 0, BCM43xx_DMA_RINGMEMSIZE);

return 0;
out_err:
printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
return -ENOMEM;
}

static void free_ringmemory(struct bcm43xx_dmaring *ring)
Expand Down Expand Up @@ -407,6 +441,29 @@ static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
if (unlikely(!skb))
return -ENOMEM;
dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
/* This hardware bug work-around adapted from the b44 driver.
The chip may be unable to do PCI DMA to/from anything above 1GB */
if (pci_dma_mapping_error(dmaaddr) ||
dmaaddr + ring->rx_buffersize > ring->bcm->dma_mask) {
/* This one has 30-bit addressing... */
if (!pci_dma_mapping_error(dmaaddr))
pci_unmap_single(ring->bcm->pci_dev,
dmaaddr, ring->rx_buffersize,
PCI_DMA_FROMDEVICE);
dev_kfree_skb_any(skb);
skb = __dev_alloc_skb(ring->rx_buffersize,GFP_DMA);
if (skb == NULL)
return -ENOMEM;
dmaaddr = pci_map_single(ring->bcm->pci_dev,
skb->data, ring->rx_buffersize,
PCI_DMA_FROMDEVICE);
if (pci_dma_mapping_error(dmaaddr) ||
dmaaddr + ring->rx_buffersize > ring->bcm->dma_mask) {
assert(0);
dev_kfree_skb_any(skb);
return -ENOMEM;
}
}
meta->skb = skb;
meta->dmaaddr = dmaaddr;
skb->dev = ring->bcm->net_dev;
Expand Down Expand Up @@ -636,8 +693,10 @@ struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm,
err = dmacontroller_setup(ring);
if (err)
goto err_free_ringmemory;
return ring;

out:
printk(KERN_ERR PFX "Error in bcm43xx_setup_dmaring\n");
return ring;

err_free_ringmemory:
Expand Down Expand Up @@ -705,30 +764,16 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
struct bcm43xx_dmaring *ring;
int err = -ENOMEM;
int dma64 = 0;
u64 mask = bcm43xx_get_supported_dma_mask(bcm);
int nobits;

if (mask == DMA_64BIT_MASK) {
bcm->dma_mask = bcm43xx_get_supported_dma_mask(bcm);
if (bcm->dma_mask == DMA_64BIT_MASK)
dma64 = 1;
nobits = 64;
} else if (mask == DMA_32BIT_MASK)
nobits = 32;
else
nobits = 30;
err = pci_set_dma_mask(bcm->pci_dev, mask);
err |= pci_set_consistent_dma_mask(bcm->pci_dev, mask);
if (err) {
#ifdef CONFIG_BCM43XX_PIO
printk(KERN_WARNING PFX "DMA not supported on this device."
" Falling back to PIO.\n");
bcm->__using_pio = 1;
return -ENOSYS;
#else
printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
"Please recompile the driver with PIO support.\n");
return -ENODEV;
#endif /* CONFIG_BCM43XX_PIO */
}
err = pci_set_dma_mask(bcm->pci_dev, bcm->dma_mask);
if (err)
goto no_dma;
err = pci_set_consistent_dma_mask(bcm->pci_dev, bcm->dma_mask);
if (err)
goto no_dma;

/* setup TX DMA channels. */
ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
Expand Down Expand Up @@ -774,7 +819,9 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
dma->rx_ring3 = ring;
}

dprintk(KERN_INFO PFX "%d-bit DMA initialized\n", nobits);
dprintk(KERN_INFO PFX "%d-bit DMA initialized\n",
(bcm->dma_mask == DMA_64BIT_MASK) ? 64 :
(bcm->dma_mask == DMA_32BIT_MASK) ? 32 : 30);
err = 0;
out:
return err;
Expand All @@ -800,7 +847,17 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
err_destroy_tx0:
bcm43xx_destroy_dmaring(dma->tx_ring0);
dma->tx_ring0 = NULL;
goto out;
no_dma:
#ifdef CONFIG_BCM43XX_PIO
printk(KERN_WARNING PFX "DMA not supported on this device."
" Falling back to PIO.\n");
bcm->__using_pio = 1;
return -ENOSYS;
#else
printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
"Please recompile the driver with PIO support.\n");
return -ENODEV;
#endif /* CONFIG_BCM43XX_PIO */
}

/* Generate a cookie for the TX header. */
Expand Down Expand Up @@ -905,6 +962,7 @@ static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
struct bcm43xx_dmadesc_generic *desc;
struct bcm43xx_dmadesc_meta *meta;
dma_addr_t dmaaddr;
struct sk_buff *bounce_skb;

assert(skb_shinfo(skb)->nr_frags == 0);

Expand All @@ -924,9 +982,28 @@ static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
skb->len - sizeof(struct bcm43xx_txhdr),
(cur_frag == 0),
generate_cookie(ring, slot));
dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
if (dma_mapping_error(dmaaddr) || dmaaddr + skb->len > ring->bcm->dma_mask) {
/* chip cannot handle DMA to/from > 1GB, use bounce buffer (copied from b44 driver) */
if (!dma_mapping_error(dmaaddr))
unmap_descbuffer(ring, dmaaddr, skb->len, 1);
bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC|GFP_DMA);
if (!bounce_skb)
return;
dmaaddr = map_descbuffer(ring, bounce_skb->data, bounce_skb->len, 1);
if (dma_mapping_error(dmaaddr) || dmaaddr + skb->len > ring->bcm->dma_mask) {
if (!dma_mapping_error(dmaaddr))
unmap_descbuffer(ring, dmaaddr, skb->len, 1);
dev_kfree_skb_any(bounce_skb);
assert(0);
return;
}
memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len);
dev_kfree_skb_any(skb);
skb = bounce_skb;
}

meta->skb = skb;
dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
meta->dmaaddr = dmaaddr;

fill_descriptor(ring, desc, dmaaddr,
Expand Down
25 changes: 15 additions & 10 deletions drivers/net/wireless/bcm43xx/bcm43xx_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,9 @@ static int modparam_noleds;
module_param_named(noleds, modparam_noleds, int, 0444);
MODULE_PARM_DESC(noleds, "Turn off all LED activity");

#ifdef CONFIG_BCM43XX_DEBUG
static char modparam_fwpostfix[64];
module_param_string(fwpostfix, modparam_fwpostfix, 64, 0444);
MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for debugging.");
#else
# define modparam_fwpostfix ""
#endif /* CONFIG_BCM43XX_DEBUG*/
MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for using multiple firmware image versions.");


/* If you want to debug with just a single device, enable this,
Expand Down Expand Up @@ -2983,8 +2979,10 @@ static int bcm43xx_chipset_attach(struct bcm43xx_private *bcm)
err = bcm43xx_pctl_set_crystal(bcm, 1);
if (err)
goto out;
bcm43xx_pci_read_config16(bcm, PCI_STATUS, &pci_status);
bcm43xx_pci_write_config16(bcm, PCI_STATUS, pci_status & ~PCI_STATUS_SIG_TARGET_ABORT);
err = bcm43xx_pci_read_config16(bcm, PCI_STATUS, &pci_status);
if (err)
goto out;
err = bcm43xx_pci_write_config16(bcm, PCI_STATUS, pci_status & ~PCI_STATUS_SIG_TARGET_ABORT);

out:
return err;
Expand Down Expand Up @@ -3796,12 +3794,18 @@ static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
}
net_dev->base_addr = (unsigned long)bcm->mmio_addr;

bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
err = bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
&bcm->board_vendor);
bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_ID,
if (err)
goto err_iounmap;
err = bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_ID,
&bcm->board_type);
bcm43xx_pci_read_config16(bcm, PCI_REVISION_ID,
if (err)
goto err_iounmap;
err = bcm43xx_pci_read_config16(bcm, PCI_REVISION_ID,
&bcm->board_revision);
if (err)
goto err_iounmap;

err = bcm43xx_chipset_attach(bcm);
if (err)
Expand Down Expand Up @@ -3892,6 +3896,7 @@ static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
pci_release_regions(pci_dev);
err_pci_disable:
pci_disable_device(pci_dev);
printk(KERN_ERR PFX "Unable to attach board\n");
goto out;
}

Expand Down
28 changes: 14 additions & 14 deletions drivers/net/wireless/bcm43xx/bcm43xx_wx.c
Original file line number Diff line number Diff line change
Expand Up @@ -261,22 +261,22 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
if (phy->type == BCM43xx_PHYTYPE_A ||
phy->type == BCM43xx_PHYTYPE_G) {
range->num_bitrates = 8;
range->bitrate[i++] = IEEE80211_OFDM_RATE_6MB;
range->bitrate[i++] = IEEE80211_OFDM_RATE_9MB;
range->bitrate[i++] = IEEE80211_OFDM_RATE_12MB;
range->bitrate[i++] = IEEE80211_OFDM_RATE_18MB;
range->bitrate[i++] = IEEE80211_OFDM_RATE_24MB;
range->bitrate[i++] = IEEE80211_OFDM_RATE_36MB;
range->bitrate[i++] = IEEE80211_OFDM_RATE_48MB;
range->bitrate[i++] = IEEE80211_OFDM_RATE_54MB;
range->bitrate[i++] = IEEE80211_OFDM_RATE_6MB * 500000;
range->bitrate[i++] = IEEE80211_OFDM_RATE_9MB * 500000;
range->bitrate[i++] = IEEE80211_OFDM_RATE_12MB * 500000;
range->bitrate[i++] = IEEE80211_OFDM_RATE_18MB * 500000;
range->bitrate[i++] = IEEE80211_OFDM_RATE_24MB * 500000;
range->bitrate[i++] = IEEE80211_OFDM_RATE_36MB * 500000;
range->bitrate[i++] = IEEE80211_OFDM_RATE_48MB * 500000;
range->bitrate[i++] = IEEE80211_OFDM_RATE_54MB * 500000;
}
if (phy->type == BCM43xx_PHYTYPE_B ||
phy->type == BCM43xx_PHYTYPE_G) {
range->num_bitrates += 4;
range->bitrate[i++] = IEEE80211_CCK_RATE_1MB;
range->bitrate[i++] = IEEE80211_CCK_RATE_2MB;
range->bitrate[i++] = IEEE80211_CCK_RATE_5MB;
range->bitrate[i++] = IEEE80211_CCK_RATE_11MB;
range->bitrate[i++] = IEEE80211_CCK_RATE_1MB * 500000;
range->bitrate[i++] = IEEE80211_CCK_RATE_2MB * 500000;
range->bitrate[i++] = IEEE80211_CCK_RATE_5MB * 500000;
range->bitrate[i++] = IEEE80211_CCK_RATE_11MB * 500000;
}

geo = ieee80211_get_geo(bcm->ieee);
Expand All @@ -286,15 +286,15 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
if (j == IW_MAX_FREQUENCIES)
break;
range->freq[j].i = j + 1;
range->freq[j].m = geo->a[i].freq;//FIXME?
range->freq[j].m = geo->a[i].freq * 100000;
range->freq[j].e = 1;
j++;
}
for (i = 0; i < geo->bg_channels; i++) {
if (j == IW_MAX_FREQUENCIES)
break;
range->freq[j].i = j + 1;
range->freq[j].m = geo->bg[i].freq;//FIXME?
range->freq[j].m = geo->bg[i].freq * 100000;
range->freq[j].e = 1;
j++;
}
Expand Down
Loading

0 comments on commit a3cc2de

Please sign in to comment.