diff options
Diffstat (limited to 'drivers')
290 files changed, 6981 insertions, 7147 deletions
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index b1d08a8f500..e6b4606e36b 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -1499,7 +1499,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev, * off. */ if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x2652) { - int rc = piix_disable_ahci(pdev); + rc = piix_disable_ahci(pdev); if (rc) return rc; } diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c index 3ead02fe379..5032c32fa50 100644 --- a/drivers/ata/sata_inic162x.c +++ b/drivers/ata/sata_inic162x.c @@ -96,6 +96,7 @@ enum { PORT_SCR = 0x20, /* HOST_CTL bits */ + HCTL_LEDEN = (1 << 3), /* enable LED operation */ HCTL_IRQOFF = (1 << 8), /* global IRQ off */ HCTL_FTHD0 = (1 << 10), /* fifo threshold 0 */ HCTL_FTHD1 = (1 << 11), /* fifo threshold 1*/ @@ -540,7 +541,7 @@ static unsigned int inic_qc_issue(struct ata_queued_cmd *qc) void __iomem *port_base = inic_port_base(ap); /* fire up the ADMA engine */ - writew(HCTL_FTHD0, port_base + HOST_CTL); + writew(HCTL_FTHD0 | HCTL_LEDEN, port_base + HOST_CTL); writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL); writeb(0, port_base + PORT_CPB_PTQFIFO); diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 1e1f3f3757a..14601dc05e4 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c @@ -309,6 +309,8 @@ static void nv_nf2_freeze(struct ata_port *ap); static void nv_nf2_thaw(struct ata_port *ap); static void nv_ck804_freeze(struct ata_port *ap); static void nv_ck804_thaw(struct ata_port *ap); +static int nv_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline); static int nv_adma_slave_config(struct scsi_device *sdev); static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc); static void nv_adma_qc_prep(struct ata_queued_cmd *qc); @@ -403,28 +405,45 @@ static struct scsi_host_template nv_swncq_sht = { .slave_configure = nv_swncq_slave_config, }; -static struct ata_port_operations nv_generic_ops = { +/* OSDL bz3352 reports that some nv controllers can't determine device + * signature reliably and nv_hardreset is implemented to work around + * the problem. This was reported on nf3 and it's unclear whether any + * other controllers are affected. However, the workaround has been + * applied to all variants and there isn't much to gain by trying to + * find out exactly which ones are affected at this point especially + * because NV has moved over to ahci for newer controllers. + */ +static struct ata_port_operations nv_common_ops = { .inherits = &ata_bmdma_port_ops, - .hardreset = ATA_OP_NULL, + .hardreset = nv_hardreset, .scr_read = nv_scr_read, .scr_write = nv_scr_write, }; +/* OSDL bz11195 reports that link doesn't come online after hardreset + * on generic nv's and there have been several other similar reports + * on linux-ide. Disable hardreset for generic nv's. + */ +static struct ata_port_operations nv_generic_ops = { + .inherits = &nv_common_ops, + .hardreset = ATA_OP_NULL, +}; + static struct ata_port_operations nv_nf2_ops = { - .inherits = &nv_generic_ops, + .inherits = &nv_common_ops, .freeze = nv_nf2_freeze, .thaw = nv_nf2_thaw, }; static struct ata_port_operations nv_ck804_ops = { - .inherits = &nv_generic_ops, + .inherits = &nv_common_ops, .freeze = nv_ck804_freeze, .thaw = nv_ck804_thaw, .host_stop = nv_ck804_host_stop, }; static struct ata_port_operations nv_adma_ops = { - .inherits = &nv_generic_ops, + .inherits = &nv_common_ops, .check_atapi_dma = nv_adma_check_atapi_dma, .sff_tf_read = nv_adma_tf_read, @@ -448,7 +467,7 @@ static struct ata_port_operations nv_adma_ops = { }; static struct ata_port_operations nv_swncq_ops = { - .inherits = &nv_generic_ops, + .inherits = &nv_common_ops, .qc_defer = ata_std_qc_defer, .qc_prep = nv_swncq_qc_prep, @@ -1586,6 +1605,21 @@ static void nv_mcp55_thaw(struct ata_port *ap) ata_sff_thaw(ap); } +static int nv_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline) +{ + int rc; + + /* SATA hardreset fails to retrieve proper device signature on + * some controllers. Request follow up SRST. For more info, + * see http://bugzilla.kernel.org/show_bug.cgi?id=3352 + */ + rc = sata_sff_hardreset(link, class, deadline); + if (rc) + return rc; + return -EAGAIN; +} + static void nv_adma_error_handler(struct ata_port *ap) { struct nv_adma_port_priv *pp = ap->private_data; diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 41b2204ebc6..5503bfc8e13 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c @@ -1270,7 +1270,7 @@ static int comp_tx(struct eni_dev *eni_dev,int *pcr,int reserved,int *pre, if (*pre < 3) (*pre)++; /* else fail later */ div = pre_div[*pre]*-*pcr; DPRINTK("max div %d\n",div); - *res = (TS_CLOCK+div-1)/div-1; + *res = DIV_ROUND_UP(TS_CLOCK, div)-1; } if (*res < 0) *res = 0; if (*res > MID_SEG_MAX_RATE) *res = MID_SEG_MAX_RATE; diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index c0ac728dc56..615412364e9 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -635,7 +635,7 @@ static int make_rate (const hrz_dev * dev, u32 c, rounding r, // take care of rounding switch (r) { case round_down: - pre = (br+(c<<div)-1)/(c<<div); + pre = DIV_ROUND_UP(br, c<<div); // but p must be non-zero if (!pre) pre = 1; @@ -668,7 +668,7 @@ static int make_rate (const hrz_dev * dev, u32 c, rounding r, // take care of rounding switch (r) { case round_down: - pre = (br+(c<<div)-1)/(c<<div); + pre = DIV_ROUND_UP(br, c<<div); break; case round_nearest: pre = (br+(c<<div)/2)/(c<<div); @@ -698,7 +698,7 @@ got_it: if (bits) *bits = (div<<CLOCK_SELECT_SHIFT) | (pre-1); if (actual) { - *actual = (br + (pre<<div) - 1) / (pre<<div); + *actual = DIV_ROUND_UP(br, pre<<div); PRINTD (DBG_QOS, "actual rate: %u", *actual); } return 0; @@ -1967,7 +1967,7 @@ static int __devinit hrz_init (hrz_dev * dev) { // Set the max AAL5 cell count to be just enough to contain the // largest AAL5 frame that the user wants to receive wr_regw (dev, MAX_AAL5_CELL_COUNT_OFF, - (max_rx_size + ATM_AAL5_TRAILER + ATM_CELL_PAYLOAD - 1) / ATM_CELL_PAYLOAD); + DIV_ROUND_UP(max_rx_size + ATM_AAL5_TRAILER, ATM_CELL_PAYLOAD)); // Enable receive wr_regw (dev, RX_CONFIG_OFF, rd_regw (dev, RX_CONFIG_OFF) | RX_ENABLE); diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index 3a504e94a4d..e33ae0025b1 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c @@ -1114,11 +1114,8 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe) rpp = &vc->rcv.rx_pool; + __skb_queue_tail(&rpp->queue, skb); rpp->len += skb->len; - if (!rpp->count++) - rpp->first = skb; - *rpp->last = skb; - rpp->last = &skb->next; if (stat & SAR_RSQE_EPDU) { unsigned char *l1l2; @@ -1145,7 +1142,7 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe) atomic_inc(&vcc->stats->rx_err); return; } - if (rpp->count > 1) { + if (skb_queue_len(&rpp->queue) > 1) { struct sk_buff *sb; skb = dev_alloc_skb(rpp->len); @@ -1161,12 +1158,9 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe) dev_kfree_skb(skb); return; } - sb = rpp->first; - for (i = 0; i < rpp->count; i++) { + skb_queue_walk(&rpp->queue, sb) memcpy(skb_put(skb, sb->len), sb->data, sb->len); - sb = sb->next; - } recycle_rx_pool_skb(card, rpp); @@ -1180,7 +1174,6 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe) return; } - skb->next = NULL; flush_rx_pool(card, rpp); if (!atm_charge(vcc, skb->truesize)) { @@ -1918,25 +1911,18 @@ recycle_rx_skb(struct idt77252_dev *card, struct sk_buff *skb) static void flush_rx_pool(struct idt77252_dev *card, struct rx_pool *rpp) { + skb_queue_head_init(&rpp->queue); rpp->len = 0; - rpp->count = 0; - rpp->first = NULL; - rpp->last = &rpp->first; } static void recycle_rx_pool_skb(struct idt77252_dev *card, struct rx_pool *rpp) { - struct sk_buff *skb, *next; - int i; + struct sk_buff *skb, *tmp; - skb = rpp->first; - for (i = 0; i < rpp->count; i++) { - next = skb->next; - skb->next = NULL; + skb_queue_walk_safe(&rpp->queue, skb, tmp) recycle_rx_skb(card, skb); - skb = next; - } + flush_rx_pool(card, rpp); } @@ -2537,7 +2523,7 @@ idt77252_close(struct atm_vcc *vcc) waitfor_idle(card); spin_unlock_irqrestore(&card->cmd_lock, flags); - if (vc->rcv.rx_pool.count) { + if (skb_queue_len(&vc->rcv.rx_pool.queue) != 0) { DPRINTK("%s: closing a VC with pending rx buffers.\n", card->name); @@ -2970,7 +2956,7 @@ close_card_oam(struct idt77252_dev *card) waitfor_idle(card); spin_unlock_irqrestore(&card->cmd_lock, flags); - if (vc->rcv.rx_pool.count) { + if (skb_queue_len(&vc->rcv.rx_pool.queue) != 0) { DPRINTK("%s: closing a VC " "with pending rx buffers.\n", card->name); diff --git a/drivers/atm/idt77252.h b/drivers/atm/idt77252.h index e83eaf120da..5042bb2dab1 100644 --- a/drivers/atm/idt77252.h +++ b/drivers/atm/idt77252.h @@ -173,10 +173,8 @@ struct scq_info }; struct rx_pool { - struct sk_buff *first; - struct sk_buff **last; + struct sk_buff_head queue; unsigned int len; - unsigned int count; }; struct aal1 { diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 58583c6ac5b..752b1ba81f7 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c @@ -496,8 +496,8 @@ static int open_rx_first(struct atm_vcc *vcc) vcc->qos.rxtp.max_sdu = 65464; /* fix this - we may want to receive 64kB SDUs later */ - cells = (vcc->qos.rxtp.max_sdu+ATM_AAL5_TRAILER+ - ATM_CELL_PAYLOAD-1)/ATM_CELL_PAYLOAD; + cells = DIV_ROUND_UP(vcc->qos.rxtp.max_sdu + ATM_AAL5_TRAILER, + ATM_CELL_PAYLOAD); zatm_vcc->pool = pool_index(cells*ATM_CELL_PAYLOAD); } else { @@ -820,7 +820,7 @@ static int alloc_shaper(struct atm_dev *dev,int *pcr,int min,int max,int ubr) } else { i = 255; - m = (ATM_OC3_PCR*255+max-1)/max; + m = DIV_ROUND_UP(ATM_OC3_PCR*255, max); } } if (i > m) { diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index 5b4c6e649c1..93f3690396a 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h @@ -159,11 +159,8 @@ struct aoedev { sector_t ssize; struct timer_list timer; spinlock_t lock; - struct sk_buff *sendq_hd; /* packets needing to be sent, list head */ - struct sk_buff *sendq_tl; - struct sk_buff *skbpool_hd; - struct sk_buff *skbpool_tl; - int nskbpool; + struct sk_buff_head sendq; + struct sk_buff_head skbpool; mempool_t *bufpool; /* for deadlock-free Buf allocation */ struct list_head bufq; /* queue of bios to work on */ struct buf *inprocess; /* the one we're currently working on */ @@ -199,7 +196,7 @@ int aoedev_flush(const char __user *str, size_t size); int aoenet_init(void); void aoenet_exit(void); -void aoenet_xmit(struct sk_buff *); +void aoenet_xmit(struct sk_buff_head *); int is_aoe_netif(struct net_device *ifp); int set_aoe_iflist(const char __user *str, size_t size); diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index 0c39782b266..fd2cf5439a1 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c @@ -158,9 +158,9 @@ aoeblk_release(struct inode *inode, struct file *filp) static int aoeblk_make_request(struct request_queue *q, struct bio *bio) { + struct sk_buff_head queue; struct aoedev *d; struct buf *buf; - struct sk_buff *sl; ulong flags; blk_queue_bounce(q, &bio); @@ -213,11 +213,11 @@ aoeblk_make_request(struct request_queue *q, struct bio *bio) list_add_tail(&buf->bufs, &d->bufq); aoecmd_work(d); - sl = d->sendq_hd; - d->sendq_hd = d->sendq_tl = NULL; + __skb_queue_head_init(&queue); + skb_queue_splice_init(&d->sendq, &queue); spin_unlock_irqrestore(&d->lock, flags); - aoenet_xmit(sl); + aoenet_xmit(&queue); return 0; } diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c index 181ebb85f0b..1f56d2c5b7f 100644 --- a/drivers/block/aoe/aoechr.c +++ b/drivers/block/aoe/aoechr.c @@ -9,6 +9,7 @@ #include <linux/completion.h> #include <linux/delay.h> #include <linux/smp_lock.h> +#include <linux/skbuff.h> #include "aoe.h" enum { @@ -103,7 +104,12 @@ loop: spin_lock_irqsave(&d->lock, flags); goto loop; } - aoenet_xmit(skb); + if (skb) { + struct sk_buff_head queue; + __skb_queue_head_init(&queue); + __skb_queue_tail(&queue, skb); + aoenet_xmit(&queue); + } aoecmd_cfg(major, minor); return 0; } diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 2f1746295d0..e33da30be4c 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c @@ -114,29 +114,22 @@ ifrotate(struct aoetgt *t) static void skb_pool_put(struct aoedev *d, struct sk_buff *skb) { - if (!d->skbpool_hd) - d->skbpool_hd = skb; - else - d->skbpool_tl->next = skb; - d->skbpool_tl = skb; + __skb_queue_tail(&d->skbpool, skb); } static struct sk_buff * skb_pool_get(struct aoedev *d) { - struct sk_buff *skb; + struct sk_buff *skb = skb_peek(&d->skbpool); - skb = d->skbpool_hd; if (skb && atomic_read(&skb_shinfo(skb)->dataref) == 1) { - d->skbpool_hd = skb->next; - skb->next = NULL; + __skb_unlink(skb, &d->skbpool); return skb; } - if (d->nskbpool < NSKBPOOLMAX - && (skb = new_skb(ETH_ZLEN))) { - d->nskbpool++; + if (skb_queue_len(&d->skbpool) < NSKBPOOLMAX && + (skb = new_skb(ETH_ZLEN))) return skb; - } + return NULL; } @@ -293,29 +286,22 @@ aoecmd_ata_rw(struct aoedev *d) skb->dev = t->ifp->nd; skb = skb_clone(skb, GFP_ATOMIC); - if (skb) { - if (d->sendq_hd) - d->sendq_tl->next = skb; - else - d->sendq_hd = skb; - d->sendq_tl = skb; - } + if (skb) + __skb_queue_tail(&d->sendq, skb); return 1; } /* some callers cannot sleep, and they can call this function, * transmitting the packets later, when interrupts are on */ -static struct sk_buff * -aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) +static void +aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff_head *queue) { struct aoe_hdr *h; struct aoe_cfghdr *ch; - struct sk_buff *skb, *sl, *sl_tail; + struct sk_buff *skb; struct net_device *ifp; - sl = sl_tail = NULL; - read_lock(&dev_base_lock); for_each_netdev(&init_net, ifp) { dev_hold(ifp); @@ -329,8 +315,7 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) } skb_put(skb, sizeof *h + sizeof *ch); skb->dev = ifp; - if (sl_tail == NULL) - sl_tail = skb; + __skb_queue_tail(queue, skb); h = (struct aoe_hdr *) skb_mac_header(skb); memset(h, 0, sizeof *h + sizeof *ch); @@ -342,16 +327,10 @@ aoecmd_cfg_pkts(ushort aoemajor, unsigned char aoeminor, struct sk_buff **tail) h->minor = aoeminor; h->cmd = AOECMD_CFG; - skb->next = sl; - sl = skb; cont: dev_put(ifp); } read_unlock(&dev_base_lock); - - if (tail != NULL) - *tail = sl_tail; - return sl; } static void @@ -406,11 +385,7 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f) skb = skb_clone(skb, GFP_ATOMIC); if (skb == NULL) return; - if (d->sendq_hd) - d->sendq_tl->next = skb; - else - d->sendq_hd = skb; - d->sendq_tl = skb; + __skb_queue_tail(&d->sendq, skb); } static int @@ -508,16 +483,15 @@ ata_scnt(unsigned char *packet) { static void rexmit_timer(ulong vp) { + struct sk_buff_head queue; struct aoedev *d; struct aoetgt *t, **tt, **te; struct aoeif *ifp; struct frame *f, *e; - struct sk_buff *sl; register long timeout; ulong flags, n; d = (struct aoedev *) vp; - sl = NULL; /* timeout is always ~150% of the moving average */ timeout = d->rttavg; @@ -589,7 +563,7 @@ rexmit_timer(ulong vp) } } - if (d->sendq_hd) { + if (!skb_queue_empty(&d->sendq)) { n = d->rttavg <<= 1; if (n > MAXTIMER) d->rttavg = MAXTIMER; @@ -600,15 +574,15 @@ rexmit_timer(ulong vp) aoecmd_work(d); } - sl = d->sendq_hd; - d->sendq_hd = d->sendq_tl = NULL; + __skb_queue_head_init(&queue); + skb_queue_splice_init(&d->sendq, &queue); d->timer.expires = jiffies + TIMERTICK; add_timer(&d->timer); spin_unlock_irqrestore(&d->lock, flags); - aoenet_xmit(sl); + aoenet_xmit(&queue); } /* enters with d->lock held */ @@ -767,12 +741,12 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector void aoecmd_ata_rsp(struct sk_buff *skb) { + struct sk_buff_head queue; struct aoedev *d; struct aoe_hdr *hin, *hout; struct aoe_atahdr *ahin, *ahout; struct frame *f; struct buf *buf; - struct sk_buff *sl; struct aoetgt *t; struct aoeif *ifp; register long n; @@ -893,21 +867,21 @@ aoecmd_ata_rsp(struct sk_buff *skb) aoecmd_work(d); xmit: - sl = d->sendq_hd; - d->sendq_hd = d->sendq_tl = NULL; + __skb_queue_head_init(&queue); + skb_queue_splice_init(&d->sendq, &queue); spin_unlock_irqrestore(&d->lock, flags); - aoenet_xmit(sl); + aoenet_xmit(&queue); } void aoecmd_cfg(ushort aoemajor, unsigned char aoeminor) { - struct sk_buff *sl; - - sl = aoecmd_cfg_pkts(aoemajor, aoeminor, NULL); + struct sk_buff_head queue; - aoenet_xmit(sl); + __skb_queue_head_init(&queue); + aoecmd_cfg_pkts(aoemajor, aoeminor, &queue); + aoenet_xmit(&queue); } struct sk_buff * @@ -1076,7 +1050,12 @@ aoecmd_cfg_rsp(struct sk_buff *skb) spin_unlock_irqrestore(&d->lock, flags); - aoenet_xmit(sl); + if (sl) { + struct sk_buff_head queue; + __skb_queue_head_init(&queue); + __skb_queue_tail(&queue, sl); + aoenet_xmit(&queue); + } } void diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index a1d813ab0d6..75a610adf51 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c @@ -188,14 +188,12 @@ skbfree(struct sk_buff *skb) static void skbpoolfree(struct aoedev *d) { - struct sk_buff *skb; + struct sk_buff *skb, *tmp; - while ((skb = d->skbpool_hd)) { - d->skbpool_hd = skb->next; - skb->next = NULL; + skb_queue_walk_safe(&d->skbpool, skb, tmp) skbfree(skb); - } - d->skbpool_tl = NULL; + + __skb_queue_head_init(&d->skbpool); } /* find it or malloc it */ @@ -217,6 +215,8 @@ aoedev_by_sysminor_m(ulong sysminor) goto out; INIT_WORK(&d->work, aoecmd_sleepwork); spin_lock_init(&d->lock); + skb_queue_head_init(&d->sendq); + skb_queue_head_init(&d->skbpool); init_timer(&d->timer); d->timer.data = (ulong) d; d->timer.function = dummy_timer; diff --git a/drivers/block/aoe/aoemain.c b/drivers/block/aoe/aoemain.c index 7b15a5e9cec..7f83ad90e76 100644 --- a/drivers/block/aoe/aoemain.c +++ b/drivers/block/aoe/aoemain.c @@ -7,6 +7,7 @@ #include <linux/hdreg.h> #include <linux/blkdev.h> #include <linux/module.h> +#include <linux/skbuff.h> #include "aoe.h" MODULE_LICENSE("GPL"); diff --git a/drivers/block/aoe/aoenet.c b/drivers/block/aoe/aoenet.c index 0c81ca73128..9157d64270c 100644 --- a/drivers/block/aoe/aoenet.c +++ b/drivers/block/aoe/aoenet.c @@ -95,13 +95,12 @@ mac_addr(char addr[6]) } void -aoenet_xmit(struct sk_buff *sl) +aoenet_xmit(struct sk_buff_head *queue) { - struct sk_buff *skb; + struct sk_buff *skb, *tmp; - while ((skb = sl)) { - sl = sl->next; - skb->next = skb->prev = NULL; + skb_queue_walk_safe(queue, skb, tmp) { + __skb_unlink(skb, queue); dev_queue_xmit(skb); } } diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 6a010681ecf..29ae99817c6 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -104,6 +104,9 @@ static struct usb_device_id blacklist_table[] = { /* Broadcom BCM2046 */ { USB_DEVICE(0x0a5c, 0x2151), .driver_info = BTUSB_RESET }, + /* Apple MacBook Pro with Broadcom chip */ + { USB_DEVICE(0x05ac, 0x820f), .driver_info = BTUSB_RESET }, + /* IBM/Lenovo ThinkPad with Broadcom chip */ { USB_DEVICE(0x0a5c, 0x201e), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, { USB_DEVICE(0x0a5c, 0x2110), .driver_info = BTUSB_RESET | BTUSB_WRONG_SCO_MTU }, @@ -169,6 +172,7 @@ static struct usb_device_id blacklist_table[] = { struct btusb_data { struct hci_dev *hdev; struct usb_device *udev; + struct usb_interface *intf; struct usb_interface *isoc; spinlock_t lock; @@ -516,7 +520,7 @@ static int btusb_open(struct hci_dev *hdev) err = btusb_submit_intr_urb(hdev); if (err < 0) { - clear_bit(BTUSB_INTR_RUNNING, &hdev->flags); + clear_bit(BTUSB_INTR_RUNNING, &data->flags); clear_bit(HCI_RUNNING, &hdev->flags); } @@ -532,8 +536,10 @@ static int btusb_close(struct hci_dev *hdev) if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) return 0; + cancel_work_sync(&data->work); + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); - usb_kill_anchored_urbs(&data->intr_anchor); + usb_kill_anchored_urbs(&data->isoc_anchor); clear_bit(BTUSB_BULK_RUNNING, &data->flags); usb_kill_anchored_urbs(&data->bulk_anchor); @@ -821,6 +827,7 @@ static int btusb_probe(struct usb_interface *intf, } data->udev = interface_to_usbdev(intf); + data->intf = intf; spin_lock_init(&data->lock); @@ -889,7 +896,7 @@ static int btusb_probe(struct usb_interface *intf, if (data->isoc) { err = usb_driver_claim_interface(&btusb_driver, - data->isoc, NULL); + data->isoc, data); if (err < 0) { hci_free_dev(hdev); kfree(data); @@ -921,13 +928,22 @@ static void btusb_disconnect(struct usb_interface *intf) hdev = data->hdev; - if (data->isoc) - usb_driver_release_interface(&btusb_driver, data->isoc); + __hci_dev_hold(hdev); - usb_set_intfdata(intf, NULL); + usb_set_intfdata(data->intf, NULL); + + if (data->isoc) + usb_set_intfdata(data->isoc, NULL); hci_unregister_dev(hdev); + if (intf == data->isoc) + usb_driver_release_interface(&btusb_driver, data->intf); + else if (data->isoc) + usb_driver_release_interface(&btusb_driver, data->isoc); + + __hci_dev_put(hdev); + hci_free_dev(hdev); } diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c index 4d37bb312ee..7938062c1cc 100644 --- a/drivers/bluetooth/hci_bcsp.c +++ b/drivers/bluetooth/hci_bcsp.c @@ -352,14 +352,14 @@ static int bcsp_flush(struct hci_uart *hu) /* Remove ack'ed packets */ static void bcsp_pkt_cull(struct bcsp_struct *bcsp) { + struct sk_buff *skb, *tmp; unsigned long flags; - struct sk_buff *skb; int i, pkts_to_be_removed; u8 seqno; spin_lock_irqsave(&bcsp->unack.lock, flags); - pkts_to_be_removed = bcsp->unack.qlen; + pkts_to_be_removed = skb_queue_len(&bcsp->unack); seqno = bcsp->msgq_txseq; while (pkts_to_be_removed) { @@ -373,19 +373,19 @@ static void bcsp_pkt_cull(struct bcsp_struct *bcsp) BT_ERR("Peer acked invalid packet"); BT_DBG("Removing %u pkts out of %u, up to seqno %u", - pkts_to_be_removed, bcsp->unack.qlen, (seqno - 1) & 0x07); + pkts_to_be_removed, skb_queue_len(&bcsp->unack), + (seqno - 1) & 0x07); - for (i = 0, skb = ((struct sk_buff *) &bcsp->unack)->next; i < pkts_to_be_removed - && skb != (struct sk_buff *) &bcsp->unack; i++) { - struct sk_buff *nskb; + i = 0; + skb_queue_walk_safe(&bcsp->unack, skb, tmp) { + if (i++ >= pkts_to_be_removed) + break; - nskb = skb->next; __skb_unlink(skb, &bcsp->unack); kfree_skb(skb); - skb = nskb; } - if (bcsp->unack.qlen == 0) + if (skb_queue_empty(&bcsp->unack)) del_timer(&bcsp->tbcsp); spin_unlock_irqrestore(&bcsp->unack.lock, flags); diff --git a/drivers/bluetooth/hci_usb.h b/drivers/bluetooth/hci_usb.h index 1790cc8e431..8e659914523 100644 --- a/drivers/bluetooth/hci_usb.h +++ b/drivers/bluetooth/hci_usb.h @@ -70,8 +70,8 @@ static inline void _urb_queue_head(struct _urb_queue *q, struct _urb *_urb) { unsigned long flags; spin_lock_irqsave(&q->lock, flags); - /* _urb_unlink needs to know which spinlock to use, thus mb(). */ - _urb->queue = q; mb(); list_add(&_urb->list, &q->head); + /* _urb_unlink needs to know which spinlock to use, thus smp_mb(). */ + _urb->queue = q; smp_mb(); list_add(&_urb->list, &q->head); spin_unlock_irqrestore(&q->lock, flags); } @@ -79,8 +79,8 @@ static inline void _urb_queue_tail(struct _urb_queue *q, struct _urb *_urb) { unsigned long flags; spin_lock_irqsave(&q->lock, flags); - /* _urb_unlink needs to know which spinlock to use, thus mb(). */ - _urb->queue = q; mb(); list_add_tail(&_urb->list, &q->head); + /* _urb_unlink needs to know which spinlock to use, thus smp_mb(). */ + _urb->queue = q; smp_mb(); list_add_tail(&_urb->list, &q->head); spin_unlock_irqrestore(&q->lock, flags); } @@ -89,7 +89,7 @@ static inline void _urb_unlink(struct _urb *_urb) struct _urb_queue *q; unsigned long flags; - mb(); + smp_mb(); q = _urb->queue; /* If q is NULL, it will die at easy-to-debug NULL pointer dereference. No need to BUG(). */ diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index daeb8f76697..e4dce870954 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -695,13 +695,23 @@ struct tty_driver *tty_find_polling_driver(char *name, int *line) { struct tty_driver *p, *res = NULL; int tty_line = 0; + int len; char *str; + for (str = name; *str; str++) + if ((*str >= '0' && *str <= '9') || *str == ',') + break; + if (!*str) + return NULL; + + len = str - name; + tty_line = simple_strtoul(str, &str, 10); + mutex_lock(&tty_mutex); /* Search through the tty devices to look for a match */ list_for_each_entry(p, &tty_drivers, tty_drivers) { - str = name + strlen(p->name); - tty_line = simple_strtoul(str, &str, 10); + if (strncmp(name, p->name, len) != 0) + continue; if (*str == ',') str++; if (*str == '\0') diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 4eee533f3f4..71d2ac4e3f4 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c @@ -178,11 +178,13 @@ static int verify_pmtmr_rate(void) /* Number of monotonicity checks to perform during initialization */ #define ACPI_PM_MONOTONICITY_CHECKS 10 +/* Number of reads we try to get two different values */ +#define ACPI_PM_READ_CHECKS 10000 static int __init init_acpi_pm_clocksource(void) { cycle_t value1, value2; - unsigned int i, j, good = 0; + unsigned int i, j = 0; if (!pmtmr_ioport) return -ENODEV; @@ -192,29 +194,26 @@ static int __init init_acpi_pm_clocksource(void) /* "verify" this timing source: */ for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) { + udelay(100 * j); value1 = clocksource_acpi_pm.read(); - for (i = 0; i < 10000; i++) { + for (i = 0; i < ACPI_PM_READ_CHECKS; i++) { value2 = clocksource_acpi_pm.read(); if (value2 == value1) continue; if (value2 > value1) - good++; break; if ((value2 < value1) && ((value2) < 0xFFF)) - good++; break; printk(KERN_INFO "PM-Timer had inconsistent results:" " 0x%#llx, 0x%#llx - aborting.\n", value1, value2); return -EINVAL; } - udelay(300 * i); - } - - if (good != ACPI_PM_MONOTONICITY_CHECKS) { - printk(KERN_INFO "PM-Timer failed consistency check " - " (0x%#llx) - aborting.\n", value1); - return -ENODEV; + if (i == ACPI_PM_READ_CHECKS) { + printk(KERN_INFO "PM-Timer failed consistency check " + " (0x%#llx) - aborting.\n", value1); + return -ENODEV; + } } if (verify_pmtmr_rate() != 0) diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index ee827a7f7c6..b6ad3ac5916 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -1157,6 +1157,8 @@ static int aead_authenc_givencrypt( edesc->desc.hdr = ctx->desc_hdr_template | DESC_HDR_MODE0_ENCRYPT; memcpy(req->giv, ctx->iv, crypto_aead_ivsize(authenc)); + /* avoid consecutive packets going out with same IV */ + *(__be64 *)req->giv ^= cpu_to_be64(req->seq); return ipsec_esp(edesc, areq, req->giv, req->seq, ipsec_esp_encrypt_done); @@ -1449,6 +1451,8 @@ static int talitos_probe(struct of_device *ofdev, priv->ofdev = ofdev; + INIT_LIST_HEAD(&priv->alg_list); + tasklet_init(&priv->done_task, talitos_done, (unsigned long)dev); tasklet_init(&priv->error_task, talitos_error, (unsigned long)dev); @@ -1575,8 +1579,6 @@ static int talitos_probe(struct of_device *ofdev, } /* register crypto algorithms the device supports */ - INIT_LIST_HEAD(&priv->alg_list); - for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { if (hw_supports(dev, driver_algs[i].desc_hdr_template)) { struct talitos_crypto_alg *t_alg; diff --git a/drivers/hwmon/ad7414.c b/drivers/hwmon/ad7414.c index ce8d94fbfd7..bfda8c80ef2 100644 --- a/drivers/hwmon/ad7414.c +++ b/drivers/hwmon/ad7414.c @@ -69,7 +69,7 @@ static inline int ad7414_write(struct i2c_client *client, u8 reg, u8 value) return i2c_smbus_write_byte_data(client, reg, value); } -struct ad7414_data *ad7414_update_device(struct device *dev) +static struct ad7414_data *ad7414_update_device(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct ad7414_data *data = i2c_get_clientdata(client); diff --git a/drivers/hwmon/atxp1.c b/drivers/hwmon/atxp1.c index d191118ba0c..d6b490d3e36 100644 --- a/drivers/hwmon/atxp1.c +++ b/drivers/hwmon/atxp1.c @@ -31,7 +31,7 @@ MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("System voltages control via Attansic ATXP1"); -MODULE_VERSION("0.6.2"); +MODULE_VERSION("0.6.3"); MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>"); #define ATXP1_VID 0x00 @@ -289,16 +289,16 @@ static int atxp1_detect(struct i2c_client *new_client, int kind, if (!((i2c_smbus_read_byte_data(new_client, 0x3e) == 0) && (i2c_smbus_read_byte_data(new_client, 0x3f) == 0) && (i2c_smbus_read_byte_data(new_client, 0xfe) == 0) && - (i2c_smbus_read_byte_data(new_client, 0xff) == 0) )) { + (i2c_smbus_read_byte_data(new_client, 0xff) == 0))) + return -ENODEV; - /* No vendor ID, now checking if registers 0x10,0x11 (non-existent) - * showing the same as register 0x00 */ - temp = i2c_smbus_read_byte_data(new_client, 0x00); + /* No vendor ID, now checking if registers 0x10,0x11 (non-existent) + * showing the same as register 0x00 */ + temp = i2c_smbus_read_byte_data(new_client, 0x00); - if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) && - (i2c_smbus_read_byte_data(new_client, 0x11) == temp) )) - return -ENODEV; - } + if (!((i2c_smbus_read_byte_data(new_client, 0x10) == temp) && + (i2c_smbus_read_byte_data(new_client, 0x11) == temp))) + return -ENODEV; /* Get VRM */ temp = vid_which_vrm(); diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 30cdb095677..f1133081cc4 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c @@ -273,10 +273,10 @@ struct it87_data { static inline int has_16bit_fans(const struct it87_data *data) { /* IT8705F Datasheet 0.4.1, 3h == Version G. - IT8712F Datasheet 0.9.1, section 8.3.5 indicates 7h == Version I. + IT8712F Datasheet 0.9.1, section 8.3.5 indicates 8h == Version J. These are the first revisions with 16bit tachometer support. */ return (data->type == it87 && data->revision >= 0x03) - || (data->type == it8712 && data->revision >= 0x07) + || (data->type == it8712 && data->revision >= 0x08) || data->type == it8716 || data->type == it8718; } diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c index 22f6d5c00d8..0e7b1c6724a 100644 --- a/drivers/i2c/busses/i2c-powermac.c +++ b/drivers/i2c/busses/i2c-powermac.c @@ -180,7 +180,7 @@ static const struct i2c_algorithm i2c_powermac_algorithm = { }; -static int i2c_powermac_remove(struct platform_device *dev) +static int __devexit i2c_powermac_remove(struct platform_device *dev) { struct i2c_adapter *adapter = platform_get_drvdata(dev); struct pmac_i2c_bus *bus = i2c_get_adapdata(adapter); @@ -200,7 +200,7 @@ static int i2c_powermac_remove(struct platform_device *dev) } -static int __devexit i2c_powermac_probe(struct platform_device *dev) +static int __devinit i2c_powermac_probe(struct platform_device *dev) { struct pmac_i2c_bus *bus = dev->dev.platform_data; struct device_node *parent = NULL; diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c index af4491fa7e3..307d976c9b6 100644 --- a/drivers/i2c/i2c-dev.c +++ b/drivers/i2c/i2c-dev.c @@ -583,8 +583,10 @@ static int __init i2c_dev_init(void) goto out; i2c_dev_class = class_create(THIS_MODULE, "i2c-dev"); - if (IS_ERR(i2c_dev_class)) + if (IS_ERR(i2c_dev_class)) { + res = PTR_ERR(i2c_dev_class); goto out_unreg_chrdev; + } res = i2c_add_driver(&i2cdev_driver); if (res) diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index fc735ab08ff..8e93a797c93 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -292,6 +292,20 @@ config IDE_GENERIC tristate "generic/default IDE chipset support" depends on ALPHA || X86 || IA64 || M32R || MIPS help + This is the generic IDE driver. This driver attaches to the + fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and + so on). Please note that if this driver is built into the + kernel or loaded before other ATA (IDE or libata) drivers + and the controller is located at legacy ports, this driver + may grab those ports and thus can prevent the controller + specific driver from attaching. + + Also, currently, IDE generic doesn't allow IRQ sharing + meaning that the IRQs it grabs won't be available to other + controllers sharing those IRQs which usually makes drivers + for those controllers fail. Generally, it's not a good idea + to load IDE generic driver on modern systems. + If unsure, say N. config BLK_DEV_PLATFORM diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index f1489999cf9..49a8c589e34 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c @@ -1933,7 +1933,6 @@ static void ide_cd_remove(ide_drive_t *drive) ide_proc_unregister_driver(drive, info->driver); - blk_unregister_filter(info->disk); del_gendisk(info->disk); ide_cd_put(info); @@ -2159,7 +2158,6 @@ static int ide_cd_probe(ide_drive_t *drive) g->fops = &idecd_ops; g->flags |= GENHD_FL_REMOVABLE; add_disk(g); - blk_register_filter(g); return 0; out_free_cd: diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 1bce84b5663..3833189144e 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -2338,7 +2338,7 @@ static void idetape_get_inquiry_results(ide_drive_t *drive) { idetape_tape_t *tape = drive->driver_data; struct ide_atapi_pc pc; - char fw_rev[6], vendor_id[10], product_id[18]; + char fw_rev[4], vendor_id[8], product_id[16]; idetape_create_inquiry_cmd(&pc); if (idetape_queue_pc_tail(drive, &pc)) { @@ -2350,11 +2350,11 @@ static void idetape_get_inquiry_results(ide_drive_t *drive) memcpy(product_id, &pc.buf[16], 16); memcpy(fw_rev, &pc.buf[32], 4); - ide_fixstring(vendor_id, 10, 0); - ide_fixstring(product_id, 18, 0); - ide_fixstring(fw_rev, 6, 0); + ide_fixstring(vendor_id, 8, 0); + ide_fixstring(product_id, 16, 0); + ide_fixstring(fw_rev, 4, 0); - printk(KERN_INFO "ide-tape: %s <-> %s: %s %s rev %s\n", + printk(KERN_INFO "ide-tape: %s <-> %s: %.8s %.16s rev %.4s\n", drive->name, tape->name, vendor_id, product_id, fw_rev); } diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c index badf79fc9e3..39c9ee99585 100644 --- a/drivers/ide/mips/swarm.c +++ b/drivers/ide/mips/swarm.c @@ -107,6 +107,7 @@ static int __devinit swarm_ide_probe(struct device *dev) base = ioremap(offset, size); + memset(&hw, 0, sizeof(hw)); for (i = 0; i <= 7; i++) hw.io_ports_array[i] = (unsigned long)(base + ((0x1f0 + i) << 5)); diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c index eb107eef0db..c37ab174381 100644 --- a/drivers/ide/pci/hpt366.c +++ b/drivers/ide/pci/hpt366.c @@ -613,6 +613,14 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list) return 0; } +static struct hpt_info *hpt3xx_get_info(struct device *dev) +{ + struct ide_host *host = dev_get_drvdata(dev); + struct hpt_info *info = (struct hpt_info *)host->host_priv; + + return dev == host->dev[1] ? info + 1 : info; +} + /* * The Marvell bridge chips used on the HighPoint SATA cards do not seem * to support the UltraDMA modes 1, 2, and 3 as well as any MWDMA modes... @@ -621,9 +629,7 @@ static int check_in_drive_list(ide_drive_t *drive, const char **list) static u8 hpt3xx_udma_filter(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = to_pci_dev(hwif->dev); - struct ide_host *host = pci_get_drvdata(dev); - struct hpt_info *info = host->host_priv + (hwif->dev == host->dev[1]); + struct hpt_info *info = hpt3xx_get_info(hwif->dev); u8 mask = hwif->ultra_mask; switch (info->chip_type) { @@ -662,9 +668,7 @@ static u8 hpt3xx_udma_filter(ide_drive_t *drive) static u8 hpt3xx_mdma_filter(ide_drive_t *drive) { ide_hwif_t *hwif = HWIF(drive); - struct pci_dev *dev = to_pci_dev(hwif->dev); - struct ide_host *host = pci_get_drvdata(dev); - struct hpt_info *info = host->host_priv + (hwif->dev == host->dev[1]); + struct hpt_info *info = hpt3xx_get_info(hwif->dev); switch (info->chip_type) { case HPT372 : @@ -700,8 +704,7 @@ static void hpt3xx_set_mode(ide_drive_t *drive, const u8 speed) { ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); - struct ide_host *host = pci_get_drvdata(dev); - struct hpt_info *info = host->host_priv + (hwif->dev == host->dev[1]); + struct hpt_info *info = hpt3xx_get_info(hwif->dev); struct hpt_timings *t = info->timings; u8 itr_addr = 0x40 + (drive->dn * 4); u32 old_itr = 0; @@ -744,8 +747,7 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask) { ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = to_pci_dev(hwif->dev); - struct ide_host *host = pci_get_drvdata(dev); - struct hpt_info *info = host->host_priv + (hwif->dev == host->dev[1]); + struct hpt_info *info = hpt3xx_get_info(hwif->dev); if (drive->quirk_list) { if (info->chip_type >= HPT370) { @@ -973,8 +975,7 @@ static int __devinit hpt37x_calibrate_dpll(struct pci_dev *dev, u16 f_low, u16 f static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev) { unsigned long io_base = pci_resource_start(dev, 4); - struct ide_host *host = pci_get_drvdata(dev); - struct hpt_info *info = host->host_priv + (&dev->dev == host->dev[1]); + struct hpt_info *info = hpt3xx_get_info(&dev->dev); const char *name = DRV_NAME; u8 pci_clk, dpll_clk = 0; /* PCI and DPLL clock in MHz */ u8 chip_type; @@ -1217,8 +1218,7 @@ static unsigned int __devinit init_chipset_hpt366(struct pci_dev *dev) static u8 hpt3xx_cable_detect(ide_hwif_t *hwif) { struct pci_dev *dev = to_pci_dev(hwif->dev); - struct ide_host *host = pci_get_drvdata(dev); - struct hpt_info *info = host->host_priv + (hwif->dev == host->dev[1]); + struct hpt_info *info = hpt3xx_get_info(hwif->dev); u8 chip_type = info->chip_type; u8 scr1 = 0, ata66 = hwif->channel ? 0x01 : 0x02; @@ -1262,8 +1262,7 @@ static u8 hpt3xx_cable_detect(ide_hwif_t *hwif) static void __devinit init_hwif_hpt366(ide_hwif_t *hwif) { struct pci_dev *dev = to_pci_dev(hwif->dev); - struct ide_host *host = pci_get_drvdata(dev); - struct hpt_info *info = host->host_priv + (hwif->dev == host->dev[1]); + struct hpt_info *info = hpt3xx_get_info(hwif->dev); int serialize = HPT_SERIALIZE_IO; u8 chip_type = info->chip_type; u8 new_mcr, old_mcr = 0; diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index f29dbb767e8..9559248f265 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c @@ -1342,6 +1342,12 @@ static __be32 convert_access(int acc) static void set_fmr_seg(struct mlx4_wqe_fmr_seg *fseg, struct ib_send_wr *wr) { struct mlx4_ib_fast_reg_page_list *mfrpl = to_mfrpl(wr->wr.fast_reg.page_list); + int i; + + for (i = 0; i < wr->wr.fast_reg.page_list_len; ++i) + wr->wr.fast_reg.page_list->page_list[i] = + cpu_to_be64(wr->wr.fast_reg.page_list->page_list[i] | + MLX4_MTT_FLAG_PRESENT); fseg->flags = convert_access(wr->wr.fast_reg.access_flags); fseg->mem_key = cpu_to_be32(wr->wr.fast_reg.rkey); diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 9f0b964b2c9..499d3cf83e1 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1956,13 +1956,6 @@ static int mini_cm_reject(struct nes_cm_core *cm_core, return ret; cleanup_retrans_entry(cm_node); cm_node->state = NES_CM_STATE_CLOSED; - ret = send_fin(cm_node, NULL); - - if (cm_node->accept_pend) { - BUG_ON(!cm_node->listener); - atomic_dec(&cm_node->listener->pend_accepts_cnt); - BUG_ON(atomic_read(&cm_node->listener->pend_accepts_cnt) < 0); - } ret = send_reset(cm_node, NULL); return ret; @@ -2383,6 +2376,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) atomic_inc(&cm_disconnects); cm_event.event = IW_CM_EVENT_DISCONNECT; if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) { + issued_disconnect_reset = 1; cm_event.status = IW_CM_EVENT_STATUS_RESET; nes_debug(NES_DBG_CM, "Generating a CM " "Disconnect Event (status reset) for " @@ -2508,7 +2502,6 @@ static int nes_disconnect(struct nes_qp *nesqp, int abrupt) nes_debug(NES_DBG_CM, "Call close API\n"); g_cm_core->api->close(g_cm_core, nesqp->cm_node); - nesqp->cm_node = NULL; } return ret; @@ -2837,6 +2830,7 @@ int nes_connect(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) cm_node->apbvt_set = 1; nesqp->cm_node = cm_node; cm_node->nesqp = nesqp; + nes_add_ref(&nesqp->ibqp); return 0; } @@ -3167,7 +3161,6 @@ static void cm_event_connect_error(struct nes_cm_event *event) if (ret) printk(KERN_ERR "%s[%u] OFA CM event_handler returned, " "ret=%d\n", __func__, __LINE__, ret); - nes_rem_ref(&nesqp->ibqp); cm_id->rem_ref(cm_id); rem_ref_cm_node(event->cm_node->cm_core, event->cm_node); diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index b0ffc9abe8c..05eb41b8ab6 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -293,6 +293,7 @@ struct ipoib_dev_priv { struct delayed_work pkey_poll_task; struct delayed_work mcast_task; + struct work_struct carrier_on_task; struct work_struct flush_light; struct work_struct flush_normal; struct work_struct flush_heavy; @@ -464,6 +465,7 @@ int ipoib_dev_init(struct net_device *dev, struct ib_device *ca, int port); void ipoib_dev_cleanup(struct net_device *dev); void ipoib_mcast_join_task(struct work_struct *work); +void ipoib_mcast_carrier_on_task(struct work_struct *work); void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb); void ipoib_mcast_restart_task(struct work_struct *work); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 7e9e218738f..e9ca3cb57d5 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c @@ -404,7 +404,7 @@ static void path_rec_completion(int status, struct net_device *dev = path->dev; struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_ah *ah = NULL; - struct ipoib_ah *old_ah; + struct ipoib_ah *old_ah = NULL; struct ipoib_neigh *neigh, *tn; struct sk_buff_head skqueue; struct sk_buff *skb; @@ -428,12 +428,12 @@ static void path_rec_completion(int status, spin_lock_irqsave(&priv->lock, flags); - old_ah = path->ah; - path->ah = ah; - if (ah) { path->pathrec = *pathrec; + old_ah = path->ah; + path->ah = ah; + ipoib_dbg(priv, "created address handle %p for LID 0x%04x, SL %d\n", ah, be16_to_cpu(pathrec->dlid), pathrec->sl); @@ -1075,6 +1075,7 @@ static void ipoib_setup(struct net_device *dev) INIT_DELAYED_WORK(&priv->pkey_poll_task, ipoib_pkey_poll); INIT_DELAYED_WORK(&priv->mcast_task, ipoib_mcast_join_task); + INIT_WORK(&priv->carrier_on_task, ipoib_mcast_carrier_on_task); INIT_WORK(&priv->flush_light, ipoib_ib_dev_flush_light); INIT_WORK(&priv->flush_normal, ipoib_ib_dev_flush_normal); INIT_WORK(&priv->flush_heavy, ipoib_ib_dev_flush_heavy); diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index ac33c8f3ea8..aae28620a6e 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c @@ -366,6 +366,21 @@ static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast) return ret; } +void ipoib_mcast_carrier_on_task(struct work_struct *work) +{ + struct ipoib_dev_priv *priv = container_of(work, struct ipoib_dev_priv, + carrier_on_task); + + /* + * Take rtnl_lock to avoid racing with ipoib_stop() and + * turning the carrier back on while a device is being + * removed. + */ + rtnl_lock(); + netif_carrier_on(priv->dev); + rtnl_unlock(); +} + static int ipoib_mcast_join_complete(int status, struct ib_sa_multicast *multicast) { @@ -392,16 +407,12 @@ static int ipoib_mcast_join_complete(int status, &priv->mcast_task, 0); mutex_unlock(&mcast_mutex); - if (mcast == priv->broadcast) { - /* - * Take RTNL lock here to avoid racing with - * ipoib_stop() and turning the carrier back - * on while a device is being removed. - */ - rtnl_lock(); - netif_carrier_on(dev); - rtnl_unlock(); - } + /* + * Defer carrier on work to ipoib_workqueue to avoid a + * deadlock on rtnl_lock here. + */ + if (mcast == priv->broadcast) + queue_work(ipoib_workqueue, &priv->carrier_on_task); return 0; } diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index 18f4d7f6ce6..2998a6ac9ae 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -351,8 +351,9 @@ static int report_tp_state(struct bcm5974 *dev, int size) #define BCM5974_WELLSPRING_MODE_REQUEST_VALUE 0x300 #define BCM5974_WELLSPRING_MODE_REQUEST_INDEX 0 #define BCM5974_WELLSPRING_MODE_VENDOR_VALUE 0x01 +#define BCM5974_WELLSPRING_MODE_NORMAL_VALUE 0x08 -static int bcm5974_wellspring_mode(struct bcm5974 *dev) +static int bcm5974_wellspring_mode(struct bcm5974 *dev, bool on) { char *data = kmalloc(8, GFP_KERNEL); int retval = 0, size; @@ -377,7 +378,9 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev) } /* apply the mode switch */ - data[0] = BCM5974_WELLSPRING_MODE_VENDOR_VALUE; + data[0] = on ? + BCM5974_WELLSPRING_MODE_VENDOR_VALUE : + BCM5974_WELLSPRING_MODE_NORMAL_VALUE; /* write configuration */ size = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), @@ -392,7 +395,8 @@ static int bcm5974_wellspring_mode(struct bcm5974 *dev) goto out; } - dprintk(2, "bcm5974: switched to wellspring mode.\n"); + dprintk(2, "bcm5974: switched to %s mode.\n", + on ? "wellspring" : "normal"); out: kfree(data); @@ -481,7 +485,7 @@ exit: */ static int bcm5974_start_traffic(struct bcm5974 *dev) { - if (bcm5974_wellspring_mode(dev)) { + if (bcm5974_wellspring_mode(dev, true)) { dprintk(1, "bcm5974: mode switch failed\n"); goto error; } @@ -504,6 +508,7 @@ static void bcm5974_pause_traffic(struct bcm5974 *dev) { usb_kill_urb(dev->tp_urb); usb_kill_urb(dev->bt_urb); + bcm5974_wellspring_mode(dev, false); } /* diff --git a/drivers/input/touchscreen/jornada720_ts.c b/drivers/input/touchscreen/jornada720_ts.c index bf44f9d6834..c8b7e8a45c4 100644 --- a/drivers/input/touchscreen/jornada720_ts.c +++ b/drivers/input/touchscreen/jornada720_ts.c @@ -119,8 +119,8 @@ static int __devinit jornada720_ts_probe(struct platform_device *pdev) input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; - input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); - input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); input_set_abs_params(input_dev, ABS_X, 270, 3900, 0, 0); input_set_abs_params(input_dev, ABS_Y, 180, 3700, 0, 0); diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c index 75726ea0fbb..5360c4fd473 100644 --- a/drivers/isdn/capi/kcapi.c +++ b/drivers/isdn/capi/kcapi.c @@ -828,15 +828,18 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data) return -ESRCH; if (card->load_firmware == NULL) { printk(KERN_DEBUG "kcapi: load: no load function\n"); + capi_ctr_put(card); return -ESRCH; } if (ldef.t4file.len <= 0) { printk(KERN_DEBUG "kcapi: load: invalid parameter: length of t4file is %d ?\n", ldef.t4file.len); + capi_ctr_put(card); return -EINVAL; } if (ldef.t4file.data == NULL) { printk(KERN_DEBUG "kcapi: load: invalid parameter: dataptr is 0\n"); + capi_ctr_put(card); return -EINVAL; } @@ -849,6 +852,7 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data) if (card->cardstate != CARD_DETECTED) { printk(KERN_INFO "kcapi: load: contr=%d not in detect state\n", ldef.contr); + capi_ctr_put(card); return -EBUSY; } card->cardstate = CARD_LOADING; diff --git a/drivers/isdn/hardware/mISDN/hfc_pci.h b/drivers/isdn/hardware/mISDN/hfc_pci.h index fd2c9be6d84..5783d22a18f 100644 --- a/drivers/isdn/hardware/mISDN/hfc_pci.h +++ b/drivers/isdn/hardware/mISDN/hfc_pci.h @@ -183,8 +183,8 @@ #define D_FREG_MASK 0xF struct zt { - unsigned short z1; /* Z1 pointer 16 Bit */ - unsigned short z2; /* Z2 pointer 16 Bit */ + __le16 z1; /* Z1 pointer 16 Bit */ + __le16 z2; /* Z2 pointer 16 Bit */ }; struct dfifo { diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c index 9cf5edbb1a9..cd8302af40e 100644 --- a/drivers/isdn/hardware/mISDN/hfcpci.c +++ b/drivers/isdn/hardware/mISDN/hfcpci.c @@ -43,7 +43,7 @@ MODULE_LICENSE("GPL"); module_param(debug, uint, 0); static LIST_HEAD(HFClist); -DEFINE_RWLOCK(HFClock); +static DEFINE_RWLOCK(HFClock); enum { HFC_CCD_2BD0, @@ -88,7 +88,7 @@ struct hfcPCI_hw { unsigned char bswapped; unsigned char protocol; int nt_timer; - unsigned char *pci_io; /* start of PCI IO memory */ + unsigned char __iomem *pci_io; /* start of PCI IO memory */ dma_addr_t dmahandle; void *fifos; /* FIFO memory */ int last_bfifo_cnt[2]; @@ -153,7 +153,7 @@ release_io_hfcpci(struct hfc_pci *hc) pci_write_config_word(hc->pdev, PCI_COMMAND, 0); del_timer(&hc->hw.timer); pci_free_consistent(hc->pdev, 0x8000, hc->hw.fifos, hc->hw.dmahandle); - iounmap((void *)hc->hw.pci_io); + iounmap(hc->hw.pci_io); } /* @@ -366,8 +366,7 @@ static void hfcpci_clear_fifo_tx(struct hfc_pci *hc, int fifo) bzt->f2 = MAX_B_FRAMES; bzt->f1 = bzt->f2; /* init F pointers to remain constant */ bzt->za[MAX_B_FRAMES].z1 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 1); - bzt->za[MAX_B_FRAMES].z2 = cpu_to_le16( - le16_to_cpu(bzt->za[MAX_B_FRAMES].z1 - 1)); + bzt->za[MAX_B_FRAMES].z2 = cpu_to_le16(B_FIFO_SIZE + B_SUB_VAL - 2); if (fifo_state) hc->hw.fifo_en |= fifo_state; Write_hfc(hc, HFCPCI_FIFO_EN, hc->hw.fifo_en); @@ -482,7 +481,7 @@ receive_dmsg(struct hfc_pci *hc) df->f2 = ((df->f2 + 1) & MAX_D_FRAMES) | (MAX_D_FRAMES + 1); /* next buffer */ df->za[df->f2 & D_FREG_MASK].z2 = - cpu_to_le16((zp->z2 + rcnt) & (D_FIFO_SIZE - 1)); + cpu_to_le16((le16_to_cpu(zp->z2) + rcnt) & (D_FIFO_SIZE - 1)); } else { dch->rx_skb = mI_alloc_skb(rcnt - 3, GFP_ATOMIC); if (!dch->rx_skb) { @@ -523,10 +522,10 @@ receive_dmsg(struct hfc_pci *hc) /* * check for transparent receive data and read max one threshold size if avail */ -int +static int hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata) { - unsigned short *z1r, *z2r; + __le16 *z1r, *z2r; int new_z2, fcnt, maxlen; u_char *ptr, *ptr1; @@ -576,7 +575,7 @@ hfcpci_empty_fifo_trans(struct bchannel *bch, struct bzfifo *bz, u_char *bdata) /* * B-channel main receive routine */ -void +static void main_rec_hfcpci(struct bchannel *bch) { struct hfc_pci *hc = bch->hw; @@ -724,7 +723,7 @@ hfcpci_fill_fifo(struct bchannel *bch) struct bzfifo *bz; u_char *bdata; u_char new_f1, *src, *dst; - unsigned short *z1t, *z2t; + __le16 *z1t, *z2t; if ((bch->debug & DEBUG_HW_BCHANNEL) && !(bch->debug & DEBUG_HW_BFIFO)) printk(KERN_DEBUG "%s\n", __func__); @@ -1679,7 +1678,7 @@ hfcpci_l2l1B(struct mISDNchannel *ch, struct sk_buff *skb) * called for card init message */ -void +static void inithfcpci(struct hfc_pci *hc) { printk(KERN_DEBUG "inithfcpci: entered\n"); @@ -1966,7 +1965,7 @@ setup_hw(struct hfc_pci *hc) printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); return 1; } - hc->hw.pci_io = (char *)(ulong)hc->pdev->resource[1].start; + hc->hw.pci_io = (char __iomem *)(unsigned long)hc->pdev->resource[1].start; if (!hc->hw.pci_io) { printk(KERN_WARNING "HFC-PCI: No IO-Mem for PCI card found\n"); diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c index 127cfdad68e..77c280ef2eb 100644 --- a/drivers/isdn/i4l/isdn_ppp.c +++ b/drivers/isdn/i4l/isdn_ppp.c @@ -1533,8 +1533,10 @@ static int isdn_ppp_mp_bundle_array_init(void) int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle); if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL ) return -ENOMEM; - for( i = 0; i < ISDN_MAX_CHANNELS; i++ ) + for (i = 0; i < ISDN_MAX_CHANNELS; i++) { spin_lock_init(&isdn_ppp_bundle_arr[i].lock); + skb_queue_head_init(&isdn_ppp_bundle_arr[i].frags); + } return 0; } @@ -1567,7 +1569,7 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL) return -ENOMEM; lp->next = lp->last = lp; /* nobody else in a queue */ - lp->netdev->pb->frags = NULL; + skb_queue_head_init(&lp->netdev->pb->frags); lp->netdev->pb->frames = 0; lp->netdev->pb->seq = UINT_MAX; } @@ -1579,28 +1581,29 @@ static int isdn_ppp_mp_init( isdn_net_local * lp, ippp_bundle * add_to ) static u32 isdn_ppp_mp_get_seq( int short_seq, struct sk_buff * skb, u32 last_seq ); -static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, - struct sk_buff * from, struct sk_buff * to ); -static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, - struct sk_buff * from, struct sk_buff * to ); -static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb ); +static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from, + struct sk_buff *to); +static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp, + struct sk_buff *from, struct sk_buff *to, + u32 lastseq); +static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb); static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb ); static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, - struct sk_buff *skb) + struct sk_buff *skb) { - struct ippp_struct *is; - isdn_net_local * lpq; - ippp_bundle * mp; - isdn_mppp_stats * stats; - struct sk_buff * newfrag, * frag, * start, *nextf; + struct sk_buff *newfrag, *frag, *start, *nextf; u32 newseq, minseq, thisseq; + isdn_mppp_stats *stats; + struct ippp_struct *is; unsigned long flags; + isdn_net_local *lpq; + ippp_bundle *mp; int slot; spin_lock_irqsave(&net_dev->pb->lock, flags); - mp = net_dev->pb; - stats = &mp->stats; + mp = net_dev->pb; + stats = &mp->stats; slot = lp->ppp_slot; if (slot < 0 || slot >= ISDN_MAX_CHANNELS) { printk(KERN_ERR "%s: lp->ppp_slot(%d)\n", @@ -1611,20 +1614,19 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, return; } is = ippp_table[slot]; - if( ++mp->frames > stats->max_queue_len ) + if (++mp->frames > stats->max_queue_len) stats->max_queue_len = mp->frames; - + if (is->debug & 0x8) isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb); - newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, - skb, is->last_link_seqno); - + newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ, + skb, is->last_link_seqno); /* if this packet seq # is less than last already processed one, * toss it right away, but check for sequence start case first */ - if( mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT) ) { + if (mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT)) { mp->seq = newseq; /* the first packet: required for * rfc1990 non-compliant clients -- * prevents constant packet toss */ @@ -1634,7 +1636,7 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, spin_unlock_irqrestore(&mp->lock, flags); return; } - + /* find the minimum received sequence number over all links */ is->last_link_seqno = minseq = newseq; for (lpq = net_dev->queue;;) { @@ -1655,22 +1657,31 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * packets */ newfrag = skb; - /* if this new fragment is before the first one, then enqueue it now. */ - if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) { - newfrag->next = frag; - mp->frags = frag = newfrag; - newfrag = NULL; - } + /* Insert new fragment into the proper sequence slot. */ + skb_queue_walk(&mp->frags, frag) { + if (MP_SEQ(frag) == newseq) { + isdn_ppp_mp_free_skb(mp, newfrag); + newfrag = NULL; + break; + } + if (MP_LT(newseq, MP_SEQ(frag))) { + __skb_queue_before(&mp->frags, frag, newfrag); + newfrag = NULL; + break; + } + } + if (newfrag) + __skb_queue_tail(&mp->frags, newfrag); - start = MP_FLAGS(frag) & MP_BEGIN_FRAG && - MP_SEQ(frag) == mp->seq ? frag : NULL; + frag = skb_peek(&mp->frags); + start = ((MP_FLAGS(frag) & MP_BEGIN_FRAG) && + (MP_SEQ(frag) == mp->seq)) ? frag : NULL; + if (!start) + goto check_overflow; - /* - * main fragment traversing loop + /* main fragment traversing loop * * try to accomplish several tasks: - * - insert new fragment into the proper sequence slot (once that's done - * newfrag will be set to NULL) * - reassemble any complete fragment sequence (non-null 'start' * indicates there is a continguous sequence present) * - discard any incomplete sequences that are below minseq -- due @@ -1679,71 +1690,46 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * come to complete such sequence and it should be discarded * * loop completes when we accomplished the following tasks: - * - new fragment is inserted in the proper sequence ('newfrag' is - * set to NULL) * - we hit a gap in the sequence, so no reassembly/processing is * possible ('start' would be set to NULL) * * algorithm for this code is derived from code in the book * 'PPP Design And Debugging' by James Carlson (Addison-Wesley) */ - while (start != NULL || newfrag != NULL) { - - thisseq = MP_SEQ(frag); - nextf = frag->next; - - /* drop any duplicate fragments */ - if (newfrag != NULL && thisseq == newseq) { - isdn_ppp_mp_free_skb(mp, newfrag); - newfrag = NULL; - } - - /* insert new fragment before next element if possible. */ - if (newfrag != NULL && (nextf == NULL || - MP_LT(newseq, MP_SEQ(nextf)))) { - newfrag->next = nextf; - frag->next = nextf = newfrag; - newfrag = NULL; - } - - if (start != NULL) { - /* check for misplaced start */ - if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) { - printk(KERN_WARNING"isdn_mppp(seq %d): new " - "BEGIN flag with no prior END", thisseq); - stats->seqerrs++; - stats->frame_drops++; - start = isdn_ppp_mp_discard(mp, start,frag); - nextf = frag->next; - } - } else if (MP_LE(thisseq, minseq)) { - if (MP_FLAGS(frag) & MP_BEGIN_FRAG) + skb_queue_walk_safe(&mp->frags, frag, nextf) { + thisseq = MP_SEQ(frag); + + /* check for misplaced start */ + if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) { + printk(KERN_WARNING"isdn_mppp(seq %d): new " + "BEGIN flag with no prior END", thisseq); + stats->seqerrs++; + stats->frame_drops++; + isdn_ppp_mp_discard(mp, start, frag); + start = frag; + } else if (MP_LE(thisseq, minseq)) { + if (MP_FLAGS(frag) & MP_BEGIN_FRAG) start = frag; - else { + else { if (MP_FLAGS(frag) & MP_END_FRAG) - stats->frame_drops++; - if( mp->frags == frag ) - mp->frags = nextf; + stats->frame_drops++; + __skb_unlink(skb, &mp->frags); isdn_ppp_mp_free_skb(mp, frag); - frag = nextf; continue; - } + } } - - /* if start is non-null and we have end fragment, then - * we have full reassembly sequence -- reassemble - * and process packet now + + /* if we have end fragment, then we have full reassembly + * sequence -- reassemble and process packet now */ - if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) { - minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK; - /* Reassemble the packet then dispatch it */ - isdn_ppp_mp_reassembly(net_dev, lp, start, nextf); - - start = NULL; - frag = NULL; + if (MP_FLAGS(frag) & MP_END_FRAG) { + minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK; + /* Reassemble the packet then dispatch it */ + isdn_ppp_mp_reassembly(net_dev, lp, start, frag, thisseq); - mp->frags = nextf; - } + start = NULL; + frag = NULL; + } /* check if need to update start pointer: if we just * reassembled the packet and sequence is contiguous @@ -1754,26 +1740,25 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * below low watermark and set start to the next frag or * clear start ptr. */ - if (nextf != NULL && + if (nextf != (struct sk_buff *)&mp->frags && ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) { - /* if we just reassembled and the next one is here, - * then start another reassembly. */ - - if (frag == NULL) { + /* if we just reassembled and the next one is here, + * then start another reassembly. + */ + if (frag == NULL) { if (MP_FLAGS(nextf) & MP_BEGIN_FRAG) - start = nextf; - else - { - printk(KERN_WARNING"isdn_mppp(seq %d):" - " END flag with no following " - "BEGIN", thisseq); + start = nextf; + else { + printk(KERN_WARNING"isdn_mppp(seq %d):" + " END flag with no following " + "BEGIN", thisseq); stats->seqerrs++; } } - - } else { - if ( nextf != NULL && frag != NULL && - MP_LT(thisseq, minseq)) { + } else { + if (nextf != (struct sk_buff *)&mp->frags && + frag != NULL && + MP_LT(thisseq, minseq)) { /* we've got a break in the sequence * and we not at the end yet * and we did not just reassembled @@ -1782,41 +1767,39 @@ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, * discard all the frames below low watermark * and start over */ stats->frame_drops++; - mp->frags = isdn_ppp_mp_discard(mp,start,nextf); + isdn_ppp_mp_discard(mp, start, nextf); } /* break in the sequence, no reassembly */ - start = NULL; - } - - frag = nextf; - } /* while -- main loop */ - - if (mp->frags == NULL) - mp->frags = frag; - + start = NULL; + } + if (!start) + break; + } + +check_overflow: /* rather straighforward way to deal with (not very) possible - * queue overflow */ + * queue overflow + */ if (mp->frames > MP_MAX_QUEUE_LEN) { stats->overflows++; - while (mp->frames > MP_MAX_QUEUE_LEN) { - frag = mp->frags->next; - isdn_ppp_mp_free_skb(mp, mp->frags); - mp->frags = frag; + skb_queue_walk_safe(&mp->frags, frag, nextf) { + if (mp->frames <= MP_MAX_QUEUE_LEN) + break; + __skb_unlink(frag, &mp->frags); + isdn_ppp_mp_free_skb(mp, frag); } } spin_unlock_irqrestore(&mp->lock, flags); } -static void isdn_ppp_mp_cleanup( isdn_net_local * lp ) +static void isdn_ppp_mp_cleanup(isdn_net_local *lp) { - struct sk_buff * frag = lp->netdev->pb->frags; - struct sk_buff * nextfrag; - while( frag ) { - nextfrag = frag->next; - isdn_ppp_mp_free_skb(lp->netdev->pb, frag); - frag = nextfrag; - } - lp->netdev->pb->frags = NULL; + struct sk_buff *skb, *tmp; + + skb_queue_walk_safe(&lp->netdev->pb->frags, skb, tmp) { + __skb_unlink(skb, &lp->netdev->pb->frags); + isdn_ppp_mp_free_skb(lp->netdev->pb, skb); + } } static u32 isdn_ppp_mp_get_seq( int short_seq, @@ -1853,72 +1836,115 @@ static u32 isdn_ppp_mp_get_seq( int short_seq, return seq; } -struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp, - struct sk_buff * from, struct sk_buff * to ) +static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from, + struct sk_buff *to) { - if( from ) - while (from != to) { - struct sk_buff * next = from->next; - isdn_ppp_mp_free_skb(mp, from); - from = next; + if (from) { + struct sk_buff *skb, *tmp; + int freeing = 0; + + skb_queue_walk_safe(&mp->frags, skb, tmp) { + if (skb == to) + break; + if (skb == from) + freeing = 1; + if (!freeing) + continue; + __skb_unlink(skb, &mp->frags); + isdn_ppp_mp_free_skb(mp, skb); } - return from; + } } -void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp, - struct sk_buff * from, struct sk_buff * to ) +static unsigned int calc_tot_len(struct sk_buff_head *queue, + struct sk_buff *from, struct sk_buff *to) { - ippp_bundle * mp = net_dev->pb; - int proto; - struct sk_buff * skb; + unsigned int tot_len = 0; + struct sk_buff *skb; + int found_start = 0; + + skb_queue_walk(queue, skb) { + if (skb == from) + found_start = 1; + if (!found_start) + continue; + tot_len += skb->len - MP_HEADER_LEN; + if (skb == to) + break; + } + return tot_len; +} + +/* Reassemble packet using fragments in the reassembly queue from + * 'from' until 'to', inclusive. + */ +static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp, + struct sk_buff *from, struct sk_buff *to, + u32 lastseq) +{ + ippp_bundle *mp = net_dev->pb; unsigned int tot_len; + struct sk_buff *skb; + int proto; if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) { printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n", __func__, lp->ppp_slot); return; } - if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) { - if( ippp_table[lp->ppp_slot]->debug & 0x40 ) + + tot_len = calc_tot_len(&mp->frags, from, to); + + if (MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG)) { + if (ippp_table[lp->ppp_slot]->debug & 0x40) printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, " - "len %d\n", MP_SEQ(from), from->len ); + "len %d\n", MP_SEQ(from), from->len); skb = from; skb_pull(skb, MP_HEADER_LEN); + __skb_unlink(skb, &mp->frags); mp->frames--; } else { - struct sk_buff * frag; - int n; + struct sk_buff *walk, *tmp; + int found_start = 0; - for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++) - tot_len += frag->len - MP_HEADER_LEN; - - if( ippp_table[lp->ppp_slot]->debug & 0x40 ) + if (ippp_table[lp->ppp_slot]->debug & 0x40) printk(KERN_DEBUG"isdn_mppp: reassembling frames %d " - "to %d, len %d\n", MP_SEQ(from), - (MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len ); - if( (skb = dev_alloc_skb(tot_len)) == NULL ) { + "to %d, len %d\n", MP_SEQ(from), lastseq, + tot_len); + + skb = dev_alloc_skb(tot_len); + if (!skb) printk(KERN_ERR "isdn_mppp: cannot allocate sk buff " - "of size %d\n", tot_len); - isdn_ppp_mp_discard(mp, from, to); - return; - } + "of size %d\n", tot_len); + + found_start = 0; + skb_queue_walk_safe(&mp->frags, walk, tmp) { + if (walk == from) + found_start = 1; + if (!found_start) + continue; - while( from != to ) { - unsigned int len = from->len - MP_HEADER_LEN; + if (skb) { + unsigned int len = walk->len - MP_HEADER_LEN; + skb_copy_from_linear_data_offset(walk, MP_HEADER_LEN, + skb_put(skb, len), + len); + } + __skb_unlink(walk, &mp->frags); + isdn_ppp_mp_free_skb(mp, walk); - skb_copy_from_linear_data_offset(from, MP_HEADER_LEN, - skb_put(skb,len), - len); - frag = from->next; - isdn_ppp_mp_free_skb(mp, from); - from = frag; + if (walk == to) + break; } } + if (!skb) + return; + proto = isdn_ppp_strip_proto(skb); isdn_ppp_push_higher(net_dev, lp, skb, proto); } -static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb) +static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb) { dev_kfree_skb(skb); mp->frames--; diff --git a/drivers/isdn/mISDN/timerdev.c b/drivers/isdn/mISDN/timerdev.c index b5fabc7019d..e7462924b50 100644 --- a/drivers/isdn/mISDN/timerdev.c +++ b/drivers/isdn/mISDN/timerdev.c @@ -124,18 +124,6 @@ mISDN_read(struct file *filep, char *buf, size_t count, loff_t *off) return ret; } -static loff_t -mISDN_llseek(struct file *filep, loff_t offset, int orig) -{ - return -ESPIPE; -} - -static ssize_t -mISDN_write(struct file *filep, const char *buf, size_t count, loff_t *off) -{ - return -EOPNOTSUPP; -} - static unsigned int mISDN_poll(struct file *filep, poll_table *wait) { @@ -157,8 +145,9 @@ mISDN_poll(struct file *filep, poll_table *wait) } static void -dev_expire_timer(struct mISDNtimer *timer) +dev_expire_timer(unsigned long data) { + struct mISDNtimer *timer = (void *)data; u_long flags; spin_lock_irqsave(&timer->dev->lock, flags); @@ -191,7 +180,7 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout) spin_unlock_irqrestore(&dev->lock, flags); timer->dev = dev; timer->tl.data = (long)timer; - timer->tl.function = (void *) dev_expire_timer; + timer->tl.function = dev_expire_timer; init_timer(&timer->tl); timer->tl.expires = jiffies + ((HZ * (u_long)timeout) / 1000); add_timer(&timer->tl); @@ -211,6 +200,9 @@ misdn_del_timer(struct mISDNtimerdev *dev, int id) list_for_each_entry(timer, &dev->pending, list) { if (timer->id == id) { list_del_init(&timer->list); + /* RED-PEN AK: race -- timer can be still running on + * other CPU. Needs reference count I think + */ del_timer(&timer->tl); ret = timer->id; kfree(timer); @@ -268,9 +260,7 @@ mISDN_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, } static struct file_operations mISDN_fops = { - .llseek = mISDN_llseek, .read = mISDN_read, - .write = mISDN_write, .poll = mISDN_poll, .ioctl = mISDN_ioctl, .open = mISDN_open, diff --git a/drivers/md/md.c b/drivers/md/md.c index 4790c83d78d..deeac4b4417 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -5761,7 +5761,11 @@ void md_do_sync(mddev_t *mddev) * time 'round when curr_resync == 2 */ continue; - prepare_to_wait(&resync_wait, &wq, TASK_UNINTERRUPTIBLE); + /* We need to wait 'interruptible' so as not to + * contribute to the load average, and not to + * be caught by 'softlockup' + */ + prepare_to_wait(&resync_wait, &wq, TASK_INTERRUPTIBLE); if (!kthread_should_stop() && mddev2->curr_resync >= mddev->curr_resync) { printk(KERN_INFO "md: delaying %s of %s" @@ -5769,6 +5773,8 @@ void md_do_sync(mddev_t *mddev) " share one or more physical units)\n", desc, mdname(mddev), mdname(mddev2)); mddev_put(mddev2); + if (signal_pending(current)) + flush_signals(current); schedule(); finish_wait(&resync_wait, &wq); goto try_again; diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index ecbfa1b39b7..3e9e0dcd217 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -968,7 +968,7 @@ config VIDEO_PXA27x config VIDEO_SH_MOBILE_CEU tristate "SuperH Mobile CEU Interface driver" - depends on VIDEO_DEV + depends on VIDEO_DEV && HAS_DMA select SOC_CAMERA select VIDEOBUF_DMA_CONTIG ---help--- diff --git a/drivers/memstick/core/memstick.c b/drivers/memstick/core/memstick.c index a38005008a2..cea46906408 100644 --- a/drivers/memstick/core/memstick.c +++ b/drivers/memstick/core/memstick.c @@ -185,7 +185,7 @@ static void memstick_free(struct device *dev) } static struct class memstick_host_class = { - .name = "memstick_host", + .name = "memstick_host", .dev_release = memstick_free }; @@ -264,7 +264,7 @@ EXPORT_SYMBOL(memstick_new_req); * @sg - TPC argument */ void memstick_init_req_sg(struct memstick_request *mrq, unsigned char tpc, - struct scatterlist *sg) + const struct scatterlist *sg) { mrq->tpc = tpc; if (tpc & 8) @@ -294,7 +294,7 @@ EXPORT_SYMBOL(memstick_init_req_sg); * user supplied buffer. */ void memstick_init_req(struct memstick_request *mrq, unsigned char tpc, - void *buf, size_t length) + const void *buf, size_t length) { mrq->tpc = tpc; if (tpc & 8) @@ -439,7 +439,7 @@ static void memstick_check(struct work_struct *work) if (!host->card) { if (memstick_power_on(host)) goto out_power_off; - } else + } else if (host->card->stop) host->card->stop(host->card); card = memstick_alloc_card(host); @@ -458,7 +458,7 @@ static void memstick_check(struct work_struct *work) || !(host->card->check(host->card))) { device_unregister(&host->card->dev); host->card = NULL; - } else + } else if (host->card->start) host->card->start(host->card); } diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index 44b1817f2f2..d2d2318dafa 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c @@ -30,6 +30,8 @@ module_param(major, int, 0644); #define MSPRO_BLOCK_SIGNATURE 0xa5c3 #define MSPRO_BLOCK_MAX_ATTRIBUTES 41 +#define MSPRO_BLOCK_PART_SHIFT 3 + enum { MSPRO_BLOCK_ID_SYSINFO = 0x10, MSPRO_BLOCK_ID_MODELNAME = 0x15, @@ -195,7 +197,7 @@ static int mspro_block_bd_open(struct inode *inode, struct file *filp) static int mspro_block_disk_release(struct gendisk *disk) { struct mspro_block_data *msb = disk->private_data; - int disk_id = disk->first_minor >> MEMSTICK_PART_SHIFT; + int disk_id = disk->first_minor >> MSPRO_BLOCK_PART_SHIFT; mutex_lock(&mspro_block_disk_lock); @@ -877,6 +879,7 @@ static int mspro_block_switch_interface(struct memstick_dev *card) struct mspro_block_data *msb = memstick_get_drvdata(card); int rc = 0; +try_again: if (msb->caps & MEMSTICK_CAP_PAR4) rc = mspro_block_set_interface(card, MEMSTICK_SYS_PAR4); else @@ -930,6 +933,18 @@ static int mspro_block_switch_interface(struct memstick_dev *card) rc = memstick_set_rw_addr(card); if (!rc) rc = mspro_block_set_interface(card, msb->system); + + if (!rc) { + msleep(150); + rc = mspro_block_wait_for_ced(card); + if (rc) + return rc; + + if (msb->caps & MEMSTICK_CAP_PAR8) { + msb->caps &= ~MEMSTICK_CAP_PAR8; + goto try_again; + } + } } return rc; } @@ -1117,14 +1132,16 @@ static int mspro_block_init_card(struct memstick_dev *card) return -EIO; msb->caps = host->caps; - rc = mspro_block_switch_interface(card); + + msleep(150); + rc = mspro_block_wait_for_ced(card); if (rc) return rc; - msleep(200); - rc = mspro_block_wait_for_ced(card); + rc = mspro_block_switch_interface(card); if (rc) return rc; + dev_dbg(&card->dev, "card activated\n"); if (msb->system != MEMSTICK_SYS_SERIAL) msb->caps |= MEMSTICK_CAP_AUTO_GET_INT; @@ -1192,12 +1209,12 @@ static int mspro_block_init_disk(struct memstick_dev *card) if (rc) return rc; - if ((disk_id << MEMSTICK_PART_SHIFT) > 255) { + if ((disk_id << MSPRO_BLOCK_PART_SHIFT) > 255) { rc = -ENOSPC; goto out_release_id; } - msb->disk = alloc_disk(1 << MEMSTICK_PART_SHIFT); + msb->disk = alloc_disk(1 << MSPRO_BLOCK_PART_SHIFT); if (!msb->disk) { rc = -ENOMEM; goto out_release_id; @@ -1220,7 +1237,7 @@ static int mspro_block_init_disk(struct memstick_dev *card) MSPRO_BLOCK_MAX_PAGES * msb->page_size); msb->disk->major = major; - msb->disk->first_minor = disk_id << MEMSTICK_PART_SHIFT; + msb->disk->first_minor = disk_id << MSPRO_BLOCK_PART_SHIFT; msb->disk->fops = &ms_block_bdops; msb->usage_count = 1; msb->disk->private_data = msb; @@ -1416,7 +1433,7 @@ out_unlock: static struct memstick_device_id mspro_block_id_tbl[] = { {MEMSTICK_MATCH_ALL, MEMSTICK_TYPE_PRO, MEMSTICK_CATEGORY_STORAGE_DUO, - MEMSTICK_CLASS_GENERIC_DUO}, + MEMSTICK_CLASS_DUO}, {} }; diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c index 3485c63d20b..2fb95a5b72e 100644 --- a/drivers/memstick/host/jmb38x_ms.c +++ b/drivers/memstick/host/jmb38x_ms.c @@ -81,6 +81,8 @@ struct jmb38x_ms { #define TPC_CODE_SZ_MASK 0x00000700 #define TPC_DATA_SZ_MASK 0x00000007 +#define HOST_CONTROL_TDELAY_EN 0x00040000 +#define HOST_CONTROL_HW_OC_P 0x00010000 #define HOST_CONTROL_RESET_REQ 0x00008000 #define HOST_CONTROL_REI 0x00004000 #define HOST_CONTROL_LED 0x00000400 @@ -88,6 +90,7 @@ struct jmb38x_ms { #define HOST_CONTROL_RESET 0x00000100 #define HOST_CONTROL_POWER_EN 0x00000080 #define HOST_CONTROL_CLOCK_EN 0x00000040 +#define HOST_CONTROL_REO 0x00000008 #define HOST_CONTROL_IF_SHIFT 4 #define HOST_CONTROL_IF_SERIAL 0x0 @@ -133,11 +136,15 @@ struct jmb38x_ms { #define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000 #define CLOCK_CONTROL_40MHZ 0x00000001 -#define CLOCK_CONTROL_50MHZ 0x00000002 +#define CLOCK_CONTROL_50MHZ 0x0000000a #define CLOCK_CONTROL_60MHZ 0x00000008 #define CLOCK_CONTROL_62_5MHZ 0x0000000c #define CLOCK_CONTROL_OFF 0x00000000 +#define PCI_CTL_CLOCK_DLY_ADDR 0x000000b0 +#define PCI_CTL_CLOCK_DLY_MASK_A 0x00000f00 +#define PCI_CTL_CLOCK_DLY_MASK_B 0x0000f000 + enum { CMD_READY = 0x01, FIFO_READY = 0x02, @@ -367,8 +374,7 @@ static int jmb38x_ms_issue_cmd(struct memstick_host *msh) return host->req->error; } - dev_dbg(&msh->dev, "control %08x\n", - readl(host->addr + HOST_CONTROL)); + dev_dbg(&msh->dev, "control %08x\n", readl(host->addr + HOST_CONTROL)); dev_dbg(&msh->dev, "status %08x\n", readl(host->addr + INT_STATUS)); dev_dbg(&msh->dev, "hstatus %08x\n", readl(host->addr + STATUS)); @@ -637,7 +643,7 @@ static int jmb38x_ms_reset(struct jmb38x_ms_host *host) ndelay(20); } dev_dbg(&host->chip->pdev->dev, "reset_req timeout\n"); - return -EIO; + /* return -EIO; */ reset_next: writel(HOST_CONTROL_RESET | HOST_CONTROL_CLOCK_EN @@ -680,7 +686,9 @@ static int jmb38x_ms_set_param(struct memstick_host *msh, host_ctl = 7; host_ctl |= HOST_CONTROL_POWER_EN - | HOST_CONTROL_CLOCK_EN; + | HOST_CONTROL_CLOCK_EN + | HOST_CONTROL_HW_OC_P + | HOST_CONTROL_TDELAY_EN; writel(host_ctl, host->addr + HOST_CONTROL); writel(host->id ? PAD_PU_PD_ON_MS_SOCK1 @@ -704,33 +712,40 @@ static int jmb38x_ms_set_param(struct memstick_host *msh, break; case MEMSTICK_INTERFACE: host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT); + pci_read_config_dword(host->chip->pdev, + PCI_CTL_CLOCK_DLY_ADDR, + &clock_delay); + clock_delay &= host->id ? ~PCI_CTL_CLOCK_DLY_MASK_B + : ~PCI_CTL_CLOCK_DLY_MASK_A; if (value == MEMSTICK_SERIAL) { host_ctl &= ~HOST_CONTROL_FAST_CLK; + host_ctl &= ~HOST_CONTROL_REO; host_ctl |= HOST_CONTROL_IF_SERIAL << HOST_CONTROL_IF_SHIFT; host_ctl |= HOST_CONTROL_REI; clock_ctl = CLOCK_CONTROL_40MHZ; - clock_delay = 0; } else if (value == MEMSTICK_PAR4) { - host_ctl |= HOST_CONTROL_FAST_CLK; + host_ctl |= HOST_CONTROL_FAST_CLK | HOST_CONTROL_REO; host_ctl |= HOST_CONTROL_IF_PAR4 << HOST_CONTROL_IF_SHIFT; host_ctl &= ~HOST_CONTROL_REI; clock_ctl = CLOCK_CONTROL_40MHZ; - clock_delay = 4; + clock_delay |= host->id ? (4 << 12) : (4 << 8); } else if (value == MEMSTICK_PAR8) { host_ctl |= HOST_CONTROL_FAST_CLK; host_ctl |= HOST_CONTROL_IF_PAR8 << HOST_CONTROL_IF_SHIFT; - host_ctl &= ~HOST_CONTROL_REI; - clock_ctl = CLOCK_CONTROL_60MHZ; - clock_delay = 0; + host_ctl &= ~(HOST_CONTROL_REI | HOST_CONTROL_REO); + clock_ctl = CLOCK_CONTROL_50MHZ; } else return -EINVAL; + writel(host_ctl, host->addr + HOST_CONTROL); writel(clock_ctl, host->addr + CLOCK_CONTROL); - writel(clock_delay, host->addr + CLOCK_DELAY); + pci_write_config_dword(host->chip->pdev, + PCI_CTL_CLOCK_DLY_ADDR, + clock_delay); break; }; return 0; diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c index 23c91f5f6b6..d61cee796ef 100644 --- a/drivers/misc/sgi-gru/grufile.c +++ b/drivers/misc/sgi-gru/grufile.c @@ -445,6 +445,9 @@ static void __exit gru_exit(void) int order = get_order(sizeof(struct gru_state) * GRU_CHIPLETS_PER_BLADE); + if (!IS_UV()) + return; + for (i = 0; i < GRU_CHIPLETS_PER_BLADE; i++) free_irq(IRQ_GRU + i, NULL); diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 6986f392624..ebc8b9d7761 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -615,14 +615,19 @@ static struct mmc_driver mmc_driver = { static int __init mmc_blk_init(void) { - int res = -ENOMEM; + int res; res = register_blkdev(MMC_BLOCK_MAJOR, "mmc"); if (res) goto out; - return mmc_register_driver(&mmc_driver); + res = mmc_register_driver(&mmc_driver); + if (res) + goto out2; + return 0; + out2: + unregister_blkdev(MMC_BLOCK_MAJOR, "mmc"); out: return res; } diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c index f26b01d811a..b92b172074e 100644 --- a/drivers/mmc/card/mmc_test.c +++ b/drivers/mmc/card/mmc_test.c @@ -1040,7 +1040,7 @@ static const struct mmc_test_case mmc_test_cases[] = { }; -static struct mutex mmc_test_lock; +static DEFINE_MUTEX(mmc_test_lock); static void mmc_test_run(struct mmc_test_card *test, int testcase) { @@ -1171,8 +1171,6 @@ static int mmc_test_probe(struct mmc_card *card) if ((card->type != MMC_TYPE_MMC) && (card->type != MMC_TYPE_SD)) return -ENODEV; - mutex_init(&mmc_test_lock); - ret = device_create_file(&card->dev, &dev_attr_test); if (ret) return ret; diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 0bd06f5bd62..917035e16da 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -195,7 +195,9 @@ static int atmci_regs_show(struct seq_file *s, void *v) /* Grab a more or less consistent snapshot */ spin_lock_irq(&host->mmc->lock); + clk_enable(host->mck); memcpy_fromio(buf, host->regs, MCI_REGS_SIZE); + clk_disable(host->mck); spin_unlock_irq(&host->mmc->lock); seq_printf(s, "MR:\t0x%08x%s%s CLKDIV=%u\n", @@ -216,6 +218,8 @@ static int atmci_regs_show(struct seq_file *s, void *v) atmci_show_status_reg(s, "SR", buf[MCI_SR / 4]); atmci_show_status_reg(s, "IMR", buf[MCI_IMR / 4]); + kfree(buf); + return 0; } @@ -237,7 +241,6 @@ static void atmci_init_debugfs(struct atmel_mci *host) struct mmc_host *mmc; struct dentry *root; struct dentry *node; - struct resource *res; mmc = host->mmc; root = mmc->debugfs_root; @@ -251,9 +254,6 @@ static void atmci_init_debugfs(struct atmel_mci *host) if (!node) goto err; - res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0); - node->d_inode->i_size = res->end - res->start + 1; - node = debugfs_create_file("req", S_IRUSR, root, host, &atmci_req_fops); if (!node) goto err; @@ -1059,6 +1059,10 @@ static int __init atmci_probe(struct platform_device *pdev) host->present = !gpio_get_value(host->detect_pin); } } + + if (!gpio_is_valid(host->detect_pin)) + mmc->caps |= MMC_CAP_NEEDS_POLL; + if (gpio_is_valid(host->wp_pin)) { if (gpio_request(host->wp_pin, "mmc_wp")) { dev_dbg(&mmc->class_dev, "no WP pin available\n"); diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index 9e647a06054..ba2b4240a86 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -159,10 +159,10 @@ static inline void tmio_mmc_kunmap_atomic(struct tmio_mmc_host *host, #define STATUS_TO_TEXT(a) \ do { \ if (status & TMIO_STAT_##a) \ - printf(#a); \ + printk(#a); \ } while (0) -void debug_status(u32 status) +void pr_debug_status(u32 status) { printk(KERN_DEBUG "status: %08x = ", status); STATUS_TO_TEXT(CARD_REMOVE); diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c index fdfb2b2cb73..a424869707a 100644 --- a/drivers/net/3c505.c +++ b/drivers/net/3c505.c @@ -130,12 +130,12 @@ static const char filename[] = __FILE__; static const char timeout_msg[] = "*** timeout at %s:%s (line %d) ***\n"; #define TIMEOUT_MSG(lineno) \ - printk(timeout_msg, filename,__FUNCTION__,(lineno)) + printk(timeout_msg, filename,__func__,(lineno)) static const char invalid_pcb_msg[] = "*** invalid pcb length %d at %s:%s (line %d) ***\n"; #define INVALID_PCB_MSG(len) \ - printk(invalid_pcb_msg, (len),filename,__FUNCTION__,__LINE__) + printk(invalid_pcb_msg, (len),filename,__func__,__LINE__) static char search_msg[] __initdata = KERN_INFO "%s: Looking for 3c505 adapter at address %#x..."; diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index f6ca99774cc..32e66f0d434 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c @@ -309,7 +309,7 @@ enum RTL8139_registers { Cfg9346 = 0x50, Config0 = 0x51, Config1 = 0x52, - FlashReg = 0x54, + TimerInt = 0x54, MediaStatus = 0x58, Config3 = 0x59, Config4 = 0x5A, /* absent on RTL-8139A */ @@ -325,6 +325,7 @@ enum RTL8139_registers { FIFOTMS = 0x70, /* FIFO Control and test. */ CSCR = 0x74, /* Chip Status and Configuration Register. */ PARA78 = 0x78, + FlashReg = 0xD4, /* Communication with Flash ROM, four bytes. */ PARA7c = 0x7c, /* Magic transceiver parameter register. */ Config5 = 0xD8, /* absent on RTL-8139A */ }; diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 69c81da48eb..2d6a060d92e 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1813,7 +1813,7 @@ config FEC2 config FEC_MPC52xx tristate "MPC52xx FEC driver" - depends on PPC_MERGE && PPC_MPC52xx && PPC_BESTCOMM_FEC + depends on PPC_MPC52xx && PPC_BESTCOMM_FEC select CRC32 select PHYLIB ---help--- @@ -1938,15 +1938,6 @@ config E1000 To compile this driver as a module, choose M here. The module will be called e1000. -config E1000_DISABLE_PACKET_SPLIT - bool "Disable Packet Split for PCI express adapters" - depends on E1000 - help - Say Y here if you want to use the legacy receive path for PCI express - hardware. - - If in doubt, say N. - config E1000E tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support" depends on PCI && (!SPARC32 || BROKEN) @@ -2057,6 +2048,7 @@ config R8169 tristate "Realtek 8169 gigabit ethernet support" depends on PCI select CRC32 + select MII ---help--- Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter. @@ -2273,7 +2265,7 @@ config UGETH_TX_ON_DEMAND config MV643XX_ETH tristate "Marvell Discovery (643XX) and Orion ethernet support" depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || PLAT_ORION - select MII + select PHYLIB help This driver supports the gigabit ethernet MACs in the Marvell Discovery PPC/MIPS chipset family (MV643XX) and @@ -2411,6 +2403,7 @@ config IXGBE tristate "Intel(R) 10GbE PCI Express adapters support" depends on PCI && INET select INET_LRO + select INTEL_IOATDMA ---help--- This driver supports Intel(R) 10GbE PCI Express family of adapters. For more information on how to identify your adapter, go @@ -2462,6 +2455,7 @@ config MYRI10GE select FW_LOADER select CRC32 select INET_LRO + select INTEL_IOATDMA ---help--- This driver supports Myricom Myri-10G Dual Protocol interface in Ethernet mode. If the eeprom on your board is not recent enough, diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index bdc4c0bb56d..a5b07691e46 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -442,24 +442,24 @@ static int arcnet_open(struct net_device *dev) BUGMSG(D_NORMAL, "WARNING! Station address FF may confuse " "DOS networking programs!\n"); - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); if (ASTATUS() & RESETflag) { - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); ACOMMAND(CFLAGScmd | RESETclear); } - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); /* make sure we're ready to receive IRQ's. */ AINTMASK(0); udelay(1); /* give it time to set the mask before * we reset it again. (may not even be * necessary) */ - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); lp->intmask = NORXflag | RECONflag; AINTMASK(lp->intmask); - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); netif_start_queue(dev); @@ -670,14 +670,14 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev) freeskb = 0; } - BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS()); + BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS()); /* make sure we didn't ignore a TX IRQ while we were in here */ AINTMASK(0); - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); lp->intmask |= TXFREEflag|EXCNAKflag; AINTMASK(lp->intmask); - BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS()); + BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__func__,ASTATUS()); spin_unlock_irqrestore(&lp->lock, flags); if (freeskb) { @@ -798,7 +798,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id) diagstatus = (status >> 8) & 0xFF; BUGMSG(D_DEBUG, "%s: %d: %s: status=%x\n", - __FILE__,__LINE__,__FUNCTION__,status); + __FILE__,__LINE__,__func__,status); didsomething = 0; /* diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c index 8b51313b130..70124a944e7 100644 --- a/drivers/net/arcnet/com20020.c +++ b/drivers/net/arcnet/com20020.c @@ -238,15 +238,15 @@ static int com20020_reset(struct net_device *dev, int really_reset) u_char inbyte; BUGMSG(D_DEBUG, "%s: %d: %s: dev: %p, lp: %p, dev->name: %s\n", - __FILE__,__LINE__,__FUNCTION__,dev,lp,dev->name); + __FILE__,__LINE__,__func__,dev,lp,dev->name); BUGMSG(D_INIT, "Resetting %s (status=%02Xh)\n", dev->name, ASTATUS()); - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2); /* power-up defaults */ SETCONF; - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); if (really_reset) { /* reset the card */ @@ -254,22 +254,22 @@ static int com20020_reset(struct net_device *dev, int really_reset) mdelay(RESETtime * 2); /* COM20020 seems to be slower sometimes */ } /* clear flags & end reset */ - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear); /* verify that the ARCnet signature byte is present */ - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); com20020_copy_from_card(dev, 0, 0, &inbyte, 1); - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); if (inbyte != TESTvalue) { - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n"); return 1; } /* enable extended (512-byte) packets */ ACOMMAND(CONFIGcmd | EXTconf); - BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__FUNCTION__); + BUGMSG(D_DEBUG, "%s: %d: %s\n",__FILE__,__LINE__,__func__); /* done! return success. */ return 0; diff --git a/drivers/net/atl1e/atl1e_hw.c b/drivers/net/atl1e/atl1e_hw.c index 949e75358bf..8cbc1b59bd6 100644 --- a/drivers/net/atl1e/atl1e_hw.c +++ b/drivers/net/atl1e/atl1e_hw.c @@ -397,7 +397,7 @@ static int atl1e_phy_setup_autoneg_adv(struct atl1e_hw *hw) */ int atl1e_phy_commit(struct atl1e_hw *hw) { - struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter; + struct atl1e_adapter *adapter = hw->adapter; struct pci_dev *pdev = adapter->pdev; int ret_val; u16 phy_data; @@ -431,7 +431,7 @@ int atl1e_phy_commit(struct atl1e_hw *hw) int atl1e_phy_init(struct atl1e_hw *hw) { - struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter; + struct atl1e_adapter *adapter = hw->adapter; struct pci_dev *pdev = adapter->pdev; s32 ret_val; u16 phy_val; @@ -525,7 +525,7 @@ int atl1e_phy_init(struct atl1e_hw *hw) */ int atl1e_reset_hw(struct atl1e_hw *hw) { - struct atl1e_adapter *adapter = (struct atl1e_adapter *)hw->adapter; + struct atl1e_adapter *adapter = hw->adapter; struct pci_dev *pdev = adapter->pdev; u32 idle_status_data = 0; diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c index 7685b995ff9..9b603528143 100644 --- a/drivers/net/atl1e/atl1e_main.c +++ b/drivers/net/atl1e/atl1e_main.c @@ -2390,9 +2390,7 @@ static int __devinit atl1e_probe(struct pci_dev *pdev, } /* Init GPHY as early as possible due to power saving issue */ - spin_lock(&adapter->mdio_lock); atl1e_phy_init(&adapter->hw); - spin_unlock(&adapter->mdio_lock); /* reset the controller to * put the device in a known good starting state */ err = atl1e_reset_hw(&adapter->hw); diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c index d548a67da1e..5ab9c763100 100644 --- a/drivers/net/atlx/atl2.c +++ b/drivers/net/atlx/atl2.c @@ -522,8 +522,10 @@ static void atl2_intr_tx(struct atl2_adapter *adapter) atomic_set(&adapter->txd_read_ptr, (int)txd_read_ptr); /* tx statistics: */ - if (txs->ok) + if (txs->ok) { + adapter->net_stats.tx_bytes += txs->pkt_size; adapter->net_stats.tx_packets++; + } else adapter->net_stats.tx_errors++; diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 5ee1b0557a0..92c16c37ff2 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -653,6 +653,8 @@ static struct net_device * au1000_probe(int port_num) aup = dev->priv; + spin_lock_init(&aup->lock); + /* Allocate the data buffers */ /* Snooping works fine with eth on all au1xxx */ aup->vaddr = (u32)dma_alloc_noncoherent(NULL, MAX_BUF_SIZE * @@ -753,7 +755,6 @@ static struct net_device * au1000_probe(int port_num) aup->tx_db_inuse[i] = pDB; } - spin_lock_init(&aup->lock); dev->base_addr = base; dev->irq = irq; dev->open = au1000_open; diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c index a886a4b9f7e..4207d6efddc 100644 --- a/drivers/net/ax88796.c +++ b/drivers/net/ax88796.c @@ -153,7 +153,7 @@ static void ax_reset_8390(struct net_device *dev) while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) { if (jiffies - reset_start_time > 2*HZ/100) { dev_warn(&ax->dev->dev, "%s: %s did not complete.\n", - __FUNCTION__, dev->name); + __func__, dev->name); break; } } @@ -173,7 +173,7 @@ static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, if (ei_status.dmaing) { dev_err(&ax->dev->dev, "%s: DMAing conflict in %s " "[DMAstat:%d][irqlock:%d].\n", - dev->name, __FUNCTION__, + dev->name, __func__, ei_status.dmaing, ei_status.irqlock); return; } @@ -215,7 +215,7 @@ static void ax_block_input(struct net_device *dev, int count, dev_err(&ax->dev->dev, "%s: DMAing conflict in %s " "[DMAstat:%d][irqlock:%d].\n", - dev->name, __FUNCTION__, + dev->name, __func__, ei_status.dmaing, ei_status.irqlock); return; } @@ -260,7 +260,7 @@ static void ax_block_output(struct net_device *dev, int count, if (ei_status.dmaing) { dev_err(&ax->dev->dev, "%s: DMAing conflict in %s." "[DMAstat:%d][irqlock:%d]\n", - dev->name, __FUNCTION__, + dev->name, __func__, ei_status.dmaing, ei_status.irqlock); return; } @@ -396,7 +396,7 @@ ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc) { if (phy_debug) pr_debug("%s: dev %p, %04x, %04x, %d\n", - __FUNCTION__, dev, phy_addr, reg, opc); + __func__, dev, phy_addr, reg, opc); ax_mii_ei_outbits(dev, 0x3f, 6); /* pre-amble */ ax_mii_ei_outbits(dev, 1, 2); /* frame-start */ @@ -422,7 +422,7 @@ ax_phy_read(struct net_device *dev, int phy_addr, int reg) spin_unlock_irqrestore(&ei_local->page_lock, flags); if (phy_debug) - pr_debug("%s: %04x.%04x => read %04x\n", __FUNCTION__, + pr_debug("%s: %04x.%04x => read %04x\n", __func__, phy_addr, reg, result); return result; @@ -436,7 +436,7 @@ ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value) unsigned long flags; dev_dbg(&ax->dev->dev, "%s: %p, %04x, %04x %04x\n", - __FUNCTION__, dev, phy_addr, reg, value); + __func__, dev, phy_addr, reg, value); spin_lock_irqsave(&ei->page_lock, flags); diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c index 3db7db1828e..df896e23e2c 100644 --- a/drivers/net/bfin_mac.c +++ b/drivers/net/bfin_mac.c @@ -811,7 +811,7 @@ static void bfin_mac_enable(void) { u32 opmode; - pr_debug("%s: %s\n", DRV_NAME, __FUNCTION__); + pr_debug("%s: %s\n", DRV_NAME, __func__); /* Set RX DMA */ bfin_write_DMA1_NEXT_DESC_PTR(&(rx_list_head->desc_a)); @@ -847,7 +847,7 @@ static void bfin_mac_enable(void) /* Our watchdog timed out. Called by the networking layer */ static void bfin_mac_timeout(struct net_device *dev) { - pr_debug("%s: %s\n", dev->name, __FUNCTION__); + pr_debug("%s: %s\n", dev->name, __func__); bfin_mac_disable(); @@ -949,7 +949,7 @@ static int bfin_mac_open(struct net_device *dev) { struct bfin_mac_local *lp = netdev_priv(dev); int retval; - pr_debug("%s: %s\n", dev->name, __FUNCTION__); + pr_debug("%s: %s\n", dev->name, __func__); /* * Check that the address is valid. If its not, refuse @@ -989,7 +989,7 @@ static int bfin_mac_open(struct net_device *dev) static int bfin_mac_close(struct net_device *dev) { struct bfin_mac_local *lp = netdev_priv(dev); - pr_debug("%s: %s\n", dev->name, __FUNCTION__); + pr_debug("%s: %s\n", dev->name, __func__); netif_stop_queue(dev); netif_carrier_off(dev); diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 682b8f07752..edc7774f2f2 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6597,7 +6597,7 @@ struct flash_spec { struct bnx2_irq { irq_handler_t handler; - u16 vector; + unsigned int vector; u8 requested; char name[16]; }; diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 3d39278a63e..ade5f3f6693 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -38,6 +38,7 @@ #include <linux/in.h> #include <net/ipx.h> #include <net/arp.h> +#include <net/ipv6.h> #include <asm/byteorder.h> #include "bonding.h" #include "bond_alb.h" @@ -81,6 +82,7 @@ #define RLB_PROMISC_TIMEOUT 10*ALB_TIMER_TICKS_PER_SEC static const u8 mac_bcast[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff}; +static const u8 mac_v6_allmcast[ETH_ALEN] = {0x33,0x33,0x00,0x00,0x00,0x01}; static const int alb_delta_in_ticks = HZ / ALB_TIMER_TICKS_PER_SEC; #pragma pack(1) @@ -1290,6 +1292,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) u32 hash_index = 0; const u8 *hash_start = NULL; int res = 1; + struct ipv6hdr *ip6hdr; skb_reset_mac_header(skb); eth_data = eth_hdr(skb); @@ -1319,11 +1322,32 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev) } break; case ETH_P_IPV6: + /* IPv6 doesn't really use broadcast mac address, but leave + * that here just in case. + */ if (memcmp(eth_data->h_dest, mac_bcast, ETH_ALEN) == 0) { do_tx_balance = 0; break; } + /* IPv6 uses all-nodes multicast as an equivalent to + * broadcasts in IPv4. + */ + if (memcmp(eth_data->h_dest, mac_v6_allmcast, ETH_ALEN) == 0) { + do_tx_balance = 0; + break; + } + + /* Additianally, DAD probes should not be tx-balanced as that + * will lead to false positives for duplicate addresses and + * prevent address configuration from working. + */ + ip6hdr = ipv6_hdr(skb); + if (ipv6_addr_any(&ip6hdr->saddr)) { + do_tx_balance = 0; + break; + } + hash_start = (char *)&(ipv6_hdr(skb)->daddr); hash_size = sizeof(ipv6_hdr(skb)->daddr); break; diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index babe4610c39..8e2be24f3fe 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -4493,6 +4493,12 @@ static void bond_ethtool_get_drvinfo(struct net_device *bond_dev, static const struct ethtool_ops bond_ethtool_ops = { .get_drvinfo = bond_ethtool_get_drvinfo, + .get_link = ethtool_op_get_link, + .get_tx_csum = ethtool_op_get_tx_csum, + .get_sg = ethtool_op_get_sg, + .get_tso = ethtool_op_get_tso, + .get_ufo = ethtool_op_get_ufo, + .get_flags = ethtool_op_get_flags, }; /* diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index fb730ec0396..ffb668dd6d3 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h @@ -32,7 +32,7 @@ #ifdef BONDING_DEBUG #define dprintk(fmt, args...) \ printk(KERN_DEBUG \ - DRV_NAME ": %s() %d: " fmt, __FUNCTION__, __LINE__ , ## args ) + DRV_NAME ": %s() %d: " fmt, __func__, __LINE__ , ## args ) #else #define dprintk(fmt, args...) #endif /* BONDING_DEBUG */ @@ -333,5 +333,13 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active); void bond_register_arp(struct bonding *); void bond_unregister_arp(struct bonding *); +/* exported from bond_main.c */ +extern struct list_head bond_dev_list; +extern struct bond_parm_tbl bond_lacp_tbl[]; +extern struct bond_parm_tbl bond_mode_tbl[]; +extern struct bond_parm_tbl xmit_hashtype_tbl[]; +extern struct bond_parm_tbl arp_validate_tbl[]; +extern struct bond_parm_tbl fail_over_mac_tbl[]; + #endif /* _LINUX_BONDING_H */ diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c index f1936d51b45..86909cfb14d 100644 --- a/drivers/net/cassini.c +++ b/drivers/net/cassini.c @@ -74,6 +74,7 @@ #include <linux/slab.h> #include <linux/delay.h> #include <linux/init.h> +#include <linux/vmalloc.h> #include <linux/ioport.h> #include <linux/pci.h> #include <linux/mm.h> @@ -91,6 +92,7 @@ #include <linux/ip.h> #include <linux/tcp.h> #include <linux/mutex.h> +#include <linux/firmware.h> #include <net/checksum.h> @@ -197,6 +199,7 @@ static int link_mode; MODULE_AUTHOR("Adrian Sun (asun@darksunrising.com)"); MODULE_DESCRIPTION("Sun Cassini(+) ethernet driver"); MODULE_LICENSE("GPL"); +MODULE_FIRMWARE("sun/cassini.bin"); module_param(cassini_debug, int, 0); MODULE_PARM_DESC(cassini_debug, "Cassini bitmapped debugging message enable value"); module_param(link_mode, int, 0); @@ -812,9 +815,44 @@ static int cas_reset_mii_phy(struct cas *cp) return (limit <= 0); } +static int cas_saturn_firmware_init(struct cas *cp) +{ + const struct firmware *fw; + const char fw_name[] = "sun/cassini.bin"; + int err; + + if (PHY_NS_DP83065 != cp->phy_id) + return 0; + + err = request_firmware(&fw, fw_name, &cp->pdev->dev); + if (err) { + printk(KERN_ERR "cassini: Failed to load firmware \"%s\"\n", + fw_name); + return err; + } + if (fw->size < 2) { + printk(KERN_ERR "cassini: bogus length %zu in \"%s\"\n", + fw->size, fw_name); + err = -EINVAL; + goto out; + } + cp->fw_load_addr= fw->data[1] << 8 | fw->data[0]; + cp->fw_size = fw->size - 2; + cp->fw_data = vmalloc(cp->fw_size); + if (!cp->fw_data) { + err = -ENOMEM; + printk(KERN_ERR "cassini: \"%s\" Failed %d\n", fw_name, err); + goto out; + } + memcpy(cp->fw_data, &fw->data[2], cp->fw_size); +out: + release_firmware(fw); + return err; +} + static void cas_saturn_firmware_load(struct cas *cp) { - cas_saturn_patch_t *patch = cas_saturn_patch; + int i; cas_phy_powerdown(cp); @@ -833,11 +871,9 @@ static void cas_saturn_firmware_load(struct cas *cp) /* download new firmware */ cas_phy_write(cp, DP83065_MII_MEM, 0x1); - cas_phy_write(cp, DP83065_MII_REGE, patch->addr); - while (patch->addr) { - cas_phy_write(cp, DP83065_MII_REGD, patch->val); - patch++; - } + cas_phy_write(cp, DP83065_MII_REGE, cp->fw_load_addr); + for (i = 0; i < cp->fw_size; i++) + cas_phy_write(cp, DP83065_MII_REGD, cp->fw_data[i]); /* enable firmware */ cas_phy_write(cp, DP83065_MII_REGE, 0x8ff8); @@ -2182,7 +2218,7 @@ static inline void cas_rx_flow_pkt(struct cas *cp, const u64 *words, * do any additional locking here. stick the buffer * at the end. */ - __skb_insert(skb, flow->prev, (struct sk_buff *) flow, flow); + __skb_queue_tail(flow, skb); if (words[0] & RX_COMP1_RELEASE_FLOW) { while ((skb = __skb_dequeue(flow))) { cas_skb_release(skb); @@ -5108,6 +5144,9 @@ static int __devinit cas_init_one(struct pci_dev *pdev, cas_reset(cp, 0); if (cas_check_invariants(cp)) goto err_out_iounmap; + if (cp->cas_flags & CAS_FLAG_SATURN) + if (cas_saturn_firmware_init(cp)) + goto err_out_iounmap; cp->init_block = (struct cas_init_block *) pci_alloc_consistent(pdev, sizeof(struct cas_init_block), @@ -5217,6 +5256,9 @@ static void __devexit cas_remove_one(struct pci_dev *pdev) cp = netdev_priv(dev); unregister_netdev(dev); + if (cp->fw_data) + vfree(cp->fw_data); + mutex_lock(&cp->pm_mutex); flush_scheduled_work(); if (cp->hw_running) diff --git a/drivers/net/cassini.h b/drivers/net/cassini.h index 552af89ca1c..fd17a002b45 100644 --- a/drivers/net/cassini.h +++ b/drivers/net/cassini.h @@ -2514,1523 +2514,6 @@ static cas_hp_inst_t cas_prog_null[] = { {NULL} }; #define CAS_HP_FIRMWARE cas_prog_null #endif -/* firmware patch for NS_DP83065 */ -typedef struct cas_saturn_patch { - u16 addr; - u16 val; -} cas_saturn_patch_t; - -#if 1 -cas_saturn_patch_t cas_saturn_patch[] = { -{0x8200, 0x007e}, {0x8201, 0x0082}, {0x8202, 0x0009}, -{0x8203, 0x0000}, {0x8204, 0x0000}, {0x8205, 0x0000}, -{0x8206, 0x0000}, {0x8207, 0x0000}, {0x8208, 0x0000}, -{0x8209, 0x008e}, {0x820a, 0x008e}, {0x820b, 0x00ff}, -{0x820c, 0x00ce}, {0x820d, 0x0082}, {0x820e, 0x0025}, -{0x820f, 0x00ff}, {0x8210, 0x0001}, {0x8211, 0x000f}, -{0x8212, 0x00ce}, {0x8213, 0x0084}, {0x8214, 0x0026}, -{0x8215, 0x00ff}, {0x8216, 0x0001}, {0x8217, 0x0011}, -{0x8218, 0x00ce}, {0x8219, 0x0085}, {0x821a, 0x003d}, -{0x821b, 0x00df}, {0x821c, 0x00e5}, {0x821d, 0x0086}, -{0x821e, 0x0039}, {0x821f, 0x00b7}, {0x8220, 0x008f}, -{0x8221, 0x00f8}, {0x8222, 0x007e}, {0x8223, 0x00c3}, -{0x8224, 0x00c2}, {0x8225, 0x0096}, {0x8226, 0x0047}, -{0x8227, 0x0084}, {0x8228, 0x00f3}, {0x8229, 0x008a}, -{0x822a, 0x0000}, {0x822b, 0x0097}, {0x822c, 0x0047}, -{0x822d, 0x00ce}, {0x822e, 0x0082}, {0x822f, 0x0033}, -{0x8230, 0x00ff}, {0x8231, 0x0001}, {0x8232, 0x000f}, -{0x8233, 0x0096}, {0x8234, 0x0046}, {0x8235, 0x0084}, -{0x8236, 0x000c}, {0x8237, 0x0081}, {0x8238, 0x0004}, -{0x8239, 0x0027}, {0x823a, 0x000b}, {0x823b, 0x0096}, -{0x823c, 0x0046}, {0x823d, 0x0084}, {0x823e, 0x000c}, -{0x823f, 0x0081}, {0x8240, 0x0008}, {0x8241, 0x0027}, -{0x8242, 0x0057}, {0x8243, 0x007e}, {0x8244, 0x0084}, -{0x8245, 0x0025}, {0x8246, 0x0096}, {0x8247, 0x0047}, -{0x8248, 0x0084}, {0x8249, 0x00f3}, {0x824a, 0x008a}, -{0x824b, 0x0004}, {0x824c, 0x0097}, {0x824d, 0x0047}, -{0x824e, 0x00ce}, {0x824f, 0x0082}, {0x8250, 0x0054}, -{0x8251, 0x00ff}, {0x8252, 0x0001}, {0x8253, 0x000f}, -{0x8254, 0x0096}, {0x8255, 0x0046}, {0x8256, 0x0084}, -{0x8257, 0x000c}, {0x8258, 0x0081}, {0x8259, 0x0004}, -{0x825a, 0x0026}, {0x825b, 0x0038}, {0x825c, 0x00b6}, -{0x825d, 0x0012}, {0x825e, 0x0020}, {0x825f, 0x0084}, -{0x8260, 0x0020}, {0x8261, 0x0026}, {0x8262, 0x0003}, -{0x8263, 0x007e}, {0x8264, 0x0084}, {0x8265, 0x0025}, -{0x8266, 0x0096}, {0x8267, 0x007b}, {0x8268, 0x00d6}, -{0x8269, 0x007c}, {0x826a, 0x00fe}, {0x826b, 0x008f}, -{0x826c, 0x0056}, {0x826d, 0x00bd}, {0x826e, 0x00f7}, -{0x826f, 0x00b6}, {0x8270, 0x00fe}, {0x8271, 0x008f}, -{0x8272, 0x004e}, {0x8273, 0x00bd}, {0x8274, 0x00ec}, -{0x8275, 0x008e}, {0x8276, 0x00bd}, {0x8277, 0x00fa}, -{0x8278, 0x00f7}, {0x8279, 0x00bd}, {0x827a, 0x00f7}, -{0x827b, 0x0028}, {0x827c, 0x00ce}, {0x827d, 0x0082}, -{0x827e, 0x0082}, {0x827f, 0x00ff}, {0x8280, 0x0001}, -{0x8281, 0x000f}, {0x8282, 0x0096}, {0x8283, 0x0046}, -{0x8284, 0x0084}, {0x8285, 0x000c}, {0x8286, 0x0081}, -{0x8287, 0x0004}, {0x8288, 0x0026}, {0x8289, 0x000a}, -{0x828a, 0x00b6}, {0x828b, 0x0012}, {0x828c, 0x0020}, -{0x828d, 0x0084}, {0x828e, 0x0020}, {0x828f, 0x0027}, -{0x8290, 0x00b5}, {0x8291, 0x007e}, {0x8292, 0x0084}, -{0x8293, 0x0025}, {0x8294, 0x00bd}, {0x8295, 0x00f7}, -{0x8296, 0x001f}, {0x8297, 0x007e}, {0x8298, 0x0084}, -{0x8299, 0x001f}, {0x829a, 0x0096}, {0x829b, 0x0047}, -{0x829c, 0x0084}, {0x829d, 0x00f3}, {0x829e, 0x008a}, -{0x829f, 0x0008}, {0x82a0, 0x0097}, {0x82a1, 0x0047}, -{0x82a2, 0x00de}, {0x82a3, 0x00e1}, {0x82a4, 0x00ad}, -{0x82a5, 0x0000}, {0x82a6, 0x00ce}, {0x82a7, 0x0082}, -{0x82a8, 0x00af}, {0x82a9, 0x00ff}, {0x82aa, 0x0001}, -{0x82ab, 0x000f}, {0x82ac, 0x007e}, {0x82ad, 0x0084}, -{0x82ae, 0x0025}, {0x82af, 0x0096}, {0x82b0, 0x0041}, -{0x82b1, 0x0085}, {0x82b2, 0x0010}, {0x82b3, 0x0026}, -{0x82b4, 0x0006}, {0x82b5, 0x0096}, {0x82b6, 0x0023}, -{0x82b7, 0x0085}, {0x82b8, 0x0040}, {0x82b9, 0x0027}, -{0x82ba, 0x0006}, {0x82bb, 0x00bd}, {0x82bc, 0x00ed}, -{0x82bd, 0x0000}, {0x82be, 0x007e}, {0x82bf, 0x0083}, -{0x82c0, 0x00a2}, {0x82c1, 0x00de}, {0x82c2, 0x0042}, -{0x82c3, 0x00bd}, {0x82c4, 0x00eb}, {0x82c5, 0x008e}, -{0x82c6, 0x0096}, {0x82c7, 0x0024}, {0x82c8, 0x0084}, -{0x82c9, 0x0008}, {0x82ca, 0x0027}, {0x82cb, 0x0003}, -{0x82cc, 0x007e}, {0x82cd, 0x0083}, {0x82ce, 0x00df}, -{0x82cf, 0x0096}, {0x82d0, 0x007b}, {0x82d1, 0x00d6}, -{0x82d2, 0x007c}, {0x82d3, 0x00fe}, {0x82d4, 0x008f}, -{0x82d5, 0x0056}, {0x82d6, 0x00bd}, {0x82d7, 0x00f7}, -{0x82d8, 0x00b6}, {0x82d9, 0x00fe}, {0x82da, 0x008f}, -{0x82db, 0x0050}, {0x82dc, 0x00bd}, {0x82dd, 0x00ec}, -{0x82de, 0x008e}, {0x82df, 0x00bd}, {0x82e0, 0x00fa}, -{0x82e1, 0x00f7}, {0x82e2, 0x0086}, {0x82e3, 0x0011}, -{0x82e4, 0x00c6}, {0x82e5, 0x0049}, {0x82e6, 0x00bd}, -{0x82e7, 0x00e4}, {0x82e8, 0x0012}, {0x82e9, 0x00ce}, -{0x82ea, 0x0082}, {0x82eb, 0x00ef}, {0x82ec, 0x00ff}, -{0x82ed, 0x0001}, {0x82ee, 0x000f}, {0x82ef, 0x0096}, -{0x82f0, 0x0046}, {0x82f1, 0x0084}, {0x82f2, 0x000c}, -{0x82f3, 0x0081}, {0x82f4, 0x0000}, {0x82f5, 0x0027}, -{0x82f6, 0x0017}, {0x82f7, 0x00c6}, {0x82f8, 0x0049}, -{0x82f9, 0x00bd}, {0x82fa, 0x00e4}, {0x82fb, 0x0091}, -{0x82fc, 0x0024}, {0x82fd, 0x000d}, {0x82fe, 0x00b6}, -{0x82ff, 0x0012}, {0x8300, 0x0020}, {0x8301, 0x0085}, -{0x8302, 0x0020}, {0x8303, 0x0026}, {0x8304, 0x000c}, -{0x8305, 0x00ce}, {0x8306, 0x0082}, {0x8307, 0x00c1}, -{0x8308, 0x00ff}, {0x8309, 0x0001}, {0x830a, 0x000f}, -{0x830b, 0x007e}, {0x830c, 0x0084}, {0x830d, 0x0025}, -{0x830e, 0x007e}, {0x830f, 0x0084}, {0x8310, 0x0016}, -{0x8311, 0x00fe}, {0x8312, 0x008f}, {0x8313, 0x0052}, -{0x8314, 0x00bd}, {0x8315, 0x00ec}, {0x8316, 0x008e}, -{0x8317, 0x00bd}, {0x8318, 0x00fa}, {0x8319, 0x00f7}, -{0x831a, 0x0086}, {0x831b, 0x006a}, {0x831c, 0x00c6}, -{0x831d, 0x0049}, {0x831e, 0x00bd}, {0x831f, 0x00e4}, -{0x8320, 0x0012}, {0x8321, 0x00ce}, {0x8322, 0x0083}, -{0x8323, 0x0027}, {0x8324, 0x00ff}, {0x8325, 0x0001}, -{0x8326, 0x000f}, {0x8327, 0x0096}, {0x8328, 0x0046}, -{0x8329, 0x0084}, {0x832a, 0x000c}, {0x832b, 0x0081}, -{0x832c, 0x0000}, {0x832d, 0x0027}, {0x832e, 0x000a}, -{0x832f, 0x00c6}, {0x8330, 0x0049}, {0x8331, 0x00bd}, -{0x8332, 0x00e4}, {0x8333, 0x0091}, {0x8334, 0x0025}, -{0x8335, 0x0006}, {0x8336, 0x007e}, {0x8337, 0x0084}, -{0x8338, 0x0025}, {0x8339, 0x007e}, {0x833a, 0x0084}, -{0x833b, 0x0016}, {0x833c, 0x00b6}, {0x833d, 0x0018}, -{0x833e, 0x0070}, {0x833f, 0x00bb}, {0x8340, 0x0019}, -{0x8341, 0x0070}, {0x8342, 0x002a}, {0x8343, 0x0004}, -{0x8344, 0x0081}, {0x8345, 0x00af}, {0x8346, 0x002e}, -{0x8347, 0x0019}, {0x8348, 0x0096}, {0x8349, 0x007b}, -{0x834a, 0x00f6}, {0x834b, 0x0020}, {0x834c, 0x0007}, -{0x834d, 0x00fa}, {0x834e, 0x0020}, {0x834f, 0x0027}, -{0x8350, 0x00c4}, {0x8351, 0x0038}, {0x8352, 0x0081}, -{0x8353, 0x0038}, {0x8354, 0x0027}, {0x8355, 0x000b}, -{0x8356, 0x00f6}, {0x8357, 0x0020}, {0x8358, 0x0007}, -{0x8359, 0x00fa}, {0x835a, 0x0020}, {0x835b, 0x0027}, -{0x835c, 0x00cb}, {0x835d, 0x0008}, {0x835e, 0x007e}, -{0x835f, 0x0082}, {0x8360, 0x00d3}, {0x8361, 0x00bd}, -{0x8362, 0x00f7}, {0x8363, 0x0066}, {0x8364, 0x0086}, -{0x8365, 0x0074}, {0x8366, 0x00c6}, {0x8367, 0x0049}, -{0x8368, 0x00bd}, {0x8369, 0x00e4}, {0x836a, 0x0012}, -{0x836b, 0x00ce}, {0x836c, 0x0083}, {0x836d, 0x0071}, -{0x836e, 0x00ff}, {0x836f, 0x0001}, {0x8370, 0x000f}, -{0x8371, 0x0096}, {0x8372, 0x0046}, {0x8373, 0x0084}, -{0x8374, 0x000c}, {0x8375, 0x0081}, {0x8376, 0x0008}, -{0x8377, 0x0026}, {0x8378, 0x000a}, {0x8379, 0x00c6}, -{0x837a, 0x0049}, {0x837b, 0x00bd}, {0x837c, 0x00e4}, -{0x837d, 0x0091}, {0x837e, 0x0025}, {0x837f, 0x0006}, -{0x8380, 0x007e}, {0x8381, 0x0084}, {0x8382, 0x0025}, -{0x8383, 0x007e}, {0x8384, 0x0084}, {0x8385, 0x0016}, -{0x8386, 0x00bd}, {0x8387, 0x00f7}, {0x8388, 0x003e}, -{0x8389, 0x0026}, {0x838a, 0x000e}, {0x838b, 0x00bd}, -{0x838c, 0x00e5}, {0x838d, 0x0009}, {0x838e, 0x0026}, -{0x838f, 0x0006}, {0x8390, 0x00ce}, {0x8391, 0x0082}, -{0x8392, 0x00c1}, {0x8393, 0x00ff}, {0x8394, 0x0001}, -{0x8395, 0x000f}, {0x8396, 0x007e}, {0x8397, 0x0084}, -{0x8398, 0x0025}, {0x8399, 0x00fe}, {0x839a, 0x008f}, -{0x839b, 0x0054}, {0x839c, 0x00bd}, {0x839d, 0x00ec}, -{0x839e, 0x008e}, {0x839f, 0x00bd}, {0x83a0, 0x00fa}, -{0x83a1, 0x00f7}, {0x83a2, 0x00bd}, {0x83a3, 0x00f7}, -{0x83a4, 0x0033}, {0x83a5, 0x0086}, {0x83a6, 0x000f}, -{0x83a7, 0x00c6}, {0x83a8, 0x0051}, {0x83a9, 0x00bd}, -{0x83aa, 0x00e4}, {0x83ab, 0x0012}, {0x83ac, 0x00ce}, -{0x83ad, 0x0083}, {0x83ae, 0x00b2}, {0x83af, 0x00ff}, -{0x83b0, 0x0001}, {0x83b1, 0x000f}, {0x83b2, 0x0096}, -{0x83b3, 0x0046}, {0x83b4, 0x0084}, {0x83b5, 0x000c}, -{0x83b6, 0x0081}, {0x83b7, 0x0008}, {0x83b8, 0x0026}, -{0x83b9, 0x005c}, {0x83ba, 0x00b6}, {0x83bb, 0x0012}, -{0x83bc, 0x0020}, {0x83bd, 0x0084}, {0x83be, 0x003f}, -{0x83bf, 0x0081}, {0x83c0, 0x003a}, {0x83c1, 0x0027}, -{0x83c2, 0x001c}, {0x83c3, 0x0096}, {0x83c4, 0x0023}, -{0x83c5, 0x0085}, {0x83c6, 0x0040}, {0x83c7, 0x0027}, -{0x83c8, 0x0003}, {0x83c9, 0x007e}, {0x83ca, 0x0084}, -{0x83cb, 0x0025}, {0x83cc, 0x00c6}, {0x83cd, 0x0051}, -{0x83ce, 0x00bd}, {0x83cf, 0x00e4}, {0x83d0, 0x0091}, -{0x83d1, 0x0025}, {0x83d2, 0x0003}, {0x83d3, 0x007e}, -{0x83d4, 0x0084}, {0x83d5, 0x0025}, {0x83d6, 0x00ce}, -{0x83d7, 0x0082}, {0x83d8, 0x00c1}, {0x83d9, 0x00ff}, -{0x83da, 0x0001}, {0x83db, 0x000f}, {0x83dc, 0x007e}, -{0x83dd, 0x0084}, {0x83de, 0x0025}, {0x83df, 0x00bd}, -{0x83e0, 0x00f8}, {0x83e1, 0x0037}, {0x83e2, 0x007c}, -{0x83e3, 0x0000}, {0x83e4, 0x007a}, {0x83e5, 0x00ce}, -{0x83e6, 0x0083}, {0x83e7, 0x00ee}, {0x83e8, 0x00ff}, -{0x83e9, 0x0001}, {0x83ea, 0x000f}, {0x83eb, 0x007e}, -{0x83ec, 0x0084}, {0x83ed, 0x0025}, {0x83ee, 0x0096}, -{0x83ef, 0x0046}, {0x83f0, 0x0084}, {0x83f1, 0x000c}, -{0x83f2, 0x0081}, {0x83f3, 0x0008}, {0x83f4, 0x0026}, -{0x83f5, 0x0020}, {0x83f6, 0x0096}, {0x83f7, 0x0024}, -{0x83f8, 0x0084}, {0x83f9, 0x0008}, {0x83fa, 0x0026}, -{0x83fb, 0x0029}, {0x83fc, 0x00b6}, {0x83fd, 0x0018}, -{0x83fe, 0x0082}, {0x83ff, 0x00bb}, {0x8400, 0x0019}, -{0x8401, 0x0082}, {0x8402, 0x00b1}, {0x8403, 0x0001}, -{0x8404, 0x003b}, {0x8405, 0x0022}, {0x8406, 0x0009}, -{0x8407, 0x00b6}, {0x8408, 0x0012}, {0x8409, 0x0020}, -{0x840a, 0x0084}, {0x840b, 0x0037}, {0x840c, 0x0081}, -{0x840d, 0x0032}, {0x840e, 0x0027}, {0x840f, 0x0015}, -{0x8410, 0x00bd}, {0x8411, 0x00f8}, {0x8412, 0x0044}, -{0x8413, 0x007e}, {0x8414, 0x0082}, {0x8415, 0x00c1}, -{0x8416, 0x00bd}, {0x8417, 0x00f7}, {0x8418, 0x001f}, -{0x8419, 0x00bd}, {0x841a, 0x00f8}, {0x841b, 0x0044}, -{0x841c, 0x00bd}, {0x841d, 0x00fc}, {0x841e, 0x0029}, -{0x841f, 0x00ce}, {0x8420, 0x0082}, {0x8421, 0x0025}, -{0x8422, 0x00ff}, {0x8423, 0x0001}, {0x8424, 0x000f}, -{0x8425, 0x0039}, {0x8426, 0x0096}, {0x8427, 0x0047}, -{0x8428, 0x0084}, {0x8429, 0x00fc}, {0x842a, 0x008a}, -{0x842b, 0x0000}, {0x842c, 0x0097}, {0x842d, 0x0047}, -{0x842e, 0x00ce}, {0x842f, 0x0084}, {0x8430, 0x0034}, -{0x8431, 0x00ff}, {0x8432, 0x0001}, {0x8433, 0x0011}, -{0x8434, 0x0096}, {0x8435, 0x0046}, {0x8436, 0x0084}, -{0x8437, 0x0003}, {0x8438, 0x0081}, {0x8439, 0x0002}, -{0x843a, 0x0027}, {0x843b, 0x0003}, {0x843c, 0x007e}, -{0x843d, 0x0085}, {0x843e, 0x001e}, {0x843f, 0x0096}, -{0x8440, 0x0047}, {0x8441, 0x0084}, {0x8442, 0x00fc}, -{0x8443, 0x008a}, {0x8444, 0x0002}, {0x8445, 0x0097}, -{0x8446, 0x0047}, {0x8447, 0x00de}, {0x8448, 0x00e1}, -{0x8449, 0x00ad}, {0x844a, 0x0000}, {0x844b, 0x0086}, -{0x844c, 0x0001}, {0x844d, 0x00b7}, {0x844e, 0x0012}, -{0x844f, 0x0051}, {0x8450, 0x00bd}, {0x8451, 0x00f7}, -{0x8452, 0x0014}, {0x8453, 0x00b6}, {0x8454, 0x0010}, -{0x8455, 0x0031}, {0x8456, 0x0084}, {0x8457, 0x00fd}, -{0x8458, 0x00b7}, {0x8459, 0x0010}, {0x845a, 0x0031}, -{0x845b, 0x00bd}, {0x845c, 0x00f8}, {0x845d, 0x001e}, -{0x845e, 0x0096}, {0x845f, 0x0081}, {0x8460, 0x00d6}, -{0x8461, 0x0082}, {0x8462, 0x00fe}, {0x8463, 0x008f}, -{0x8464, 0x005a}, {0x8465, 0x00bd}, {0x8466, 0x00f7}, -{0x8467, 0x00b6}, {0x8468, 0x00fe}, {0x8469, 0x008f}, -{0x846a, 0x005c}, {0x846b, 0x00bd}, {0x846c, 0x00ec}, -{0x846d, 0x008e}, {0x846e, 0x00bd}, {0x846f, 0x00fa}, -{0x8470, 0x00f7}, {0x8471, 0x0086}, {0x8472, 0x0008}, -{0x8473, 0x00d6}, {0x8474, 0x0000}, {0x8475, 0x00c5}, -{0x8476, 0x0010}, {0x8477, 0x0026}, {0x8478, 0x0002}, -{0x8479, 0x008b}, {0x847a, 0x0020}, {0x847b, 0x00c6}, -{0x847c, 0x0051}, {0x847d, 0x00bd}, {0x847e, 0x00e4}, -{0x847f, 0x0012}, {0x8480, 0x00ce}, {0x8481, 0x0084}, -{0x8482, 0x0086}, {0x8483, 0x00ff}, {0x8484, 0x0001}, -{0x8485, 0x0011}, {0x8486, 0x0096}, {0x8487, 0x0046}, -{0x8488, 0x0084}, {0x8489, 0x0003}, {0x848a, 0x0081}, -{0x848b, 0x0002}, {0x848c, 0x0027}, {0x848d, 0x0003}, -{0x848e, 0x007e}, {0x848f, 0x0085}, {0x8490, 0x000f}, -{0x8491, 0x00c6}, {0x8492, 0x0051}, {0x8493, 0x00bd}, -{0x8494, 0x00e4}, {0x8495, 0x0091}, {0x8496, 0x0025}, -{0x8497, 0x0003}, {0x8498, 0x007e}, {0x8499, 0x0085}, -{0x849a, 0x001e}, {0x849b, 0x0096}, {0x849c, 0x0044}, -{0x849d, 0x0085}, {0x849e, 0x0010}, {0x849f, 0x0026}, -{0x84a0, 0x000a}, {0x84a1, 0x00b6}, {0x84a2, 0x0012}, -{0x84a3, 0x0050}, {0x84a4, 0x00ba}, {0x84a5, 0x0001}, -{0x84a6, 0x003c}, {0x84a7, 0x0085}, {0x84a8, 0x0010}, -{0x84a9, 0x0027}, {0x84aa, 0x00a8}, {0x84ab, 0x00bd}, -{0x84ac, 0x00f7}, {0x84ad, 0x0066}, {0x84ae, 0x00ce}, -{0x84af, 0x0084}, {0x84b0, 0x00b7}, {0x84b1, 0x00ff}, -{0x84b2, 0x0001}, {0x84b3, 0x0011}, {0x84b4, 0x007e}, -{0x84b5, 0x0085}, {0x84b6, 0x001e}, {0x84b7, 0x0096}, -{0x84b8, 0x0046}, {0x84b9, 0x0084}, {0x84ba, 0x0003}, -{0x84bb, 0x0081}, {0x84bc, 0x0002}, {0x84bd, 0x0026}, -{0x84be, 0x0050}, {0x84bf, 0x00b6}, {0x84c0, 0x0012}, -{0x84c1, 0x0030}, {0x84c2, 0x0084}, {0x84c3, 0x0003}, -{0x84c4, 0x0081}, {0x84c5, 0x0001}, {0x84c6, 0x0027}, -{0x84c7, 0x0003}, {0x84c8, 0x007e}, {0x84c9, 0x0085}, -{0x84ca, 0x001e}, {0x84cb, 0x0096}, {0x84cc, 0x0044}, -{0x84cd, 0x0085}, {0x84ce, 0x0010}, {0x84cf, 0x0026}, -{0x84d0, 0x0013}, {0x84d1, 0x00b6}, {0x84d2, 0x0012}, -{0x84d3, 0x0050}, {0x84d4, 0x00ba}, {0x84d5, 0x0001}, -{0x84d6, 0x003c}, {0x84d7, 0x0085}, {0x84d8, 0x0010}, -{0x84d9, 0x0026}, {0x84da, 0x0009}, {0x84db, 0x00ce}, -{0x84dc, 0x0084}, {0x84dd, 0x0053}, {0x84de, 0x00ff}, -{0x84df, 0x0001}, {0x84e0, 0x0011}, {0x84e1, 0x007e}, -{0x84e2, 0x0085}, {0x84e3, 0x001e}, {0x84e4, 0x00b6}, -{0x84e5, 0x0010}, {0x84e6, 0x0031}, {0x84e7, 0x008a}, -{0x84e8, 0x0002}, {0x84e9, 0x00b7}, {0x84ea, 0x0010}, -{0x84eb, 0x0031}, {0x84ec, 0x00bd}, {0x84ed, 0x0085}, -{0x84ee, 0x001f}, {0x84ef, 0x00bd}, {0x84f0, 0x00f8}, -{0x84f1, 0x0037}, {0x84f2, 0x007c}, {0x84f3, 0x0000}, -{0x84f4, 0x0080}, {0x84f5, 0x00ce}, {0x84f6, 0x0084}, -{0x84f7, 0x00fe}, {0x84f8, 0x00ff}, {0x84f9, 0x0001}, -{0x84fa, 0x0011}, {0x84fb, 0x007e}, {0x84fc, 0x0085}, -{0x84fd, 0x001e}, {0x84fe, 0x0096}, {0x84ff, 0x0046}, -{0x8500, 0x0084}, {0x8501, 0x0003}, {0x8502, 0x0081}, -{0x8503, 0x0002}, {0x8504, 0x0026}, {0x8505, 0x0009}, -{0x8506, 0x00b6}, {0x8507, 0x0012}, {0x8508, 0x0030}, -{0x8509, 0x0084}, {0x850a, 0x0003}, {0x850b, 0x0081}, -{0x850c, 0x0001}, {0x850d, 0x0027}, {0x850e, 0x000f}, -{0x850f, 0x00bd}, {0x8510, 0x00f8}, {0x8511, 0x0044}, -{0x8512, 0x00bd}, {0x8513, 0x00f7}, {0x8514, 0x000b}, -{0x8515, 0x00bd}, {0x8516, 0x00fc}, {0x8517, 0x0029}, -{0x8518, 0x00ce}, {0x8519, 0x0084}, {0x851a, 0x0026}, -{0x851b, 0x00ff}, {0x851c, 0x0001}, {0x851d, 0x0011}, -{0x851e, 0x0039}, {0x851f, 0x00d6}, {0x8520, 0x0022}, -{0x8521, 0x00c4}, {0x8522, 0x000f}, {0x8523, 0x00b6}, -{0x8524, 0x0012}, {0x8525, 0x0030}, {0x8526, 0x00ba}, -{0x8527, 0x0012}, {0x8528, 0x0032}, {0x8529, 0x0084}, -{0x852a, 0x0004}, {0x852b, 0x0027}, {0x852c, 0x000d}, -{0x852d, 0x0096}, {0x852e, 0x0022}, {0x852f, 0x0085}, -{0x8530, 0x0004}, {0x8531, 0x0027}, {0x8532, 0x0005}, -{0x8533, 0x00ca}, {0x8534, 0x0010}, {0x8535, 0x007e}, -{0x8536, 0x0085}, {0x8537, 0x003a}, {0x8538, 0x00ca}, -{0x8539, 0x0020}, {0x853a, 0x00d7}, {0x853b, 0x0022}, -{0x853c, 0x0039}, {0x853d, 0x0086}, {0x853e, 0x0000}, -{0x853f, 0x0097}, {0x8540, 0x0083}, {0x8541, 0x0018}, -{0x8542, 0x00ce}, {0x8543, 0x001c}, {0x8544, 0x0000}, -{0x8545, 0x00bd}, {0x8546, 0x00eb}, {0x8547, 0x0046}, -{0x8548, 0x0096}, {0x8549, 0x0057}, {0x854a, 0x0085}, -{0x854b, 0x0001}, {0x854c, 0x0027}, {0x854d, 0x0002}, -{0x854e, 0x004f}, {0x854f, 0x0039}, {0x8550, 0x0085}, -{0x8551, 0x0002}, {0x8552, 0x0027}, {0x8553, 0x0001}, -{0x8554, 0x0039}, {0x8555, 0x007f}, {0x8556, 0x008f}, -{0x8557, 0x007d}, {0x8558, 0x0086}, {0x8559, 0x0004}, -{0x855a, 0x00b7}, {0x855b, 0x0012}, {0x855c, 0x0004}, -{0x855d, 0x0086}, {0x855e, 0x0008}, {0x855f, 0x00b7}, -{0x8560, 0x0012}, {0x8561, 0x0007}, {0x8562, 0x0086}, -{0x8563, 0x0010}, {0x8564, 0x00b7}, {0x8565, 0x0012}, -{0x8566, 0x000c}, {0x8567, 0x0086}, {0x8568, 0x0007}, -{0x8569, 0x00b7}, {0x856a, 0x0012}, {0x856b, 0x0006}, -{0x856c, 0x00b6}, {0x856d, 0x008f}, {0x856e, 0x007d}, -{0x856f, 0x00b7}, {0x8570, 0x0012}, {0x8571, 0x0070}, -{0x8572, 0x0086}, {0x8573, 0x0001}, {0x8574, 0x00ba}, -{0x8575, 0x0012}, {0x8576, 0x0004}, {0x8577, 0x00b7}, -{0x8578, 0x0012}, {0x8579, 0x0004}, {0x857a, 0x0001}, -{0x857b, 0x0001}, {0x857c, 0x0001}, {0x857d, 0x0001}, -{0x857e, 0x0001}, {0x857f, 0x0001}, {0x8580, 0x00b6}, -{0x8581, 0x0012}, {0x8582, 0x0004}, {0x8583, 0x0084}, -{0x8584, 0x00fe}, {0x8585, 0x008a}, {0x8586, 0x0002}, -{0x8587, 0x00b7}, {0x8588, 0x0012}, {0x8589, 0x0004}, -{0x858a, 0x0001}, {0x858b, 0x0001}, {0x858c, 0x0001}, -{0x858d, 0x0001}, {0x858e, 0x0001}, {0x858f, 0x0001}, -{0x8590, 0x0086}, {0x8591, 0x00fd}, {0x8592, 0x00b4}, -{0x8593, 0x0012}, {0x8594, 0x0004}, {0x8595, 0x00b7}, -{0x8596, 0x0012}, {0x8597, 0x0004}, {0x8598, 0x00b6}, -{0x8599, 0x0012}, {0x859a, 0x0000}, {0x859b, 0x0084}, -{0x859c, 0x0008}, {0x859d, 0x0081}, {0x859e, 0x0008}, -{0x859f, 0x0027}, {0x85a0, 0x0016}, {0x85a1, 0x00b6}, -{0x85a2, 0x008f}, {0x85a3, 0x007d}, {0x85a4, 0x0081}, -{0x85a5, 0x000c}, {0x85a6, 0x0027}, {0x85a7, 0x0008}, -{0x85a8, 0x008b}, {0x85a9, 0x0004}, {0x85aa, 0x00b7}, -{0x85ab, 0x008f}, {0x85ac, 0x007d}, {0x85ad, 0x007e}, -{0x85ae, 0x0085}, {0x85af, 0x006c}, {0x85b0, 0x0086}, -{0x85b1, 0x0003}, {0x85b2, 0x0097}, {0x85b3, 0x0040}, -{0x85b4, 0x007e}, {0x85b5, 0x0089}, {0x85b6, 0x006e}, -{0x85b7, 0x0086}, {0x85b8, 0x0007}, {0x85b9, 0x00b7}, -{0x85ba, 0x0012}, {0x85bb, 0x0006}, {0x85bc, 0x005f}, -{0x85bd, 0x00f7}, {0x85be, 0x008f}, {0x85bf, 0x0082}, -{0x85c0, 0x005f}, {0x85c1, 0x00f7}, {0x85c2, 0x008f}, -{0x85c3, 0x007f}, {0x85c4, 0x00f7}, {0x85c5, 0x008f}, -{0x85c6, 0x0070}, {0x85c7, 0x00f7}, {0x85c8, 0x008f}, -{0x85c9, 0x0071}, {0x85ca, 0x00f7}, {0x85cb, 0x008f}, -{0x85cc, 0x0072}, {0x85cd, 0x00f7}, {0x85ce, 0x008f}, -{0x85cf, 0x0073}, {0x85d0, 0x00f7}, {0x85d1, 0x008f}, -{0x85d2, 0x0074}, {0x85d3, 0x00f7}, {0x85d4, 0x008f}, -{0x85d5, 0x0075}, {0x85d6, 0x00f7}, {0x85d7, 0x008f}, -{0x85d8, 0x0076}, {0x85d9, 0x00f7}, {0x85da, 0x008f}, -{0x85db, 0x0077}, {0x85dc, 0x00f7}, {0x85dd, 0x008f}, -{0x85de, 0x0078}, {0x85df, 0x00f7}, {0x85e0, 0x008f}, -{0x85e1, 0x0079}, {0x85e2, 0x00f7}, {0x85e3, 0x008f}, -{0x85e4, 0x007a}, {0x85e5, 0x00f7}, {0x85e6, 0x008f}, -{0x85e7, 0x007b}, {0x85e8, 0x00b6}, {0x85e9, 0x0012}, -{0x85ea, 0x0004}, {0x85eb, 0x008a}, {0x85ec, 0x0010}, -{0x85ed, 0x00b7}, {0x85ee, 0x0012}, {0x85ef, 0x0004}, -{0x85f0, 0x0086}, {0x85f1, 0x00e4}, {0x85f2, 0x00b7}, -{0x85f3, 0x0012}, {0x85f4, 0x0070}, {0x85f5, 0x00b7}, -{0x85f6, 0x0012}, {0x85f7, 0x0007}, {0x85f8, 0x00f7}, -{0x85f9, 0x0012}, {0x85fa, 0x0005}, {0x85fb, 0x00f7}, -{0x85fc, 0x0012}, {0x85fd, 0x0009}, {0x85fe, 0x0086}, -{0x85ff, 0x0008}, {0x8600, 0x00ba}, {0x8601, 0x0012}, -{0x8602, 0x0004}, {0x8603, 0x00b7}, {0x8604, 0x0012}, -{0x8605, 0x0004}, {0x8606, 0x0086}, {0x8607, 0x00f7}, -{0x8608, 0x00b4}, {0x8609, 0x0012}, {0x860a, 0x0004}, -{0x860b, 0x00b7}, {0x860c, 0x0012}, {0x860d, 0x0004}, -{0x860e, 0x0001}, {0x860f, 0x0001}, {0x8610, 0x0001}, -{0x8611, 0x0001}, {0x8612, 0x0001}, {0x8613, 0x0001}, -{0x8614, 0x00b6}, {0x8615, 0x0012}, {0x8616, 0x0008}, -{0x8617, 0x0027}, {0x8618, 0x007f}, {0x8619, 0x0081}, -{0x861a, 0x0080}, {0x861b, 0x0026}, {0x861c, 0x000b}, -{0x861d, 0x0086}, {0x861e, 0x0008}, {0x861f, 0x00ce}, -{0x8620, 0x008f}, {0x8621, 0x0079}, {0x8622, 0x00bd}, -{0x8623, 0x0089}, {0x8624, 0x007b}, {0x8625, 0x007e}, -{0x8626, 0x0086}, {0x8627, 0x008e}, {0x8628, 0x0081}, -{0x8629, 0x0040}, {0x862a, 0x0026}, {0x862b, 0x000b}, -{0x862c, 0x0086}, {0x862d, 0x0004}, {0x862e, 0x00ce}, -{0x862f, 0x008f}, {0x8630, 0x0076}, {0x8631, 0x00bd}, -{0x8632, 0x0089}, {0x8633, 0x007b}, {0x8634, 0x007e}, -{0x8635, 0x0086}, {0x8636, 0x008e}, {0x8637, 0x0081}, -{0x8638, 0x0020}, {0x8639, 0x0026}, {0x863a, 0x000b}, -{0x863b, 0x0086}, {0x863c, 0x0002}, {0x863d, 0x00ce}, -{0x863e, 0x008f}, {0x863f, 0x0073}, {0x8640, 0x00bd}, -{0x8641, 0x0089}, {0x8642, 0x007b}, {0x8643, 0x007e}, -{0x8644, 0x0086}, {0x8645, 0x008e}, {0x8646, 0x0081}, -{0x8647, 0x0010}, {0x8648, 0x0026}, {0x8649, 0x000b}, -{0x864a, 0x0086}, {0x864b, 0x0001}, {0x864c, 0x00ce}, -{0x864d, 0x008f}, {0x864e, 0x0070}, {0x864f, 0x00bd}, -{0x8650, 0x0089}, {0x8651, 0x007b}, {0x8652, 0x007e}, -{0x8653, 0x0086}, {0x8654, 0x008e}, {0x8655, 0x0081}, -{0x8656, 0x0008}, {0x8657, 0x0026}, {0x8658, 0x000b}, -{0x8659, 0x0086}, {0x865a, 0x0008}, {0x865b, 0x00ce}, -{0x865c, 0x008f}, {0x865d, 0x0079}, {0x865e, 0x00bd}, -{0x865f, 0x0089}, {0x8660, 0x007f}, {0x8661, 0x007e}, -{0x8662, 0x0086}, {0x8663, 0x008e}, {0x8664, 0x0081}, -{0x8665, 0x0004}, {0x8666, 0x0026}, {0x8667, 0x000b}, -{0x8668, 0x0086}, {0x8669, 0x0004}, {0x866a, 0x00ce}, -{0x866b, 0x008f}, {0x866c, 0x0076}, {0x866d, 0x00bd}, -{0x866e, 0x0089}, {0x866f, 0x007f}, {0x8670, 0x007e}, -{0x8671, 0x0086}, {0x8672, 0x008e}, {0x8673, 0x0081}, -{0x8674, 0x0002}, {0x8675, 0x0026}, {0x8676, 0x000b}, -{0x8677, 0x008a}, {0x8678, 0x0002}, {0x8679, 0x00ce}, -{0x867a, 0x008f}, {0x867b, 0x0073}, {0x867c, 0x00bd}, -{0x867d, 0x0089}, {0x867e, 0x007f}, {0x867f, 0x007e}, -{0x8680, 0x0086}, {0x8681, 0x008e}, {0x8682, 0x0081}, -{0x8683, 0x0001}, {0x8684, 0x0026}, {0x8685, 0x0008}, -{0x8686, 0x0086}, {0x8687, 0x0001}, {0x8688, 0x00ce}, -{0x8689, 0x008f}, {0x868a, 0x0070}, {0x868b, 0x00bd}, -{0x868c, 0x0089}, {0x868d, 0x007f}, {0x868e, 0x00b6}, -{0x868f, 0x008f}, {0x8690, 0x007f}, {0x8691, 0x0081}, -{0x8692, 0x000f}, {0x8693, 0x0026}, {0x8694, 0x0003}, -{0x8695, 0x007e}, {0x8696, 0x0087}, {0x8697, 0x0047}, -{0x8698, 0x00b6}, {0x8699, 0x0012}, {0x869a, 0x0009}, -{0x869b, 0x0084}, {0x869c, 0x0003}, {0x869d, 0x0081}, -{0x869e, 0x0003}, {0x869f, 0x0027}, {0x86a0, 0x0006}, -{0x86a1, 0x007c}, {0x86a2, 0x0012}, {0x86a3, 0x0009}, -{0x86a4, 0x007e}, {0x86a5, 0x0085}, {0x86a6, 0x00fe}, -{0x86a7, 0x00b6}, {0x86a8, 0x0012}, {0x86a9, 0x0006}, -{0x86aa, 0x0084}, {0x86ab, 0x0007}, {0x86ac, 0x0081}, -{0x86ad, 0x0007}, {0x86ae, 0x0027}, {0x86af, 0x0008}, -{0x86b0, 0x008b}, {0x86b1, 0x0001}, {0x86b2, 0x00b7}, -{0x86b3, 0x0012}, {0x86b4, 0x0006}, {0x86b5, 0x007e}, -{0x86b6, 0x0086}, {0x86b7, 0x00d5}, {0x86b8, 0x00b6}, -{0x86b9, 0x008f}, {0x86ba, 0x0082}, {0x86bb, 0x0026}, -{0x86bc, 0x000a}, {0x86bd, 0x007c}, {0x86be, 0x008f}, -{0x86bf, 0x0082}, {0x86c0, 0x004f}, {0x86c1, 0x00b7}, -{0x86c2, 0x0012}, {0x86c3, 0x0006}, {0x86c4, 0x007e}, -{0x86c5, 0x0085}, {0x86c6, 0x00c0}, {0x86c7, 0x00b6}, -{0x86c8, 0x0012}, {0x86c9, 0x0006}, {0x86ca, 0x0084}, -{0x86cb, 0x003f}, {0x86cc, 0x0081}, {0x86cd, 0x003f}, -{0x86ce, 0x0027}, {0x86cf, 0x0010}, {0x86d0, 0x008b}, -{0x86d1, 0x0008}, {0x86d2, 0x00b7}, {0x86d3, 0x0012}, -{0x86d4, 0x0006}, {0x86d5, 0x00b6}, {0x86d6, 0x0012}, -{0x86d7, 0x0009}, {0x86d8, 0x0084}, {0x86d9, 0x00fc}, -{0x86da, 0x00b7}, {0x86db, 0x0012}, {0x86dc, 0x0009}, -{0x86dd, 0x007e}, {0x86de, 0x0085}, {0x86df, 0x00fe}, -{0x86e0, 0x00ce}, {0x86e1, 0x008f}, {0x86e2, 0x0070}, -{0x86e3, 0x0018}, {0x86e4, 0x00ce}, {0x86e5, 0x008f}, -{0x86e6, 0x0084}, {0x86e7, 0x00c6}, {0x86e8, 0x000c}, -{0x86e9, 0x00bd}, {0x86ea, 0x0089}, {0x86eb, 0x006f}, -{0x86ec, 0x00ce}, {0x86ed, 0x008f}, {0x86ee, 0x0084}, -{0x86ef, 0x0018}, {0x86f0, 0x00ce}, {0x86f1, 0x008f}, -{0x86f2, 0x0070}, {0x86f3, 0x00c6}, {0x86f4, 0x000c}, -{0x86f5, 0x00bd}, {0x86f6, 0x0089}, {0x86f7, 0x006f}, -{0x86f8, 0x00d6}, {0x86f9, 0x0083}, {0x86fa, 0x00c1}, -{0x86fb, 0x004f}, {0x86fc, 0x002d}, {0x86fd, 0x0003}, -{0x86fe, 0x007e}, {0x86ff, 0x0087}, {0x8700, 0x0040}, -{0x8701, 0x00b6}, {0x8702, 0x008f}, {0x8703, 0x007f}, -{0x8704, 0x0081}, {0x8705, 0x0007}, {0x8706, 0x0027}, -{0x8707, 0x000f}, {0x8708, 0x0081}, {0x8709, 0x000b}, -{0x870a, 0x0027}, {0x870b, 0x0015}, {0x870c, 0x0081}, -{0x870d, 0x000d}, {0x870e, 0x0027}, {0x870f, 0x001b}, -{0x8710, 0x0081}, {0x8711, 0x000e}, {0x8712, 0x0027}, -{0x8713, 0x0021}, {0x8714, 0x007e}, {0x8715, 0x0087}, -{0x8716, 0x0040}, {0x8717, 0x00f7}, {0x8718, 0x008f}, -{0x8719, 0x007b}, {0x871a, 0x0086}, {0x871b, 0x0002}, -{0x871c, 0x00b7}, {0x871d, 0x008f}, {0x871e, 0x007a}, -{0x871f, 0x0020}, {0x8720, 0x001c}, {0x8721, 0x00f7}, -{0x8722, 0x008f}, {0x8723, 0x0078}, {0x8724, 0x0086}, -{0x8725, 0x0002}, {0x8726, 0x00b7}, {0x8727, 0x008f}, -{0x8728, 0x0077}, {0x8729, 0x0020}, {0x872a, 0x0012}, -{0x872b, 0x00f7}, {0x872c, 0x008f}, {0x872d, 0x0075}, -{0x872e, 0x0086}, {0x872f, 0x0002}, {0x8730, 0x00b7}, -{0x8731, 0x008f}, {0x8732, 0x0074}, {0x8733, 0x0020}, -{0x8734, 0x0008}, {0x8735, 0x00f7}, {0x8736, 0x008f}, -{0x8737, 0x0072}, {0x8738, 0x0086}, {0x8739, 0x0002}, -{0x873a, 0x00b7}, {0x873b, 0x008f}, {0x873c, 0x0071}, -{0x873d, 0x007e}, {0x873e, 0x0087}, {0x873f, 0x0047}, -{0x8740, 0x0086}, {0x8741, 0x0004}, {0x8742, 0x0097}, -{0x8743, 0x0040}, {0x8744, 0x007e}, {0x8745, 0x0089}, -{0x8746, 0x006e}, {0x8747, 0x00ce}, {0x8748, 0x008f}, -{0x8749, 0x0072}, {0x874a, 0x00bd}, {0x874b, 0x0089}, -{0x874c, 0x00f7}, {0x874d, 0x00ce}, {0x874e, 0x008f}, -{0x874f, 0x0075}, {0x8750, 0x00bd}, {0x8751, 0x0089}, -{0x8752, 0x00f7}, {0x8753, 0x00ce}, {0x8754, 0x008f}, -{0x8755, 0x0078}, {0x8756, 0x00bd}, {0x8757, 0x0089}, -{0x8758, 0x00f7}, {0x8759, 0x00ce}, {0x875a, 0x008f}, -{0x875b, 0x007b}, {0x875c, 0x00bd}, {0x875d, 0x0089}, -{0x875e, 0x00f7}, {0x875f, 0x004f}, {0x8760, 0x00b7}, -{0x8761, 0x008f}, {0x8762, 0x007d}, {0x8763, 0x00b7}, -{0x8764, 0x008f}, {0x8765, 0x0081}, {0x8766, 0x00b6}, -{0x8767, 0x008f}, {0x8768, 0x0072}, {0x8769, 0x0027}, -{0x876a, 0x0047}, {0x876b, 0x007c}, {0x876c, 0x008f}, -{0x876d, 0x007d}, {0x876e, 0x00b6}, {0x876f, 0x008f}, -{0x8770, 0x0075}, {0x8771, 0x0027}, {0x8772, 0x003f}, -{0x8773, 0x007c}, {0x8774, 0x008f}, {0x8775, 0x007d}, -{0x8776, 0x00b6}, {0x8777, 0x008f}, {0x8778, 0x0078}, -{0x8779, 0x0027}, {0x877a, 0x0037}, {0x877b, 0x007c}, -{0x877c, 0x008f}, {0x877d, 0x007d}, {0x877e, 0x00b6}, -{0x877f, 0x008f}, {0x8780, 0x007b}, {0x8781, 0x0027}, -{0x8782, 0x002f}, {0x8783, 0x007f}, {0x8784, 0x008f}, -{0x8785, 0x007d}, {0x8786, 0x007c}, {0x8787, 0x008f}, -{0x8788, 0x0081}, {0x8789, 0x007a}, {0x878a, 0x008f}, -{0x878b, 0x0072}, {0x878c, 0x0027}, {0x878d, 0x001b}, -{0x878e, 0x007c}, {0x878f, 0x008f}, {0x8790, 0x007d}, -{0x8791, 0x007a}, {0x8792, 0x008f}, {0x8793, 0x0075}, -{0x8794, 0x0027}, {0x8795, 0x0016}, {0x8796, 0x007c}, -{0x8797, 0x008f}, {0x8798, 0x007d}, {0x8799, 0x007a}, -{0x879a, 0x008f}, {0x879b, 0x0078}, {0x879c, 0x0027}, -{0x879d, 0x0011}, {0x879e, 0x007c}, {0x879f, 0x008f}, -{0x87a0, 0x007d}, {0x87a1, 0x007a}, {0x87a2, 0x008f}, -{0x87a3, 0x007b}, {0x87a4, 0x0027}, {0x87a5, 0x000c}, -{0x87a6, 0x007e}, {0x87a7, 0x0087}, {0x87a8, 0x0083}, -{0x87a9, 0x007a}, {0x87aa, 0x008f}, {0x87ab, 0x0075}, -{0x87ac, 0x007a}, {0x87ad, 0x008f}, {0x87ae, 0x0078}, -{0x87af, 0x007a}, {0x87b0, 0x008f}, {0x87b1, 0x007b}, -{0x87b2, 0x00ce}, {0x87b3, 0x00c1}, {0x87b4, 0x00fc}, -{0x87b5, 0x00f6}, {0x87b6, 0x008f}, {0x87b7, 0x007d}, -{0x87b8, 0x003a}, {0x87b9, 0x00a6}, {0x87ba, 0x0000}, -{0x87bb, 0x00b7}, {0x87bc, 0x0012}, {0x87bd, 0x0070}, -{0x87be, 0x00b6}, {0x87bf, 0x008f}, {0x87c0, 0x0072}, -{0x87c1, 0x0026}, {0x87c2, 0x0003}, {0x87c3, 0x007e}, -{0x87c4, 0x0087}, {0x87c5, 0x00fa}, {0x87c6, 0x00b6}, -{0x87c7, 0x008f}, {0x87c8, 0x0075}, {0x87c9, 0x0026}, -{0x87ca, 0x000a}, {0x87cb, 0x0018}, {0x87cc, 0x00ce}, -{0x87cd, 0x008f}, {0x87ce, 0x0073}, {0x87cf, 0x00bd}, -{0x87d0, 0x0089}, {0x87d1, 0x00d5}, {0x87d2, 0x007e}, -{0x87d3, 0x0087}, {0x87d4, 0x00fa}, {0x87d5, 0x00b6}, -{0x87d6, 0x008f}, {0x87d7, 0x0078}, {0x87d8, 0x0026}, -{0x87d9, 0x000a}, {0x87da, 0x0018}, {0x87db, 0x00ce}, -{0x87dc, 0x008f}, {0x87dd, 0x0076}, {0x87de, 0x00bd}, -{0x87df, 0x0089}, {0x87e0, 0x00d5}, {0x87e1, 0x007e}, -{0x87e2, 0x0087}, {0x87e3, 0x00fa}, {0x87e4, 0x00b6}, -{0x87e5, 0x008f}, {0x87e6, 0x007b}, {0x87e7, 0x0026}, -{0x87e8, 0x000a}, {0x87e9, 0x0018}, {0x87ea, 0x00ce}, -{0x87eb, 0x008f}, {0x87ec, 0x0079}, {0x87ed, 0x00bd}, -{0x87ee, 0x0089}, {0x87ef, 0x00d5}, {0x87f0, 0x007e}, -{0x87f1, 0x0087}, {0x87f2, 0x00fa}, {0x87f3, 0x0086}, -{0x87f4, 0x0005}, {0x87f5, 0x0097}, {0x87f6, 0x0040}, -{0x87f7, 0x007e}, {0x87f8, 0x0089}, {0x87f9, 0x0000}, -{0x87fa, 0x00b6}, {0x87fb, 0x008f}, {0x87fc, 0x0075}, -{0x87fd, 0x0081}, {0x87fe, 0x0007}, {0x87ff, 0x002e}, -{0x8800, 0x00f2}, {0x8801, 0x00f6}, {0x8802, 0x0012}, -{0x8803, 0x0006}, {0x8804, 0x00c4}, {0x8805, 0x00f8}, -{0x8806, 0x001b}, {0x8807, 0x00b7}, {0x8808, 0x0012}, -{0x8809, 0x0006}, {0x880a, 0x00b6}, {0x880b, 0x008f}, -{0x880c, 0x0078}, {0x880d, 0x0081}, {0x880e, 0x0007}, -{0x880f, 0x002e}, {0x8810, 0x00e2}, {0x8811, 0x0048}, -{0x8812, 0x0048}, {0x8813, 0x0048}, {0x8814, 0x00f6}, -{0x8815, 0x0012}, {0x8816, 0x0006}, {0x8817, 0x00c4}, -{0x8818, 0x00c7}, {0x8819, 0x001b}, {0x881a, 0x00b7}, -{0x881b, 0x0012}, {0x881c, 0x0006}, {0x881d, 0x00b6}, -{0x881e, 0x008f}, {0x881f, 0x007b}, {0x8820, 0x0081}, -{0x8821, 0x0007}, {0x8822, 0x002e}, {0x8823, 0x00cf}, -{0x8824, 0x00f6}, {0x8825, 0x0012}, {0x8826, 0x0005}, -{0x8827, 0x00c4}, {0x8828, 0x00f8}, {0x8829, 0x001b}, -{0x882a, 0x00b7}, {0x882b, 0x0012}, {0x882c, 0x0005}, -{0x882d, 0x0086}, {0x882e, 0x0000}, {0x882f, 0x00f6}, -{0x8830, 0x008f}, {0x8831, 0x0071}, {0x8832, 0x00bd}, -{0x8833, 0x0089}, {0x8834, 0x0094}, {0x8835, 0x0086}, -{0x8836, 0x0001}, {0x8837, 0x00f6}, {0x8838, 0x008f}, -{0x8839, 0x0074}, {0x883a, 0x00bd}, {0x883b, 0x0089}, -{0x883c, 0x0094}, {0x883d, 0x0086}, {0x883e, 0x0002}, -{0x883f, 0x00f6}, {0x8840, 0x008f}, {0x8841, 0x0077}, -{0x8842, 0x00bd}, {0x8843, 0x0089}, {0x8844, 0x0094}, -{0x8845, 0x0086}, {0x8846, 0x0003}, {0x8847, 0x00f6}, -{0x8848, 0x008f}, {0x8849, 0x007a}, {0x884a, 0x00bd}, -{0x884b, 0x0089}, {0x884c, 0x0094}, {0x884d, 0x00ce}, -{0x884e, 0x008f}, {0x884f, 0x0070}, {0x8850, 0x00a6}, -{0x8851, 0x0001}, {0x8852, 0x0081}, {0x8853, 0x0001}, -{0x8854, 0x0027}, {0x8855, 0x0007}, {0x8856, 0x0081}, -{0x8857, 0x0003}, {0x8858, 0x0027}, {0x8859, 0x0003}, -{0x885a, 0x007e}, {0x885b, 0x0088}, {0x885c, 0x0066}, -{0x885d, 0x00a6}, {0x885e, 0x0000}, {0x885f, 0x00b8}, -{0x8860, 0x008f}, {0x8861, 0x0081}, {0x8862, 0x0084}, -{0x8863, 0x0001}, {0x8864, 0x0026}, {0x8865, 0x000b}, -{0x8866, 0x008c}, {0x8867, 0x008f}, {0x8868, 0x0079}, -{0x8869, 0x002c}, {0x886a, 0x000e}, {0x886b, 0x0008}, -{0x886c, 0x0008}, {0x886d, 0x0008}, {0x886e, 0x007e}, -{0x886f, 0x0088}, {0x8870, 0x0050}, {0x8871, 0x00b6}, -{0x8872, 0x0012}, {0x8873, 0x0004}, {0x8874, 0x008a}, -{0x8875, 0x0040}, {0x8876, 0x00b7}, {0x8877, 0x0012}, -{0x8878, 0x0004}, {0x8879, 0x00b6}, {0x887a, 0x0012}, -{0x887b, 0x0004}, {0x887c, 0x0084}, {0x887d, 0x00fb}, -{0x887e, 0x0084}, {0x887f, 0x00ef}, {0x8880, 0x00b7}, -{0x8881, 0x0012}, {0x8882, 0x0004}, {0x8883, 0x00b6}, -{0x8884, 0x0012}, {0x8885, 0x0007}, {0x8886, 0x0036}, -{0x8887, 0x00b6}, {0x8888, 0x008f}, {0x8889, 0x007c}, -{0x888a, 0x0048}, {0x888b, 0x0048}, {0x888c, 0x00b7}, -{0x888d, 0x0012}, {0x888e, 0x0007}, {0x888f, 0x0086}, -{0x8890, 0x0001}, {0x8891, 0x00ba}, {0x8892, 0x0012}, -{0x8893, 0x0004}, {0x8894, 0x00b7}, {0x8895, 0x0012}, -{0x8896, 0x0004}, {0x8897, 0x0001}, {0x8898, 0x0001}, -{0x8899, 0x0001}, {0x889a, 0x0001}, {0x889b, 0x0001}, -{0x889c, 0x0001}, {0x889d, 0x0086}, {0x889e, 0x00fe}, -{0x889f, 0x00b4}, {0x88a0, 0x0012}, {0x88a1, 0x0004}, -{0x88a2, 0x00b7}, {0x88a3, 0x0012}, {0x88a4, 0x0004}, -{0x88a5, 0x0086}, {0x88a6, 0x0002}, {0x88a7, 0x00ba}, -{0x88a8, 0x0012}, {0x88a9, 0x0004}, {0x88aa, 0x00b7}, -{0x88ab, 0x0012}, {0x88ac, 0x0004}, {0x88ad, 0x0086}, -{0x88ae, 0x00fd}, {0x88af, 0x00b4}, {0x88b0, 0x0012}, -{0x88b1, 0x0004}, {0x88b2, 0x00b7}, {0x88b3, 0x0012}, -{0x88b4, 0x0004}, {0x88b5, 0x0032}, {0x88b6, 0x00b7}, -{0x88b7, 0x0012}, {0x88b8, 0x0007}, {0x88b9, 0x00b6}, -{0x88ba, 0x0012}, {0x88bb, 0x0000}, {0x88bc, 0x0084}, -{0x88bd, 0x0008}, {0x88be, 0x0081}, {0x88bf, 0x0008}, -{0x88c0, 0x0027}, {0x88c1, 0x000f}, {0x88c2, 0x007c}, -{0x88c3, 0x0082}, {0x88c4, 0x0008}, {0x88c5, 0x0026}, -{0x88c6, 0x0007}, {0x88c7, 0x0086}, {0x88c8, 0x0076}, -{0x88c9, 0x0097}, {0x88ca, 0x0040}, {0x88cb, 0x007e}, -{0x88cc, 0x0089}, {0x88cd, 0x006e}, {0x88ce, 0x007e}, -{0x88cf, 0x0086}, {0x88d0, 0x00ec}, {0x88d1, 0x00b6}, -{0x88d2, 0x008f}, {0x88d3, 0x007f}, {0x88d4, 0x0081}, -{0x88d5, 0x000f}, {0x88d6, 0x0027}, {0x88d7, 0x003c}, -{0x88d8, 0x00bd}, {0x88d9, 0x00e6}, {0x88da, 0x00c7}, -{0x88db, 0x00b7}, {0x88dc, 0x0012}, {0x88dd, 0x000d}, -{0x88de, 0x00bd}, {0x88df, 0x00e6}, {0x88e0, 0x00cb}, -{0x88e1, 0x00b6}, {0x88e2, 0x0012}, {0x88e3, 0x0004}, -{0x88e4, 0x008a}, {0x88e5, 0x0020}, {0x88e6, 0x00b7}, -{0x88e7, 0x0012}, {0x88e8, 0x0004}, {0x88e9, 0x00ce}, -{0x88ea, 0x00ff}, {0x88eb, 0x00ff}, {0x88ec, 0x00b6}, -{0x88ed, 0x0012}, {0x88ee, 0x0000}, {0x88ef, 0x0081}, -{0x88f0, 0x000c}, {0x88f1, 0x0026}, {0x88f2, 0x0005}, -{0x88f3, 0x0009}, {0x88f4, 0x0026}, {0x88f5, 0x00f6}, -{0x88f6, 0x0027}, {0x88f7, 0x001c}, {0x88f8, 0x00b6}, -{0x88f9, 0x0012}, {0x88fa, 0x0004}, {0x88fb, 0x0084}, -{0x88fc, 0x00df}, {0x88fd, 0x00b7}, {0x88fe, 0x0012}, -{0x88ff, 0x0004}, {0x8900, 0x0096}, {0x8901, 0x0083}, -{0x8902, 0x0081}, {0x8903, 0x0007}, {0x8904, 0x002c}, -{0x8905, 0x0005}, {0x8906, 0x007c}, {0x8907, 0x0000}, -{0x8908, 0x0083}, {0x8909, 0x0020}, {0x890a, 0x0006}, -{0x890b, 0x0096}, {0x890c, 0x0083}, {0x890d, 0x008b}, -{0x890e, 0x0008}, {0x890f, 0x0097}, {0x8910, 0x0083}, -{0x8911, 0x007e}, {0x8912, 0x0085}, {0x8913, 0x0041}, -{0x8914, 0x007f}, {0x8915, 0x008f}, {0x8916, 0x007e}, -{0x8917, 0x0086}, {0x8918, 0x0080}, {0x8919, 0x00b7}, -{0x891a, 0x0012}, {0x891b, 0x000c}, {0x891c, 0x0086}, -{0x891d, 0x0001}, {0x891e, 0x00b7}, {0x891f, 0x008f}, -{0x8920, 0x007d}, {0x8921, 0x00b6}, {0x8922, 0x0012}, -{0x8923, 0x000c}, {0x8924, 0x0084}, {0x8925, 0x007f}, -{0x8926, 0x00b7}, {0x8927, 0x0012}, {0x8928, 0x000c}, -{0x8929, 0x008a}, {0x892a, 0x0080}, {0x892b, 0x00b7}, -{0x892c, 0x0012}, {0x892d, 0x000c}, {0x892e, 0x0086}, -{0x892f, 0x000a}, {0x8930, 0x00bd}, {0x8931, 0x008a}, -{0x8932, 0x0006}, {0x8933, 0x00b6}, {0x8934, 0x0012}, -{0x8935, 0x000a}, {0x8936, 0x002a}, {0x8937, 0x0009}, -{0x8938, 0x00b6}, {0x8939, 0x0012}, {0x893a, 0x000c}, -{0x893b, 0x00ba}, {0x893c, 0x008f}, {0x893d, 0x007d}, -{0x893e, 0x00b7}, {0x893f, 0x0012}, {0x8940, 0x000c}, -{0x8941, 0x00b6}, {0x8942, 0x008f}, {0x8943, 0x007e}, -{0x8944, 0x0081}, {0x8945, 0x0060}, {0x8946, 0x0027}, -{0x8947, 0x001a}, {0x8948, 0x008b}, {0x8949, 0x0020}, -{0x894a, 0x00b7}, {0x894b, 0x008f}, {0x894c, 0x007e}, -{0x894d, 0x00b6}, {0x894e, 0x0012}, {0x894f, 0x000c}, -{0x8950, 0x0084}, {0x8951, 0x009f}, {0x8952, 0x00ba}, -{0x8953, 0x008f}, {0x8954, 0x007e}, {0x8955, 0x00b7}, -{0x8956, 0x0012}, {0x8957, 0x000c}, {0x8958, 0x00b6}, -{0x8959, 0x008f}, {0x895a, 0x007d}, {0x895b, 0x0048}, -{0x895c, 0x00b7}, {0x895d, 0x008f}, {0x895e, 0x007d}, -{0x895f, 0x007e}, {0x8960, 0x0089}, {0x8961, 0x0021}, -{0x8962, 0x00b6}, {0x8963, 0x0012}, {0x8964, 0x0004}, -{0x8965, 0x008a}, {0x8966, 0x0020}, {0x8967, 0x00b7}, -{0x8968, 0x0012}, {0x8969, 0x0004}, {0x896a, 0x00bd}, -{0x896b, 0x008a}, {0x896c, 0x000a}, {0x896d, 0x004f}, -{0x896e, 0x0039}, {0x896f, 0x00a6}, {0x8970, 0x0000}, -{0x8971, 0x0018}, {0x8972, 0x00a7}, {0x8973, 0x0000}, -{0x8974, 0x0008}, {0x8975, 0x0018}, {0x8976, 0x0008}, -{0x8977, 0x005a}, {0x8978, 0x0026}, {0x8979, 0x00f5}, -{0x897a, 0x0039}, {0x897b, 0x0036}, {0x897c, 0x006c}, -{0x897d, 0x0000}, {0x897e, 0x0032}, {0x897f, 0x00ba}, -{0x8980, 0x008f}, {0x8981, 0x007f}, {0x8982, 0x00b7}, -{0x8983, 0x008f}, {0x8984, 0x007f}, {0x8985, 0x00b6}, -{0x8986, 0x0012}, {0x8987, 0x0009}, {0x8988, 0x0084}, -{0x8989, 0x0003}, {0x898a, 0x00a7}, {0x898b, 0x0001}, -{0x898c, 0x00b6}, {0x898d, 0x0012}, {0x898e, 0x0006}, -{0x898f, 0x0084}, {0x8990, 0x003f}, {0x8991, 0x00a7}, -{0x8992, 0x0002}, {0x8993, 0x0039}, {0x8994, 0x0036}, -{0x8995, 0x0086}, {0x8996, 0x0003}, {0x8997, 0x00b7}, -{0x8998, 0x008f}, {0x8999, 0x0080}, {0x899a, 0x0032}, -{0x899b, 0x00c1}, {0x899c, 0x0000}, {0x899d, 0x0026}, -{0x899e, 0x0006}, {0x899f, 0x00b7}, {0x89a0, 0x008f}, -{0x89a1, 0x007c}, {0x89a2, 0x007e}, {0x89a3, 0x0089}, -{0x89a4, 0x00c9}, {0x89a5, 0x00c1}, {0x89a6, 0x0001}, -{0x89a7, 0x0027}, {0x89a8, 0x0018}, {0x89a9, 0x00c1}, -{0x89aa, 0x0002}, {0x89ab, 0x0027}, {0x89ac, 0x000c}, -{0x89ad, 0x00c1}, {0x89ae, 0x0003}, {0x89af, 0x0027}, -{0x89b0, 0x0000}, {0x89b1, 0x00f6}, {0x89b2, 0x008f}, -{0x89b3, 0x0080}, {0x89b4, 0x0005}, {0x89b5, 0x0005}, -{0x89b6, 0x00f7}, {0x89b7, 0x008f}, {0x89b8, 0x0080}, -{0x89b9, 0x00f6}, {0x89ba, 0x008f}, {0x89bb, 0x0080}, -{0x89bc, 0x0005}, {0x89bd, 0x0005}, {0x89be, 0x00f7}, -{0x89bf, 0x008f}, {0x89c0, 0x0080}, {0x89c1, 0x00f6}, -{0x89c2, 0x008f}, {0x89c3, 0x0080}, {0x89c4, 0x0005}, -{0x89c5, 0x0005}, {0x89c6, 0x00f7}, {0x89c7, 0x008f}, -{0x89c8, 0x0080}, {0x89c9, 0x00f6}, {0x89ca, 0x008f}, -{0x89cb, 0x0080}, {0x89cc, 0x0053}, {0x89cd, 0x00f4}, -{0x89ce, 0x0012}, {0x89cf, 0x0007}, {0x89d0, 0x001b}, -{0x89d1, 0x00b7}, {0x89d2, 0x0012}, {0x89d3, 0x0007}, -{0x89d4, 0x0039}, {0x89d5, 0x00ce}, {0x89d6, 0x008f}, -{0x89d7, 0x0070}, {0x89d8, 0x00a6}, {0x89d9, 0x0000}, -{0x89da, 0x0018}, {0x89db, 0x00e6}, {0x89dc, 0x0000}, -{0x89dd, 0x0018}, {0x89de, 0x00a7}, {0x89df, 0x0000}, -{0x89e0, 0x00e7}, {0x89e1, 0x0000}, {0x89e2, 0x00a6}, -{0x89e3, 0x0001}, {0x89e4, 0x0018}, {0x89e5, 0x00e6}, -{0x89e6, 0x0001}, {0x89e7, 0x0018}, {0x89e8, 0x00a7}, -{0x89e9, 0x0001}, {0x89ea, 0x00e7}, {0x89eb, 0x0001}, -{0x89ec, 0x00a6}, {0x89ed, 0x0002}, {0x89ee, 0x0018}, -{0x89ef, 0x00e6}, {0x89f0, 0x0002}, {0x89f1, 0x0018}, -{0x89f2, 0x00a7}, {0x89f3, 0x0002}, {0x89f4, 0x00e7}, -{0x89f5, 0x0002}, {0x89f6, 0x0039}, {0x89f7, 0x00a6}, -{0x89f8, 0x0000}, {0x89f9, 0x0084}, {0x89fa, 0x0007}, -{0x89fb, 0x00e6}, {0x89fc, 0x0000}, {0x89fd, 0x00c4}, -{0x89fe, 0x0038}, {0x89ff, 0x0054}, {0x8a00, 0x0054}, -{0x8a01, 0x0054}, {0x8a02, 0x001b}, {0x8a03, 0x00a7}, -{0x8a04, 0x0000}, {0x8a05, 0x0039}, {0x8a06, 0x004a}, -{0x8a07, 0x0026}, {0x8a08, 0x00fd}, {0x8a09, 0x0039}, -{0x8a0a, 0x0096}, {0x8a0b, 0x0022}, {0x8a0c, 0x0084}, -{0x8a0d, 0x000f}, {0x8a0e, 0x0097}, {0x8a0f, 0x0022}, -{0x8a10, 0x0086}, {0x8a11, 0x0001}, {0x8a12, 0x00b7}, -{0x8a13, 0x008f}, {0x8a14, 0x0070}, {0x8a15, 0x00b6}, -{0x8a16, 0x0012}, {0x8a17, 0x0007}, {0x8a18, 0x00b7}, -{0x8a19, 0x008f}, {0x8a1a, 0x0071}, {0x8a1b, 0x00f6}, -{0x8a1c, 0x0012}, {0x8a1d, 0x000c}, {0x8a1e, 0x00c4}, -{0x8a1f, 0x000f}, {0x8a20, 0x00c8}, {0x8a21, 0x000f}, -{0x8a22, 0x00f7}, {0x8a23, 0x008f}, {0x8a24, 0x0072}, -{0x8a25, 0x00f6}, {0x8a26, 0x008f}, {0x8a27, 0x0072}, -{0x8a28, 0x00b6}, {0x8a29, 0x008f}, {0x8a2a, 0x0071}, -{0x8a2b, 0x0084}, {0x8a2c, 0x0003}, {0x8a2d, 0x0027}, -{0x8a2e, 0x0014}, {0x8a2f, 0x0081}, {0x8a30, 0x0001}, -{0x8a31, 0x0027}, {0x8a32, 0x001c}, {0x8a33, 0x0081}, -{0x8a34, 0x0002}, {0x8a35, 0x0027}, {0x8a36, 0x0024}, -{0x8a37, 0x00f4}, {0x8a38, 0x008f}, {0x8a39, 0x0070}, -{0x8a3a, 0x0027}, {0x8a3b, 0x002a}, {0x8a3c, 0x0096}, -{0x8a3d, 0x0022}, {0x8a3e, 0x008a}, {0x8a3f, 0x0080}, -{0x8a40, 0x007e}, {0x8a41, 0x008a}, {0x8a42, 0x0064}, -{0x8a43, 0x00f4}, {0x8a44, 0x008f}, {0x8a45, 0x0070}, -{0x8a46, 0x0027}, {0x8a47, 0x001e}, {0x8a48, 0x0096}, -{0x8a49, 0x0022}, {0x8a4a, 0x008a}, {0x8a4b, 0x0010}, -{0x8a4c, 0x007e}, {0x8a4d, 0x008a}, {0x8a4e, 0x0064}, -{0x8a4f, 0x00f4}, {0x8a50, 0x008f}, {0x8a51, 0x0070}, -{0x8a52, 0x0027}, {0x8a53, 0x0012}, {0x8a54, 0x0096}, -{0x8a55, 0x0022}, {0x8a56, 0x008a}, {0x8a57, 0x0020}, -{0x8a58, 0x007e}, {0x8a59, 0x008a}, {0x8a5a, 0x0064}, -{0x8a5b, 0x00f4}, {0x8a5c, 0x008f}, {0x8a5d, 0x0070}, -{0x8a5e, 0x0027}, {0x8a5f, 0x0006}, {0x8a60, 0x0096}, -{0x8a61, 0x0022}, {0x8a62, 0x008a}, {0x8a63, 0x0040}, -{0x8a64, 0x0097}, {0x8a65, 0x0022}, {0x8a66, 0x0074}, -{0x8a67, 0x008f}, {0x8a68, 0x0071}, {0x8a69, 0x0074}, -{0x8a6a, 0x008f}, {0x8a6b, 0x0071}, {0x8a6c, 0x0078}, -{0x8a6d, 0x008f}, {0x8a6e, 0x0070}, {0x8a6f, 0x00b6}, -{0x8a70, 0x008f}, {0x8a71, 0x0070}, {0x8a72, 0x0085}, -{0x8a73, 0x0010}, {0x8a74, 0x0027}, {0x8a75, 0x00af}, -{0x8a76, 0x00d6}, {0x8a77, 0x0022}, {0x8a78, 0x00c4}, -{0x8a79, 0x0010}, {0x8a7a, 0x0058}, {0x8a7b, 0x00b6}, -{0x8a7c, 0x0012}, {0x8a7d, 0x0070}, {0x8a7e, 0x0081}, -{0x8a7f, 0x00e4}, {0x8a80, 0x0027}, {0x8a81, 0x0036}, -{0x8a82, 0x0081}, {0x8a83, 0x00e1}, {0x8a84, 0x0026}, -{0x8a85, 0x000c}, {0x8a86, 0x0096}, {0x8a87, 0x0022}, -{0x8a88, 0x0084}, {0x8a89, 0x0020}, {0x8a8a, 0x0044}, -{0x8a8b, 0x001b}, {0x8a8c, 0x00d6}, {0x8a8d, 0x0022}, -{0x8a8e, 0x00c4}, {0x8a8f, 0x00cf}, {0x8a90, 0x0020}, -{0x8a91, 0x0023}, {0x8a92, 0x0058}, {0x8a93, 0x0081}, -{0x8a94, 0x00c6}, {0x8a95, 0x0026}, {0x8a96, 0x000d}, -{0x8a97, 0x0096}, {0x8a98, 0x0022}, {0x8a99, 0x0084}, -{0x8a9a, 0x0040}, {0x8a9b, 0x0044}, {0x8a9c, 0x0044}, -{0x8a9d, 0x001b}, {0x8a9e, 0x00d6}, {0x8a9f, 0x0022}, -{0x8aa0, 0x00c4}, {0x8aa1, 0x00af}, {0x8aa2, 0x0020}, -{0x8aa3, 0x0011}, {0x8aa4, 0x0058}, {0x8aa5, 0x0081}, -{0x8aa6, 0x0027}, {0x8aa7, 0x0026}, {0x8aa8, 0x000f}, -{0x8aa9, 0x0096}, {0x8aaa, 0x0022}, {0x8aab, 0x0084}, -{0x8aac, 0x0080}, {0x8aad, 0x0044}, {0x8aae, 0x0044}, -{0x8aaf, 0x0044}, {0x8ab0, 0x001b}, {0x8ab1, 0x00d6}, -{0x8ab2, 0x0022}, {0x8ab3, 0x00c4}, {0x8ab4, 0x006f}, -{0x8ab5, 0x001b}, {0x8ab6, 0x0097}, {0x8ab7, 0x0022}, -{0x8ab8, 0x0039}, {0x8ab9, 0x0027}, {0x8aba, 0x000c}, -{0x8abb, 0x007c}, {0x8abc, 0x0082}, {0x8abd, 0x0006}, -{0x8abe, 0x00bd}, {0x8abf, 0x00d9}, {0x8ac0, 0x00ed}, -{0x8ac1, 0x00b6}, {0x8ac2, 0x0082}, {0x8ac3, 0x0007}, -{0x8ac4, 0x007e}, {0x8ac5, 0x008a}, {0x8ac6, 0x00b9}, -{0x8ac7, 0x007f}, {0x8ac8, 0x0082}, {0x8ac9, 0x0006}, -{0x8aca, 0x0039}, { 0x0, 0x0 } -}; -#else -cas_saturn_patch_t cas_saturn_patch[] = { -{0x8200, 0x007e}, {0x8201, 0x0082}, {0x8202, 0x0009}, -{0x8203, 0x0000}, {0x8204, 0x0000}, {0x8205, 0x0000}, -{0x8206, 0x0000}, {0x8207, 0x0000}, {0x8208, 0x0000}, -{0x8209, 0x008e}, {0x820a, 0x008e}, {0x820b, 0x00ff}, -{0x820c, 0x00ce}, {0x820d, 0x0082}, {0x820e, 0x0025}, -{0x820f, 0x00ff}, {0x8210, 0x0001}, {0x8211, 0x000f}, -{0x8212, 0x00ce}, {0x8213, 0x0084}, {0x8214, 0x0026}, -{0x8215, 0x00ff}, {0x8216, 0x0001}, {0x8217, 0x0011}, -{0x8218, 0x00ce}, {0x8219, 0x0085}, {0x821a, 0x003d}, -{0x821b, 0x00df}, {0x821c, 0x00e5}, {0x821d, 0x0086}, -{0x821e, 0x0039}, {0x821f, 0x00b7}, {0x8220, 0x008f}, -{0x8221, 0x00f8}, {0x8222, 0x007e}, {0x8223, 0x00c3}, -{0x8224, 0x00c2}, {0x8225, 0x0096}, {0x8226, 0x0047}, -{0x8227, 0x0084}, {0x8228, 0x00f3}, {0x8229, 0x008a}, -{0x822a, 0x0000}, {0x822b, 0x0097}, {0x822c, 0x0047}, -{0x822d, 0x00ce}, {0x822e, 0x0082}, {0x822f, 0x0033}, -{0x8230, 0x00ff}, {0x8231, 0x0001}, {0x8232, 0x000f}, -{0x8233, 0x0096}, {0x8234, 0x0046}, {0x8235, 0x0084}, -{0x8236, 0x000c}, {0x8237, 0x0081}, {0x8238, 0x0004}, -{0x8239, 0x0027}, {0x823a, 0x000b}, {0x823b, 0x0096}, -{0x823c, 0x0046}, {0x823d, 0x0084}, {0x823e, 0x000c}, -{0x823f, 0x0081}, {0x8240, 0x0008}, {0x8241, 0x0027}, -{0x8242, 0x0057}, {0x8243, 0x007e}, {0x8244, 0x0084}, -{0x8245, 0x0025}, {0x8246, 0x0096}, {0x8247, 0x0047}, -{0x8248, 0x0084}, {0x8249, 0x00f3}, {0x824a, 0x008a}, -{0x824b, 0x0004}, {0x824c, 0x0097}, {0x824d, 0x0047}, -{0x824e, 0x00ce}, {0x824f, 0x0082}, {0x8250, 0x0054}, -{0x8251, 0x00ff}, {0x8252, 0x0001}, {0x8253, 0x000f}, -{0x8254, 0x0096}, {0x8255, 0x0046}, {0x8256, 0x0084}, -{0x8257, 0x000c}, {0x8258, 0x0081}, {0x8259, 0x0004}, -{0x825a, 0x0026}, {0x825b, 0x0038}, {0x825c, 0x00b6}, -{0x825d, 0x0012}, {0x825e, 0x0020}, {0x825f, 0x0084}, -{0x8260, 0x0020}, {0x8261, 0x0026}, {0x8262, 0x0003}, -{0x8263, 0x007e}, {0x8264, 0x0084}, {0x8265, 0x0025}, -{0x8266, 0x0096}, {0x8267, 0x007b}, {0x8268, 0x00d6}, -{0x8269, 0x007c}, {0x826a, 0x00fe}, {0x826b, 0x008f}, -{0x826c, 0x0056}, {0x826d, 0x00bd}, {0x826e, 0x00f7}, -{0x826f, 0x00b6}, {0x8270, 0x00fe}, {0x8271, 0x008f}, -{0x8272, 0x004e}, {0x8273, 0x00bd}, {0x8274, 0x00ec}, -{0x8275, 0x008e}, {0x8276, 0x00bd}, {0x8277, 0x00fa}, -{0x8278, 0x00f7}, {0x8279, 0x00bd}, {0x827a, 0x00f7}, -{0x827b, 0x0028}, {0x827c, 0x00ce}, {0x827d, 0x0082}, -{0x827e, 0x0082}, {0x827f, 0x00ff}, {0x8280, 0x0001}, -{0x8281, 0x000f}, {0x8282, 0x0096}, {0x8283, 0x0046}, -{0x8284, 0x0084}, {0x8285, 0x000c}, {0x8286, 0x0081}, -{0x8287, 0x0004}, {0x8288, 0x0026}, {0x8289, 0x000a}, -{0x828a, 0x00b6}, {0x828b, 0x0012}, {0x828c, 0x0020}, -{0x828d, 0x0084}, {0x828e, 0x0020}, {0x828f, 0x0027}, -{0x8290, 0x00b5}, {0x8291, 0x007e}, {0x8292, 0x0084}, -{0x8293, 0x0025}, {0x8294, 0x00bd}, {0x8295, 0x00f7}, -{0x8296, 0x001f}, {0x8297, 0x007e}, {0x8298, 0x0084}, -{0x8299, 0x001f}, {0x829a, 0x0096}, {0x829b, 0x0047}, -{0x829c, 0x0084}, {0x829d, 0x00f3}, {0x829e, 0x008a}, -{0x829f, 0x0008}, {0x82a0, 0x0097}, {0x82a1, 0x0047}, -{0x82a2, 0x00de}, {0x82a3, 0x00e1}, {0x82a4, 0x00ad}, -{0x82a5, 0x0000}, {0x82a6, 0x00ce}, {0x82a7, 0x0082}, -{0x82a8, 0x00af}, {0x82a9, 0x00ff}, {0x82aa, 0x0001}, -{0x82ab, 0x000f}, {0x82ac, 0x007e}, {0x82ad, 0x0084}, -{0x82ae, 0x0025}, {0x82af, 0x0096}, {0x82b0, 0x0041}, -{0x82b1, 0x0085}, {0x82b2, 0x0010}, {0x82b3, 0x0026}, -{0x82b4, 0x0006}, {0x82b5, 0x0096}, {0x82b6, 0x0023}, -{0x82b7, 0x0085}, {0x82b8, 0x0040}, {0x82b9, 0x0027}, -{0x82ba, 0x0006}, {0x82bb, 0x00bd}, {0x82bc, 0x00ed}, -{0x82bd, 0x0000}, {0x82be, 0x007e}, {0x82bf, 0x0083}, -{0x82c0, 0x00a2}, {0x82c1, 0x00de}, {0x82c2, 0x0042}, -{0x82c3, 0x00bd}, {0x82c4, 0x00eb}, {0x82c5, 0x008e}, -{0x82c6, 0x0096}, {0x82c7, 0x0024}, {0x82c8, 0x0084}, -{0x82c9, 0x0008}, {0x82ca, 0x0027}, {0x82cb, 0x0003}, -{0x82cc, 0x007e}, {0x82cd, 0x0083}, {0x82ce, 0x00df}, -{0x82cf, 0x0096}, {0x82d0, 0x007b}, {0x82d1, 0x00d6}, -{0x82d2, 0x007c}, {0x82d3, 0x00fe}, {0x82d4, 0x008f}, -{0x82d5, 0x0056}, {0x82d6, 0x00bd}, {0x82d7, 0x00f7}, -{0x82d8, 0x00b6}, {0x82d9, 0x00fe}, {0x82da, 0x008f}, -{0x82db, 0x0050}, {0x82dc, 0x00bd}, {0x82dd, 0x00ec}, -{0x82de, 0x008e}, {0x82df, 0x00bd}, {0x82e0, 0x00fa}, -{0x82e1, 0x00f7}, {0x82e2, 0x0086}, {0x82e3, 0x0011}, -{0x82e4, 0x00c6}, {0x82e5, 0x0049}, {0x82e6, 0x00bd}, -{0x82e7, 0x00e4}, {0x82e8, 0x0012}, {0x82e9, 0x00ce}, -{0x82ea, 0x0082}, {0x82eb, 0x00ef}, {0x82ec, 0x00ff}, -{0x82ed, 0x0001}, {0x82ee, 0x000f}, {0x82ef, 0x0096}, -{0x82f0, 0x0046}, {0x82f1, 0x0084}, {0x82f2, 0x000c}, -{0x82f3, 0x0081}, {0x82f4, 0x0000}, {0x82f5, 0x0027}, -{0x82f6, 0x0017}, {0x82f7, 0x00c6}, {0x82f8, 0x0049}, -{0x82f9, 0x00bd}, {0x82fa, 0x00e4}, {0x82fb, 0x0091}, -{0x82fc, 0x0024}, {0x82fd, 0x000d}, {0x82fe, 0x00b6}, -{0x82ff, 0x0012}, {0x8300, 0x0020}, {0x8301, 0x0085}, -{0x8302, 0x0020}, {0x8303, 0x0026}, {0x8304, 0x000c}, -{0x8305, 0x00ce}, {0x8306, 0x0082}, {0x8307, 0x00c1}, -{0x8308, 0x00ff}, {0x8309, 0x0001}, {0x830a, 0x000f}, -{0x830b, 0x007e}, {0x830c, 0x0084}, {0x830d, 0x0025}, -{0x830e, 0x007e}, {0x830f, 0x0084}, {0x8310, 0x0016}, -{0x8311, 0x00fe}, {0x8312, 0x008f}, {0x8313, 0x0052}, -{0x8314, 0x00bd}, {0x8315, 0x00ec}, {0x8316, 0x008e}, -{0x8317, 0x00bd}, {0x8318, 0x00fa}, {0x8319, 0x00f7}, -{0x831a, 0x0086}, {0x831b, 0x006a}, {0x831c, 0x00c6}, -{0x831d, 0x0049}, {0x831e, 0x00bd}, {0x831f, 0x00e4}, -{0x8320, 0x0012}, {0x8321, 0x00ce}, {0x8322, 0x0083}, -{0x8323, 0x0027}, {0x8324, 0x00ff}, {0x8325, 0x0001}, -{0x8326, 0x000f}, {0x8327, 0x0096}, {0x8328, 0x0046}, -{0x8329, 0x0084}, {0x832a, 0x000c}, {0x832b, 0x0081}, -{0x832c, 0x0000}, {0x832d, 0x0027}, {0x832e, 0x000a}, -{0x832f, 0x00c6}, {0x8330, 0x0049}, {0x8331, 0x00bd}, -{0x8332, 0x00e4}, {0x8333, 0x0091}, {0x8334, 0x0025}, -{0x8335, 0x0006}, {0x8336, 0x007e}, {0x8337, 0x0084}, -{0x8338, 0x0025}, {0x8339, 0x007e}, {0x833a, 0x0084}, -{0x833b, 0x0016}, {0x833c, 0x00b6}, {0x833d, 0x0018}, -{0x833e, 0x0070}, {0x833f, 0x00bb}, {0x8340, 0x0019}, -{0x8341, 0x0070}, {0x8342, 0x002a}, {0x8343, 0x0004}, -{0x8344, 0x0081}, {0x8345, 0x00af}, {0x8346, 0x002e}, -{0x8347, 0x0019}, {0x8348, 0x0096}, {0x8349, 0x007b}, -{0x834a, 0x00f6}, {0x834b, 0x0020}, {0x834c, 0x0007}, -{0x834d, 0x00fa}, {0x834e, 0x0020}, {0x834f, 0x0027}, -{0x8350, 0x00c4}, {0x8351, 0x0038}, {0x8352, 0x0081}, -{0x8353, 0x0038}, {0x8354, 0x0027}, {0x8355, 0x000b}, -{0x8356, 0x00f6}, {0x8357, 0x0020}, {0x8358, 0x0007}, -{0x8359, 0x00fa}, {0x835a, 0x0020}, {0x835b, 0x0027}, -{0x835c, 0x00cb}, {0x835d, 0x0008}, {0x835e, 0x007e}, -{0x835f, 0x0082}, {0x8360, 0x00d3}, {0x8361, 0x00bd}, -{0x8362, 0x00f7}, {0x8363, 0x0066}, {0x8364, 0x0086}, -{0x8365, 0x0074}, {0x8366, 0x00c6}, {0x8367, 0x0049}, -{0x8368, 0x00bd}, {0x8369, 0x00e4}, {0x836a, 0x0012}, -{0x836b, 0x00ce}, {0x836c, 0x0083}, {0x836d, 0x0071}, -{0x836e, 0x00ff}, {0x836f, 0x0001}, {0x8370, 0x000f}, -{0x8371, 0x0096}, {0x8372, 0x0046}, {0x8373, 0x0084}, -{0x8374, 0x000c}, {0x8375, 0x0081}, {0x8376, 0x0008}, -{0x8377, 0x0026}, {0x8378, 0x000a}, {0x8379, 0x00c6}, -{0x837a, 0x0049}, {0x837b, 0x00bd}, {0x837c, 0x00e4}, -{0x837d, 0x0091}, {0x837e, 0x0025}, {0x837f, 0x0006}, -{0x8380, 0x007e}, {0x8381, 0x0084}, {0x8382, 0x0025}, -{0x8383, 0x007e}, {0x8384, 0x0084}, {0x8385, 0x0016}, -{0x8386, 0x00bd}, {0x8387, 0x00f7}, {0x8388, 0x003e}, -{0x8389, 0x0026}, {0x838a, 0x000e}, {0x838b, 0x00bd}, -{0x838c, 0x00e5}, {0x838d, 0x0009}, {0x838e, 0x0026}, -{0x838f, 0x0006}, {0x8390, 0x00ce}, {0x8391, 0x0082}, -{0x8392, 0x00c1}, {0x8393, 0x00ff}, {0x8394, 0x0001}, -{0x8395, 0x000f}, {0x8396, 0x007e}, {0x8397, 0x0084}, -{0x8398, 0x0025}, {0x8399, 0x00fe}, {0x839a, 0x008f}, -{0x839b, 0x0054}, {0x839c, 0x00bd}, {0x839d, 0x00ec}, -{0x839e, 0x008e}, {0x839f, 0x00bd}, {0x83a0, 0x00fa}, -{0x83a1, 0x00f7}, {0x83a2, 0x00bd}, {0x83a3, 0x00f7}, -{0x83a4, 0x0033}, {0x83a5, 0x0086}, {0x83a6, 0x000f}, -{0x83a7, 0x00c6}, {0x83a8, 0x0051}, {0x83a9, 0x00bd}, -{0x83aa, 0x00e4}, {0x83ab, 0x0012}, {0x83ac, 0x00ce}, -{0x83ad, 0x0083}, {0x83ae, 0x00b2}, {0x83af, 0x00ff}, -{0x83b0, 0x0001}, {0x83b1, 0x000f}, {0x83b2, 0x0096}, -{0x83b3, 0x0046}, {0x83b4, 0x0084}, {0x83b5, 0x000c}, -{0x83b6, 0x0081}, {0x83b7, 0x0008}, {0x83b8, 0x0026}, -{0x83b9, 0x005c}, {0x83ba, 0x00b6}, {0x83bb, 0x0012}, -{0x83bc, 0x0020}, {0x83bd, 0x0084}, {0x83be, 0x003f}, -{0x83bf, 0x0081}, {0x83c0, 0x003a}, {0x83c1, 0x0027}, -{0x83c2, 0x001c}, {0x83c3, 0x0096}, {0x83c4, 0x0023}, -{0x83c5, 0x0085}, {0x83c6, 0x0040}, {0x83c7, 0x0027}, -{0x83c8, 0x0003}, {0x83c9, 0x007e}, {0x83ca, 0x0084}, -{0x83cb, 0x0025}, {0x83cc, 0x00c6}, {0x83cd, 0x0051}, -{0x83ce, 0x00bd}, {0x83cf, 0x00e4}, {0x83d0, 0x0091}, -{0x83d1, 0x0025}, {0x83d2, 0x0003}, {0x83d3, 0x007e}, -{0x83d4, 0x0084}, {0x83d5, 0x0025}, {0x83d6, 0x00ce}, -{0x83d7, 0x0082}, {0x83d8, 0x00c1}, {0x83d9, 0x00ff}, -{0x83da, 0x0001}, {0x83db, 0x000f}, {0x83dc, 0x007e}, -{0x83dd, 0x0084}, {0x83de, 0x0025}, {0x83df, 0x00bd}, -{0x83e0, 0x00f8}, {0x83e1, 0x0037}, {0x83e2, 0x007c}, -{0x83e3, 0x0000}, {0x83e4, 0x007a}, {0x83e5, 0x00ce}, -{0x83e6, 0x0083}, {0x83e7, 0x00ee}, {0x83e8, 0x00ff}, -{0x83e9, 0x0001}, {0x83ea, 0x000f}, {0x83eb, 0x007e}, -{0x83ec, 0x0084}, {0x83ed, 0x0025}, {0x83ee, 0x0096}, -{0x83ef, 0x0046}, {0x83f0, 0x0084}, {0x83f1, 0x000c}, -{0x83f2, 0x0081}, {0x83f3, 0x0008}, {0x83f4, 0x0026}, -{0x83f5, 0x0020}, {0x83f6, 0x0096}, {0x83f7, 0x0024}, -{0x83f8, 0x0084}, {0x83f9, 0x0008}, {0x83fa, 0x0026}, -{0x83fb, 0x0029}, {0x83fc, 0x00b6}, {0x83fd, 0x0018}, -{0x83fe, 0x0082}, {0x83ff, 0x00bb}, {0x8400, 0x0019}, -{0x8401, 0x0082}, {0x8402, 0x00b1}, {0x8403, 0x0001}, -{0x8404, 0x003b}, {0x8405, 0x0022}, {0x8406, 0x0009}, -{0x8407, 0x00b6}, {0x8408, 0x0012}, {0x8409, 0x0020}, -{0x840a, 0x0084}, {0x840b, 0x0037}, {0x840c, 0x0081}, -{0x840d, 0x0032}, {0x840e, 0x0027}, {0x840f, 0x0015}, -{0x8410, 0x00bd}, {0x8411, 0x00f8}, {0x8412, 0x0044}, -{0x8413, 0x007e}, {0x8414, 0x0082}, {0x8415, 0x00c1}, -{0x8416, 0x00bd}, {0x8417, 0x00f7}, {0x8418, 0x001f}, -{0x8419, 0x00bd}, {0x841a, 0x00f8}, {0x841b, 0x0044}, -{0x841c, 0x00bd}, {0x841d, 0x00fc}, {0x841e, 0x0029}, -{0x841f, 0x00ce}, {0x8420, 0x0082}, {0x8421, 0x0025}, -{0x8422, 0x00ff}, {0x8423, 0x0001}, {0x8424, 0x000f}, -{0x8425, 0x0039}, {0x8426, 0x0096}, {0x8427, 0x0047}, -{0x8428, 0x0084}, {0x8429, 0x00fc}, {0x842a, 0x008a}, -{0x842b, 0x0000}, {0x842c, 0x0097}, {0x842d, 0x0047}, -{0x842e, 0x00ce}, {0x842f, 0x0084}, {0x8430, 0x0034}, -{0x8431, 0x00ff}, {0x8432, 0x0001}, {0x8433, 0x0011}, -{0x8434, 0x0096}, {0x8435, 0x0046}, {0x8436, 0x0084}, -{0x8437, 0x0003}, {0x8438, 0x0081}, {0x8439, 0x0002}, -{0x843a, 0x0027}, {0x843b, 0x0003}, {0x843c, 0x007e}, -{0x843d, 0x0085}, {0x843e, 0x001e}, {0x843f, 0x0096}, -{0x8440, 0x0047}, {0x8441, 0x0084}, {0x8442, 0x00fc}, -{0x8443, 0x008a}, {0x8444, 0x0002}, {0x8445, 0x0097}, -{0x8446, 0x0047}, {0x8447, 0x00de}, {0x8448, 0x00e1}, -{0x8449, 0x00ad}, {0x844a, 0x0000}, {0x844b, 0x0086}, -{0x844c, 0x0001}, {0x844d, 0x00b7}, {0x844e, 0x0012}, -{0x844f, 0x0051}, {0x8450, 0x00bd}, {0x8451, 0x00f7}, -{0x8452, 0x0014}, {0x8453, 0x00b6}, {0x8454, 0x0010}, -{0x8455, 0x0031}, {0x8456, 0x0084}, {0x8457, 0x00fd}, -{0x8458, 0x00b7}, {0x8459, 0x0010}, {0x845a, 0x0031}, -{0x845b, 0x00bd}, {0x845c, 0x00f8}, {0x845d, 0x001e}, -{0x845e, 0x0096}, {0x845f, 0x0081}, {0x8460, 0x00d6}, -{0x8461, 0x0082}, {0x8462, 0x00fe}, {0x8463, 0x008f}, -{0x8464, 0x005a}, {0x8465, 0x00bd}, {0x8466, 0x00f7}, -{0x8467, 0x00b6}, {0x8468, 0x00fe}, {0x8469, 0x008f}, -{0x846a, 0x005c}, {0x846b, 0x00bd}, {0x846c, 0x00ec}, -{0x846d, 0x008e}, {0x846e, 0x00bd}, {0x846f, 0x00fa}, -{0x8470, 0x00f7}, {0x8471, 0x0086}, {0x8472, 0x0008}, -{0x8473, 0x00d6}, {0x8474, 0x0000}, {0x8475, 0x00c5}, -{0x8476, 0x0010}, {0x8477, 0x0026}, {0x8478, 0x0002}, -{0x8479, 0x008b}, {0x847a, 0x0020}, {0x847b, 0x00c6}, -{0x847c, 0x0051}, {0x847d, 0x00bd}, {0x847e, 0x00e4}, -{0x847f, 0x0012}, {0x8480, 0x00ce}, {0x8481, 0x0084}, -{0x8482, 0x0086}, {0x8483, 0x00ff}, {0x8484, 0x0001}, -{0x8485, 0x0011}, {0x8486, 0x0096}, {0x8487, 0x0046}, -{0x8488, 0x0084}, {0x8489, 0x0003}, {0x848a, 0x0081}, -{0x848b, 0x0002}, {0x848c, 0x0027}, {0x848d, 0x0003}, -{0x848e, 0x007e}, {0x848f, 0x0085}, {0x8490, 0x000f}, -{0x8491, 0x00c6}, {0x8492, 0x0051}, {0x8493, 0x00bd}, -{0x8494, 0x00e4}, {0x8495, 0x0091}, {0x8496, 0x0025}, -{0x8497, 0x0003}, {0x8498, 0x007e}, {0x8499, 0x0085}, -{0x849a, 0x001e}, {0x849b, 0x0096}, {0x849c, 0x0044}, -{0x849d, 0x0085}, {0x849e, 0x0010}, {0x849f, 0x0026}, -{0x84a0, 0x000a}, {0x84a1, 0x00b6}, {0x84a2, 0x0012}, -{0x84a3, 0x0050}, {0x84a4, 0x00ba}, {0x84a5, 0x0001}, -{0x84a6, 0x003c}, {0x84a7, 0x0085}, {0x84a8, 0x0010}, -{0x84a9, 0x0027}, {0x84aa, 0x00a8}, {0x84ab, 0x00bd}, -{0x84ac, 0x00f7}, {0x84ad, 0x0066}, {0x84ae, 0x00ce}, -{0x84af, 0x0084}, {0x84b0, 0x00b7}, {0x84b1, 0x00ff}, -{0x84b2, 0x0001}, {0x84b3, 0x0011}, {0x84b4, 0x007e}, -{0x84b5, 0x0085}, {0x84b6, 0x001e}, {0x84b7, 0x0096}, -{0x84b8, 0x0046}, {0x84b9, 0x0084}, {0x84ba, 0x0003}, -{0x84bb, 0x0081}, {0x84bc, 0x0002}, {0x84bd, 0x0026}, -{0x84be, 0x0050}, {0x84bf, 0x00b6}, {0x84c0, 0x0012}, -{0x84c1, 0x0030}, {0x84c2, 0x0084}, {0x84c3, 0x0003}, -{0x84c4, 0x0081}, {0x84c5, 0x0001}, {0x84c6, 0x0027}, -{0x84c7, 0x0003}, {0x84c8, 0x007e}, {0x84c9, 0x0085}, -{0x84ca, 0x001e}, {0x84cb, 0x0096}, {0x84cc, 0x0044}, -{0x84cd, 0x0085}, {0x84ce, 0x0010}, {0x84cf, 0x0026}, -{0x84d0, 0x0013}, {0x84d1, 0x00b6}, {0x84d2, 0x0012}, -{0x84d3, 0x0050}, {0x84d4, 0x00ba}, {0x84d5, 0x0001}, -{0x84d6, 0x003c}, {0x84d7, 0x0085}, {0x84d8, 0x0010}, -{0x84d9, 0x0026}, {0x84da, 0x0009}, {0x84db, 0x00ce}, -{0x84dc, 0x0084}, {0x84dd, 0x0053}, {0x84de, 0x00ff}, -{0x84df, 0x0001}, {0x84e0, 0x0011}, {0x84e1, 0x007e}, -{0x84e2, 0x0085}, {0x84e3, 0x001e}, {0x84e4, 0x00b6}, -{0x84e5, 0x0010}, {0x84e6, 0x0031}, {0x84e7, 0x008a}, -{0x84e8, 0x0002}, {0x84e9, 0x00b7}, {0x84ea, 0x0010}, -{0x84eb, 0x0031}, {0x84ec, 0x00bd}, {0x84ed, 0x0085}, -{0x84ee, 0x001f}, {0x84ef, 0x00bd}, {0x84f0, 0x00f8}, -{0x84f1, 0x0037}, {0x84f2, 0x007c}, {0x84f3, 0x0000}, -{0x84f4, 0x0080}, {0x84f5, 0x00ce}, {0x84f6, 0x0084}, -{0x84f7, 0x00fe}, {0x84f8, 0x00ff}, {0x84f9, 0x0001}, -{0x84fa, 0x0011}, {0x84fb, 0x007e}, {0x84fc, 0x0085}, -{0x84fd, 0x001e}, {0x84fe, 0x0096}, {0x84ff, 0x0046}, -{0x8500, 0x0084}, {0x8501, 0x0003}, {0x8502, 0x0081}, -{0x8503, 0x0002}, {0x8504, 0x0026}, {0x8505, 0x0009}, -{0x8506, 0x00b6}, {0x8507, 0x0012}, {0x8508, 0x0030}, -{0x8509, 0x0084}, {0x850a, 0x0003}, {0x850b, 0x0081}, -{0x850c, 0x0001}, {0x850d, 0x0027}, {0x850e, 0x000f}, -{0x850f, 0x00bd}, {0x8510, 0x00f8}, {0x8511, 0x0044}, -{0x8512, 0x00bd}, {0x8513, 0x00f7}, {0x8514, 0x000b}, -{0x8515, 0x00bd}, {0x8516, 0x00fc}, {0x8517, 0x0029}, -{0x8518, 0x00ce}, {0x8519, 0x0084}, {0x851a, 0x0026}, -{0x851b, 0x00ff}, {0x851c, 0x0001}, {0x851d, 0x0011}, -{0x851e, 0x0039}, {0x851f, 0x00d6}, {0x8520, 0x0022}, -{0x8521, 0x00c4}, {0x8522, 0x000f}, {0x8523, 0x00b6}, -{0x8524, 0x0012}, {0x8525, 0x0030}, {0x8526, 0x00ba}, -{0x8527, 0x0012}, {0x8528, 0x0032}, {0x8529, 0x0084}, -{0x852a, 0x0004}, {0x852b, 0x0027}, {0x852c, 0x000d}, -{0x852d, 0x0096}, {0x852e, 0x0022}, {0x852f, 0x0085}, -{0x8530, 0x0004}, {0x8531, 0x0027}, {0x8532, 0x0005}, -{0x8533, 0x00ca}, {0x8534, 0x0010}, {0x8535, 0x007e}, -{0x8536, 0x0085}, {0x8537, 0x003a}, {0x8538, 0x00ca}, -{0x8539, 0x0020}, {0x853a, 0x00d7}, {0x853b, 0x0022}, -{0x853c, 0x0039}, {0x853d, 0x0086}, {0x853e, 0x0000}, -{0x853f, 0x0097}, {0x8540, 0x0083}, {0x8541, 0x0018}, -{0x8542, 0x00ce}, {0x8543, 0x001c}, {0x8544, 0x0000}, -{0x8545, 0x00bd}, {0x8546, 0x00eb}, {0x8547, 0x0046}, -{0x8548, 0x0096}, {0x8549, 0x0057}, {0x854a, 0x0085}, -{0x854b, 0x0001}, {0x854c, 0x0027}, {0x854d, 0x0002}, -{0x854e, 0x004f}, {0x854f, 0x0039}, {0x8550, 0x0085}, -{0x8551, 0x0002}, {0x8552, 0x0027}, {0x8553, 0x0001}, -{0x8554, 0x0039}, {0x8555, 0x007f}, {0x8556, 0x008f}, -{0x8557, 0x007d}, {0x8558, 0x0086}, {0x8559, 0x0004}, -{0x855a, 0x00b7}, {0x855b, 0x0012}, {0x855c, 0x0004}, -{0x855d, 0x0086}, {0x855e, 0x0008}, {0x855f, 0x00b7}, -{0x8560, 0x0012}, {0x8561, 0x0007}, {0x8562, 0x0086}, -{0x8563, 0x0010}, {0x8564, 0x00b7}, {0x8565, 0x0012}, -{0x8566, 0x000c}, {0x8567, 0x0086}, {0x8568, 0x0007}, -{0x8569, 0x00b7}, {0x856a, 0x0012}, {0x856b, 0x0006}, -{0x856c, 0x00b6}, {0x856d, 0x008f}, {0x856e, 0x007d}, -{0x856f, 0x00b7}, {0x8570, 0x0012}, {0x8571, 0x0070}, -{0x8572, 0x0086}, {0x8573, 0x0001}, {0x8574, 0x00ba}, -{0x8575, 0x0012}, {0x8576, 0x0004}, {0x8577, 0x00b7}, -{0x8578, 0x0012}, {0x8579, 0x0004}, {0x857a, 0x0001}, -{0x857b, 0x0001}, {0x857c, 0x0001}, {0x857d, 0x0001}, -{0x857e, 0x0001}, {0x857f, 0x0001}, {0x8580, 0x00b6}, -{0x8581, 0x0012}, {0x8582, 0x0004}, {0x8583, 0x0084}, -{0x8584, 0x00fe}, {0x8585, 0x008a}, {0x8586, 0x0002}, -{0x8587, 0x00b7}, {0x8588, 0x0012}, {0x8589, 0x0004}, -{0x858a, 0x0001}, {0x858b, 0x0001}, {0x858c, 0x0001}, -{0x858d, 0x0001}, {0x858e, 0x0001}, {0x858f, 0x0001}, -{0x8590, 0x0086}, {0x8591, 0x00fd}, {0x8592, 0x00b4}, -{0x8593, 0x0012}, {0x8594, 0x0004}, {0x8595, 0x00b7}, -{0x8596, 0x0012}, {0x8597, 0x0004}, {0x8598, 0x00b6}, -{0x8599, 0x0012}, {0x859a, 0x0000}, {0x859b, 0x0084}, -{0x859c, 0x0008}, {0x859d, 0x0081}, {0x859e, 0x0008}, -{0x859f, 0x0027}, {0x85a0, 0x0016}, {0x85a1, 0x00b6}, -{0x85a2, 0x008f}, {0x85a3, 0x007d}, {0x85a4, 0x0081}, -{0x85a5, 0x000c}, {0x85a6, 0x0027}, {0x85a7, 0x0008}, -{0x85a8, 0x008b}, {0x85a9, 0x0004}, {0x85aa, 0x00b7}, -{0x85ab, 0x008f}, {0x85ac, 0x007d}, {0x85ad, 0x007e}, -{0x85ae, 0x0085}, {0x85af, 0x006c}, {0x85b0, 0x0086}, -{0x85b1, 0x0003}, {0x85b2, 0x0097}, {0x85b3, 0x0040}, -{0x85b4, 0x007e}, {0x85b5, 0x0089}, {0x85b6, 0x006e}, -{0x85b7, 0x0086}, {0x85b8, 0x0007}, {0x85b9, 0x00b7}, -{0x85ba, 0x0012}, {0x85bb, 0x0006}, {0x85bc, 0x005f}, -{0x85bd, 0x00f7}, {0x85be, 0x008f}, {0x85bf, 0x0082}, -{0x85c0, 0x005f}, {0x85c1, 0x00f7}, {0x85c2, 0x008f}, -{0x85c3, 0x007f}, {0x85c4, 0x00f7}, {0x85c5, 0x008f}, -{0x85c6, 0x0070}, {0x85c7, 0x00f7}, {0x85c8, 0x008f}, -{0x85c9, 0x0071}, {0x85ca, 0x00f7}, {0x85cb, 0x008f}, -{0x85cc, 0x0072}, {0x85cd, 0x00f7}, {0x85ce, 0x008f}, -{0x85cf, 0x0073}, {0x85d0, 0x00f7}, {0x85d1, 0x008f}, -{0x85d2, 0x0074}, {0x85d3, 0x00f7}, {0x85d4, 0x008f}, -{0x85d5, 0x0075}, {0x85d6, 0x00f7}, {0x85d7, 0x008f}, -{0x85d8, 0x0076}, {0x85d9, 0x00f7}, {0x85da, 0x008f}, -{0x85db, 0x0077}, {0x85dc, 0x00f7}, {0x85dd, 0x008f}, -{0x85de, 0x0078}, {0x85df, 0x00f7}, {0x85e0, 0x008f}, -{0x85e1, 0x0079}, {0x85e2, 0x00f7}, {0x85e3, 0x008f}, -{0x85e4, 0x007a}, {0x85e5, 0x00f7}, {0x85e6, 0x008f}, -{0x85e7, 0x007b}, {0x85e8, 0x00b6}, {0x85e9, 0x0012}, -{0x85ea, 0x0004}, {0x85eb, 0x008a}, {0x85ec, 0x0010}, -{0x85ed, 0x00b7}, {0x85ee, 0x0012}, {0x85ef, 0x0004}, -{0x85f0, 0x0086}, {0x85f1, 0x00e4}, {0x85f2, 0x00b7}, -{0x85f3, 0x0012}, {0x85f4, 0x0070}, {0x85f5, 0x00b7}, -{0x85f6, 0x0012}, {0x85f7, 0x0007}, {0x85f8, 0x00f7}, -{0x85f9, 0x0012}, {0x85fa, 0x0005}, {0x85fb, 0x00f7}, -{0x85fc, 0x0012}, {0x85fd, 0x0009}, {0x85fe, 0x0086}, -{0x85ff, 0x0008}, {0x8600, 0x00ba}, {0x8601, 0x0012}, -{0x8602, 0x0004}, {0x8603, 0x00b7}, {0x8604, 0x0012}, -{0x8605, 0x0004}, {0x8606, 0x0086}, {0x8607, 0x00f7}, -{0x8608, 0x00b4}, {0x8609, 0x0012}, {0x860a, 0x0004}, -{0x860b, 0x00b7}, {0x860c, 0x0012}, {0x860d, 0x0004}, -{0x860e, 0x0001}, {0x860f, 0x0001}, {0x8610, 0x0001}, -{0x8611, 0x0001}, {0x8612, 0x0001}, {0x8613, 0x0001}, -{0x8614, 0x00b6}, {0x8615, 0x0012}, {0x8616, 0x0008}, -{0x8617, 0x0027}, {0x8618, 0x007f}, {0x8619, 0x0081}, -{0x861a, 0x0080}, {0x861b, 0x0026}, {0x861c, 0x000b}, -{0x861d, 0x0086}, {0x861e, 0x0008}, {0x861f, 0x00ce}, -{0x8620, 0x008f}, {0x8621, 0x0079}, {0x8622, 0x00bd}, -{0x8623, 0x0089}, {0x8624, 0x007b}, {0x8625, 0x007e}, -{0x8626, 0x0086}, {0x8627, 0x008e}, {0x8628, 0x0081}, -{0x8629, 0x0040}, {0x862a, 0x0026}, {0x862b, 0x000b}, -{0x862c, 0x0086}, {0x862d, 0x0004}, {0x862e, 0x00ce}, -{0x862f, 0x008f}, {0x8630, 0x0076}, {0x8631, 0x00bd}, -{0x8632, 0x0089}, {0x8633, 0x007b}, {0x8634, 0x007e}, -{0x8635, 0x0086}, {0x8636, 0x008e}, {0x8637, 0x0081}, -{0x8638, 0x0020}, {0x8639, 0x0026}, {0x863a, 0x000b}, -{0x863b, 0x0086}, {0x863c, 0x0002}, {0x863d, 0x00ce}, -{0x863e, 0x008f}, {0x863f, 0x0073}, {0x8640, 0x00bd}, -{0x8641, 0x0089}, {0x8642, 0x007b}, {0x8643, 0x007e}, -{0x8644, 0x0086}, {0x8645, 0x008e}, {0x8646, 0x0081}, -{0x8647, 0x0010}, {0x8648, 0x0026}, {0x8649, 0x000b}, -{0x864a, 0x0086}, {0x864b, 0x0001}, {0x864c, 0x00ce}, -{0x864d, 0x008f}, {0x864e, 0x0070}, {0x864f, 0x00bd}, -{0x8650, 0x0089}, {0x8651, 0x007b}, {0x8652, 0x007e}, -{0x8653, 0x0086}, {0x8654, 0x008e}, {0x8655, 0x0081}, -{0x8656, 0x0008}, {0x8657, 0x0026}, {0x8658, 0x000b}, -{0x8659, 0x0086}, {0x865a, 0x0008}, {0x865b, 0x00ce}, -{0x865c, 0x008f}, {0x865d, 0x0079}, {0x865e, 0x00bd}, -{0x865f, 0x0089}, {0x8660, 0x007f}, {0x8661, 0x007e}, -{0x8662, 0x0086}, {0x8663, 0x008e}, {0x8664, 0x0081}, -{0x8665, 0x0004}, {0x8666, 0x0026}, {0x8667, 0x000b}, -{0x8668, 0x0086}, {0x8669, 0x0004}, {0x866a, 0x00ce}, -{0x866b, 0x008f}, {0x866c, 0x0076}, {0x866d, 0x00bd}, -{0x866e, 0x0089}, {0x866f, 0x007f}, {0x8670, 0x007e}, -{0x8671, 0x0086}, {0x8672, 0x008e}, {0x8673, 0x0081}, -{0x8674, 0x0002}, {0x8675, 0x0026}, {0x8676, 0x000b}, -{0x8677, 0x008a}, {0x8678, 0x0002}, {0x8679, 0x00ce}, -{0x867a, 0x008f}, {0x867b, 0x0073}, {0x867c, 0x00bd}, -{0x867d, 0x0089}, {0x867e, 0x007f}, {0x867f, 0x007e}, -{0x8680, 0x0086}, {0x8681, 0x008e}, {0x8682, 0x0081}, -{0x8683, 0x0001}, {0x8684, 0x0026}, {0x8685, 0x0008}, -{0x8686, 0x0086}, {0x8687, 0x0001}, {0x8688, 0x00ce}, -{0x8689, 0x008f}, {0x868a, 0x0070}, {0x868b, 0x00bd}, -{0x868c, 0x0089}, {0x868d, 0x007f}, {0x868e, 0x00b6}, -{0x868f, 0x008f}, {0x8690, 0x007f}, {0x8691, 0x0081}, -{0x8692, 0x000f}, {0x8693, 0x0026}, {0x8694, 0x0003}, -{0x8695, 0x007e}, {0x8696, 0x0087}, {0x8697, 0x0047}, -{0x8698, 0x00b6}, {0x8699, 0x0012}, {0x869a, 0x0009}, -{0x869b, 0x0084}, {0x869c, 0x0003}, {0x869d, 0x0081}, -{0x869e, 0x0003}, {0x869f, 0x0027}, {0x86a0, 0x0006}, -{0x86a1, 0x007c}, {0x86a2, 0x0012}, {0x86a3, 0x0009}, -{0x86a4, 0x007e}, {0x86a5, 0x0085}, {0x86a6, 0x00fe}, -{0x86a7, 0x00b6}, {0x86a8, 0x0012}, {0x86a9, 0x0006}, -{0x86aa, 0x0084}, {0x86ab, 0x0007}, {0x86ac, 0x0081}, -{0x86ad, 0x0007}, {0x86ae, 0x0027}, {0x86af, 0x0008}, -{0x86b0, 0x008b}, {0x86b1, 0x0001}, {0x86b2, 0x00b7}, -{0x86b3, 0x0012}, {0x86b4, 0x0006}, {0x86b5, 0x007e}, -{0x86b6, 0x0086}, {0x86b7, 0x00d5}, {0x86b8, 0x00b6}, -{0x86b9, 0x008f}, {0x86ba, 0x0082}, {0x86bb, 0x0026}, -{0x86bc, 0x000a}, {0x86bd, 0x007c}, {0x86be, 0x008f}, -{0x86bf, 0x0082}, {0x86c0, 0x004f}, {0x86c1, 0x00b7}, -{0x86c2, 0x0012}, {0x86c3, 0x0006}, {0x86c4, 0x007e}, -{0x86c5, 0x0085}, {0x86c6, 0x00c0}, {0x86c7, 0x00b6}, -{0x86c8, 0x0012}, {0x86c9, 0x0006}, {0x86ca, 0x0084}, -{0x86cb, 0x003f}, {0x86cc, 0x0081}, {0x86cd, 0x003f}, -{0x86ce, 0x0027}, {0x86cf, 0x0010}, {0x86d0, 0x008b}, -{0x86d1, 0x0008}, {0x86d2, 0x00b7}, {0x86d3, 0x0012}, -{0x86d4, 0x0006}, {0x86d5, 0x00b6}, {0x86d6, 0x0012}, -{0x86d7, 0x0009}, {0x86d8, 0x0084}, {0x86d9, 0x00fc}, -{0x86da, 0x00b7}, {0x86db, 0x0012}, {0x86dc, 0x0009}, -{0x86dd, 0x007e}, {0x86de, 0x0085}, {0x86df, 0x00fe}, -{0x86e0, 0x00ce}, {0x86e1, 0x008f}, {0x86e2, 0x0070}, -{0x86e3, 0x0018}, {0x86e4, 0x00ce}, {0x86e5, 0x008f}, -{0x86e6, 0x0084}, {0x86e7, 0x00c6}, {0x86e8, 0x000c}, -{0x86e9, 0x00bd}, {0x86ea, 0x0089}, {0x86eb, 0x006f}, -{0x86ec, 0x00ce}, {0x86ed, 0x008f}, {0x86ee, 0x0084}, -{0x86ef, 0x0018}, {0x86f0, 0x00ce}, {0x86f1, 0x008f}, -{0x86f2, 0x0070}, {0x86f3, 0x00c6}, {0x86f4, 0x000c}, -{0x86f5, 0x00bd}, {0x86f6, 0x0089}, {0x86f7, 0x006f}, -{0x86f8, 0x00d6}, {0x86f9, 0x0083}, {0x86fa, 0x00c1}, -{0x86fb, 0x004f}, {0x86fc, 0x002d}, {0x86fd, 0x0003}, -{0x86fe, 0x007e}, {0x86ff, 0x0087}, {0x8700, 0x0040}, -{0x8701, 0x00b6}, {0x8702, 0x008f}, {0x8703, 0x007f}, -{0x8704, 0x0081}, {0x8705, 0x0007}, {0x8706, 0x0027}, -{0x8707, 0x000f}, {0x8708, 0x0081}, {0x8709, 0x000b}, -{0x870a, 0x0027}, {0x870b, 0x0015}, {0x870c, 0x0081}, -{0x870d, 0x000d}, {0x870e, 0x0027}, {0x870f, 0x001b}, -{0x8710, 0x0081}, {0x8711, 0x000e}, {0x8712, 0x0027}, -{0x8713, 0x0021}, {0x8714, 0x007e}, {0x8715, 0x0087}, -{0x8716, 0x0040}, {0x8717, 0x00f7}, {0x8718, 0x008f}, -{0x8719, 0x007b}, {0x871a, 0x0086}, {0x871b, 0x0002}, -{0x871c, 0x00b7}, {0x871d, 0x008f}, {0x871e, 0x007a}, -{0x871f, 0x0020}, {0x8720, 0x001c}, {0x8721, 0x00f7}, -{0x8722, 0x008f}, {0x8723, 0x0078}, {0x8724, 0x0086}, -{0x8725, 0x0002}, {0x8726, 0x00b7}, {0x8727, 0x008f}, -{0x8728, 0x0077}, {0x8729, 0x0020}, {0x872a, 0x0012}, -{0x872b, 0x00f7}, {0x872c, 0x008f}, {0x872d, 0x0075}, -{0x872e, 0x0086}, {0x872f, 0x0002}, {0x8730, 0x00b7}, -{0x8731, 0x008f}, {0x8732, 0x0074}, {0x8733, 0x0020}, -{0x8734, 0x0008}, {0x8735, 0x00f7}, {0x8736, 0x008f}, -{0x8737, 0x0072}, {0x8738, 0x0086}, {0x8739, 0x0002}, -{0x873a, 0x00b7}, {0x873b, 0x008f}, {0x873c, 0x0071}, -{0x873d, 0x007e}, {0x873e, 0x0087}, {0x873f, 0x0047}, -{0x8740, 0x0086}, {0x8741, 0x0004}, {0x8742, 0x0097}, -{0x8743, 0x0040}, {0x8744, 0x007e}, {0x8745, 0x0089}, -{0x8746, 0x006e}, {0x8747, 0x00ce}, {0x8748, 0x008f}, -{0x8749, 0x0072}, {0x874a, 0x00bd}, {0x874b, 0x0089}, -{0x874c, 0x00f7}, {0x874d, 0x00ce}, {0x874e, 0x008f}, -{0x874f, 0x0075}, {0x8750, 0x00bd}, {0x8751, 0x0089}, -{0x8752, 0x00f7}, {0x8753, 0x00ce}, {0x8754, 0x008f}, -{0x8755, 0x0078}, {0x8756, 0x00bd}, {0x8757, 0x0089}, -{0x8758, 0x00f7}, {0x8759, 0x00ce}, {0x875a, 0x008f}, -{0x875b, 0x007b}, {0x875c, 0x00bd}, {0x875d, 0x0089}, -{0x875e, 0x00f7}, {0x875f, 0x004f}, {0x8760, 0x00b7}, -{0x8761, 0x008f}, {0x8762, 0x007d}, {0x8763, 0x00b7}, -{0x8764, 0x008f}, {0x8765, 0x0081}, {0x8766, 0x00b6}, -{0x8767, 0x008f}, {0x8768, 0x0072}, {0x8769, 0x0027}, -{0x876a, 0x0047}, {0x876b, 0x007c}, {0x876c, 0x008f}, -{0x876d, 0x007d}, {0x876e, 0x00b6}, {0x876f, 0x008f}, -{0x8770, 0x0075}, {0x8771, 0x0027}, {0x8772, 0x003f}, -{0x8773, 0x007c}, {0x8774, 0x008f}, {0x8775, 0x007d}, -{0x8776, 0x00b6}, {0x8777, 0x008f}, {0x8778, 0x0078}, -{0x8779, 0x0027}, {0x877a, 0x0037}, {0x877b, 0x007c}, -{0x877c, 0x008f}, {0x877d, 0x007d}, {0x877e, 0x00b6}, -{0x877f, 0x008f}, {0x8780, 0x007b}, {0x8781, 0x0027}, -{0x8782, 0x002f}, {0x8783, 0x007f}, {0x8784, 0x008f}, -{0x8785, 0x007d}, {0x8786, 0x007c}, {0x8787, 0x008f}, -{0x8788, 0x0081}, {0x8789, 0x007a}, {0x878a, 0x008f}, -{0x878b, 0x0072}, {0x878c, 0x0027}, {0x878d, 0x001b}, -{0x878e, 0x007c}, {0x878f, 0x008f}, {0x8790, 0x007d}, -{0x8791, 0x007a}, {0x8792, 0x008f}, {0x8793, 0x0075}, -{0x8794, 0x0027}, {0x8795, 0x0016}, {0x8796, 0x007c}, -{0x8797, 0x008f}, {0x8798, 0x007d}, {0x8799, 0x007a}, -{0x879a, 0x008f}, {0x879b, 0x0078}, {0x879c, 0x0027}, -{0x879d, 0x0011}, {0x879e, 0x007c}, {0x879f, 0x008f}, -{0x87a0, 0x007d}, {0x87a1, 0x007a}, {0x87a2, 0x008f}, -{0x87a3, 0x007b}, {0x87a4, 0x0027}, {0x87a5, 0x000c}, -{0x87a6, 0x007e}, {0x87a7, 0x0087}, {0x87a8, 0x0083}, -{0x87a9, 0x007a}, {0x87aa, 0x008f}, {0x87ab, 0x0075}, -{0x87ac, 0x007a}, {0x87ad, 0x008f}, {0x87ae, 0x0078}, -{0x87af, 0x007a}, {0x87b0, 0x008f}, {0x87b1, 0x007b}, -{0x87b2, 0x00ce}, {0x87b3, 0x00c1}, {0x87b4, 0x00fc}, -{0x87b5, 0x00f6}, {0x87b6, 0x008f}, {0x87b7, 0x007d}, -{0x87b8, 0x003a}, {0x87b9, 0x00a6}, {0x87ba, 0x0000}, -{0x87bb, 0x00b7}, {0x87bc, 0x0012}, {0x87bd, 0x0070}, -{0x87be, 0x00b6}, {0x87bf, 0x008f}, {0x87c0, 0x0072}, -{0x87c1, 0x0026}, {0x87c2, 0x0003}, {0x87c3, 0x007e}, -{0x87c4, 0x0087}, {0x87c5, 0x00fa}, {0x87c6, 0x00b6}, -{0x87c7, 0x008f}, {0x87c8, 0x0075}, {0x87c9, 0x0026}, -{0x87ca, 0x000a}, {0x87cb, 0x0018}, {0x87cc, 0x00ce}, -{0x87cd, 0x008f}, {0x87ce, 0x0073}, {0x87cf, 0x00bd}, -{0x87d0, 0x0089}, {0x87d1, 0x00d5}, {0x87d2, 0x007e}, -{0x87d3, 0x0087}, {0x87d4, 0x00fa}, {0x87d5, 0x00b6}, -{0x87d6, 0x008f}, {0x87d7, 0x0078}, {0x87d8, 0x0026}, -{0x87d9, 0x000a}, {0x87da, 0x0018}, {0x87db, 0x00ce}, -{0x87dc, 0x008f}, {0x87dd, 0x0076}, {0x87de, 0x00bd}, -{0x87df, 0x0089}, {0x87e0, 0x00d5}, {0x87e1, 0x007e}, -{0x87e2, 0x0087}, {0x87e3, 0x00fa}, {0x87e4, 0x00b6}, -{0x87e5, 0x008f}, {0x87e6, 0x007b}, {0x87e7, 0x0026}, -{0x87e8, 0x000a}, {0x87e9, 0x0018}, {0x87ea, 0x00ce}, -{0x87eb, 0x008f}, {0x87ec, 0x0079}, {0x87ed, 0x00bd}, -{0x87ee, 0x0089}, {0x87ef, 0x00d5}, {0x87f0, 0x007e}, -{0x87f1, 0x0087}, {0x87f2, 0x00fa}, {0x87f3, 0x0086}, -{0x87f4, 0x0005}, {0x87f5, 0x0097}, {0x87f6, 0x0040}, -{0x87f7, 0x007e}, {0x87f8, 0x0089}, {0x87f9, 0x006e}, -{0x87fa, 0x00b6}, {0x87fb, 0x008f}, {0x87fc, 0x0075}, -{0x87fd, 0x0081}, {0x87fe, 0x0007}, {0x87ff, 0x002e}, -{0x8800, 0x00f2}, {0x8801, 0x00f6}, {0x8802, 0x0012}, -{0x8803, 0x0006}, {0x8804, 0x00c4}, {0x8805, 0x00f8}, -{0x8806, 0x001b}, {0x8807, 0x00b7}, {0x8808, 0x0012}, -{0x8809, 0x0006}, {0x880a, 0x00b6}, {0x880b, 0x008f}, -{0x880c, 0x0078}, {0x880d, 0x0081}, {0x880e, 0x0007}, -{0x880f, 0x002e}, {0x8810, 0x00e2}, {0x8811, 0x0048}, -{0x8812, 0x0048}, {0x8813, 0x0048}, {0x8814, 0x00f6}, -{0x8815, 0x0012}, {0x8816, 0x0006}, {0x8817, 0x00c4}, -{0x8818, 0x00c7}, {0x8819, 0x001b}, {0x881a, 0x00b7}, -{0x881b, 0x0012}, {0x881c, 0x0006}, {0x881d, 0x00b6}, -{0x881e, 0x008f}, {0x881f, 0x007b}, {0x8820, 0x0081}, -{0x8821, 0x0007}, {0x8822, 0x002e}, {0x8823, 0x00cf}, -{0x8824, 0x00f6}, {0x8825, 0x0012}, {0x8826, 0x0005}, -{0x8827, 0x00c4}, {0x8828, 0x00f8}, {0x8829, 0x001b}, -{0x882a, 0x00b7}, {0x882b, 0x0012}, {0x882c, 0x0005}, -{0x882d, 0x0086}, {0x882e, 0x0000}, {0x882f, 0x00f6}, -{0x8830, 0x008f}, {0x8831, 0x0071}, {0x8832, 0x00bd}, -{0x8833, 0x0089}, {0x8834, 0x0094}, {0x8835, 0x0086}, -{0x8836, 0x0001}, {0x8837, 0x00f6}, {0x8838, 0x008f}, -{0x8839, 0x0074}, {0x883a, 0x00bd}, {0x883b, 0x0089}, -{0x883c, 0x0094}, {0x883d, 0x0086}, {0x883e, 0x0002}, -{0x883f, 0x00f6}, {0x8840, 0x008f}, {0x8841, 0x0077}, -{0x8842, 0x00bd}, {0x8843, 0x0089}, {0x8844, 0x0094}, -{0x8845, 0x0086}, {0x8846, 0x0003}, {0x8847, 0x00f6}, -{0x8848, 0x008f}, {0x8849, 0x007a}, {0x884a, 0x00bd}, -{0x884b, 0x0089}, {0x884c, 0x0094}, {0x884d, 0x00ce}, -{0x884e, 0x008f}, {0x884f, 0x0070}, {0x8850, 0x00a6}, -{0x8851, 0x0001}, {0x8852, 0x0081}, {0x8853, 0x0001}, -{0x8854, 0x0027}, {0x8855, 0x0007}, {0x8856, 0x0081}, -{0x8857, 0x0003}, {0x8858, 0x0027}, {0x8859, 0x0003}, -{0x885a, 0x007e}, {0x885b, 0x0088}, {0x885c, 0x0066}, -{0x885d, 0x00a6}, {0x885e, 0x0000}, {0x885f, 0x00b8}, -{0x8860, 0x008f}, {0x8861, 0x0081}, {0x8862, 0x0084}, -{0x8863, 0x0001}, {0x8864, 0x0026}, {0x8865, 0x000b}, -{0x8866, 0x008c}, {0x8867, 0x008f}, {0x8868, 0x0079}, -{0x8869, 0x002c}, {0x886a, 0x000e}, {0x886b, 0x0008}, -{0x886c, 0x0008}, {0x886d, 0x0008}, {0x886e, 0x007e}, -{0x886f, 0x0088}, {0x8870, 0x0050}, {0x8871, 0x00b6}, -{0x8872, 0x0012}, {0x8873, 0x0004}, {0x8874, 0x008a}, -{0x8875, 0x0040}, {0x8876, 0x00b7}, {0x8877, 0x0012}, -{0x8878, 0x0004}, {0x8879, 0x00b6}, {0x887a, 0x0012}, -{0x887b, 0x0004}, {0x887c, 0x0084}, {0x887d, 0x00fb}, -{0x887e, 0x0084}, {0x887f, 0x00ef}, {0x8880, 0x00b7}, -{0x8881, 0x0012}, {0x8882, 0x0004}, {0x8883, 0x00b6}, -{0x8884, 0x0012}, {0x8885, 0x0007}, {0x8886, 0x0036}, -{0x8887, 0x00b6}, {0x8888, 0x008f}, {0x8889, 0x007c}, -{0x888a, 0x0048}, {0x888b, 0x0048}, {0x888c, 0x00b7}, -{0x888d, 0x0012}, {0x888e, 0x0007}, {0x888f, 0x0086}, -{0x8890, 0x0001}, {0x8891, 0x00ba}, {0x8892, 0x0012}, -{0x8893, 0x0004}, {0x8894, 0x00b7}, {0x8895, 0x0012}, -{0x8896, 0x0004}, {0x8897, 0x0001}, {0x8898, 0x0001}, -{0x8899, 0x0001}, {0x889a, 0x0001}, {0x889b, 0x0001}, -{0x889c, 0x0001}, {0x889d, 0x0086}, {0x889e, 0x00fe}, -{0x889f, 0x00b4}, {0x88a0, 0x0012}, {0x88a1, 0x0004}, -{0x88a2, 0x00b7}, {0x88a3, 0x0012}, {0x88a4, 0x0004}, -{0x88a5, 0x0086}, {0x88a6, 0x0002}, {0x88a7, 0x00ba}, -{0x88a8, 0x0012}, {0x88a9, 0x0004}, {0x88aa, 0x00b7}, -{0x88ab, 0x0012}, {0x88ac, 0x0004}, {0x88ad, 0x0086}, -{0x88ae, 0x00fd}, {0x88af, 0x00b4}, {0x88b0, 0x0012}, -{0x88b1, 0x0004}, {0x88b2, 0x00b7}, {0x88b3, 0x0012}, -{0x88b4, 0x0004}, {0x88b5, 0x0032}, {0x88b6, 0x00b7}, -{0x88b7, 0x0012}, {0x88b8, 0x0007}, {0x88b9, 0x00b6}, -{0x88ba, 0x0012}, {0x88bb, 0x0000}, {0x88bc, 0x0084}, -{0x88bd, 0x0008}, {0x88be, 0x0081}, {0x88bf, 0x0008}, -{0x88c0, 0x0027}, {0x88c1, 0x000f}, {0x88c2, 0x007c}, -{0x88c3, 0x0082}, {0x88c4, 0x0008}, {0x88c5, 0x0026}, -{0x88c6, 0x0007}, {0x88c7, 0x0086}, {0x88c8, 0x0076}, -{0x88c9, 0x0097}, {0x88ca, 0x0040}, {0x88cb, 0x007e}, -{0x88cc, 0x0089}, {0x88cd, 0x006e}, {0x88ce, 0x007e}, -{0x88cf, 0x0086}, {0x88d0, 0x00ec}, {0x88d1, 0x00b6}, -{0x88d2, 0x008f}, {0x88d3, 0x007f}, {0x88d4, 0x0081}, -{0x88d5, 0x000f}, {0x88d6, 0x0027}, {0x88d7, 0x003c}, -{0x88d8, 0x00bd}, {0x88d9, 0x00e6}, {0x88da, 0x00c7}, -{0x88db, 0x00b7}, {0x88dc, 0x0012}, {0x88dd, 0x000d}, -{0x88de, 0x00bd}, {0x88df, 0x00e6}, {0x88e0, 0x00cb}, -{0x88e1, 0x00b6}, {0x88e2, 0x0012}, {0x88e3, 0x0004}, -{0x88e4, 0x008a}, {0x88e5, 0x0020}, {0x88e6, 0x00b7}, -{0x88e7, 0x0012}, {0x88e8, 0x0004}, {0x88e9, 0x00ce}, -{0x88ea, 0x00ff}, {0x88eb, 0x00ff}, {0x88ec, 0x00b6}, -{0x88ed, 0x0012}, {0x88ee, 0x0000}, {0x88ef, 0x0081}, -{0x88f0, 0x000c}, {0x88f1, 0x0026}, {0x88f2, 0x0005}, -{0x88f3, 0x0009}, {0x88f4, 0x0026}, {0x88f5, 0x00f6}, -{0x88f6, 0x0027}, {0x88f7, 0x001c}, {0x88f8, 0x00b6}, -{0x88f9, 0x0012}, {0x88fa, 0x0004}, {0x88fb, 0x0084}, -{0x88fc, 0x00df}, {0x88fd, 0x00b7}, {0x88fe, 0x0012}, -{0x88ff, 0x0004}, {0x8900, 0x0096}, {0x8901, 0x0083}, -{0x8902, 0x0081}, {0x8903, 0x0007}, {0x8904, 0x002c}, -{0x8905, 0x0005}, {0x8906, 0x007c}, {0x8907, 0x0000}, -{0x8908, 0x0083}, {0x8909, 0x0020}, {0x890a, 0x0006}, -{0x890b, 0x0096}, {0x890c, 0x0083}, {0x890d, 0x008b}, -{0x890e, 0x0008}, {0x890f, 0x0097}, {0x8910, 0x0083}, -{0x8911, 0x007e}, {0x8912, 0x0085}, {0x8913, 0x0041}, -{0x8914, 0x007f}, {0x8915, 0x008f}, {0x8916, 0x007e}, -{0x8917, 0x0086}, {0x8918, 0x0080}, {0x8919, 0x00b7}, -{0x891a, 0x0012}, {0x891b, 0x000c}, {0x891c, 0x0086}, -{0x891d, 0x0001}, {0x891e, 0x00b7}, {0x891f, 0x008f}, -{0x8920, 0x007d}, {0x8921, 0x00b6}, {0x8922, 0x0012}, -{0x8923, 0x000c}, {0x8924, 0x0084}, {0x8925, 0x007f}, -{0x8926, 0x00b7}, {0x8927, 0x0012}, {0x8928, 0x000c}, -{0x8929, 0x008a}, {0x892a, 0x0080}, {0x892b, 0x00b7}, -{0x892c, 0x0012}, {0x892d, 0x000c}, {0x892e, 0x0086}, -{0x892f, 0x000a}, {0x8930, 0x00bd}, {0x8931, 0x008a}, -{0x8932, 0x0006}, {0x8933, 0x00b6}, {0x8934, 0x0012}, -{0x8935, 0x000a}, {0x8936, 0x002a}, {0x8937, 0x0009}, -{0x8938, 0x00b6}, {0x8939, 0x0012}, {0x893a, 0x000c}, -{0x893b, 0x00ba}, {0x893c, 0x008f}, {0x893d, 0x007d}, -{0x893e, 0x00b7}, {0x893f, 0x0012}, {0x8940, 0x000c}, -{0x8941, 0x00b6}, {0x8942, 0x008f}, {0x8943, 0x007e}, -{0x8944, 0x0081}, {0x8945, 0x0060}, {0x8946, 0x0027}, -{0x8947, 0x001a}, {0x8948, 0x008b}, {0x8949, 0x0020}, -{0x894a, 0x00b7}, {0x894b, 0x008f}, {0x894c, 0x007e}, -{0x894d, 0x00b6}, {0x894e, 0x0012}, {0x894f, 0x000c}, -{0x8950, 0x0084}, {0x8951, 0x009f}, {0x8952, 0x00ba}, -{0x8953, 0x008f}, {0x8954, 0x007e}, {0x8955, 0x00b7}, -{0x8956, 0x0012}, {0x8957, 0x000c}, {0x8958, 0x00b6}, -{0x8959, 0x008f}, {0x895a, 0x007d}, {0x895b, 0x0048}, -{0x895c, 0x00b7}, {0x895d, 0x008f}, {0x895e, 0x007d}, -{0x895f, 0x007e}, {0x8960, 0x0089}, {0x8961, 0x0021}, -{0x8962, 0x00b6}, {0x8963, 0x0012}, {0x8964, 0x0004}, -{0x8965, 0x008a}, {0x8966, 0x0020}, {0x8967, 0x00b7}, -{0x8968, 0x0012}, {0x8969, 0x0004}, {0x896a, 0x00bd}, -{0x896b, 0x008a}, {0x896c, 0x000a}, {0x896d, 0x004f}, -{0x896e, 0x0039}, {0x896f, 0x00a6}, {0x8970, 0x0000}, -{0x8971, 0x0018}, {0x8972, 0x00a7}, {0x8973, 0x0000}, -{0x8974, 0x0008}, {0x8975, 0x0018}, {0x8976, 0x0008}, -{0x8977, 0x005a}, {0x8978, 0x0026}, {0x8979, 0x00f5}, -{0x897a, 0x0039}, {0x897b, 0x0036}, {0x897c, 0x006c}, -{0x897d, 0x0000}, {0x897e, 0x0032}, {0x897f, 0x00ba}, -{0x8980, 0x008f}, {0x8981, 0x007f}, {0x8982, 0x00b7}, -{0x8983, 0x008f}, {0x8984, 0x007f}, {0x8985, 0x00b6}, -{0x8986, 0x0012}, {0x8987, 0x0009}, {0x8988, 0x0084}, -{0x8989, 0x0003}, {0x898a, 0x00a7}, {0x898b, 0x0001}, -{0x898c, 0x00b6}, {0x898d, 0x0012}, {0x898e, 0x0006}, -{0x898f, 0x0084}, {0x8990, 0x003f}, {0x8991, 0x00a7}, -{0x8992, 0x0002}, {0x8993, 0x0039}, {0x8994, 0x0036}, -{0x8995, 0x0086}, {0x8996, 0x0003}, {0x8997, 0x00b7}, -{0x8998, 0x008f}, {0x8999, 0x0080}, {0x899a, 0x0032}, -{0x899b, 0x00c1}, {0x899c, 0x0000}, {0x899d, 0x0026}, -{0x899e, 0x0006}, {0x899f, 0x00b7}, {0x89a0, 0x008f}, -{0x89a1, 0x007c}, {0x89a2, 0x007e}, {0x89a3, 0x0089}, -{0x89a4, 0x00c9}, {0x89a5, 0x00c1}, {0x89a6, 0x0001}, -{0x89a7, 0x0027}, {0x89a8, 0x0018}, {0x89a9, 0x00c1}, -{0x89aa, 0x0002}, {0x89ab, 0x0027}, {0x89ac, 0x000c}, -{0x89ad, 0x00c1}, {0x89ae, 0x0003}, {0x89af, 0x0027}, -{0x89b0, 0x0000}, {0x89b1, 0x00f6}, {0x89b2, 0x008f}, -{0x89b3, 0x0080}, {0x89b4, 0x0005}, {0x89b5, 0x0005}, -{0x89b6, 0x00f7}, {0x89b7, 0x008f}, {0x89b8, 0x0080}, -{0x89b9, 0x00f6}, {0x89ba, 0x008f}, {0x89bb, 0x0080}, -{0x89bc, 0x0005}, {0x89bd, 0x0005}, {0x89be, 0x00f7}, -{0x89bf, 0x008f}, {0x89c0, 0x0080}, {0x89c1, 0x00f6}, -{0x89c2, 0x008f}, {0x89c3, 0x0080}, {0x89c4, 0x0005}, -{0x89c5, 0x0005}, {0x89c6, 0x00f7}, {0x89c7, 0x008f}, -{0x89c8, 0x0080}, {0x89c9, 0x00f6}, {0x89ca, 0x008f}, -{0x89cb, 0x0080}, {0x89cc, 0x0053}, {0x89cd, 0x00f4}, -{0x89ce, 0x0012}, {0x89cf, 0x0007}, {0x89d0, 0x001b}, -{0x89d1, 0x00b7}, {0x89d2, 0x0012}, {0x89d3, 0x0007}, -{0x89d4, 0x0039}, {0x89d5, 0x00ce}, {0x89d6, 0x008f}, -{0x89d7, 0x0070}, {0x89d8, 0x00a6}, {0x89d9, 0x0000}, -{0x89da, 0x0018}, {0x89db, 0x00e6}, {0x89dc, 0x0000}, -{0x89dd, 0x0018}, {0x89de, 0x00a7}, {0x89df, 0x0000}, -{0x89e0, 0x00e7}, {0x89e1, 0x0000}, {0x89e2, 0x00a6}, -{0x89e3, 0x0001}, {0x89e4, 0x0018}, {0x89e5, 0x00e6}, -{0x89e6, 0x0001}, {0x89e7, 0x0018}, {0x89e8, 0x00a7}, -{0x89e9, 0x0001}, {0x89ea, 0x00e7}, {0x89eb, 0x0001}, -{0x89ec, 0x00a6}, {0x89ed, 0x0002}, {0x89ee, 0x0018}, -{0x89ef, 0x00e6}, {0x89f0, 0x0002}, {0x89f1, 0x0018}, -{0x89f2, 0x00a7}, {0x89f3, 0x0002}, {0x89f4, 0x00e7}, -{0x89f5, 0x0002}, {0x89f6, 0x0039}, {0x89f7, 0x00a6}, -{0x89f8, 0x0000}, {0x89f9, 0x0084}, {0x89fa, 0x0007}, -{0x89fb, 0x00e6}, {0x89fc, 0x0000}, {0x89fd, 0x00c4}, -{0x89fe, 0x0038}, {0x89ff, 0x0054}, {0x8a00, 0x0054}, -{0x8a01, 0x0054}, {0x8a02, 0x001b}, {0x8a03, 0x00a7}, -{0x8a04, 0x0000}, {0x8a05, 0x0039}, {0x8a06, 0x004a}, -{0x8a07, 0x0026}, {0x8a08, 0x00fd}, {0x8a09, 0x0039}, -{0x8a0a, 0x0096}, {0x8a0b, 0x0022}, {0x8a0c, 0x0084}, -{0x8a0d, 0x000f}, {0x8a0e, 0x0097}, {0x8a0f, 0x0022}, -{0x8a10, 0x0086}, {0x8a11, 0x0001}, {0x8a12, 0x00b7}, -{0x8a13, 0x008f}, {0x8a14, 0x0070}, {0x8a15, 0x00b6}, -{0x8a16, 0x0012}, {0x8a17, 0x0007}, {0x8a18, 0x00b7}, -{0x8a19, 0x008f}, {0x8a1a, 0x0071}, {0x8a1b, 0x00f6}, -{0x8a1c, 0x0012}, {0x8a1d, 0x000c}, {0x8a1e, 0x00c4}, -{0x8a1f, 0x000f}, {0x8a20, 0x00c8}, {0x8a21, 0x000f}, -{0x8a22, 0x00f7}, {0x8a23, 0x008f}, {0x8a24, 0x0072}, -{0x8a25, 0x00f6}, {0x8a26, 0x008f}, {0x8a27, 0x0072}, -{0x8a28, 0x00b6}, {0x8a29, 0x008f}, {0x8a2a, 0x0071}, -{0x8a2b, 0x0084}, {0x8a2c, 0x0003}, {0x8a2d, 0x0027}, -{0x8a2e, 0x0014}, {0x8a2f, 0x0081}, {0x8a30, 0x0001}, -{0x8a31, 0x0027}, {0x8a32, 0x001c}, {0x8a33, 0x0081}, -{0x8a34, 0x0002}, {0x8a35, 0x0027}, {0x8a36, 0x0024}, -{0x8a37, 0x00f4}, {0x8a38, 0x008f}, {0x8a39, 0x0070}, -{0x8a3a, 0x0027}, {0x8a3b, 0x002a}, {0x8a3c, 0x0096}, -{0x8a3d, 0x0022}, {0x8a3e, 0x008a}, {0x8a3f, 0x0080}, -{0x8a40, 0x007e}, {0x8a41, 0x008a}, {0x8a42, 0x0064}, -{0x8a43, 0x00f4}, {0x8a44, 0x008f}, {0x8a45, 0x0070}, -{0x8a46, 0x0027}, {0x8a47, 0x001e}, {0x8a48, 0x0096}, -{0x8a49, 0x0022}, {0x8a4a, 0x008a}, {0x8a4b, 0x0010}, -{0x8a4c, 0x007e}, {0x8a4d, 0x008a}, {0x8a4e, 0x0064}, -{0x8a4f, 0x00f4}, {0x8a50, 0x008f}, {0x8a51, 0x0070}, -{0x8a52, 0x0027}, {0x8a53, 0x0012}, {0x8a54, 0x0096}, -{0x8a55, 0x0022}, {0x8a56, 0x008a}, {0x8a57, 0x0020}, -{0x8a58, 0x007e}, {0x8a59, 0x008a}, {0x8a5a, 0x0064}, -{0x8a5b, 0x00f4}, {0x8a5c, 0x008f}, {0x8a5d, 0x0070}, -{0x8a5e, 0x0027}, {0x8a5f, 0x0006}, {0x8a60, 0x0096}, -{0x8a61, 0x0022}, {0x8a62, 0x008a}, {0x8a63, 0x0040}, -{0x8a64, 0x0097}, {0x8a65, 0x0022}, {0x8a66, 0x0074}, -{0x8a67, 0x008f}, {0x8a68, 0x0071}, {0x8a69, 0x0074}, -{0x8a6a, 0x008f}, {0x8a6b, 0x0071}, {0x8a6c, 0x0078}, -{0x8a6d, 0x008f}, {0x8a6e, 0x0070}, {0x8a6f, 0x00b6}, -{0x8a70, 0x008f}, {0x8a71, 0x0070}, {0x8a72, 0x0085}, -{0x8a73, 0x0010}, {0x8a74, 0x0027}, {0x8a75, 0x00af}, -{0x8a76, 0x00d6}, {0x8a77, 0x0022}, {0x8a78, 0x00c4}, -{0x8a79, 0x0010}, {0x8a7a, 0x0058}, {0x8a7b, 0x00b6}, -{0x8a7c, 0x0012}, {0x8a7d, 0x0070}, {0x8a7e, 0x0081}, -{0x8a7f, 0x00e4}, {0x8a80, 0x0027}, {0x8a81, 0x0036}, -{0x8a82, 0x0081}, {0x8a83, 0x00e1}, {0x8a84, 0x0026}, -{0x8a85, 0x000c}, {0x8a86, 0x0096}, {0x8a87, 0x0022}, -{0x8a88, 0x0084}, {0x8a89, 0x0020}, {0x8a8a, 0x0044}, -{0x8a8b, 0x001b}, {0x8a8c, 0x00d6}, {0x8a8d, 0x0022}, -{0x8a8e, 0x00c4}, {0x8a8f, 0x00cf}, {0x8a90, 0x0020}, -{0x8a91, 0x0023}, {0x8a92, 0x0058}, {0x8a93, 0x0081}, -{0x8a94, 0x00c6}, {0x8a95, 0x0026}, {0x8a96, 0x000d}, -{0x8a97, 0x0096}, {0x8a98, 0x0022}, {0x8a99, 0x0084}, -{0x8a9a, 0x0040}, {0x8a9b, 0x0044}, {0x8a9c, 0x0044}, -{0x8a9d, 0x001b}, {0x8a9e, 0x00d6}, {0x8a9f, 0x0022}, -{0x8aa0, 0x00c4}, {0x8aa1, 0x00af}, {0x8aa2, 0x0020}, -{0x8aa3, 0x0011}, {0x8aa4, 0x0058}, {0x8aa5, 0x0081}, -{0x8aa6, 0x0027}, {0x8aa7, 0x0026}, {0x8aa8, 0x000f}, -{0x8aa9, 0x0096}, {0x8aaa, 0x0022}, {0x8aab, 0x0084}, -{0x8aac, 0x0080}, {0x8aad, 0x0044}, {0x8aae, 0x0044}, -{0x8aaf, 0x0044}, {0x8ab0, 0x001b}, {0x8ab1, 0x00d6}, -{0x8ab2, 0x0022}, {0x8ab3, 0x00c4}, {0x8ab4, 0x006f}, -{0x8ab5, 0x001b}, {0x8ab6, 0x0097}, {0x8ab7, 0x0022}, -{0x8ab8, 0x0039}, {0x8ab9, 0x0027}, {0x8aba, 0x000c}, -{0x8abb, 0x007c}, {0x8abc, 0x0082}, {0x8abd, 0x0006}, -{0x8abe, 0x00bd}, {0x8abf, 0x00d9}, {0x8ac0, 0x00ed}, -{0x8ac1, 0x00b6}, {0x8ac2, 0x0082}, {0x8ac3, 0x0007}, -{0x8ac4, 0x007e}, {0x8ac5, 0x008a}, {0x8ac6, 0x00b9}, -{0x8ac7, 0x007f}, {0x8ac8, 0x0082}, {0x8ac9, 0x0006}, -{0x8aca, 0x0039}, { 0x0, 0x0 } -}; -#endif - - /* phy types */ #define CAS_PHY_UNKNOWN 0x00 #define CAS_PHY_SERDES 0x01 @@ -4389,6 +2872,11 @@ struct cas { dma_addr_t block_dvma, tx_tiny_dvma[N_TX_RINGS]; struct pci_dev *pdev; struct net_device *dev; + + /* Firmware Info */ + u16 fw_load_addr; + u32 fw_size; + u8 *fw_data; }; #define TX_DESC_NEXT(r, x) (((x) + 1) & (TX_DESC_RINGN_SIZE(r) - 1)) diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c index ea6144a9565..b0b66766ed2 100644 --- a/drivers/net/cs89x0.c +++ b/drivers/net/cs89x0.c @@ -1397,9 +1397,7 @@ net_open(struct net_device *dev) release_dma: #if ALLOW_DMA free_dma(dev->dma); -#endif release_irq: -#if ALLOW_DMA release_dma_buff(lp); #endif writereg(dev, PP_LineCTL, readreg(dev, PP_LineCTL) & ~(SERIAL_TX_ON | SERIAL_RX_ON)); diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h index 271140433b0..4f5cc6987ec 100644 --- a/drivers/net/cxgb3/adapter.h +++ b/drivers/net/cxgb3/adapter.h @@ -124,8 +124,7 @@ struct sge_rspq { /* state for an SGE response queue */ dma_addr_t phys_addr; /* physical address of the ring */ unsigned int cntxt_id; /* SGE context id for the response q */ spinlock_t lock; /* guards response processing */ - struct sk_buff *rx_head; /* offload packet receive queue head */ - struct sk_buff *rx_tail; /* offload packet receive queue tail */ + struct sk_buff_head rx_queue; /* offload packet receive queue */ struct sk_buff *pg_skb; /* used to build frag list in napi handler */ unsigned long offload_pkts; diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c index c5b3de1bb45..0f6fd63b284 100644 --- a/drivers/net/cxgb3/cxgb3_offload.c +++ b/drivers/net/cxgb3/cxgb3_offload.c @@ -1018,7 +1018,7 @@ static void set_l2t_ix(struct t3cdev *tdev, u32 tid, struct l2t_entry *e) skb = alloc_skb(sizeof(*req), GFP_ATOMIC); if (!skb) { - printk(KERN_ERR "%s: cannot allocate skb!\n", __FUNCTION__); + printk(KERN_ERR "%s: cannot allocate skb!\n", __func__); return; } skb->priority = CPL_PRIORITY_CONTROL; @@ -1049,14 +1049,14 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) return; if (!is_offloading(newdev)) { printk(KERN_WARNING "%s: Redirect to non-offload " - "device ignored.\n", __FUNCTION__); + "device ignored.\n", __func__); return; } tdev = dev2t3cdev(olddev); BUG_ON(!tdev); if (tdev != dev2t3cdev(newdev)) { printk(KERN_WARNING "%s: Redirect to different " - "offload device ignored.\n", __FUNCTION__); + "offload device ignored.\n", __func__); return; } @@ -1064,7 +1064,7 @@ void cxgb_redirect(struct dst_entry *old, struct dst_entry *new) e = t3_l2t_get(tdev, new->neighbour, newdev); if (!e) { printk(KERN_ERR "%s: couldn't allocate new l2t entry!\n", - __FUNCTION__); + __func__); return; } diff --git a/drivers/net/cxgb3/l2t.c b/drivers/net/cxgb3/l2t.c index 825e510bd9e..b2c5314582a 100644 --- a/drivers/net/cxgb3/l2t.c +++ b/drivers/net/cxgb3/l2t.c @@ -86,6 +86,7 @@ static int setup_l2e_send_pending(struct t3cdev *dev, struct sk_buff *skb, struct l2t_entry *e) { struct cpl_l2t_write_req *req; + struct sk_buff *tmp; if (!skb) { skb = alloc_skb(sizeof(*req), GFP_ATOMIC); @@ -103,13 +104,11 @@ static int setup_l2e_send_pending(struct t3cdev *dev, struct sk_buff *skb, memcpy(req->dst_mac, e->dmac, sizeof(req->dst_mac)); skb->priority = CPL_PRIORITY_CONTROL; cxgb3_ofld_send(dev, skb); - while (e->arpq_head) { - skb = e->arpq_head; - e->arpq_head = skb->next; - skb->next = NULL; + + skb_queue_walk_safe(&e->arpq, skb, tmp) { + __skb_unlink(skb, &e->arpq); cxgb3_ofld_send(dev, skb); } - e->arpq_tail = NULL; e->state = L2T_STATE_VALID; return 0; @@ -121,12 +120,7 @@ static int setup_l2e_send_pending(struct t3cdev *dev, struct sk_buff *skb, */ static inline void arpq_enqueue(struct l2t_entry *e, struct sk_buff *skb) { - skb->next = NULL; - if (e->arpq_head) - e->arpq_tail->next = skb; - else - e->arpq_head = skb; - e->arpq_tail = skb; + __skb_queue_tail(&e->arpq, skb); } int t3_l2t_send_slow(struct t3cdev *dev, struct sk_buff *skb, @@ -167,7 +161,7 @@ again: break; spin_lock_bh(&e->lock); - if (e->arpq_head) + if (!skb_queue_empty(&e->arpq)) setup_l2e_send_pending(dev, skb, e); else /* we lost the race */ __kfree_skb(skb); @@ -357,14 +351,14 @@ EXPORT_SYMBOL(t3_l2t_get); * XXX: maybe we should abandon the latter behavior and just require a failure * handler. */ -static void handle_failed_resolution(struct t3cdev *dev, struct sk_buff *arpq) +static void handle_failed_resolution(struct t3cdev *dev, struct sk_buff_head *arpq) { - while (arpq) { - struct sk_buff *skb = arpq; + struct sk_buff *skb, *tmp; + + skb_queue_walk_safe(arpq, skb, tmp) { struct l2t_skb_cb *cb = L2T_SKB_CB(skb); - arpq = skb->next; - skb->next = NULL; + __skb_unlink(skb, arpq); if (cb->arp_failure_handler) cb->arp_failure_handler(dev, skb); else @@ -378,8 +372,8 @@ static void handle_failed_resolution(struct t3cdev *dev, struct sk_buff *arpq) */ void t3_l2t_update(struct t3cdev *dev, struct neighbour *neigh) { + struct sk_buff_head arpq; struct l2t_entry *e; - struct sk_buff *arpq = NULL; struct l2t_data *d = L2DATA(dev); u32 addr = *(u32 *) neigh->primary_key; int ifidx = neigh->dev->ifindex; @@ -395,6 +389,8 @@ void t3_l2t_update(struct t3cdev *dev, struct neighbour *neigh) return; found: + __skb_queue_head_init(&arpq); + read_unlock(&d->lock); if (atomic_read(&e->refcnt)) { if (neigh != e->neigh) @@ -402,8 +398,7 @@ found: if (e->state == L2T_STATE_RESOLVING) { if (neigh->nud_state & NUD_FAILED) { - arpq = e->arpq_head; - e->arpq_head = e->arpq_tail = NULL; + skb_queue_splice_init(&e->arpq, &arpq); } else if (neigh->nud_state & (NUD_CONNECTED|NUD_STALE)) setup_l2e_send_pending(dev, NULL, e); } else { @@ -415,8 +410,8 @@ found: } spin_unlock_bh(&e->lock); - if (arpq) - handle_failed_resolution(dev, arpq); + if (!skb_queue_empty(&arpq)) + handle_failed_resolution(dev, &arpq); } struct l2t_data *t3_init_l2t(unsigned int l2t_capacity) diff --git a/drivers/net/cxgb3/l2t.h b/drivers/net/cxgb3/l2t.h index d79001336cf..42ce65f76a8 100644 --- a/drivers/net/cxgb3/l2t.h +++ b/drivers/net/cxgb3/l2t.h @@ -64,8 +64,7 @@ struct l2t_entry { struct neighbour *neigh; /* associated neighbour */ struct l2t_entry *first; /* start of hash chain */ struct l2t_entry *next; /* next l2t_entry on chain */ - struct sk_buff *arpq_head; /* queue of packets awaiting resolution */ - struct sk_buff *arpq_tail; + struct sk_buff_head arpq; /* queue of packets awaiting resolution */ spinlock_t lock; atomic_t refcnt; /* entry reference count */ u8 dmac[6]; /* neighbour's MAC address */ diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c index 1b0861d73ab..89efd04be4e 100644 --- a/drivers/net/cxgb3/sge.c +++ b/drivers/net/cxgb3/sge.c @@ -1704,16 +1704,15 @@ int t3_offload_tx(struct t3cdev *tdev, struct sk_buff *skb) */ static inline void offload_enqueue(struct sge_rspq *q, struct sk_buff *skb) { - skb->next = skb->prev = NULL; - if (q->rx_tail) - q->rx_tail->next = skb; - else { + int was_empty = skb_queue_empty(&q->rx_queue); + + __skb_queue_tail(&q->rx_queue, skb); + + if (was_empty) { struct sge_qset *qs = rspq_to_qset(q); napi_schedule(&qs->napi); - q->rx_head = skb; } - q->rx_tail = skb; } /** @@ -1754,26 +1753,29 @@ static int ofld_poll(struct napi_struct *napi, int budget) int work_done = 0; while (work_done < budget) { - struct sk_buff *head, *tail, *skbs[RX_BUNDLE_SIZE]; + struct sk_buff *skb, *tmp, *skbs[RX_BUNDLE_SIZE]; + struct sk_buff_head queue; int ngathered; spin_lock_irq(&q->lock); - head = q->rx_head; - if (!head) { + __skb_queue_head_init(&queue); + skb_queue_splice_init(&q->rx_queue, &queue); + if (skb_queue_empty(&queue)) { napi_complete(napi); spin_unlock_irq(&q->lock); return work_done; } - - tail = q->rx_tail; - q->rx_head = q->rx_tail = NULL; spin_unlock_irq(&q->lock); - for (ngathered = 0; work_done < budget && head; work_done++) { - prefetch(head->data); - skbs[ngathered] = head; - head = head->next; - skbs[ngathered]->next = NULL; + ngathered = 0; + skb_queue_walk_safe(&queue, skb, tmp) { + if (work_done >= budget) + break; + work_done++; + + __skb_unlink(skb, &queue); + prefetch(skb->data); + skbs[ngathered] = skb; if (++ngathered == RX_BUNDLE_SIZE) { q->offload_bundles++; adapter->tdev.recv(&adapter->tdev, skbs, @@ -1781,12 +1783,10 @@ static int ofld_poll(struct napi_struct *napi, int budget) ngathered = 0; } } - if (head) { /* splice remaining packets back onto Rx queue */ + if (!skb_queue_empty(&queue)) { + /* splice remaining packets back onto Rx queue */ spin_lock_irq(&q->lock); - tail->next = q->rx_head; - if (!q->rx_head) - q->rx_tail = tail; - q->rx_head = head; + skb_queue_splice(&queue, &q->rx_queue); spin_unlock_irq(&q->lock); } deliver_partial_bundle(&adapter->tdev, q, skbs, ngathered); @@ -1937,38 +1937,6 @@ static inline int lro_frame_ok(const struct cpl_rx_pkt *p) eh->h_proto == htons(ETH_P_IP) && ih->ihl == (sizeof(*ih) >> 2); } -#define TCP_FLAG_MASK (TCP_FLAG_CWR | TCP_FLAG_ECE | TCP_FLAG_URG |\ - TCP_FLAG_ACK | TCP_FLAG_PSH | TCP_FLAG_RST |\ - TCP_FLAG_SYN | TCP_FLAG_FIN) -#define TSTAMP_WORD ((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |\ - (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP) - -/** - * lro_segment_ok - check if a TCP segment is eligible for LRO - * @tcph: the TCP header of the packet - * - * Returns true if a TCP packet is eligible for LRO. This requires that - * the packet have only the ACK flag set and no TCP options besides - * time stamps. - */ -static inline int lro_segment_ok(const struct tcphdr *tcph) -{ - int optlen; - - if (unlikely((tcp_flag_word(tcph) & TCP_FLAG_MASK) != TCP_FLAG_ACK)) - return 0; - - optlen = (tcph->doff << 2) - sizeof(*tcph); - if (optlen) { - const u32 *opt = (const u32 *)(tcph + 1); - - if (optlen != TCPOLEN_TSTAMP_ALIGNED || - *opt != htonl(TSTAMP_WORD) || !opt[2]) - return 0; - } - return 1; -} - static int t3_get_lro_header(void **eh, void **iph, void **tcph, u64 *hdr_flags, void *priv) { @@ -1981,9 +1949,6 @@ static int t3_get_lro_header(void **eh, void **iph, void **tcph, *iph = (struct iphdr *)((struct ethhdr *)*eh + 1); *tcph = (struct tcphdr *)((struct iphdr *)*iph + 1); - if (!lro_segment_ok(*tcph)) - return -1; - *hdr_flags = LRO_IPV4 | LRO_TCP; return 0; } @@ -2934,6 +2899,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports, q->rspq.gen = 1; q->rspq.size = p->rspq_size; spin_lock_init(&q->rspq.lock); + skb_queue_head_init(&q->rspq.rx_queue); q->txq[TXQ_ETH].stop_thres = nports * flits_to_desc(sgl_len(MAX_SKB_FRAGS + 1) + 3); diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 453115acaad..3d69fae781c 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -191,7 +191,7 @@ MODULE_PARM_DESC(use_io, "Force use of i/o access mode"); #define DPRINTK(nlevel, klevel, fmt, args...) \ (void)((NETIF_MSG_##nlevel & nic->msg_enable) && \ printk(KERN_##klevel PFX "%s: %s: " fmt, nic->netdev->name, \ - __FUNCTION__ , ## args)) + __func__ , ## args)) #define INTEL_8255X_ETHERNET_DEVICE(device_id, ich) {\ PCI_VENDOR_ID_INTEL, device_id, PCI_ANY_ID, PCI_ANY_ID, \ @@ -2738,9 +2738,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, nic->flags |= wol_magic; /* ack any pending wake events, disable PME */ - err = pci_enable_wake(pdev, 0, 0); - if (err) - DPRINTK(PROBE, ERR, "Error clearing wake event\n"); + pci_pme_active(pdev, false); strcpy(netdev->name, "eth%d"); if((err = register_netdev(netdev))) { diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h index 19e317eaf5b..62f62970f97 100644 --- a/drivers/net/e1000/e1000.h +++ b/drivers/net/e1000/e1000.h @@ -155,8 +155,6 @@ do { \ #endif #define E1000_MNG_VLAN_NONE (-1) -/* Number of packet split data buffers (not including the header buffer) */ -#define PS_PAGE_BUFFERS (MAX_PS_BUFFERS - 1) /* wrapper around a pointer to a socket buffer, * so a DMA handle can be stored along with the buffer */ @@ -168,14 +166,6 @@ struct e1000_buffer { u16 next_to_watch; }; -struct e1000_ps_page { - struct page *ps_page[PS_PAGE_BUFFERS]; -}; - -struct e1000_ps_page_dma { - u64 ps_page_dma[PS_PAGE_BUFFERS]; -}; - struct e1000_tx_ring { /* pointer to the descriptor ring memory */ void *desc; @@ -213,9 +203,6 @@ struct e1000_rx_ring { unsigned int next_to_clean; /* array of buffer information structs */ struct e1000_buffer *buffer_info; - /* arrays of page information for packet split */ - struct e1000_ps_page *ps_page; - struct e1000_ps_page_dma *ps_page_dma; /* cpu for rx queue */ int cpu; @@ -228,8 +215,6 @@ struct e1000_rx_ring { ((((R)->next_to_clean > (R)->next_to_use) \ ? 0 : (R)->count) + (R)->next_to_clean - (R)->next_to_use - 1) -#define E1000_RX_DESC_PS(R, i) \ - (&(((union e1000_rx_desc_packet_split *)((R).desc))[i])) #define E1000_RX_DESC_EXT(R, i) \ (&(((union e1000_rx_desc_extended *)((R).desc))[i])) #define E1000_GET_DESC(R, i, type) (&(((struct type *)((R).desc))[i])) @@ -311,10 +296,8 @@ struct e1000_adapter { u32 rx_int_delay; u32 rx_abs_int_delay; bool rx_csum; - unsigned int rx_ps_pages; u32 gorcl; u64 gorcl_old; - u16 rx_ps_bsize0; /* OS defined structs */ struct net_device *netdev; diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c index 9d6edf3e73f..d04eef53571 100644 --- a/drivers/net/e1000/e1000_hw.c +++ b/drivers/net/e1000/e1000_hw.c @@ -144,6 +144,8 @@ static s32 e1000_host_if_read_cookie(struct e1000_hw *hw, u8 *buffer); static u8 e1000_calculate_mng_checksum(char *buffer, u32 length); static s32 e1000_configure_kmrn_for_10_100(struct e1000_hw *hw, u16 duplex); static s32 e1000_configure_kmrn_for_1000(struct e1000_hw *hw); +static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); +static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); /* IGP cable length table */ static const @@ -168,6 +170,8 @@ u16 e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] = 83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124, 104, 109, 114, 118, 121, 124}; +static DEFINE_SPINLOCK(e1000_eeprom_lock); + /****************************************************************************** * Set the phy type member in the hw struct. * @@ -4904,6 +4908,15 @@ static s32 e1000_spi_eeprom_ready(struct e1000_hw *hw) *****************************************************************************/ s32 e1000_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { + s32 ret; + spin_lock(&e1000_eeprom_lock); + ret = e1000_do_read_eeprom(hw, offset, words, data); + spin_unlock(&e1000_eeprom_lock); + return ret; +} + +static s32 e1000_do_read_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +{ struct e1000_eeprom_info *eeprom = &hw->eeprom; u32 i = 0; @@ -5236,6 +5249,16 @@ s32 e1000_update_eeprom_checksum(struct e1000_hw *hw) *****************************************************************************/ s32 e1000_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) { + s32 ret; + spin_lock(&e1000_eeprom_lock); + ret = e1000_do_write_eeprom(hw, offset, words, data); + spin_unlock(&e1000_eeprom_lock); + return ret; +} + + +static s32 e1000_do_write_eeprom(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +{ struct e1000_eeprom_info *eeprom = &hw->eeprom; s32 status = 0; diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ad6da7b67e5..2ab44db29fa 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -137,15 +137,9 @@ static int e1000_clean(struct napi_struct *napi, int budget); static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, struct e1000_rx_ring *rx_ring, int *work_done, int work_to_do); -static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring, - int *work_done, int work_to_do); static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, struct e1000_rx_ring *rx_ring, int cleaned_count); -static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring, - int cleaned_count); static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); @@ -1331,7 +1325,6 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter) pci_read_config_word(pdev, PCI_COMMAND, &hw->pci_cmd_word); adapter->rx_buffer_len = MAXIMUM_ETHERNET_VLAN_SIZE; - adapter->rx_ps_bsize0 = E1000_RXBUFFER_128; hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE; hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE; @@ -1815,26 +1808,6 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter, } memset(rxdr->buffer_info, 0, size); - rxdr->ps_page = kcalloc(rxdr->count, sizeof(struct e1000_ps_page), - GFP_KERNEL); - if (!rxdr->ps_page) { - vfree(rxdr->buffer_info); - DPRINTK(PROBE, ERR, - "Unable to allocate memory for the receive descriptor ring\n"); - return -ENOMEM; - } - - rxdr->ps_page_dma = kcalloc(rxdr->count, - sizeof(struct e1000_ps_page_dma), - GFP_KERNEL); - if (!rxdr->ps_page_dma) { - vfree(rxdr->buffer_info); - kfree(rxdr->ps_page); - DPRINTK(PROBE, ERR, - "Unable to allocate memory for the receive descriptor ring\n"); - return -ENOMEM; - } - if (hw->mac_type <= e1000_82547_rev_2) desc_len = sizeof(struct e1000_rx_desc); else @@ -1852,8 +1825,6 @@ static int e1000_setup_rx_resources(struct e1000_adapter *adapter, "Unable to allocate memory for the receive descriptor ring\n"); setup_rx_desc_die: vfree(rxdr->buffer_info); - kfree(rxdr->ps_page); - kfree(rxdr->ps_page_dma); return -ENOMEM; } @@ -1932,11 +1903,7 @@ int e1000_setup_all_rx_resources(struct e1000_adapter *adapter) static void e1000_setup_rctl(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; - u32 rctl, rfctl; - u32 psrctl = 0; -#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT - u32 pages = 0; -#endif + u32 rctl; rctl = er32(RCTL); @@ -1988,55 +1955,6 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) break; } -#ifndef CONFIG_E1000_DISABLE_PACKET_SPLIT - /* 82571 and greater support packet-split where the protocol - * header is placed in skb->data and the packet data is - * placed in pages hanging off of skb_shinfo(skb)->nr_frags. - * In the case of a non-split, skb->data is linearly filled, - * followed by the page buffers. Therefore, skb->data is - * sized to hold the largest protocol header. - */ - /* allocations using alloc_page take too long for regular MTU - * so only enable packet split for jumbo frames */ - pages = PAGE_USE_COUNT(adapter->netdev->mtu); - if ((hw->mac_type >= e1000_82571) && (pages <= 3) && - PAGE_SIZE <= 16384 && (rctl & E1000_RCTL_LPE)) - adapter->rx_ps_pages = pages; - else - adapter->rx_ps_pages = 0; -#endif - if (adapter->rx_ps_pages) { - /* Configure extra packet-split registers */ - rfctl = er32(RFCTL); - rfctl |= E1000_RFCTL_EXTEN; - /* disable packet split support for IPv6 extension headers, - * because some malformed IPv6 headers can hang the RX */ - rfctl |= (E1000_RFCTL_IPV6_EX_DIS | - E1000_RFCTL_NEW_IPV6_EXT_DIS); - - ew32(RFCTL, rfctl); - - rctl |= E1000_RCTL_DTYP_PS; - - psrctl |= adapter->rx_ps_bsize0 >> - E1000_PSRCTL_BSIZE0_SHIFT; - - switch (adapter->rx_ps_pages) { - case 3: - psrctl |= PAGE_SIZE << - E1000_PSRCTL_BSIZE3_SHIFT; - case 2: - psrctl |= PAGE_SIZE << - E1000_PSRCTL_BSIZE2_SHIFT; - case 1: - psrctl |= PAGE_SIZE >> - E1000_PSRCTL_BSIZE1_SHIFT; - break; - } - - ew32(PSRCTL, psrctl); - } - ew32(RCTL, rctl); } @@ -2053,18 +1971,10 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; u32 rdlen, rctl, rxcsum, ctrl_ext; - if (adapter->rx_ps_pages) { - /* this is a 32 byte descriptor */ - rdlen = adapter->rx_ring[0].count * - sizeof(union e1000_rx_desc_packet_split); - adapter->clean_rx = e1000_clean_rx_irq_ps; - adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps; - } else { - rdlen = adapter->rx_ring[0].count * - sizeof(struct e1000_rx_desc); - adapter->clean_rx = e1000_clean_rx_irq; - adapter->alloc_rx_buf = e1000_alloc_rx_buffers; - } + rdlen = adapter->rx_ring[0].count * + sizeof(struct e1000_rx_desc); + adapter->clean_rx = e1000_clean_rx_irq; + adapter->alloc_rx_buf = e1000_alloc_rx_buffers; /* disable receives while setting up the descriptors */ rctl = er32(RCTL); @@ -2109,28 +2019,14 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) /* Enable 82543 Receive Checksum Offload for TCP and UDP */ if (hw->mac_type >= e1000_82543) { rxcsum = er32(RXCSUM); - if (adapter->rx_csum) { + if (adapter->rx_csum) rxcsum |= E1000_RXCSUM_TUOFL; - - /* Enable 82571 IPv4 payload checksum for UDP fragments - * Must be used in conjunction with packet-split. */ - if ((hw->mac_type >= e1000_82571) && - (adapter->rx_ps_pages)) { - rxcsum |= E1000_RXCSUM_IPPCSE; - } - } else { - rxcsum &= ~E1000_RXCSUM_TUOFL; + else /* don't need to clear IPPCSE as it defaults to 0 */ - } + rxcsum &= ~E1000_RXCSUM_TUOFL; ew32(RXCSUM, rxcsum); } - /* enable early receives on 82573, only takes effect if using > 2048 - * byte total frame size. for example only for jumbo frames */ -#define E1000_ERT_2048 0x100 - if (hw->mac_type == e1000_82573) - ew32(ERT, E1000_ERT_2048); - /* Enable Receives */ ew32(RCTL, rctl); } @@ -2256,10 +2152,6 @@ static void e1000_free_rx_resources(struct e1000_adapter *adapter, vfree(rx_ring->buffer_info); rx_ring->buffer_info = NULL; - kfree(rx_ring->ps_page); - rx_ring->ps_page = NULL; - kfree(rx_ring->ps_page_dma); - rx_ring->ps_page_dma = NULL; pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma); @@ -2292,11 +2184,9 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter, { struct e1000_hw *hw = &adapter->hw; struct e1000_buffer *buffer_info; - struct e1000_ps_page *ps_page; - struct e1000_ps_page_dma *ps_page_dma; struct pci_dev *pdev = adapter->pdev; unsigned long size; - unsigned int i, j; + unsigned int i; /* Free all the Rx ring sk_buffs */ for (i = 0; i < rx_ring->count; i++) { @@ -2310,25 +2200,10 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter, dev_kfree_skb(buffer_info->skb); buffer_info->skb = NULL; } - ps_page = &rx_ring->ps_page[i]; - ps_page_dma = &rx_ring->ps_page_dma[i]; - for (j = 0; j < adapter->rx_ps_pages; j++) { - if (!ps_page->ps_page[j]) break; - pci_unmap_page(pdev, - ps_page_dma->ps_page_dma[j], - PAGE_SIZE, PCI_DMA_FROMDEVICE); - ps_page_dma->ps_page_dma[j] = 0; - put_page(ps_page->ps_page[j]); - ps_page->ps_page[j] = NULL; - } } size = sizeof(struct e1000_buffer) * rx_ring->count; memset(rx_ring->buffer_info, 0, size); - size = sizeof(struct e1000_ps_page) * rx_ring->count; - memset(rx_ring->ps_page, 0, size); - size = sizeof(struct e1000_ps_page_dma) * rx_ring->count; - memset(rx_ring->ps_page_dma, 0, size); /* Zero out the descriptor ring */ @@ -4235,181 +4110,6 @@ next_desc: } /** - * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split - * @adapter: board private structure - **/ - -static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring, - int *work_done, int work_to_do) -{ - union e1000_rx_desc_packet_split *rx_desc, *next_rxd; - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - struct e1000_buffer *buffer_info, *next_buffer; - struct e1000_ps_page *ps_page; - struct e1000_ps_page_dma *ps_page_dma; - struct sk_buff *skb; - unsigned int i, j; - u32 length, staterr; - int cleaned_count = 0; - bool cleaned = false; - unsigned int total_rx_bytes=0, total_rx_packets=0; - - i = rx_ring->next_to_clean; - rx_desc = E1000_RX_DESC_PS(*rx_ring, i); - staterr = le32_to_cpu(rx_desc->wb.middle.status_error); - buffer_info = &rx_ring->buffer_info[i]; - - while (staterr & E1000_RXD_STAT_DD) { - ps_page = &rx_ring->ps_page[i]; - ps_page_dma = &rx_ring->ps_page_dma[i]; - - if (unlikely(*work_done >= work_to_do)) - break; - (*work_done)++; - - skb = buffer_info->skb; - - /* in the packet split case this is header only */ - prefetch(skb->data - NET_IP_ALIGN); - - if (++i == rx_ring->count) i = 0; - next_rxd = E1000_RX_DESC_PS(*rx_ring, i); - prefetch(next_rxd); - - next_buffer = &rx_ring->buffer_info[i]; - - cleaned = true; - cleaned_count++; - pci_unmap_single(pdev, buffer_info->dma, - buffer_info->length, - PCI_DMA_FROMDEVICE); - - if (unlikely(!(staterr & E1000_RXD_STAT_EOP))) { - E1000_DBG("%s: Packet Split buffers didn't pick up" - " the full packet\n", netdev->name); - dev_kfree_skb_irq(skb); - goto next_desc; - } - - if (unlikely(staterr & E1000_RXDEXT_ERR_FRAME_ERR_MASK)) { - dev_kfree_skb_irq(skb); - goto next_desc; - } - - length = le16_to_cpu(rx_desc->wb.middle.length0); - - if (unlikely(!length)) { - E1000_DBG("%s: Last part of the packet spanning" - " multiple descriptors\n", netdev->name); - dev_kfree_skb_irq(skb); - goto next_desc; - } - - /* Good Receive */ - skb_put(skb, length); - - { - /* this looks ugly, but it seems compiler issues make it - more efficient than reusing j */ - int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]); - - /* page alloc/put takes too long and effects small packet - * throughput, so unsplit small packets and save the alloc/put*/ - if (l1 && (l1 <= copybreak) && ((length + l1) <= adapter->rx_ps_bsize0)) { - u8 *vaddr; - /* there is no documentation about how to call - * kmap_atomic, so we can't hold the mapping - * very long */ - pci_dma_sync_single_for_cpu(pdev, - ps_page_dma->ps_page_dma[0], - PAGE_SIZE, - PCI_DMA_FROMDEVICE); - vaddr = kmap_atomic(ps_page->ps_page[0], - KM_SKB_DATA_SOFTIRQ); - memcpy(skb_tail_pointer(skb), vaddr, l1); - kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ); - pci_dma_sync_single_for_device(pdev, - ps_page_dma->ps_page_dma[0], - PAGE_SIZE, PCI_DMA_FROMDEVICE); - /* remove the CRC */ - l1 -= 4; - skb_put(skb, l1); - goto copydone; - } /* if */ - } - - for (j = 0; j < adapter->rx_ps_pages; j++) { - length = le16_to_cpu(rx_desc->wb.upper.length[j]); - if (!length) - break; - pci_unmap_page(pdev, ps_page_dma->ps_page_dma[j], - PAGE_SIZE, PCI_DMA_FROMDEVICE); - ps_page_dma->ps_page_dma[j] = 0; - skb_fill_page_desc(skb, j, ps_page->ps_page[j], 0, - length); - ps_page->ps_page[j] = NULL; - skb->len += length; - skb->data_len += length; - skb->truesize += length; - } - - /* strip the ethernet crc, problem is we're using pages now so - * this whole operation can get a little cpu intensive */ - pskb_trim(skb, skb->len - 4); - -copydone: - total_rx_bytes += skb->len; - total_rx_packets++; - - e1000_rx_checksum(adapter, staterr, - le16_to_cpu(rx_desc->wb.lower.hi_dword.csum_ip.csum), skb); - skb->protocol = eth_type_trans(skb, netdev); - - if (likely(rx_desc->wb.upper.header_status & - cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP))) - adapter->rx_hdr_split++; - - if (unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) { - vlan_hwaccel_receive_skb(skb, adapter->vlgrp, - le16_to_cpu(rx_desc->wb.middle.vlan)); - } else { - netif_receive_skb(skb); - } - - netdev->last_rx = jiffies; - -next_desc: - rx_desc->wb.middle.status_error &= cpu_to_le32(~0xFF); - buffer_info->skb = NULL; - - /* return some buffers to hardware, one at a time is too slow */ - if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) { - adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count); - cleaned_count = 0; - } - - /* use prefetched values */ - rx_desc = next_rxd; - buffer_info = next_buffer; - - staterr = le32_to_cpu(rx_desc->wb.middle.status_error); - } - rx_ring->next_to_clean = i; - - cleaned_count = E1000_DESC_UNUSED(rx_ring); - if (cleaned_count) - adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count); - - adapter->total_rx_packets += total_rx_packets; - adapter->total_rx_bytes += total_rx_bytes; - adapter->net_stats.rx_bytes += total_rx_bytes; - adapter->net_stats.rx_packets += total_rx_packets; - return cleaned; -} - -/** * e1000_alloc_rx_buffers - Replace used receive buffers; legacy & extended * @adapter: address of board private structure **/ @@ -4521,104 +4221,6 @@ map_skb: } /** - * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split - * @adapter: address of board private structure - **/ - -static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring, - int cleaned_count) -{ - struct e1000_hw *hw = &adapter->hw; - struct net_device *netdev = adapter->netdev; - struct pci_dev *pdev = adapter->pdev; - union e1000_rx_desc_packet_split *rx_desc; - struct e1000_buffer *buffer_info; - struct e1000_ps_page *ps_page; - struct e1000_ps_page_dma *ps_page_dma; - struct sk_buff *skb; - unsigned int i, j; - - i = rx_ring->next_to_use; - buffer_info = &rx_ring->buffer_info[i]; - ps_page = &rx_ring->ps_page[i]; - ps_page_dma = &rx_ring->ps_page_dma[i]; - - while (cleaned_count--) { - rx_desc = E1000_RX_DESC_PS(*rx_ring, i); - - for (j = 0; j < PS_PAGE_BUFFERS; j++) { - if (j < adapter->rx_ps_pages) { - if (likely(!ps_page->ps_page[j])) { - ps_page->ps_page[j] = - alloc_page(GFP_ATOMIC); - if (unlikely(!ps_page->ps_page[j])) { - adapter->alloc_rx_buff_failed++; - goto no_buffers; - } - ps_page_dma->ps_page_dma[j] = - pci_map_page(pdev, - ps_page->ps_page[j], - 0, PAGE_SIZE, - PCI_DMA_FROMDEVICE); - } - /* Refresh the desc even if buffer_addrs didn't - * change because each write-back erases - * this info. - */ - rx_desc->read.buffer_addr[j+1] = - cpu_to_le64(ps_page_dma->ps_page_dma[j]); - } else - rx_desc->read.buffer_addr[j+1] = ~cpu_to_le64(0); - } - - skb = netdev_alloc_skb(netdev, - adapter->rx_ps_bsize0 + NET_IP_ALIGN); - - if (unlikely(!skb)) { - adapter->alloc_rx_buff_failed++; - break; - } - - /* Make buffer alignment 2 beyond a 16 byte boundary - * this will result in a 16 byte aligned IP header after - * the 14 byte MAC header is removed - */ - skb_reserve(skb, NET_IP_ALIGN); - - buffer_info->skb = skb; - buffer_info->length = adapter->rx_ps_bsize0; - buffer_info->dma = pci_map_single(pdev, skb->data, - adapter->rx_ps_bsize0, - PCI_DMA_FROMDEVICE); - - rx_desc->read.buffer_addr[0] = cpu_to_le64(buffer_info->dma); - - if (unlikely(++i == rx_ring->count)) i = 0; - buffer_info = &rx_ring->buffer_info[i]; - ps_page = &rx_ring->ps_page[i]; - ps_page_dma = &rx_ring->ps_page_dma[i]; - } - -no_buffers: - if (likely(rx_ring->next_to_use != i)) { - rx_ring->next_to_use = i; - if (unlikely(i-- == 0)) i = (rx_ring->count - 1); - - /* Force memory writes to complete before letting h/w - * know there are new descriptors to fetch. (Only - * applicable for weak-ordered memory model archs, - * such as IA-64). */ - wmb(); - /* Hardware increments by 16 bytes, but packet split - * descriptors are 32 bytes...so we increment tail - * twice as much. - */ - writel(i<<1, hw->hw_addr + rx_ring->rdt); - } -} - -/** * e1000_smartspeed - Workaround for SmartSpeed on 82541 and 82547 controllers. * @adapter: **/ diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 019b9c0bcdc..692251b6091 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -398,6 +398,8 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) if (!timeout) { hw_dbg(hw, "FW or HW has locked the resource for too long.\n"); + extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; + ew32(EXTCNF_CTRL, extcnf_ctrl); return -E1000_ERR_CONFIG; } diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 0925204cd2d..24d05cb7005 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c @@ -4671,13 +4671,15 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter) ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf); if (!(le16_to_cpu(buf) & (1 << 0))) { /* Deep Smart Power Down (DSPD) */ - e_warn("Warning: detected DSPD enabled in EEPROM\n"); + dev_warn(&adapter->pdev->dev, + "Warning: detected DSPD enabled in EEPROM\n"); } ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf); if (le16_to_cpu(buf) & (3 << 2)) { /* ASPM enable */ - e_warn("Warning: detected ASPM enabled in EEPROM\n"); + dev_warn(&adapter->pdev->dev, + "Warning: detected ASPM enabled in EEPROM\n"); } } diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index e01926b7b5b..5524271eedc 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -40,13 +40,13 @@ #include <asm/io.h> #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0092" +#define DRV_VERSION "EHEA_0093" /* eHEA capability flags */ #define DLPAR_PORT_ADD_REM 1 #define DLPAR_MEM_ADD 2 #define DLPAR_MEM_REM 4 -#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM | DLPAR_MEM_ADD) +#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM | DLPAR_MEM_ADD | DLPAR_MEM_REM) #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \ | NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR) diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c index 156eb6320b4..2a33a613d9e 100644 --- a/drivers/net/ehea/ehea_phyp.c +++ b/drivers/net/ehea/ehea_phyp.c @@ -535,7 +535,7 @@ u64 ehea_h_query_ehea(const u64 adapter_handle, void *cb_addr) cb_logaddr, /* R5 */ 0, 0, 0, 0, 0); /* R6-R10 */ #ifdef DEBUG - ehea_dmp(cb_addr, sizeof(struct hcp_query_ehea), "hcp_query_ehea"); + ehea_dump(cb_addr, sizeof(struct hcp_query_ehea), "hcp_query_ehea"); #endif return hret; } diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index 140f05baafd..db8a9257e68 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -595,7 +595,8 @@ static int ehea_create_busmap_callback(unsigned long pfn, end_section = start_section + ((nr_pages * PAGE_SIZE) / EHEA_SECTSIZE); mr_len = *(unsigned long *)arg; - ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL); + if (!ehea_bmap) + ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL); if (!ehea_bmap) return -ENOMEM; diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index aa0bf6e1c69..e1b441effbb 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -110,7 +110,7 @@ spi_read_buf(struct enc28j60_net *priv, int len, u8 *data) } if (ret && netif_msg_drv(priv)) printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n", - __FUNCTION__, ret); + __func__, ret); return ret; } @@ -131,7 +131,7 @@ static int spi_write_buf(struct enc28j60_net *priv, int len, ret = spi_write(priv->spi, priv->spi_transfer_buf, len + 1); if (ret && netif_msg_drv(priv)) printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n", - __FUNCTION__, ret); + __func__, ret); } return ret; } @@ -156,7 +156,7 @@ static u8 spi_read_op(struct enc28j60_net *priv, u8 op, ret = spi_write_then_read(priv->spi, tx_buf, 1, rx_buf, slen); if (ret) printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n", - __FUNCTION__, ret); + __func__, ret); else val = rx_buf[slen - 1]; @@ -176,14 +176,14 @@ static int spi_write_op(struct enc28j60_net *priv, u8 op, ret = spi_write(priv->spi, priv->spi_transfer_buf, 2); if (ret && netif_msg_drv(priv)) printk(KERN_DEBUG DRV_NAME ": %s() failed: ret = %d\n", - __FUNCTION__, ret); + __func__, ret); return ret; } static void enc28j60_soft_reset(struct enc28j60_net *priv) { if (netif_msg_hw(priv)) - printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__); + printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__); spi_write_op(priv, ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET); /* Errata workaround #1, CLKRDY check is unreliable, @@ -357,7 +357,7 @@ static void enc28j60_mem_read(struct enc28j60_net *priv, reg = nolock_regw_read(priv, ERDPTL); if (reg != addr) printk(KERN_DEBUG DRV_NAME ": %s() error writing ERDPT " - "(0x%04x - 0x%04x)\n", __FUNCTION__, reg, addr); + "(0x%04x - 0x%04x)\n", __func__, reg, addr); } #endif spi_read_buf(priv, len, data); @@ -380,7 +380,7 @@ enc28j60_packet_write(struct enc28j60_net *priv, int len, const u8 *data) if (reg != TXSTART_INIT) printk(KERN_DEBUG DRV_NAME ": %s() ERWPT:0x%04x != 0x%04x\n", - __FUNCTION__, reg, TXSTART_INIT); + __func__, reg, TXSTART_INIT); } #endif /* Set the TXND pointer to correspond to the packet size given */ @@ -390,13 +390,13 @@ enc28j60_packet_write(struct enc28j60_net *priv, int len, const u8 *data) if (netif_msg_hw(priv)) printk(KERN_DEBUG DRV_NAME ": %s() after control byte ERWPT:0x%04x\n", - __FUNCTION__, nolock_regw_read(priv, EWRPTL)); + __func__, nolock_regw_read(priv, EWRPTL)); /* copy the packet into the transmit buffer */ spi_write_buf(priv, len, data); if (netif_msg_hw(priv)) printk(KERN_DEBUG DRV_NAME ": %s() after write packet ERWPT:0x%04x, len=%d\n", - __FUNCTION__, nolock_regw_read(priv, EWRPTL), len); + __func__, nolock_regw_read(priv, EWRPTL), len); mutex_unlock(&priv->lock); } @@ -495,7 +495,7 @@ static int enc28j60_set_hw_macaddr(struct net_device *ndev) if (netif_msg_drv(priv)) printk(KERN_DEBUG DRV_NAME ": %s() Hardware must be disabled to set " - "Mac address\n", __FUNCTION__); + "Mac address\n", __func__); ret = -EBUSY; } mutex_unlock(&priv->lock); @@ -575,7 +575,7 @@ static void nolock_rxfifo_init(struct enc28j60_net *priv, u16 start, u16 end) if (start > 0x1FFF || end > 0x1FFF || start > end) { if (netif_msg_drv(priv)) printk(KERN_ERR DRV_NAME ": %s(%d, %d) RXFIFO " - "bad parameters!\n", __FUNCTION__, start, end); + "bad parameters!\n", __func__, start, end); return; } /* set receive buffer start + end */ @@ -591,7 +591,7 @@ static void nolock_txfifo_init(struct enc28j60_net *priv, u16 start, u16 end) if (start > 0x1FFF || end > 0x1FFF || start > end) { if (netif_msg_drv(priv)) printk(KERN_ERR DRV_NAME ": %s(%d, %d) TXFIFO " - "bad parameters!\n", __FUNCTION__, start, end); + "bad parameters!\n", __func__, start, end); return; } /* set transmit buffer start + end */ @@ -630,7 +630,7 @@ static int enc28j60_hw_init(struct enc28j60_net *priv) u8 reg; if (netif_msg_drv(priv)) - printk(KERN_DEBUG DRV_NAME ": %s() - %s\n", __FUNCTION__, + printk(KERN_DEBUG DRV_NAME ": %s() - %s\n", __func__, priv->full_duplex ? "FullDuplex" : "HalfDuplex"); mutex_lock(&priv->lock); @@ -661,7 +661,7 @@ static int enc28j60_hw_init(struct enc28j60_net *priv) if (reg == 0x00 || reg == 0xff) { if (netif_msg_drv(priv)) printk(KERN_DEBUG DRV_NAME ": %s() Invalid RevId %d\n", - __FUNCTION__, reg); + __func__, reg); return 0; } @@ -724,7 +724,7 @@ static void enc28j60_hw_enable(struct enc28j60_net *priv) /* enable interrupts */ if (netif_msg_hw(priv)) printk(KERN_DEBUG DRV_NAME ": %s() enabling interrupts.\n", - __FUNCTION__); + __func__); enc28j60_phy_write(priv, PHIE, PHIE_PGEIE | PHIE_PLNKIE); @@ -888,7 +888,7 @@ static void enc28j60_hw_rx(struct net_device *ndev) if (netif_msg_rx_err(priv)) dev_err(&ndev->dev, "%s() Invalid packet address!! 0x%04x\n", - __FUNCTION__, priv->next_pk_ptr); + __func__, priv->next_pk_ptr); /* packet address corrupted: reset RX logic */ mutex_lock(&priv->lock); nolock_reg_bfclr(priv, ECON1, ECON1_RXEN); @@ -917,7 +917,7 @@ static void enc28j60_hw_rx(struct net_device *ndev) rxstat |= rsv[4]; if (netif_msg_rx_status(priv)) - enc28j60_dump_rsv(priv, __FUNCTION__, next_packet, len, rxstat); + enc28j60_dump_rsv(priv, __func__, next_packet, len, rxstat); if (!RSV_GETBIT(rxstat, RSV_RXOK)) { if (netif_msg_rx_err(priv)) @@ -941,7 +941,7 @@ static void enc28j60_hw_rx(struct net_device *ndev) enc28j60_mem_read(priv, priv->next_pk_ptr + sizeof(rsv), len, skb_put(skb, len)); if (netif_msg_pktdata(priv)) - dump_packet(__FUNCTION__, skb->len, skb->data); + dump_packet(__func__, skb->len, skb->data); skb->protocol = eth_type_trans(skb, ndev); /* update statistics */ ndev->stats.rx_packets++; @@ -958,7 +958,7 @@ static void enc28j60_hw_rx(struct net_device *ndev) erxrdpt = erxrdpt_workaround(next_packet, RXSTART_INIT, RXEND_INIT); if (netif_msg_hw(priv)) printk(KERN_DEBUG DRV_NAME ": %s() ERXRDPT:0x%04x\n", - __FUNCTION__, erxrdpt); + __func__, erxrdpt); mutex_lock(&priv->lock); nolock_regw_write(priv, ERXRDPTL, erxrdpt); @@ -968,7 +968,7 @@ static void enc28j60_hw_rx(struct net_device *ndev) reg = nolock_regw_read(priv, ERXRDPTL); if (reg != erxrdpt) printk(KERN_DEBUG DRV_NAME ": %s() ERXRDPT verify " - "error (0x%04x - 0x%04x)\n", __FUNCTION__, + "error (0x%04x - 0x%04x)\n", __func__, reg, erxrdpt); } #endif @@ -1006,7 +1006,7 @@ static int enc28j60_get_free_rxfifo(struct enc28j60_net *priv) mutex_unlock(&priv->lock); if (netif_msg_rx_status(priv)) printk(KERN_DEBUG DRV_NAME ": %s() free_space = %d\n", - __FUNCTION__, free_space); + __func__, free_space); return free_space; } @@ -1022,7 +1022,7 @@ static void enc28j60_check_link_status(struct net_device *ndev) reg = enc28j60_phy_read(priv, PHSTAT2); if (netif_msg_hw(priv)) printk(KERN_DEBUG DRV_NAME ": %s() PHSTAT1: %04x, " - "PHSTAT2: %04x\n", __FUNCTION__, + "PHSTAT2: %04x\n", __func__, enc28j60_phy_read(priv, PHSTAT1), reg); duplex = reg & PHSTAT2_DPXSTAT; @@ -1095,7 +1095,7 @@ static void enc28j60_irq_work_handler(struct work_struct *work) int intflags, loop; if (netif_msg_intr(priv)) - printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__); + printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__); /* disable further interrupts */ locked_reg_bfclr(priv, EIE, EIE_INTIE); @@ -1198,7 +1198,7 @@ static void enc28j60_irq_work_handler(struct work_struct *work) /* re-enable interrupts */ locked_reg_bfset(priv, EIE, EIE_INTIE); if (netif_msg_intr(priv)) - printk(KERN_DEBUG DRV_NAME ": %s() exit\n", __FUNCTION__); + printk(KERN_DEBUG DRV_NAME ": %s() exit\n", __func__); } /* @@ -1213,7 +1213,7 @@ static void enc28j60_hw_tx(struct enc28j60_net *priv) ": Tx Packet Len:%d\n", priv->tx_skb->len); if (netif_msg_pktdata(priv)) - dump_packet(__FUNCTION__, + dump_packet(__func__, priv->tx_skb->len, priv->tx_skb->data); enc28j60_packet_write(priv, priv->tx_skb->len, priv->tx_skb->data); @@ -1254,7 +1254,7 @@ static int enc28j60_send_packet(struct sk_buff *skb, struct net_device *dev) struct enc28j60_net *priv = netdev_priv(dev); if (netif_msg_tx_queued(priv)) - printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__); + printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__); /* If some error occurs while trying to transmit this * packet, you should return '1' from this function. @@ -1325,7 +1325,7 @@ static int enc28j60_net_open(struct net_device *dev) struct enc28j60_net *priv = netdev_priv(dev); if (netif_msg_drv(priv)) - printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__); + printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__); if (!is_valid_ether_addr(dev->dev_addr)) { if (netif_msg_ifup(priv)) { @@ -1363,7 +1363,7 @@ static int enc28j60_net_close(struct net_device *dev) struct enc28j60_net *priv = netdev_priv(dev); if (netif_msg_drv(priv)) - printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __FUNCTION__); + printk(KERN_DEBUG DRV_NAME ": %s() enter\n", __func__); enc28j60_hw_disable(priv); enc28j60_lowpower(priv, true); diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h index fb83c926da5..7f677e89a78 100644 --- a/drivers/net/enic/enic.h +++ b/drivers/net/enic/enic.h @@ -33,7 +33,7 @@ #define DRV_NAME "enic" #define DRV_DESCRIPTION "Cisco 10G Ethernet Driver" -#define DRV_VERSION "0.0.1.18163.472" +#define DRV_VERSION "0.0.1-18163.472-k1" #define DRV_COPYRIGHT "Copyright 2008 Cisco Systems, Inc" #define PFX DRV_NAME ": " @@ -75,7 +75,6 @@ struct enic { struct vnic_enet_config config; struct vnic_dev_bar bar0; struct vnic_dev *vdev; - struct net_device_stats net_stats; struct timer_list notify_timer; struct work_struct reset; struct msix_entry msix_entry[ENIC_MSIX_MAX]; diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index 4cf5ec76c99..f3a47a87dbb 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c @@ -43,7 +43,6 @@ #include "enic.h" #define ENIC_NOTIFY_TIMER_PERIOD (2 * HZ) -#define ENIC_JUMBO_FIRST_BUF_SIZE 256 /* Supported devices */ static struct pci_device_id enic_id_table[] = { @@ -167,9 +166,14 @@ static void enic_get_strings(struct net_device *netdev, u32 stringset, u8 *data) } } -static int enic_get_stats_count(struct net_device *netdev) +static int enic_get_sset_count(struct net_device *netdev, int sset) { - return enic_n_tx_stats + enic_n_rx_stats; + switch (sset) { + case ETH_SS_STATS: + return enic_n_tx_stats + enic_n_rx_stats; + default: + return -EOPNOTSUPP; + } } static void enic_get_ethtool_stats(struct net_device *netdev, @@ -199,8 +203,10 @@ static int enic_set_rx_csum(struct net_device *netdev, u32 data) { struct enic *enic = netdev_priv(netdev); - enic->csum_rx_enabled = - (data && ENIC_SETTING(enic, RXCSUM)) ? 1 : 0; + if (data && !ENIC_SETTING(enic, RXCSUM)) + return -EINVAL; + + enic->csum_rx_enabled = !!data; return 0; } @@ -209,7 +215,10 @@ static int enic_set_tx_csum(struct net_device *netdev, u32 data) { struct enic *enic = netdev_priv(netdev); - if (data && ENIC_SETTING(enic, TXCSUM)) + if (data && !ENIC_SETTING(enic, TXCSUM)) + return -EINVAL; + + if (data) netdev->features |= NETIF_F_HW_CSUM; else netdev->features &= ~NETIF_F_HW_CSUM; @@ -221,7 +230,10 @@ static int enic_set_tso(struct net_device *netdev, u32 data) { struct enic *enic = netdev_priv(netdev); - if (data && ENIC_SETTING(enic, TSO)) + if (data && !ENIC_SETTING(enic, TSO)) + return -EINVAL; + + if (data) netdev->features |= NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_TSO_ECN; else @@ -250,7 +262,7 @@ static struct ethtool_ops enic_ethtool_ops = { .set_msglevel = enic_set_msglevel, .get_link = ethtool_op_get_link, .get_strings = enic_get_strings, - .get_stats_count = enic_get_stats_count, + .get_sset_count = enic_get_sset_count, .get_ethtool_stats = enic_get_ethtool_stats, .get_rx_csum = enic_get_rx_csum, .set_rx_csum = enic_set_rx_csum, @@ -652,25 +664,26 @@ static int enic_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) static struct net_device_stats *enic_get_stats(struct net_device *netdev) { struct enic *enic = netdev_priv(netdev); + struct net_device_stats *net_stats = &netdev->stats; struct vnic_stats *stats; spin_lock(&enic->devcmd_lock); vnic_dev_stats_dump(enic->vdev, &stats); spin_unlock(&enic->devcmd_lock); - enic->net_stats.tx_packets = stats->tx.tx_frames_ok; - enic->net_stats.tx_bytes = stats->tx.tx_bytes_ok; - enic->net_stats.tx_errors = stats->tx.tx_errors; - enic->net_stats.tx_dropped = stats->tx.tx_drops; + net_stats->tx_packets = stats->tx.tx_frames_ok; + net_stats->tx_bytes = stats->tx.tx_bytes_ok; + net_stats->tx_errors = stats->tx.tx_errors; + net_stats->tx_dropped = stats->tx.tx_drops; - enic->net_stats.rx_packets = stats->rx.rx_frames_ok; - enic->net_stats.rx_bytes = stats->rx.rx_bytes_ok; - enic->net_stats.rx_errors = stats->rx.rx_errors; - enic->net_stats.multicast = stats->rx.rx_multicast_frames_ok; - enic->net_stats.rx_crc_errors = stats->rx.rx_crc_errors; - enic->net_stats.rx_dropped = stats->rx.rx_no_bufs; + net_stats->rx_packets = stats->rx.rx_frames_ok; + net_stats->rx_bytes = stats->rx.rx_bytes_ok; + net_stats->rx_errors = stats->rx.rx_errors; + net_stats->multicast = stats->rx.rx_multicast_frames_ok; + net_stats->rx_crc_errors = stats->rx.rx_crc_errors; + net_stats->rx_dropped = stats->rx.rx_no_bufs; - return &enic->net_stats; + return net_stats; } static void enic_reset_mcaddrs(struct enic *enic) @@ -941,7 +954,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, if (enic->vlan_group && vlan_stripped) { - if (ENIC_SETTING(enic, LRO)) + if (ENIC_SETTING(enic, LRO) && ipv4) lro_vlan_hwaccel_receive_skb(&enic->lro_mgr, skb, enic->vlan_group, vlan, cq_desc); @@ -951,7 +964,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq, } else { - if (ENIC_SETTING(enic, LRO)) + if (ENIC_SETTING(enic, LRO) && ipv4) lro_receive_skb(&enic->lro_mgr, skb, cq_desc); else netif_receive_skb(skb); @@ -1109,7 +1122,8 @@ static void enic_notify_timer(unsigned long data) enic_notify_check(enic); - mod_timer(&enic->notify_timer, round_jiffies(ENIC_NOTIFY_TIMER_PERIOD)); + mod_timer(&enic->notify_timer, + round_jiffies(jiffies + ENIC_NOTIFY_TIMER_PERIOD)); } static void enic_free_intr(struct enic *enic) @@ -1119,9 +1133,11 @@ static void enic_free_intr(struct enic *enic) switch (vnic_dev_get_intr_mode(enic->vdev)) { case VNIC_DEV_INTR_MODE_INTX: - case VNIC_DEV_INTR_MODE_MSI: free_irq(enic->pdev->irq, netdev); break; + case VNIC_DEV_INTR_MODE_MSI: + free_irq(enic->pdev->irq, enic); + break; case VNIC_DEV_INTR_MODE_MSIX: for (i = 0; i < ARRAY_SIZE(enic->msix); i++) if (enic->msix[i].requested) @@ -1156,12 +1172,12 @@ static int enic_request_intr(struct enic *enic) case VNIC_DEV_INTR_MODE_MSIX: sprintf(enic->msix[ENIC_MSIX_RQ].devname, - "%.11s-rx", netdev->name); + "%.11s-rx-0", netdev->name); enic->msix[ENIC_MSIX_RQ].isr = enic_isr_msix_rq; enic->msix[ENIC_MSIX_RQ].devid = enic; sprintf(enic->msix[ENIC_MSIX_WQ].devname, - "%.11s-tx", netdev->name); + "%.11s-tx-0", netdev->name); enic->msix[ENIC_MSIX_WQ].isr = enic_isr_msix_wq; enic->msix[ENIC_MSIX_WQ].devid = enic; @@ -1234,13 +1250,28 @@ static int enic_open(struct net_device *netdev) unsigned int i; int err; + err = enic_request_intr(enic); + if (err) { + printk(KERN_ERR PFX "%s: Unable to request irq.\n", + netdev->name); + return err; + } + + err = enic_notify_set(enic); + if (err) { + printk(KERN_ERR PFX + "%s: Failed to alloc notify buffer, aborting.\n", + netdev->name); + goto err_out_free_intr; + } + for (i = 0; i < enic->rq_count; i++) { err = vnic_rq_fill(&enic->rq[i], enic_rq_alloc_buf); if (err) { printk(KERN_ERR PFX "%s: Unable to alloc receive buffers.\n", netdev->name); - return err; + goto err_out_notify_unset; } } @@ -1262,6 +1293,13 @@ static int enic_open(struct net_device *netdev) enic_notify_timer_start(enic); return 0; + +err_out_notify_unset: + vnic_dev_notify_unset(enic->vdev); +err_out_free_intr: + enic_free_intr(enic); + + return err; } /* rtnl lock is held, process context */ @@ -1291,6 +1329,9 @@ static int enic_stop(struct net_device *netdev) return err; } + vnic_dev_notify_unset(enic->vdev); + enic_free_intr(enic); + (void)vnic_cq_service(&enic->cq[ENIC_CQ_RQ], -1, enic_rq_service_drop, NULL); (void)vnic_cq_service(&enic->cq[ENIC_CQ_WQ], @@ -1313,14 +1354,12 @@ static int enic_change_mtu(struct net_device *netdev, int new_mtu) struct enic *enic = netdev_priv(netdev); int running = netif_running(netdev); + if (new_mtu < ENIC_MIN_MTU || new_mtu > ENIC_MAX_MTU) + return -EINVAL; + if (running) enic_stop(netdev); - if (new_mtu < ENIC_MIN_MTU) - new_mtu = ENIC_MIN_MTU; - if (new_mtu > ENIC_MAX_MTU) - new_mtu = ENIC_MAX_MTU; - netdev->mtu = new_mtu; if (netdev->mtu > enic->port_mtu) @@ -1578,18 +1617,6 @@ static int __devinit enic_probe(struct pci_dev *pdev, return -ENOMEM; } - /* Set the netdev name early so intr vectors are properly - * named and any error msgs can include netdev->name - */ - - rtnl_lock(); - err = dev_alloc_name(netdev, netdev->name); - rtnl_unlock(); - if (err < 0) { - printk(KERN_ERR PFX "Unable to allocate netdev name.\n"); - goto err_out_free_netdev; - } - pci_set_drvdata(pdev, netdev); SET_NETDEV_DEV(netdev, &pdev->dev); @@ -1604,16 +1631,14 @@ static int __devinit enic_probe(struct pci_dev *pdev, err = pci_enable_device(pdev); if (err) { printk(KERN_ERR PFX - "%s: Cannot enable PCI device, aborting.\n", - netdev->name); + "Cannot enable PCI device, aborting.\n"); goto err_out_free_netdev; } err = pci_request_regions(pdev, DRV_NAME); if (err) { printk(KERN_ERR PFX - "%s: Cannot request PCI regions, aborting.\n", - netdev->name); + "Cannot request PCI regions, aborting.\n"); goto err_out_disable_device; } @@ -1629,25 +1654,22 @@ static int __devinit enic_probe(struct pci_dev *pdev, err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); if (err) { printk(KERN_ERR PFX - "%s: No usable DMA configuration, aborting.\n", - netdev->name); + "No usable DMA configuration, aborting.\n"); goto err_out_release_regions; } err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); if (err) { printk(KERN_ERR PFX - "%s: Unable to obtain 32-bit DMA " - "for consistent allocations, aborting.\n", - netdev->name); + "Unable to obtain 32-bit DMA " + "for consistent allocations, aborting.\n"); goto err_out_release_regions; } } else { err = pci_set_consistent_dma_mask(pdev, DMA_40BIT_MASK); if (err) { printk(KERN_ERR PFX - "%s: Unable to obtain 40-bit DMA " - "for consistent allocations, aborting.\n", - netdev->name); + "Unable to obtain 40-bit DMA " + "for consistent allocations, aborting.\n"); goto err_out_release_regions; } using_dac = 1; @@ -1658,8 +1680,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) { printk(KERN_ERR PFX - "%s: BAR0 not memory-map'able, aborting.\n", - netdev->name); + "BAR0 not memory-map'able, aborting.\n"); err = -ENODEV; goto err_out_release_regions; } @@ -1670,8 +1691,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, if (!enic->bar0.vaddr) { printk(KERN_ERR PFX - "%s: Cannot memory-map BAR0 res hdr, aborting.\n", - netdev->name); + "Cannot memory-map BAR0 res hdr, aborting.\n"); err = -ENODEV; goto err_out_release_regions; } @@ -1682,8 +1702,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, enic->vdev = vnic_dev_register(NULL, enic, pdev, &enic->bar0); if (!enic->vdev) { printk(KERN_ERR PFX - "%s: vNIC registration failed, aborting.\n", - netdev->name); + "vNIC registration failed, aborting.\n"); err = -ENODEV; goto err_out_iounmap; } @@ -1694,8 +1713,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, err = enic_dev_open(enic); if (err) { printk(KERN_ERR PFX - "%s: vNIC dev open failed, aborting.\n", - netdev->name); + "vNIC dev open failed, aborting.\n"); goto err_out_vnic_unregister; } @@ -1712,8 +1730,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, err = vnic_dev_init(enic->vdev, 0); if (err) { printk(KERN_ERR PFX - "%s: vNIC dev init failed, aborting.\n", - netdev->name); + "vNIC dev init failed, aborting.\n"); goto err_out_dev_close; } @@ -1723,8 +1740,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, err = enic_get_vnic_config(enic); if (err) { printk(KERN_ERR PFX - "%s: Get vNIC configuration failed, aborting.\n", - netdev->name); + "Get vNIC configuration failed, aborting.\n"); goto err_out_dev_close; } @@ -1740,18 +1756,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, err = enic_set_intr_mode(enic); if (err) { printk(KERN_ERR PFX - "%s: Failed to set intr mode, aborting.\n", - netdev->name); - goto err_out_dev_close; - } - - /* Request interrupt vector(s) - */ - - err = enic_request_intr(enic); - if (err) { - printk(KERN_ERR PFX "%s: Unable to request irq.\n", - netdev->name); + "Failed to set intr mode, aborting.\n"); goto err_out_dev_close; } @@ -1761,8 +1766,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, err = enic_alloc_vnic_resources(enic); if (err) { printk(KERN_ERR PFX - "%s: Failed to alloc vNIC resources, aborting.\n", - netdev->name); + "Failed to alloc vNIC resources, aborting.\n"); goto err_out_free_vnic_resources; } @@ -1778,19 +1782,7 @@ static int __devinit enic_probe(struct pci_dev *pdev, ig_vlan_strip_en); if (err) { printk(KERN_ERR PFX - "%s: Failed to config nic, aborting.\n", - netdev->name); - goto err_out_free_vnic_resources; - } - - /* Setup notification buffer area - */ - - err = enic_notify_set(enic); - if (err) { - printk(KERN_ERR PFX - "%s: Failed to alloc notify buffer, aborting.\n", - netdev->name); + "Failed to config nic, aborting.\n"); goto err_out_free_vnic_resources; } @@ -1817,9 +1809,8 @@ static int __devinit enic_probe(struct pci_dev *pdev, err = enic_set_mac_addr(netdev, enic->mac_addr); if (err) { printk(KERN_ERR PFX - "%s: Invalid MAC address, aborting.\n", - netdev->name); - goto err_out_notify_unset; + "Invalid MAC address, aborting.\n"); + goto err_out_free_vnic_resources; } netdev->open = enic_open; @@ -1873,18 +1864,14 @@ static int __devinit enic_probe(struct pci_dev *pdev, err = register_netdev(netdev); if (err) { printk(KERN_ERR PFX - "%s: Cannot register net device, aborting.\n", - netdev->name); - goto err_out_notify_unset; + "Cannot register net device, aborting.\n"); + goto err_out_free_vnic_resources; } return 0; -err_out_notify_unset: - vnic_dev_notify_unset(enic->vdev); err_out_free_vnic_resources: enic_free_vnic_resources(enic); - enic_free_intr(enic); err_out_dev_close: vnic_dev_close(enic->vdev); err_out_vnic_unregister: @@ -1912,9 +1899,7 @@ static void __devexit enic_remove(struct pci_dev *pdev) flush_scheduled_work(); unregister_netdev(netdev); - vnic_dev_notify_unset(enic->vdev); enic_free_vnic_resources(enic); - enic_free_intr(enic); vnic_dev_close(enic->vdev); enic_clear_intr_mode(enic); vnic_dev_unregister(enic->vdev); diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 0b6ecef9a84..cc7328b1552 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -337,7 +337,7 @@ enum { NvRegMSIXIrqStatus = 0x3f0, NvRegPowerState2 = 0x600, -#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F11 +#define NVREG_POWERSTATE2_POWERUP_MASK 0x0F15 #define NVREG_POWERSTATE2_POWERUP_REV_A3 0x0001 #define NVREG_POWERSTATE2_PHY_RESET 0x0004 }; @@ -5643,6 +5643,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i dev->dev_addr[4] = (np->orig_mac[0] >> 8) & 0xff; dev->dev_addr[5] = (np->orig_mac[0] >> 0) & 0xff; writel(txreg|NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll); + printk(KERN_DEBUG "nv_probe: set workaround bit for reversed mac addr\n"); } memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); @@ -5890,14 +5891,12 @@ static void nv_restore_phy(struct net_device *dev) } } -static void __devexit nv_remove(struct pci_dev *pci_dev) +static void nv_restore_mac_addr(struct pci_dev *pci_dev) { struct net_device *dev = pci_get_drvdata(pci_dev); struct fe_priv *np = netdev_priv(dev); u8 __iomem *base = get_hwbase(dev); - unregister_netdev(dev); - /* special op: write back the misordered MAC address - otherwise * the next nv_probe would see a wrong address. */ @@ -5905,6 +5904,15 @@ static void __devexit nv_remove(struct pci_dev *pci_dev) writel(np->orig_mac[1], base + NvRegMacAddrB); writel(readl(base + NvRegTransmitPoll) & ~NVREG_TRANSMITPOLL_MAC_ADDR_REV, base + NvRegTransmitPoll); +} + +static void __devexit nv_remove(struct pci_dev *pci_dev) +{ + struct net_device *dev = pci_get_drvdata(pci_dev); + + unregister_netdev(dev); + + nv_restore_mac_addr(pci_dev); /* restore any phy related changes */ nv_restore_phy(dev); @@ -5975,6 +5983,8 @@ static void nv_shutdown(struct pci_dev *pdev) if (netif_running(dev)) nv_close(dev); + nv_restore_mac_addr(pdev); + pci_disable_device(pdev); if (system_state == SYSTEM_POWER_OFF) { if (pci_enable_wake(pdev, PCI_D3cold, np->wolenabled)) diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index 9d461825bf4..cb51c1fb033 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -664,23 +664,6 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } -static int fs_request_irq(struct net_device *dev, int irq, const char *name, - irq_handler_t irqf) -{ - struct fs_enet_private *fep = netdev_priv(dev); - - (*fep->ops->pre_request_irq)(dev, irq); - return request_irq(irq, irqf, IRQF_SHARED, name, dev); -} - -static void fs_free_irq(struct net_device *dev, int irq) -{ - struct fs_enet_private *fep = netdev_priv(dev); - - free_irq(irq, dev); - (*fep->ops->post_free_irq)(dev, irq); -} - static void fs_timeout(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); @@ -800,7 +783,8 @@ static int fs_enet_open(struct net_device *dev) napi_enable(&fep->napi); /* Install our interrupt handler. */ - r = fs_request_irq(dev, fep->interrupt, "fs_enet-mac", fs_enet_interrupt); + r = request_irq(fep->interrupt, fs_enet_interrupt, IRQF_SHARED, + "fs_enet-mac", dev); if (r != 0) { printk(KERN_ERR DRV_MODULE_NAME ": %s Could not allocate FS_ENET IRQ!", dev->name); @@ -842,7 +826,7 @@ static int fs_enet_close(struct net_device *dev) /* release any irqs */ phy_disconnect(fep->phydev); fep->phydev = NULL; - fs_free_irq(dev, fep->interrupt); + free_irq(fep->interrupt, dev); return 0; } diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h index db46d2e7232..85a4bab7f63 100644 --- a/drivers/net/fs_enet/fs_enet.h +++ b/drivers/net/fs_enet/fs_enet.h @@ -34,8 +34,6 @@ struct fs_ops { void (*adjust_link)(struct net_device *dev); void (*restart)(struct net_device *dev); void (*stop)(struct net_device *dev); - void (*pre_request_irq)(struct net_device *dev, int irq); - void (*post_free_irq)(struct net_device *dev, int irq); void (*napi_clear_rx_event)(struct net_device *dev); void (*napi_enable_rx)(struct net_device *dev); void (*napi_disable_rx)(struct net_device *dev); diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index 1c7ef812a8e..22e5a847a58 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -421,16 +421,6 @@ static void stop(struct net_device *dev) fs_cleanup_bds(dev); } -static void pre_request_irq(struct net_device *dev, int irq) -{ - /* nothing */ -} - -static void post_free_irq(struct net_device *dev, int irq) -{ - /* nothing */ -} - static void napi_clear_rx_event(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); @@ -540,8 +530,6 @@ const struct fs_ops fs_fcc_ops = { .set_multicast_list = set_multicast_list, .restart = restart, .stop = stop, - .pre_request_irq = pre_request_irq, - .post_free_irq = post_free_irq, .napi_clear_rx_event = napi_clear_rx_event, .napi_enable_rx = napi_enable_rx, .napi_disable_rx = napi_disable_rx, diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index 0a7d1c5c652..14e575313c8 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -313,11 +313,7 @@ static void restart(struct net_device *dev) * Clear any outstanding interrupt. */ FW(fecp, ievent, 0xffc0); -#ifndef CONFIG_PPC_MERGE - FW(fecp, ivec, (fep->interrupt / 2) << 29); -#else FW(fecp, ivec, (virq_to_hw(fep->interrupt) / 2) << 29); -#endif /* * adjust to speed (only for DUET & RMII) @@ -413,30 +409,6 @@ static void stop(struct net_device *dev) } } -static void pre_request_irq(struct net_device *dev, int irq) -{ -#ifndef CONFIG_PPC_MERGE - immap_t *immap = fs_enet_immap; - u32 siel; - - /* SIU interrupt */ - if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) { - - siel = in_be32(&immap->im_siu_conf.sc_siel); - if ((irq & 1) == 0) - siel |= (0x80000000 >> irq); - else - siel &= ~(0x80000000 >> (irq & ~1)); - out_be32(&immap->im_siu_conf.sc_siel, siel); - } -#endif -} - -static void post_free_irq(struct net_device *dev, int irq) -{ - /* nothing */ -} - static void napi_clear_rx_event(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); @@ -529,8 +501,6 @@ const struct fs_ops fs_fec_ops = { .set_multicast_list = set_multicast_list, .restart = restart, .stop = stop, - .pre_request_irq = pre_request_irq, - .post_free_irq = post_free_irq, .napi_clear_rx_event = napi_clear_rx_event, .napi_enable_rx = napi_enable_rx, .napi_disable_rx = napi_disable_rx, diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index 22f50dd8b27..008cdd9cc53 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -377,30 +377,6 @@ static void stop(struct net_device *dev) fs_cleanup_bds(dev); } -static void pre_request_irq(struct net_device *dev, int irq) -{ -#ifndef CONFIG_PPC_MERGE - immap_t *immap = fs_enet_immap; - u32 siel; - - /* SIU interrupt */ - if (irq >= SIU_IRQ0 && irq < SIU_LEVEL7) { - - siel = in_be32(&immap->im_siu_conf.sc_siel); - if ((irq & 1) == 0) - siel |= (0x80000000 >> irq); - else - siel &= ~(0x80000000 >> (irq & ~1)); - out_be32(&immap->im_siu_conf.sc_siel, siel); - } -#endif -} - -static void post_free_irq(struct net_device *dev, int irq) -{ - /* nothing */ -} - static void napi_clear_rx_event(struct net_device *dev) { struct fs_enet_private *fep = netdev_priv(dev); @@ -494,8 +470,6 @@ const struct fs_ops fs_scc_ops = { .set_multicast_list = set_multicast_list, .restart = restart, .stop = stop, - .pre_request_irq = pre_request_irq, - .post_free_irq = post_free_irq, .napi_clear_rx_event = napi_clear_rx_event, .napi_enable_rx = napi_enable_rx, .napi_disable_rx = napi_disable_rx, diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c index ebcfb27a904..678f48c6911 100644 --- a/drivers/net/gianfar_mii.c +++ b/drivers/net/gianfar_mii.c @@ -136,12 +136,12 @@ static int gfar_mdio_reset(struct mii_bus *bus) /* Wait until the bus is free */ while ((gfar_read(®s->miimind) & MIIMIND_BUSY) && - timeout--) + --timeout) cpu_relax(); mutex_unlock(&bus->mdio_lock); - if(timeout <= 0) { + if(timeout == 0) { printk(KERN_ERR "%s: The MII Bus is stuck!\n", bus->name); return -EBUSY; @@ -211,19 +211,21 @@ static int gfar_mdio_probe(struct device *dev) gfar_write(&enet_regs->tbipa, 0); for (i = PHY_MAX_ADDR; i > 0; i--) { u32 phy_id; - int r; - r = get_phy_id(new_bus, i, &phy_id); - if (r) - return r; + err = get_phy_id(new_bus, i, &phy_id); + if (err) + goto bus_register_fail; if (phy_id == 0xffffffff) break; } /* The bus is full. We don't support using 31 PHYs, sorry */ - if (i == 0) - return -EBUSY; + if (i == 0) { + err = -EBUSY; + + goto bus_register_fail; + } gfar_write(&enet_regs->tbipa, i); diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c index 8239939554b..fbbd3e660c2 100644 --- a/drivers/net/hp-plus.c +++ b/drivers/net/hp-plus.c @@ -139,7 +139,7 @@ static int __init do_hpp_probe(struct net_device *dev) #ifndef MODULE struct net_device * __init hp_plus_probe(int unit) { - struct net_device *dev = alloc_ei_netdev(); + struct net_device *dev = alloc_eip_netdev(); int err; if (!dev) @@ -284,7 +284,7 @@ hpp_open(struct net_device *dev) int option_reg; int retval; - if ((retval = request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))) { + if ((retval = request_irq(dev->irq, eip_interrupt, 0, dev->name, dev))) { return retval; } @@ -302,7 +302,7 @@ hpp_open(struct net_device *dev) /* Select the operational page. */ outw(Perf_Page, ioaddr + HP_PAGING); - ei_open(dev); + eip_open(dev); return 0; } @@ -313,7 +313,7 @@ hpp_close(struct net_device *dev) int option_reg = inw(ioaddr + HPP_OPTION); free_irq(dev->irq, dev); - ei_close(dev); + eip_close(dev); outw((option_reg & ~EnableIRQ) | MemDisable | NICReset | ChipReset, ioaddr + HPP_OPTION); diff --git a/drivers/net/ibm_newemac/Kconfig b/drivers/net/ibm_newemac/Kconfig index 70a3272ee99..bcec7320895 100644 --- a/drivers/net/ibm_newemac/Kconfig +++ b/drivers/net/ibm_newemac/Kconfig @@ -1,6 +1,6 @@ config IBM_NEW_EMAC tristate "IBM EMAC Ethernet support" - depends on PPC_DCR && PPC_MERGE + depends on PPC_DCR select CRC32 help This driver supports the IBM EMAC family of Ethernet controllers diff --git a/drivers/net/ibm_newemac/phy.c b/drivers/net/ibm_newemac/phy.c index 37bfeea8788..9164abb72d9 100644 --- a/drivers/net/ibm_newemac/phy.c +++ b/drivers/net/ibm_newemac/phy.c @@ -321,7 +321,7 @@ static struct mii_phy_def bcm5248_phy_def = { static int m88e1111_init(struct mii_phy *phy) { - pr_debug("%s: Marvell 88E1111 Ethernet\n", __FUNCTION__); + pr_debug("%s: Marvell 88E1111 Ethernet\n", __func__); phy_write(phy, 0x14, 0x0ce3); phy_write(phy, 0x18, 0x4101); phy_write(phy, 0x09, 0x0e00); diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c index 18f4b3a96ae..9c926d205de 100644 --- a/drivers/net/irda/vlsi_ir.c +++ b/drivers/net/irda/vlsi_ir.c @@ -165,7 +165,7 @@ static void vlsi_proc_pdev(struct seq_file *seq, struct pci_dev *pdev) unsigned iobase = pci_resource_start(pdev, 0); unsigned i; - seq_printf(seq, "\n%s (vid/did: %04x/%04x)\n", + seq_printf(seq, "\n%s (vid/did: [%04x:%04x])\n", pci_name(pdev), (int)pdev->vendor, (int)pdev->device); seq_printf(seq, "pci-power-state: %u\n", (unsigned) pdev->current_state); seq_printf(seq, "resources: irq=%u / io=0x%04x / dma_mask=0x%016Lx\n", diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h index 804698fc6a8..d85717e3022 100644 --- a/drivers/net/ixgb/ixgb.h +++ b/drivers/net/ixgb/ixgb.h @@ -85,7 +85,7 @@ struct ixgb_adapter; #define DPRINTK(nlevel, klevel, fmt, args...) \ (void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \ printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \ - __FUNCTION__ , ## args)) + __func__ , ## args)) /* TX/RX descriptor defines */ diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h index 90b53830196..2198b77c53e 100644 --- a/drivers/net/ixgbe/ixgbe.h +++ b/drivers/net/ixgbe/ixgbe.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2007 Intel Corporation. + Copyright(c) 1999 - 2008 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -20,7 +20,6 @@ the file called "COPYING". Contact Information: - Linux NICS <linux.nics@intel.com> e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 @@ -41,13 +40,11 @@ #include <linux/dca.h> #endif -#define IXGBE_ERR(args...) printk(KERN_ERR "ixgbe: " args) - #define PFX "ixgbe: " #define DPRINTK(nlevel, klevel, fmt, args...) \ ((void)((NETIF_MSG_##nlevel & adapter->msg_enable) && \ printk(KERN_##klevel PFX "%s: %s: " fmt, adapter->netdev->name, \ - __FUNCTION__ , ## args))) + __func__ , ## args))) /* TX/RX descriptor defines */ #define IXGBE_DEFAULT_TXD 1024 @@ -58,15 +55,6 @@ #define IXGBE_MAX_RXD 4096 #define IXGBE_MIN_RXD 64 -#define IXGBE_DEFAULT_RXQ 1 -#define IXGBE_MAX_RXQ 1 -#define IXGBE_MIN_RXQ 1 - -#define IXGBE_DEFAULT_ITR_RX_USECS 125 /* 8k irqs/sec */ -#define IXGBE_DEFAULT_ITR_TX_USECS 250 /* 4k irqs/sec */ -#define IXGBE_MIN_ITR_USECS 100 /* 500k irqs/sec */ -#define IXGBE_MAX_ITR_USECS 10000 /* 100 irqs/sec */ - /* flow control */ #define IXGBE_DEFAULT_FCRTL 0x10000 #define IXGBE_MIN_FCRTL 0x40 @@ -88,9 +76,6 @@ #define MAXIMUM_ETHERNET_VLAN_SIZE (ETH_FRAME_LEN + ETH_FCS_LEN + VLAN_HLEN) -/* How many Tx Descriptors do we need to call netif_wake_queue? */ -#define IXGBE_TX_QUEUE_WAKE 16 - /* How many Rx Buffers do we bundle into one write to the hardware ? */ #define IXGBE_RX_BUFFER_WRITE 16 /* Must be power of 2 */ @@ -119,6 +104,7 @@ struct ixgbe_rx_buffer { dma_addr_t dma; struct page *page; dma_addr_t page_dma; + unsigned int page_offset; }; struct ixgbe_queue_stats { @@ -157,14 +143,11 @@ struct ixgbe_ring { struct net_lro_mgr lro_mgr; bool lro_used; struct ixgbe_queue_stats stats; - u8 v_idx; /* maps directly to the index for this ring in the hardware - * vector array, can also be used for finding the bit in EICR - * and friends that represents the vector for this ring */ + u16 v_idx; /* maps directly to the index for this ring in the hardware + * vector array, can also be used for finding the bit in EICR + * and friends that represents the vector for this ring */ - u32 eims_value; - u16 itr_register; - char name[IFNAMSIZ + 5]; u16 work_limit; /* max work per interrupt */ u16 rx_buf_len; }; @@ -191,8 +174,8 @@ struct ixgbe_q_vector { DECLARE_BITMAP(txr_idx, MAX_TX_QUEUES); /* Tx ring indices */ u8 rxr_count; /* Rx ring count assigned to this vector */ u8 txr_count; /* Tx ring count assigned to this vector */ - u8 tx_eitr; - u8 rx_eitr; + u8 tx_itr; + u8 rx_itr; u32 eitr; }; @@ -240,7 +223,9 @@ struct ixgbe_adapter { /* TX */ struct ixgbe_ring *tx_ring; /* One per active queue */ + int num_tx_queues; u64 restart_queue; + u64 hw_csum_tx_good; u64 lsc_int; u64 hw_tso_ctxt; u64 hw_tso6_ctxt; @@ -249,12 +234,10 @@ struct ixgbe_adapter { /* RX */ struct ixgbe_ring *rx_ring; /* One per active queue */ - u64 hw_csum_tx_good; + int num_rx_queues; u64 hw_csum_rx_error; u64 hw_csum_rx_good; u64 non_eop_descs; - int num_tx_queues; - int num_rx_queues; int num_msix_vectors; struct ixgbe_ring_feature ring_feature[3]; struct msix_entry *msix_entries; @@ -301,14 +284,21 @@ struct ixgbe_adapter { struct ixgbe_hw_stats stats; /* Interrupt Throttle Rate */ - u32 rx_eitr; - u32 tx_eitr; + u32 eitr_param; unsigned long state; u64 tx_busy; u64 lro_aggregated; u64 lro_flushed; u64 lro_no_desc; + unsigned int tx_ring_count; + unsigned int rx_ring_count; + + u32 link_speed; + bool link_up; + unsigned long link_check_timeout; + + struct work_struct watchdog_task; }; enum ixbge_state_t { @@ -330,11 +320,11 @@ extern int ixgbe_up(struct ixgbe_adapter *adapter); extern void ixgbe_down(struct ixgbe_adapter *adapter); extern void ixgbe_reinit_locked(struct ixgbe_adapter *adapter); extern void ixgbe_reset(struct ixgbe_adapter *adapter); -extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); extern void ixgbe_set_ethtool_ops(struct net_device *netdev); -extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rxdr); -extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *txdr); +extern int ixgbe_setup_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); +extern int ixgbe_setup_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); +extern void ixgbe_free_rx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); +extern void ixgbe_free_tx_resources(struct ixgbe_adapter *, struct ixgbe_ring *); +extern void ixgbe_update_stats(struct ixgbe_adapter *adapter); #endif /* _IXGBE_H_ */ diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index ba09063260d..7cddcfba809 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2007 Intel Corporation. + Copyright(c) 1999 - 2008 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -20,7 +20,6 @@ the file called "COPYING". Contact Information: - Linux NICS <linux.nics@intel.com> e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 @@ -39,68 +38,59 @@ #define IXGBE_82598_MC_TBL_SIZE 128 #define IXGBE_82598_VFT_TBL_SIZE 128 -static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw); -static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed, - bool *autoneg); -static s32 ixgbe_get_copper_link_settings_82598(struct ixgbe_hw *hw, - u32 *speed, bool *autoneg); -static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw); -static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw); -static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed, - bool *link_up); -static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, u32 speed, - bool autoneg, - bool autoneg_wait_to_complete); +static s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg); static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw); -static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed, - bool autoneg, - bool autoneg_wait_to_complete); -static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw); - +static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg, + bool autoneg_wait_to_complete); +/** + */ static s32 ixgbe_get_invariants_82598(struct ixgbe_hw *hw) { - hw->mac.num_rx_queues = IXGBE_82598_MAX_RX_QUEUES; - hw->mac.num_tx_queues = IXGBE_82598_MAX_TX_QUEUES; - hw->mac.mcft_size = IXGBE_82598_MC_TBL_SIZE; - hw->mac.vft_size = IXGBE_82598_VFT_TBL_SIZE; - hw->mac.num_rar_entries = IXGBE_82598_RAR_ENTRIES; - - /* PHY ops are filled in by default properly for Fiber only */ - if (hw->mac.ops.get_media_type(hw) == ixgbe_media_type_copper) { - hw->mac.ops.setup_link = &ixgbe_setup_copper_link_82598; - hw->mac.ops.setup_link_speed = &ixgbe_setup_copper_link_speed_82598; - hw->mac.ops.get_link_settings = - &ixgbe_get_copper_link_settings_82598; - - /* Call PHY identify routine to get the phy type */ - ixgbe_identify_phy(hw); - - switch (hw->phy.type) { - case ixgbe_phy_tn: - hw->phy.ops.setup_link = &ixgbe_setup_tnx_phy_link; - hw->phy.ops.check_link = &ixgbe_check_tnx_phy_link; - hw->phy.ops.setup_link_speed = - &ixgbe_setup_tnx_phy_link_speed; - break; - default: - break; - } + struct ixgbe_mac_info *mac = &hw->mac; + struct ixgbe_phy_info *phy = &hw->phy; + + /* Call PHY identify routine to get the phy type */ + ixgbe_identify_phy_generic(hw); + + /* PHY Init */ + switch (phy->type) { + default: + break; } + if (mac->ops.get_media_type(hw) == ixgbe_media_type_copper) { + mac->ops.setup_link = &ixgbe_setup_copper_link_82598; + mac->ops.setup_link_speed = + &ixgbe_setup_copper_link_speed_82598; + mac->ops.get_link_capabilities = + &ixgbe_get_copper_link_capabilities_82598; + } + + mac->mcft_size = IXGBE_82598_MC_TBL_SIZE; + mac->vft_size = IXGBE_82598_VFT_TBL_SIZE; + mac->num_rar_entries = IXGBE_82598_RAR_ENTRIES; + mac->max_rx_queues = IXGBE_82598_MAX_RX_QUEUES; + mac->max_tx_queues = IXGBE_82598_MAX_TX_QUEUES; + return 0; } /** - * ixgbe_get_link_settings_82598 - Determines default link settings + * ixgbe_get_link_capabilities_82598 - Determines link capabilities * @hw: pointer to hardware structure * @speed: pointer to link speed * @autoneg: boolean auto-negotiation value * - * Determines the default link settings by reading the AUTOC register. + * Determines the link capabilities by reading the AUTOC register. **/ -static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed, - bool *autoneg) +static s32 ixgbe_get_link_capabilities_82598(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) { s32 status = 0; s32 autoc_reg; @@ -149,15 +139,16 @@ static s32 ixgbe_get_link_settings_82598(struct ixgbe_hw *hw, u32 *speed, } /** - * ixgbe_get_copper_link_settings_82598 - Determines default link settings + * ixgbe_get_copper_link_capabilities_82598 - Determines link capabilities * @hw: pointer to hardware structure * @speed: pointer to link speed * @autoneg: boolean auto-negotiation value * - * Determines the default link settings by reading the AUTOC register. + * Determines the link capabilities by reading the AUTOC register. **/ -static s32 ixgbe_get_copper_link_settings_82598(struct ixgbe_hw *hw, - u32 *speed, bool *autoneg) +s32 ixgbe_get_copper_link_capabilities_82598(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, + bool *autoneg) { s32 status = IXGBE_ERR_LINK_SETUP; u16 speed_ability; @@ -165,9 +156,9 @@ static s32 ixgbe_get_copper_link_settings_82598(struct ixgbe_hw *hw, *speed = 0; *autoneg = true; - status = ixgbe_read_phy_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, - &speed_ability); + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_SPEED_ABILITY, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + &speed_ability); if (status == 0) { if (speed_ability & IXGBE_MDIO_PHY_SPEED_10G) @@ -195,11 +186,9 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) case IXGBE_DEV_ID_82598AF_SINGLE_PORT: case IXGBE_DEV_ID_82598EB_CX4: case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: + case IXGBE_DEV_ID_82598EB_XF_LR: media_type = ixgbe_media_type_fiber; break; - case IXGBE_DEV_ID_82598AT_DUAL_PORT: - media_type = ixgbe_media_type_copper; - break; default: media_type = ixgbe_media_type_unknown; break; @@ -209,6 +198,122 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) } /** + * ixgbe_setup_fc_82598 - Configure flow control settings + * @hw: pointer to hardware structure + * @packetbuf_num: packet buffer number (0-7) + * + * Configures the flow control settings based on SW configuration. This + * function is used for 802.3x flow control configuration only. + **/ +s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num) +{ + u32 frctl_reg; + u32 rmcs_reg; + + if (packetbuf_num < 0 || packetbuf_num > 7) { + hw_dbg(hw, "Invalid packet buffer number [%d], expected range is" + " 0-7\n", packetbuf_num); + } + + frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); + frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE); + + rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS); + rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X); + + /* + * 10 gig parts do not have a word in the EEPROM to determine the + * default flow control setting, so we explicitly set it to full. + */ + if (hw->fc.type == ixgbe_fc_default) + hw->fc.type = ixgbe_fc_full; + + /* + * We want to save off the original Flow Control configuration just in + * case we get disconnected and then reconnected into a different hub + * or switch with different Flow Control capabilities. + */ + hw->fc.original_type = hw->fc.type; + + /* + * The possible values of the "flow_control" parameter are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause frames but not + * send pause frames). + * 2: Tx flow control is enabled (we can send pause frames but we do not + * support receiving pause frames) + * 3: Both Rx and Tx flow control (symmetric) are enabled. + * other: Invalid. + */ + switch (hw->fc.type) { + case ixgbe_fc_none: + break; + case ixgbe_fc_rx_pause: + /* + * Rx Flow control is enabled, + * and Tx Flow control is disabled. + */ + frctl_reg |= IXGBE_FCTRL_RFCE; + break; + case ixgbe_fc_tx_pause: + /* + * Tx Flow control is enabled, and Rx Flow control is disabled, + * by a software over-ride. + */ + rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; + break; + case ixgbe_fc_full: + /* + * Flow control (both Rx and Tx) is enabled by a software + * over-ride. + */ + frctl_reg |= IXGBE_FCTRL_RFCE; + rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; + break; + default: + /* We should never get here. The value should be 0-3. */ + hw_dbg(hw, "Flow control param set incorrectly\n"); + break; + } + + /* Enable 802.3x based flow control settings. */ + IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg); + IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg); + + /* + * Check for invalid software configuration, zeros are completely + * invalid for all parameters used past this point, and if we enable + * flow control with zero water marks, we blast flow control packets. + */ + if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) { + hw_dbg(hw, "Flow control structure initialized incorrectly\n"); + return IXGBE_ERR_INVALID_LINK_SETTINGS; + } + + /* + * We need to set up the Receive Threshold high and low water + * marks as well as (optionally) enabling the transmission of + * XON frames. + */ + if (hw->fc.type & ixgbe_fc_tx_pause) { + if (hw->fc.send_xon) { + IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), + (hw->fc.low_water | IXGBE_FCRTL_XONE)); + } else { + IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), + hw->fc.low_water); + } + IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), + (hw->fc.high_water)|IXGBE_FCRTH_FCEN); + } + + IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time); + IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1)); + + return 0; +} + +/** * ixgbe_setup_mac_link_82598 - Configures MAC link settings * @hw: pointer to hardware structure * @@ -252,8 +357,7 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw) } if (!(links_reg & IXGBE_LINKS_KX_AN_COMP)) { status = IXGBE_ERR_AUTONEG_NOT_COMPLETE; - hw_dbg(hw, - "Autonegotiation did not complete.\n"); + hw_dbg(hw, "Autonegotiation did not complete.\n"); } } } @@ -263,8 +367,8 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw) * case we get disconnected and then reconnected into a different hub * or switch with different Flow Control capabilities. */ - hw->fc.type = hw->fc.original_type; - ixgbe_setup_fc(hw, 0); + hw->fc.original_type = hw->fc.type; + ixgbe_setup_fc_82598(hw, 0); /* Add delay to filter out noises during initial link setup */ msleep(50); @@ -277,20 +381,35 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw) * @hw: pointer to hardware structure * @speed: pointer to link speed * @link_up: true is link is up, false otherwise + * @link_up_wait_to_complete: bool used to wait for link up or not * * Reads the links register to determine if link is up and the current speed **/ -static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed, - bool *link_up) +static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, + ixgbe_link_speed *speed, bool *link_up, + bool link_up_wait_to_complete) { u32 links_reg; + u32 i; links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); - - if (links_reg & IXGBE_LINKS_UP) - *link_up = true; - else - *link_up = false; + if (link_up_wait_to_complete) { + for (i = 0; i < IXGBE_LINK_UP_TIME; i++) { + if (links_reg & IXGBE_LINKS_UP) { + *link_up = true; + break; + } else { + *link_up = false; + } + msleep(100); + links_reg = IXGBE_READ_REG(hw, IXGBE_LINKS); + } + } else { + if (links_reg & IXGBE_LINKS_UP) + *link_up = true; + else + *link_up = false; + } if (links_reg & IXGBE_LINKS_SPEED) *speed = IXGBE_LINK_SPEED_10GB_FULL; @@ -300,6 +419,7 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed, return 0; } + /** * ixgbe_setup_mac_link_speed_82598 - Set MAC link speed * @hw: pointer to hardware structure @@ -310,18 +430,18 @@ static s32 ixgbe_check_mac_link_82598(struct ixgbe_hw *hw, u32 *speed, * Set the link speed in the AUTOC register and restarts link. **/ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, - u32 speed, bool autoneg, - bool autoneg_wait_to_complete) + ixgbe_link_speed speed, bool autoneg, + bool autoneg_wait_to_complete) { s32 status = 0; /* If speed is 10G, then check for CX4 or XAUI. */ if ((speed == IXGBE_LINK_SPEED_10GB_FULL) && - (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4))) + (!(hw->mac.link_attach_type & IXGBE_AUTOC_10G_KX4))) { hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN; - else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg)) + } else if ((speed == IXGBE_LINK_SPEED_1GB_FULL) && (!autoneg)) { hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_LINK_NO_AN; - else if (autoneg) { + } else if (autoneg) { /* BX mode - Autonegotiate 1G */ if (!(hw->mac.link_attach_type & IXGBE_AUTOC_1G_PMA_PMD)) hw->mac.link_mode_select = IXGBE_AUTOC_LMS_1G_AN; @@ -340,7 +460,7 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, * ixgbe_hw This will write the AUTOC register based on the new * stored values */ - hw->mac.ops.setup_link(hw); + ixgbe_setup_mac_link_82598(hw); } return status; @@ -358,18 +478,17 @@ static s32 ixgbe_setup_mac_link_speed_82598(struct ixgbe_hw *hw, **/ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw) { - s32 status = 0; + s32 status; /* Restart autonegotiation on PHY */ - if (hw->phy.ops.setup_link) - status = hw->phy.ops.setup_link(hw); + status = hw->phy.ops.setup_link(hw); - /* Set MAC to KX/KX4 autoneg, which defaultis to Parallel detection */ + /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */ hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX); hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN; /* Set up MAC */ - hw->mac.ops.setup_link(hw); + ixgbe_setup_mac_link_82598(hw); return status; } @@ -383,23 +502,23 @@ static s32 ixgbe_setup_copper_link_82598(struct ixgbe_hw *hw) * * Sets the link speed in the AUTOC register in the MAC and restarts link. **/ -static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed, - bool autoneg, - bool autoneg_wait_to_complete) +static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg, + bool autoneg_wait_to_complete) { - s32 status = 0; + s32 status; /* Setup the PHY according to input speed */ - if (hw->phy.ops.setup_link_speed) - status = hw->phy.ops.setup_link_speed(hw, speed, autoneg, - autoneg_wait_to_complete); + status = hw->phy.ops.setup_link_speed(hw, speed, autoneg, + autoneg_wait_to_complete); /* Set MAC to KX/KX4 autoneg, which defaults to Parallel detection */ hw->mac.link_attach_type = (IXGBE_AUTOC_10G_KX4 | IXGBE_AUTOC_1G_KX); hw->mac.link_mode_select = IXGBE_AUTOC_LMS_KX4_AN; /* Set up MAC */ - hw->mac.ops.setup_link(hw); + ixgbe_setup_mac_link_82598(hw); return status; } @@ -408,7 +527,7 @@ static s32 ixgbe_setup_copper_link_speed_82598(struct ixgbe_hw *hw, u32 speed, * ixgbe_reset_hw_82598 - Performs hardware reset * @hw: pointer to hardware structure * - * Resets the hardware by reseting the transmit and receive units, masks and + * Resets the hardware by resetting the transmit and receive units, masks and * clears all interrupts, performing a PHY reset, and performing a link (MAC) * reset. **/ @@ -422,35 +541,44 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) u8 analog_val; /* Call adapter stop to disable tx/rx and clear interrupts */ - ixgbe_stop_adapter(hw); + hw->mac.ops.stop_adapter(hw); /* - * Power up the Atlas TX lanes if they are currently powered down. - * Atlas TX lanes are powered down for MAC loopback tests, but + * Power up the Atlas Tx lanes if they are currently powered down. + * Atlas Tx lanes are powered down for MAC loopback tests, but * they are not automatically restored on reset. */ - ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val); + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val); if (analog_val & IXGBE_ATLAS_PDN_TX_REG_EN) { - /* Enable TX Atlas so packets can be transmitted again */ - ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, &analog_val); + /* Enable Tx Atlas so packets can be transmitted again */ + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, + &analog_val); analog_val &= ~IXGBE_ATLAS_PDN_TX_REG_EN; - ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, analog_val); + hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_LPBK, + analog_val); - ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, &analog_val); + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, + &analog_val); analog_val &= ~IXGBE_ATLAS_PDN_TX_10G_QL_ALL; - ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, analog_val); + hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_10G, + analog_val); - ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, &analog_val); + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, + &analog_val); analog_val &= ~IXGBE_ATLAS_PDN_TX_1G_QL_ALL; - ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, analog_val); + hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_1G, + analog_val); - ixgbe_read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, &analog_val); + hw->mac.ops.read_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, + &analog_val); analog_val &= ~IXGBE_ATLAS_PDN_TX_AN_QL_ALL; - ixgbe_write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, analog_val); + hw->mac.ops.write_analog_reg8(hw, IXGBE_ATLAS_PDN_AN, + analog_val); } /* Reset PHY */ - ixgbe_reset_phy(hw); + if (hw->phy.reset_disable == false) + hw->phy.ops.reset(hw); /* * Prevent the PCI-E bus from from hanging by disabling PCI-E master @@ -503,29 +631,311 @@ static s32 ixgbe_reset_hw_82598(struct ixgbe_hw *hw) IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); } else { hw->mac.link_attach_type = - (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE); + (autoc & IXGBE_AUTOC_LMS_ATTACH_TYPE); hw->mac.link_mode_select = (autoc & IXGBE_AUTOC_LMS_MASK); hw->mac.link_settings_loaded = true; } /* Store the permanent mac address */ - ixgbe_get_mac_addr(hw, hw->mac.perm_addr); + hw->mac.ops.get_mac_addr(hw, hw->mac.perm_addr); return status; } +/** + * ixgbe_set_vmdq_82598 - Associate a VMDq set index with a rx address + * @hw: pointer to hardware struct + * @rar: receive address register index to associate with a VMDq index + * @vmdq: VMDq set index + **/ +s32 ixgbe_set_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) +{ + u32 rar_high; + + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); + rar_high &= ~IXGBE_RAH_VIND_MASK; + rar_high |= ((vmdq << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK); + IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high); + return 0; +} + +/** + * ixgbe_clear_vmdq_82598 - Disassociate a VMDq set index from an rx address + * @hw: pointer to hardware struct + * @rar: receive address register index to associate with a VMDq index + * @vmdq: VMDq clear index (not used in 82598, but elsewhere) + **/ +static s32 ixgbe_clear_vmdq_82598(struct ixgbe_hw *hw, u32 rar, u32 vmdq) +{ + u32 rar_high; + u32 rar_entries = hw->mac.num_rar_entries; + + if (rar < rar_entries) { + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(rar)); + if (rar_high & IXGBE_RAH_VIND_MASK) { + rar_high &= ~IXGBE_RAH_VIND_MASK; + IXGBE_WRITE_REG(hw, IXGBE_RAH(rar), rar_high); + } + } else { + hw_dbg(hw, "RAR index %d is out of range.\n", rar); + } + + return 0; +} + +/** + * ixgbe_set_vfta_82598 - Set VLAN filter table + * @hw: pointer to hardware structure + * @vlan: VLAN id to write to VLAN filter + * @vind: VMDq output index that maps queue to VLAN id in VFTA + * @vlan_on: boolean flag to turn on/off VLAN in VFTA + * + * Turn on/off specified VLAN in the VLAN filter table. + **/ +s32 ixgbe_set_vfta_82598(struct ixgbe_hw *hw, u32 vlan, u32 vind, + bool vlan_on) +{ + u32 regindex; + u32 bitindex; + u32 bits; + u32 vftabyte; + + if (vlan > 4095) + return IXGBE_ERR_PARAM; + + /* Determine 32-bit word position in array */ + regindex = (vlan >> 5) & 0x7F; /* upper seven bits */ + + /* Determine the location of the (VMD) queue index */ + vftabyte = ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */ + bitindex = (vlan & 0x7) << 2; /* lower 3 bits indicate nibble */ + + /* Set the nibble for VMD queue index */ + bits = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex)); + bits &= (~(0x0F << bitindex)); + bits |= (vind << bitindex); + IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vftabyte, regindex), bits); + + /* Determine the location of the bit for this VLAN id */ + bitindex = vlan & 0x1F; /* lower five bits */ + + bits = IXGBE_READ_REG(hw, IXGBE_VFTA(regindex)); + if (vlan_on) + /* Turn on this VLAN id */ + bits |= (1 << bitindex); + else + /* Turn off this VLAN id */ + bits &= ~(1 << bitindex); + IXGBE_WRITE_REG(hw, IXGBE_VFTA(regindex), bits); + + return 0; +} + +/** + * ixgbe_clear_vfta_82598 - Clear VLAN filter table + * @hw: pointer to hardware structure + * + * Clears the VLAN filer table, and the VMDq index associated with the filter + **/ +static s32 ixgbe_clear_vfta_82598(struct ixgbe_hw *hw) +{ + u32 offset; + u32 vlanbyte; + + for (offset = 0; offset < hw->mac.vft_size; offset++) + IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); + + for (vlanbyte = 0; vlanbyte < 4; vlanbyte++) + for (offset = 0; offset < hw->mac.vft_size; offset++) + IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset), + 0); + + return 0; +} + +/** + * ixgbe_blink_led_start_82598 - Blink LED based on index. + * @hw: pointer to hardware structure + * @index: led number to blink + **/ +static s32 ixgbe_blink_led_start_82598(struct ixgbe_hw *hw, u32 index) +{ + ixgbe_link_speed speed = 0; + bool link_up = 0; + u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + + /* + * Link must be up to auto-blink the LEDs on the 82598EB MAC; + * force it if link is down. + */ + hw->mac.ops.check_link(hw, &speed, &link_up, false); + + if (!link_up) { + autoc_reg |= IXGBE_AUTOC_FLU; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); + msleep(10); + } + + led_reg &= ~IXGBE_LED_MODE_MASK(index); + led_reg |= IXGBE_LED_BLINK(index); + IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); + IXGBE_WRITE_FLUSH(hw); + + return 0; +} + +/** + * ixgbe_blink_led_stop_82598 - Stop blinking LED based on index. + * @hw: pointer to hardware structure + * @index: led number to stop blinking + **/ +static s32 ixgbe_blink_led_stop_82598(struct ixgbe_hw *hw, u32 index) +{ + u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); + + autoc_reg &= ~IXGBE_AUTOC_FLU; + autoc_reg |= IXGBE_AUTOC_AN_RESTART; + IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); + + led_reg &= ~IXGBE_LED_MODE_MASK(index); + led_reg &= ~IXGBE_LED_BLINK(index); + led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); + IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); + IXGBE_WRITE_FLUSH(hw); + + return 0; +} + +/** + * ixgbe_read_analog_reg8_82598 - Reads 8 bit Atlas analog register + * @hw: pointer to hardware structure + * @reg: analog register to read + * @val: read value + * + * Performs read operation to Atlas analog register specified. + **/ +s32 ixgbe_read_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 *val) +{ + u32 atlas_ctl; + + IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, + IXGBE_ATLASCTL_WRITE_CMD | (reg << 8)); + IXGBE_WRITE_FLUSH(hw); + udelay(10); + atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL); + *val = (u8)atlas_ctl; + + return 0; +} + +/** + * ixgbe_write_analog_reg8_82598 - Writes 8 bit Atlas analog register + * @hw: pointer to hardware structure + * @reg: atlas register to write + * @val: value to write + * + * Performs write operation to Atlas analog register specified. + **/ +s32 ixgbe_write_analog_reg8_82598(struct ixgbe_hw *hw, u32 reg, u8 val) +{ + u32 atlas_ctl; + + atlas_ctl = (reg << 8) | val; + IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl); + IXGBE_WRITE_FLUSH(hw); + udelay(10); + + return 0; +} + +/** + * ixgbe_get_supported_physical_layer_82598 - Returns physical layer type + * @hw: pointer to hardware structure + * + * Determines physical layer capabilities of the current configuration. + **/ +s32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw) +{ + s32 physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + + switch (hw->device_id) { + case IXGBE_DEV_ID_82598EB_CX4: + case IXGBE_DEV_ID_82598_CX4_DUAL_PORT: + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_CX4; + break; + case IXGBE_DEV_ID_82598AF_DUAL_PORT: + case IXGBE_DEV_ID_82598AF_SINGLE_PORT: + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_SR; + break; + case IXGBE_DEV_ID_82598EB_XF_LR: + physical_layer = IXGBE_PHYSICAL_LAYER_10GBASE_LR; + break; + + default: + physical_layer = IXGBE_PHYSICAL_LAYER_UNKNOWN; + break; + } + + return physical_layer; +} + static struct ixgbe_mac_operations mac_ops_82598 = { - .reset = &ixgbe_reset_hw_82598, + .init_hw = &ixgbe_init_hw_generic, + .reset_hw = &ixgbe_reset_hw_82598, + .start_hw = &ixgbe_start_hw_generic, + .clear_hw_cntrs = &ixgbe_clear_hw_cntrs_generic, .get_media_type = &ixgbe_get_media_type_82598, + .get_supported_physical_layer = &ixgbe_get_supported_physical_layer_82598, + .get_mac_addr = &ixgbe_get_mac_addr_generic, + .stop_adapter = &ixgbe_stop_adapter_generic, + .read_analog_reg8 = &ixgbe_read_analog_reg8_82598, + .write_analog_reg8 = &ixgbe_write_analog_reg8_82598, .setup_link = &ixgbe_setup_mac_link_82598, - .check_link = &ixgbe_check_mac_link_82598, .setup_link_speed = &ixgbe_setup_mac_link_speed_82598, - .get_link_settings = &ixgbe_get_link_settings_82598, + .check_link = &ixgbe_check_mac_link_82598, + .get_link_capabilities = &ixgbe_get_link_capabilities_82598, + .led_on = &ixgbe_led_on_generic, + .led_off = &ixgbe_led_off_generic, + .blink_led_start = &ixgbe_blink_led_start_82598, + .blink_led_stop = &ixgbe_blink_led_stop_82598, + .set_rar = &ixgbe_set_rar_generic, + .clear_rar = &ixgbe_clear_rar_generic, + .set_vmdq = &ixgbe_set_vmdq_82598, + .clear_vmdq = &ixgbe_clear_vmdq_82598, + .init_rx_addrs = &ixgbe_init_rx_addrs_generic, + .update_uc_addr_list = &ixgbe_update_uc_addr_list_generic, + .update_mc_addr_list = &ixgbe_update_mc_addr_list_generic, + .enable_mc = &ixgbe_enable_mc_generic, + .disable_mc = &ixgbe_disable_mc_generic, + .clear_vfta = &ixgbe_clear_vfta_82598, + .set_vfta = &ixgbe_set_vfta_82598, + .setup_fc = &ixgbe_setup_fc_82598, +}; + +static struct ixgbe_eeprom_operations eeprom_ops_82598 = { + .init_params = &ixgbe_init_eeprom_params_generic, + .read = &ixgbe_read_eeprom_generic, + .validate_checksum = &ixgbe_validate_eeprom_checksum_generic, + .update_checksum = &ixgbe_update_eeprom_checksum_generic, +}; + +static struct ixgbe_phy_operations phy_ops_82598 = { + .identify = &ixgbe_identify_phy_generic, + /* .identify_sfp = &ixgbe_identify_sfp_module_generic, */ + .reset = &ixgbe_reset_phy_generic, + .read_reg = &ixgbe_read_phy_reg_generic, + .write_reg = &ixgbe_write_phy_reg_generic, + .setup_link = &ixgbe_setup_phy_link_generic, + .setup_link_speed = &ixgbe_setup_phy_link_speed_generic, }; struct ixgbe_info ixgbe_82598_info = { .mac = ixgbe_mac_82598EB, .get_invariants = &ixgbe_get_invariants_82598, .mac_ops = &mac_ops_82598, + .eeprom_ops = &eeprom_ops_82598, + .phy_ops = &phy_ops_82598, }; diff --git a/drivers/net/ixgbe/ixgbe_common.c b/drivers/net/ixgbe/ixgbe_common.c index 9c0d0a1964e..f67c68404bb 100644 --- a/drivers/net/ixgbe/ixgbe_common.c +++ b/drivers/net/ixgbe/ixgbe_common.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2007 Intel Corporation. + Copyright(c) 1999 - 2008 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -20,7 +20,6 @@ the file called "COPYING". Contact Information: - Linux NICS <linux.nics@intel.com> e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 @@ -33,20 +32,28 @@ #include "ixgbe_common.h" #include "ixgbe_phy.h" -static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw); - static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw); +static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw); static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw); static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw); +static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw); +static void ixgbe_standby_eeprom(struct ixgbe_hw *hw); +static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, + u16 count); +static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count); +static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); +static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec); +static void ixgbe_release_eeprom(struct ixgbe_hw *hw); static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw); -static s32 ixgbe_clear_vfta(struct ixgbe_hw *hw); -static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw); +static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index); +static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index); static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr); static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr); +static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq); /** - * ixgbe_start_hw - Prepare hardware for TX/RX + * ixgbe_start_hw_generic - Prepare hardware for Tx/Rx * @hw: pointer to hardware structure * * Starts the hardware by filling the bus info structure and media type, clears @@ -54,7 +61,7 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr); * table, VLAN filter table, calls routine to set up link and flow control * settings, and leaves transmit and receive units disabled and uninitialized **/ -s32 ixgbe_start_hw(struct ixgbe_hw *hw) +s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) { u32 ctrl_ext; @@ -62,22 +69,22 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw) hw->phy.media_type = hw->mac.ops.get_media_type(hw); /* Identify the PHY */ - ixgbe_identify_phy(hw); + hw->phy.ops.identify(hw); /* * Store MAC address from RAR0, clear receive address registers, and * clear the multicast table */ - ixgbe_init_rx_addrs(hw); + hw->mac.ops.init_rx_addrs(hw); /* Clear the VLAN filter table */ - ixgbe_clear_vfta(hw); + hw->mac.ops.clear_vfta(hw); /* Set up link */ hw->mac.ops.setup_link(hw); /* Clear statistics registers */ - ixgbe_clear_hw_cntrs(hw); + hw->mac.ops.clear_hw_cntrs(hw); /* Set No Snoop Disable */ ctrl_ext = IXGBE_READ_REG(hw, IXGBE_CTRL_EXT); @@ -92,34 +99,34 @@ s32 ixgbe_start_hw(struct ixgbe_hw *hw) } /** - * ixgbe_init_hw - Generic hardware initialization + * ixgbe_init_hw_generic - Generic hardware initialization * @hw: pointer to hardware structure * - * Initialize the hardware by reseting the hardware, filling the bus info + * Initialize the hardware by resetting the hardware, filling the bus info * structure and media type, clears all on chip counters, initializes receive * address registers, multicast table, VLAN filter table, calls routine to set * up link and flow control settings, and leaves transmit and receive units * disabled and uninitialized **/ -s32 ixgbe_init_hw(struct ixgbe_hw *hw) +s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw) { /* Reset the hardware */ - hw->mac.ops.reset(hw); + hw->mac.ops.reset_hw(hw); /* Start the HW */ - ixgbe_start_hw(hw); + hw->mac.ops.start_hw(hw); return 0; } /** - * ixgbe_clear_hw_cntrs - Generic clear hardware counters + * ixgbe_clear_hw_cntrs_generic - Generic clear hardware counters * @hw: pointer to hardware structure * * Clears all hardware statistics counters by reading them from the hardware * Statistics counters are clear on read. **/ -static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw) +s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw) { u16 i = 0; @@ -191,7 +198,36 @@ static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw) } /** - * ixgbe_get_mac_addr - Generic get MAC address + * ixgbe_read_pba_num_generic - Reads part number from EEPROM + * @hw: pointer to hardware structure + * @pba_num: stores the part number from the EEPROM + * + * Reads the part number from the EEPROM. + **/ +s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num) +{ + s32 ret_val; + u16 data; + + ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM0_PTR, &data); + if (ret_val) { + hw_dbg(hw, "NVM Read Error\n"); + return ret_val; + } + *pba_num = (u32)(data << 16); + + ret_val = hw->eeprom.ops.read(hw, IXGBE_PBANUM1_PTR, &data); + if (ret_val) { + hw_dbg(hw, "NVM Read Error\n"); + return ret_val; + } + *pba_num |= data; + + return 0; +} + +/** + * ixgbe_get_mac_addr_generic - Generic get MAC address * @hw: pointer to hardware structure * @mac_addr: Adapter MAC address * @@ -199,7 +235,7 @@ static s32 ixgbe_clear_hw_cntrs(struct ixgbe_hw *hw) * A reset of the adapter must be performed prior to calling this function * in order for the MAC address to have been loaded from the EEPROM into RAR0 **/ -s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr) +s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr) { u32 rar_high; u32 rar_low; @@ -217,30 +253,8 @@ s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr) return 0; } -s32 ixgbe_read_part_num(struct ixgbe_hw *hw, u32 *part_num) -{ - s32 ret_val; - u16 data; - - ret_val = ixgbe_read_eeprom(hw, IXGBE_PBANUM0_PTR, &data); - if (ret_val) { - hw_dbg(hw, "NVM Read Error\n"); - return ret_val; - } - *part_num = (u32)(data << 16); - - ret_val = ixgbe_read_eeprom(hw, IXGBE_PBANUM1_PTR, &data); - if (ret_val) { - hw_dbg(hw, "NVM Read Error\n"); - return ret_val; - } - *part_num |= data; - - return 0; -} - /** - * ixgbe_stop_adapter - Generic stop TX/RX units + * ixgbe_stop_adapter_generic - Generic stop Tx/Rx units * @hw: pointer to hardware structure * * Sets the adapter_stopped flag within ixgbe_hw struct. Clears interrupts, @@ -248,7 +262,7 @@ s32 ixgbe_read_part_num(struct ixgbe_hw *hw, u32 *part_num) * the shared code and drivers to determine if the adapter is in a stopped * state and should not touch the hardware. **/ -s32 ixgbe_stop_adapter(struct ixgbe_hw *hw) +s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw) { u32 number_of_queues; u32 reg_val; @@ -264,6 +278,7 @@ s32 ixgbe_stop_adapter(struct ixgbe_hw *hw) reg_val = IXGBE_READ_REG(hw, IXGBE_RXCTRL); reg_val &= ~(IXGBE_RXCTRL_RXEN); IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_val); + IXGBE_WRITE_FLUSH(hw); msleep(2); /* Clear interrupt mask to stop from interrupts being generated */ @@ -273,7 +288,7 @@ s32 ixgbe_stop_adapter(struct ixgbe_hw *hw) IXGBE_READ_REG(hw, IXGBE_EICR); /* Disable the transmit unit. Each queue must be disabled. */ - number_of_queues = hw->mac.num_tx_queues; + number_of_queues = hw->mac.max_tx_queues; for (i = 0; i < number_of_queues; i++) { reg_val = IXGBE_READ_REG(hw, IXGBE_TXDCTL(i)); if (reg_val & IXGBE_TXDCTL_ENABLE) { @@ -282,15 +297,22 @@ s32 ixgbe_stop_adapter(struct ixgbe_hw *hw) } } + /* + * Prevent the PCI-E bus from from hanging by disabling PCI-E master + * access and verify no pending requests + */ + if (ixgbe_disable_pcie_master(hw) != 0) + hw_dbg(hw, "PCI-E Master disable polling has failed.\n"); + return 0; } /** - * ixgbe_led_on - Turns on the software controllable LEDs. + * ixgbe_led_on_generic - Turns on the software controllable LEDs. * @hw: pointer to hardware structure * @index: led number to turn on **/ -s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index) +s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) { u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); @@ -304,11 +326,11 @@ s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index) } /** - * ixgbe_led_off - Turns off the software controllable LEDs. + * ixgbe_led_off_generic - Turns off the software controllable LEDs. * @hw: pointer to hardware structure * @index: led number to turn off **/ -s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index) +s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) { u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); @@ -321,15 +343,14 @@ s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index) return 0; } - /** - * ixgbe_init_eeprom - Initialize EEPROM params + * ixgbe_init_eeprom_params_generic - Initialize EEPROM params * @hw: pointer to hardware structure * * Initializes the EEPROM parameters ixgbe_eeprom_info within the * ixgbe_hw struct in order to set up EEPROM access. **/ -s32 ixgbe_init_eeprom(struct ixgbe_hw *hw) +s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw) { struct ixgbe_eeprom_info *eeprom = &hw->eeprom; u32 eec; @@ -337,6 +358,9 @@ s32 ixgbe_init_eeprom(struct ixgbe_hw *hw) if (eeprom->type == ixgbe_eeprom_uninitialized) { eeprom->type = ixgbe_eeprom_none; + /* Set default semaphore delay to 10ms which is a well + * tested value */ + eeprom->semaphore_delay = 10; /* * Check for EEPROM present first. @@ -369,18 +393,85 @@ s32 ixgbe_init_eeprom(struct ixgbe_hw *hw) } /** - * ixgbe_read_eeprom - Read EEPROM word using EERD + * ixgbe_read_eeprom_bit_bang_generic - Read EEPROM word using bit-bang + * @hw: pointer to hardware structure + * @offset: offset within the EEPROM to be read + * @data: read 16 bit value from EEPROM + * + * Reads 16 bit value from EEPROM through bit-bang method + **/ +s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, + u16 *data) +{ + s32 status; + u16 word_in; + u8 read_opcode = IXGBE_EEPROM_READ_OPCODE_SPI; + + hw->eeprom.ops.init_params(hw); + + if (offset >= hw->eeprom.word_size) { + status = IXGBE_ERR_EEPROM; + goto out; + } + + /* Prepare the EEPROM for reading */ + status = ixgbe_acquire_eeprom(hw); + + if (status == 0) { + if (ixgbe_ready_eeprom(hw) != 0) { + ixgbe_release_eeprom(hw); + status = IXGBE_ERR_EEPROM; + } + } + + if (status == 0) { + ixgbe_standby_eeprom(hw); + + /* + * Some SPI eeproms use the 8th address bit embedded in the + * opcode + */ + if ((hw->eeprom.address_bits == 8) && (offset >= 128)) + read_opcode |= IXGBE_EEPROM_A8_OPCODE_SPI; + + /* Send the READ command (opcode + addr) */ + ixgbe_shift_out_eeprom_bits(hw, read_opcode, + IXGBE_EEPROM_OPCODE_BITS); + ixgbe_shift_out_eeprom_bits(hw, (u16)(offset*2), + hw->eeprom.address_bits); + + /* Read the data. */ + word_in = ixgbe_shift_in_eeprom_bits(hw, 16); + *data = (word_in >> 8) | (word_in << 8); + + /* End this read operation */ + ixgbe_release_eeprom(hw); + } + +out: + return status; +} + +/** + * ixgbe_read_eeprom_generic - Read EEPROM word using EERD * @hw: pointer to hardware structure * @offset: offset of word in the EEPROM to read * @data: word read from the EEPROM * * Reads a 16 bit word from the EEPROM using the EERD register. **/ -s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data) +s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data) { u32 eerd; s32 status; + hw->eeprom.ops.init_params(hw); + + if (offset >= hw->eeprom.word_size) { + status = IXGBE_ERR_EEPROM; + goto out; + } + eerd = (offset << IXGBE_EEPROM_READ_ADDR_SHIFT) + IXGBE_EEPROM_READ_REG_START; @@ -389,10 +480,11 @@ s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data) if (status == 0) *data = (IXGBE_READ_REG(hw, IXGBE_EERD) >> - IXGBE_EEPROM_READ_REG_DATA); + IXGBE_EEPROM_READ_REG_DATA); else hw_dbg(hw, "Eeprom read timed out\n"); +out: return status; } @@ -420,6 +512,58 @@ static s32 ixgbe_poll_eeprom_eerd_done(struct ixgbe_hw *hw) } /** + * ixgbe_acquire_eeprom - Acquire EEPROM using bit-bang + * @hw: pointer to hardware structure + * + * Prepares EEPROM for access using bit-bang method. This function should + * be called before issuing a command to the EEPROM. + **/ +static s32 ixgbe_acquire_eeprom(struct ixgbe_hw *hw) +{ + s32 status = 0; + u32 eec; + u32 i; + + if (ixgbe_acquire_swfw_sync(hw, IXGBE_GSSR_EEP_SM) != 0) + status = IXGBE_ERR_SWFW_SYNC; + + if (status == 0) { + eec = IXGBE_READ_REG(hw, IXGBE_EEC); + + /* Request EEPROM Access */ + eec |= IXGBE_EEC_REQ; + IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + + for (i = 0; i < IXGBE_EEPROM_GRANT_ATTEMPTS; i++) { + eec = IXGBE_READ_REG(hw, IXGBE_EEC); + if (eec & IXGBE_EEC_GNT) + break; + udelay(5); + } + + /* Release if grant not acquired */ + if (!(eec & IXGBE_EEC_GNT)) { + eec &= ~IXGBE_EEC_REQ; + IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + hw_dbg(hw, "Could not acquire EEPROM grant\n"); + + ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); + status = IXGBE_ERR_EEPROM; + } + } + + /* Setup EEPROM for Read/Write */ + if (status == 0) { + /* Clear CS and SK */ + eec &= ~(IXGBE_EEC_CS | IXGBE_EEC_SK); + IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_FLUSH(hw); + udelay(1); + } + return status; +} + +/** * ixgbe_get_eeprom_semaphore - Get hardware semaphore * @hw: pointer to hardware structure * @@ -475,7 +619,7 @@ static s32 ixgbe_get_eeprom_semaphore(struct ixgbe_hw *hw) */ if (i >= timeout) { hw_dbg(hw, "Driver can't access the Eeprom - Semaphore " - "not granted.\n"); + "not granted.\n"); ixgbe_release_eeprom_semaphore(hw); status = IXGBE_ERR_EEPROM; } @@ -503,6 +647,217 @@ static void ixgbe_release_eeprom_semaphore(struct ixgbe_hw *hw) } /** + * ixgbe_ready_eeprom - Polls for EEPROM ready + * @hw: pointer to hardware structure + **/ +static s32 ixgbe_ready_eeprom(struct ixgbe_hw *hw) +{ + s32 status = 0; + u16 i; + u8 spi_stat_reg; + + /* + * Read "Status Register" repeatedly until the LSB is cleared. The + * EEPROM will signal that the command has been completed by clearing + * bit 0 of the internal status register. If it's not cleared within + * 5 milliseconds, then error out. + */ + for (i = 0; i < IXGBE_EEPROM_MAX_RETRY_SPI; i += 5) { + ixgbe_shift_out_eeprom_bits(hw, IXGBE_EEPROM_RDSR_OPCODE_SPI, + IXGBE_EEPROM_OPCODE_BITS); + spi_stat_reg = (u8)ixgbe_shift_in_eeprom_bits(hw, 8); + if (!(spi_stat_reg & IXGBE_EEPROM_STATUS_RDY_SPI)) + break; + + udelay(5); + ixgbe_standby_eeprom(hw); + }; + + /* + * On some parts, SPI write time could vary from 0-20mSec on 3.3V + * devices (and only 0-5mSec on 5V devices) + */ + if (i >= IXGBE_EEPROM_MAX_RETRY_SPI) { + hw_dbg(hw, "SPI EEPROM Status error\n"); + status = IXGBE_ERR_EEPROM; + } + + return status; +} + +/** + * ixgbe_standby_eeprom - Returns EEPROM to a "standby" state + * @hw: pointer to hardware structure + **/ +static void ixgbe_standby_eeprom(struct ixgbe_hw *hw) +{ + u32 eec; + + eec = IXGBE_READ_REG(hw, IXGBE_EEC); + + /* Toggle CS to flush commands */ + eec |= IXGBE_EEC_CS; + IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_FLUSH(hw); + udelay(1); + eec &= ~IXGBE_EEC_CS; + IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_FLUSH(hw); + udelay(1); +} + +/** + * ixgbe_shift_out_eeprom_bits - Shift data bits out to the EEPROM. + * @hw: pointer to hardware structure + * @data: data to send to the EEPROM + * @count: number of bits to shift out + **/ +static void ixgbe_shift_out_eeprom_bits(struct ixgbe_hw *hw, u16 data, + u16 count) +{ + u32 eec; + u32 mask; + u32 i; + + eec = IXGBE_READ_REG(hw, IXGBE_EEC); + + /* + * Mask is used to shift "count" bits of "data" out to the EEPROM + * one bit at a time. Determine the starting bit based on count + */ + mask = 0x01 << (count - 1); + + for (i = 0; i < count; i++) { + /* + * A "1" is shifted out to the EEPROM by setting bit "DI" to a + * "1", and then raising and then lowering the clock (the SK + * bit controls the clock input to the EEPROM). A "0" is + * shifted out to the EEPROM by setting "DI" to "0" and then + * raising and then lowering the clock. + */ + if (data & mask) + eec |= IXGBE_EEC_DI; + else + eec &= ~IXGBE_EEC_DI; + + IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_FLUSH(hw); + + udelay(1); + + ixgbe_raise_eeprom_clk(hw, &eec); + ixgbe_lower_eeprom_clk(hw, &eec); + + /* + * Shift mask to signify next bit of data to shift in to the + * EEPROM + */ + mask = mask >> 1; + }; + + /* We leave the "DI" bit set to "0" when we leave this routine. */ + eec &= ~IXGBE_EEC_DI; + IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_FLUSH(hw); +} + +/** + * ixgbe_shift_in_eeprom_bits - Shift data bits in from the EEPROM + * @hw: pointer to hardware structure + **/ +static u16 ixgbe_shift_in_eeprom_bits(struct ixgbe_hw *hw, u16 count) +{ + u32 eec; + u32 i; + u16 data = 0; + + /* + * In order to read a register from the EEPROM, we need to shift + * 'count' bits in from the EEPROM. Bits are "shifted in" by raising + * the clock input to the EEPROM (setting the SK bit), and then reading + * the value of the "DO" bit. During this "shifting in" process the + * "DI" bit should always be clear. + */ + eec = IXGBE_READ_REG(hw, IXGBE_EEC); + + eec &= ~(IXGBE_EEC_DO | IXGBE_EEC_DI); + + for (i = 0; i < count; i++) { + data = data << 1; + ixgbe_raise_eeprom_clk(hw, &eec); + + eec = IXGBE_READ_REG(hw, IXGBE_EEC); + + eec &= ~(IXGBE_EEC_DI); + if (eec & IXGBE_EEC_DO) + data |= 1; + + ixgbe_lower_eeprom_clk(hw, &eec); + } + + return data; +} + +/** + * ixgbe_raise_eeprom_clk - Raises the EEPROM's clock input. + * @hw: pointer to hardware structure + * @eec: EEC register's current value + **/ +static void ixgbe_raise_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) +{ + /* + * Raise the clock input to the EEPROM + * (setting the SK bit), then delay + */ + *eec = *eec | IXGBE_EEC_SK; + IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); + IXGBE_WRITE_FLUSH(hw); + udelay(1); +} + +/** + * ixgbe_lower_eeprom_clk - Lowers the EEPROM's clock input. + * @hw: pointer to hardware structure + * @eecd: EECD's current value + **/ +static void ixgbe_lower_eeprom_clk(struct ixgbe_hw *hw, u32 *eec) +{ + /* + * Lower the clock input to the EEPROM (clearing the SK bit), then + * delay + */ + *eec = *eec & ~IXGBE_EEC_SK; + IXGBE_WRITE_REG(hw, IXGBE_EEC, *eec); + IXGBE_WRITE_FLUSH(hw); + udelay(1); +} + +/** + * ixgbe_release_eeprom - Release EEPROM, release semaphores + * @hw: pointer to hardware structure + **/ +static void ixgbe_release_eeprom(struct ixgbe_hw *hw) +{ + u32 eec; + + eec = IXGBE_READ_REG(hw, IXGBE_EEC); + + eec |= IXGBE_EEC_CS; /* Pull CS high */ + eec &= ~IXGBE_EEC_SK; /* Lower SCK */ + + IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + IXGBE_WRITE_FLUSH(hw); + + udelay(1); + + /* Stop requesting EEPROM access */ + eec &= ~IXGBE_EEC_REQ; + IXGBE_WRITE_REG(hw, IXGBE_EEC, eec); + + ixgbe_release_swfw_sync(hw, IXGBE_GSSR_EEP_SM); +} + +/** * ixgbe_calc_eeprom_checksum - Calculates and returns the checksum * @hw: pointer to hardware structure **/ @@ -517,7 +872,7 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw) /* Include 0x0-0x3F in the checksum */ for (i = 0; i < IXGBE_EEPROM_CHECKSUM; i++) { - if (ixgbe_read_eeprom(hw, i, &word) != 0) { + if (hw->eeprom.ops.read(hw, i, &word) != 0) { hw_dbg(hw, "EEPROM read failed\n"); break; } @@ -526,15 +881,15 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw) /* Include all data from pointers except for the fw pointer */ for (i = IXGBE_PCIE_ANALOG_PTR; i < IXGBE_FW_PTR; i++) { - ixgbe_read_eeprom(hw, i, &pointer); + hw->eeprom.ops.read(hw, i, &pointer); /* Make sure the pointer seems valid */ if (pointer != 0xFFFF && pointer != 0) { - ixgbe_read_eeprom(hw, pointer, &length); + hw->eeprom.ops.read(hw, pointer, &length); if (length != 0xFFFF && length != 0) { for (j = pointer+1; j <= pointer+length; j++) { - ixgbe_read_eeprom(hw, j, &word); + hw->eeprom.ops.read(hw, j, &word); checksum += word; } } @@ -547,14 +902,15 @@ static u16 ixgbe_calc_eeprom_checksum(struct ixgbe_hw *hw) } /** - * ixgbe_validate_eeprom_checksum - Validate EEPROM checksum + * ixgbe_validate_eeprom_checksum_generic - Validate EEPROM checksum * @hw: pointer to hardware structure * @checksum_val: calculated checksum * * Performs checksum calculation and validates the EEPROM checksum. If the * caller does not need checksum_val, the value can be NULL. **/ -s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val) +s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, + u16 *checksum_val) { s32 status; u16 checksum; @@ -565,12 +921,12 @@ s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val) * not continue or we could be in for a very long wait while every * EEPROM read fails */ - status = ixgbe_read_eeprom(hw, 0, &checksum); + status = hw->eeprom.ops.read(hw, 0, &checksum); if (status == 0) { checksum = ixgbe_calc_eeprom_checksum(hw); - ixgbe_read_eeprom(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); + hw->eeprom.ops.read(hw, IXGBE_EEPROM_CHECKSUM, &read_checksum); /* * Verify read checksum from EEPROM is the same as @@ -590,6 +946,33 @@ s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val) } /** + * ixgbe_update_eeprom_checksum_generic - Updates the EEPROM checksum + * @hw: pointer to hardware structure + **/ +s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw) +{ + s32 status; + u16 checksum; + + /* + * Read the first word from the EEPROM. If this times out or fails, do + * not continue or we could be in for a very long wait while every + * EEPROM read fails + */ + status = hw->eeprom.ops.read(hw, 0, &checksum); + + if (status == 0) { + checksum = ixgbe_calc_eeprom_checksum(hw); + status = hw->eeprom.ops.write(hw, IXGBE_EEPROM_CHECKSUM, + checksum); + } else { + hw_dbg(hw, "EEPROM read failed\n"); + } + + return status; +} + +/** * ixgbe_validate_mac_addr - Validate MAC address * @mac_addr: pointer to MAC address. * @@ -607,58 +990,137 @@ s32 ixgbe_validate_mac_addr(u8 *mac_addr) status = IXGBE_ERR_INVALID_MAC_ADDR; /* Reject the zero address */ else if (mac_addr[0] == 0 && mac_addr[1] == 0 && mac_addr[2] == 0 && - mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) + mac_addr[3] == 0 && mac_addr[4] == 0 && mac_addr[5] == 0) status = IXGBE_ERR_INVALID_MAC_ADDR; return status; } /** - * ixgbe_set_rar - Set RX address register + * ixgbe_set_rar_generic - Set Rx address register * @hw: pointer to hardware structure - * @addr: Address to put into receive address register * @index: Receive address register to write - * @vind: Vind to set RAR to + * @addr: Address to put into receive address register + * @vmdq: VMDq "set" or "pool" index * @enable_addr: set flag that address is active * * Puts an ethernet address into a receive address register. **/ -s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind, - u32 enable_addr) +s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, + u32 enable_addr) { u32 rar_low, rar_high; + u32 rar_entries = hw->mac.num_rar_entries; - /* - * HW expects these in little endian so we reverse the byte order from - * network order (big endian) to little endian - */ - rar_low = ((u32)addr[0] | - ((u32)addr[1] << 8) | - ((u32)addr[2] << 16) | - ((u32)addr[3] << 24)); + /* setup VMDq pool selection before this RAR gets enabled */ + hw->mac.ops.set_vmdq(hw, index, vmdq); - rar_high = ((u32)addr[4] | - ((u32)addr[5] << 8) | - ((vind << IXGBE_RAH_VIND_SHIFT) & IXGBE_RAH_VIND_MASK)); + /* Make sure we are using a valid rar index range */ + if (index < rar_entries) { + /* + * HW expects these in little endian so we reverse the byte + * order from network order (big endian) to little endian + */ + rar_low = ((u32)addr[0] | + ((u32)addr[1] << 8) | + ((u32)addr[2] << 16) | + ((u32)addr[3] << 24)); + /* + * Some parts put the VMDq setting in the extra RAH bits, + * so save everything except the lower 16 bits that hold part + * of the address and the address valid bit. + */ + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); + rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); + rar_high |= ((u32)addr[4] | ((u32)addr[5] << 8)); - if (enable_addr != 0) - rar_high |= IXGBE_RAH_AV; + if (enable_addr != 0) + rar_high |= IXGBE_RAH_AV; - IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low); - IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); + IXGBE_WRITE_REG(hw, IXGBE_RAL(index), rar_low); + IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); + } else { + hw_dbg(hw, "RAR index %d is out of range.\n", index); + } return 0; } /** - * ixgbe_init_rx_addrs - Initializes receive address filters. + * ixgbe_clear_rar_generic - Remove Rx address register + * @hw: pointer to hardware structure + * @index: Receive address register to write + * + * Clears an ethernet address from a receive address register. + **/ +s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index) +{ + u32 rar_high; + u32 rar_entries = hw->mac.num_rar_entries; + + /* Make sure we are using a valid rar index range */ + if (index < rar_entries) { + /* + * Some parts put the VMDq setting in the extra RAH bits, + * so save everything except the lower 16 bits that hold part + * of the address and the address valid bit. + */ + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); + rar_high &= ~(0x0000FFFF | IXGBE_RAH_AV); + + IXGBE_WRITE_REG(hw, IXGBE_RAL(index), 0); + IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); + } else { + hw_dbg(hw, "RAR index %d is out of range.\n", index); + } + + /* clear VMDq pool/queue selection for this RAR */ + hw->mac.ops.clear_vmdq(hw, index, IXGBE_CLEAR_VMDQ_ALL); + + return 0; +} + +/** + * ixgbe_enable_rar - Enable Rx address register + * @hw: pointer to hardware structure + * @index: index into the RAR table + * + * Enables the select receive address register. + **/ +static void ixgbe_enable_rar(struct ixgbe_hw *hw, u32 index) +{ + u32 rar_high; + + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); + rar_high |= IXGBE_RAH_AV; + IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); +} + +/** + * ixgbe_disable_rar - Disable Rx address register + * @hw: pointer to hardware structure + * @index: index into the RAR table + * + * Disables the select receive address register. + **/ +static void ixgbe_disable_rar(struct ixgbe_hw *hw, u32 index) +{ + u32 rar_high; + + rar_high = IXGBE_READ_REG(hw, IXGBE_RAH(index)); + rar_high &= (~IXGBE_RAH_AV); + IXGBE_WRITE_REG(hw, IXGBE_RAH(index), rar_high); +} + +/** + * ixgbe_init_rx_addrs_generic - Initializes receive address filters. * @hw: pointer to hardware structure * * Places the MAC address in receive address register 0 and clears the rest - * of the receive addresss registers. Clears the multicast table. Assumes + * of the receive address registers. Clears the multicast table. Assumes * the receiver is in reset when the routine is called. **/ -static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw) +s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw) { u32 i; u32 rar_entries = hw->mac.num_rar_entries; @@ -671,29 +1133,30 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw) if (ixgbe_validate_mac_addr(hw->mac.addr) == IXGBE_ERR_INVALID_MAC_ADDR) { /* Get the MAC address from the RAR0 for later reference */ - ixgbe_get_mac_addr(hw, hw->mac.addr); + hw->mac.ops.get_mac_addr(hw, hw->mac.addr); hw_dbg(hw, " Keeping Current RAR0 Addr =%.2X %.2X %.2X ", - hw->mac.addr[0], hw->mac.addr[1], - hw->mac.addr[2]); + hw->mac.addr[0], hw->mac.addr[1], + hw->mac.addr[2]); hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3], - hw->mac.addr[4], hw->mac.addr[5]); + hw->mac.addr[4], hw->mac.addr[5]); } else { /* Setup the receive address. */ hw_dbg(hw, "Overriding MAC Address in RAR[0]\n"); hw_dbg(hw, " New MAC Addr =%.2X %.2X %.2X ", - hw->mac.addr[0], hw->mac.addr[1], - hw->mac.addr[2]); + hw->mac.addr[0], hw->mac.addr[1], + hw->mac.addr[2]); hw_dbg(hw, "%.2X %.2X %.2X\n", hw->mac.addr[3], - hw->mac.addr[4], hw->mac.addr[5]); + hw->mac.addr[4], hw->mac.addr[5]); - ixgbe_set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); + hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); } + hw->addr_ctrl.overflow_promisc = 0; hw->addr_ctrl.rar_used_count = 1; /* Zero out the other receive addresses. */ - hw_dbg(hw, "Clearing RAR[1-15]\n"); + hw_dbg(hw, "Clearing RAR[1-%d]\n", rar_entries - 1); for (i = 1; i < rar_entries; i++) { IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); @@ -708,6 +1171,9 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw) for (i = 0; i < hw->mac.mcft_size; i++) IXGBE_WRITE_REG(hw, IXGBE_MTA(i), 0); + if (hw->mac.ops.init_uta_tables) + hw->mac.ops.init_uta_tables(hw); + return 0; } @@ -718,7 +1184,7 @@ static s32 ixgbe_init_rx_addrs(struct ixgbe_hw *hw) * * Adds it to unused receive address register or goes into promiscuous mode. **/ -void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr) +static void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr, u32 vmdq) { u32 rar_entries = hw->mac.num_rar_entries; u32 rar; @@ -733,7 +1199,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr) if (hw->addr_ctrl.rar_used_count < rar_entries) { rar = hw->addr_ctrl.rar_used_count - hw->addr_ctrl.mc_addr_in_rar_count; - ixgbe_set_rar(hw, rar, addr, 0, IXGBE_RAH_AV); + hw->mac.ops.set_rar(hw, rar, addr, vmdq, IXGBE_RAH_AV); hw_dbg(hw, "Added a secondary address to RAR[%d]\n", rar); hw->addr_ctrl.rar_used_count++; } else { @@ -744,7 +1210,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr) } /** - * ixgbe_update_uc_addr_list - Updates MAC list of secondary addresses + * ixgbe_update_uc_addr_list_generic - Updates MAC list of secondary addresses * @hw: pointer to hardware structure * @addr_list: the list of new addresses * @addr_count: number of addresses @@ -757,7 +1223,7 @@ void ixgbe_add_uc_addr(struct ixgbe_hw *hw, u8 *addr) * Drivers using secondary unicast addresses must set user_set_promisc when * manually putting the device into promiscuous mode. **/ -s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list, +s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, u32 addr_count, ixgbe_mc_addr_itr next) { u8 *addr; @@ -787,7 +1253,7 @@ s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list, for (i = 0; i < addr_count; i++) { hw_dbg(hw, " Adding the secondary addresses:\n"); addr = next(hw, &addr_list, &vmdq); - ixgbe_add_uc_addr(hw, addr); + ixgbe_add_uc_addr(hw, addr, vmdq); } if (hw->addr_ctrl.overflow_promisc) { @@ -808,7 +1274,7 @@ s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list, } } - hw_dbg(hw, "ixgbe_update_uc_addr_list Complete\n"); + hw_dbg(hw, "ixgbe_update_uc_addr_list_generic Complete\n"); return 0; } @@ -821,7 +1287,7 @@ s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *addr_list, * bit-vector to set in the multicast table. The hardware uses 12 bits, from * incoming rx multicast addresses, to determine the bit-vector to check in * the MTA. Which of the 4 combination, of 12-bits, the hardware uses is set - * by the MO field of the MCSTCTRL. The MO field is set during initalization + * by the MO field of the MCSTCTRL. The MO field is set during initialization * to mc_filter_type. **/ static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) @@ -829,19 +1295,19 @@ static s32 ixgbe_mta_vector(struct ixgbe_hw *hw, u8 *mc_addr) u32 vector = 0; switch (hw->mac.mc_filter_type) { - case 0: /* use bits [47:36] of the address */ + case 0: /* use bits [47:36] of the address */ vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); break; - case 1: /* use bits [46:35] of the address */ + case 1: /* use bits [46:35] of the address */ vector = ((mc_addr[4] >> 3) | (((u16)mc_addr[5]) << 5)); break; - case 2: /* use bits [45:34] of the address */ + case 2: /* use bits [45:34] of the address */ vector = ((mc_addr[4] >> 2) | (((u16)mc_addr[5]) << 6)); break; - case 3: /* use bits [43:32] of the address */ + case 3: /* use bits [43:32] of the address */ vector = ((mc_addr[4]) | (((u16)mc_addr[5]) << 8)); break; - default: /* Invalid mc_filter_type */ + default: /* Invalid mc_filter_type */ hw_dbg(hw, "MC filter type param set incorrectly\n"); break; } @@ -896,20 +1362,21 @@ static void ixgbe_set_mta(struct ixgbe_hw *hw, u8 *mc_addr) static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr) { u32 rar_entries = hw->mac.num_rar_entries; + u32 rar; hw_dbg(hw, " MC Addr =%.2X %.2X %.2X %.2X %.2X %.2X\n", - mc_addr[0], mc_addr[1], mc_addr[2], - mc_addr[3], mc_addr[4], mc_addr[5]); + mc_addr[0], mc_addr[1], mc_addr[2], + mc_addr[3], mc_addr[4], mc_addr[5]); /* * Place this multicast address in the RAR if there is room, * else put it in the MTA */ if (hw->addr_ctrl.rar_used_count < rar_entries) { - ixgbe_set_rar(hw, hw->addr_ctrl.rar_used_count, - mc_addr, 0, IXGBE_RAH_AV); - hw_dbg(hw, "Added a multicast address to RAR[%d]\n", - hw->addr_ctrl.rar_used_count); + /* use RAR from the end up for multicast */ + rar = rar_entries - hw->addr_ctrl.mc_addr_in_rar_count - 1; + hw->mac.ops.set_rar(hw, rar, mc_addr, 0, IXGBE_RAH_AV); + hw_dbg(hw, "Added a multicast address to RAR[%d]\n", rar); hw->addr_ctrl.rar_used_count++; hw->addr_ctrl.mc_addr_in_rar_count++; } else { @@ -920,19 +1387,19 @@ static void ixgbe_add_mc_addr(struct ixgbe_hw *hw, u8 *mc_addr) } /** - * ixgbe_update_mc_addr_list - Updates MAC list of multicast addresses + * ixgbe_update_mc_addr_list_generic - Updates MAC list of multicast addresses * @hw: pointer to hardware structure * @mc_addr_list: the list of new multicast addresses * @mc_addr_count: number of addresses * @next: iterator function to walk the multicast address list * * The given list replaces any existing list. Clears the MC addrs from receive - * address registers and the multicast table. Uses unsed receive address + * address registers and the multicast table. Uses unused receive address * registers for the first multicast addresses, and hashes the rest into the * multicast table. **/ -s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list, - u32 mc_addr_count, ixgbe_mc_addr_itr next) +s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, + u32 mc_addr_count, ixgbe_mc_addr_itr next) { u32 i; u32 rar_entries = hw->mac.num_rar_entries; @@ -948,7 +1415,8 @@ s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list, hw->addr_ctrl.mta_in_use = 0; /* Zero out the other receive addresses. */ - hw_dbg(hw, "Clearing RAR[1-15]\n"); + hw_dbg(hw, "Clearing RAR[%d-%d]\n", hw->addr_ctrl.rar_used_count, + rar_entries - 1); for (i = hw->addr_ctrl.rar_used_count; i < rar_entries; i++) { IXGBE_WRITE_REG(hw, IXGBE_RAL(i), 0); IXGBE_WRITE_REG(hw, IXGBE_RAH(i), 0); @@ -968,190 +1436,55 @@ s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list, /* Enable mta */ if (hw->addr_ctrl.mta_in_use > 0) IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, - IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); + IXGBE_MCSTCTRL_MFE | hw->mac.mc_filter_type); - hw_dbg(hw, "ixgbe_update_mc_addr_list Complete\n"); + hw_dbg(hw, "ixgbe_update_mc_addr_list_generic Complete\n"); return 0; } /** - * ixgbe_clear_vfta - Clear VLAN filter table + * ixgbe_enable_mc_generic - Enable multicast address in RAR * @hw: pointer to hardware structure * - * Clears the VLAN filer table, and the VMDq index associated with the filter + * Enables multicast address in RAR and the use of the multicast hash table. **/ -static s32 ixgbe_clear_vfta(struct ixgbe_hw *hw) +s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw) { - u32 offset; - u32 vlanbyte; + u32 i; + u32 rar_entries = hw->mac.num_rar_entries; + struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; - for (offset = 0; offset < hw->mac.vft_size; offset++) - IXGBE_WRITE_REG(hw, IXGBE_VFTA(offset), 0); + if (a->mc_addr_in_rar_count > 0) + for (i = (rar_entries - a->mc_addr_in_rar_count); + i < rar_entries; i++) + ixgbe_enable_rar(hw, i); - for (vlanbyte = 0; vlanbyte < 4; vlanbyte++) - for (offset = 0; offset < hw->mac.vft_size; offset++) - IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(vlanbyte, offset), - 0); + if (a->mta_in_use > 0) + IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, IXGBE_MCSTCTRL_MFE | + hw->mac.mc_filter_type); return 0; } /** - * ixgbe_set_vfta - Set VLAN filter table + * ixgbe_disable_mc_generic - Disable multicast address in RAR * @hw: pointer to hardware structure - * @vlan: VLAN id to write to VLAN filter - * @vind: VMDq output index that maps queue to VLAN id in VFTA - * @vlan_on: boolean flag to turn on/off VLAN in VFTA * - * Turn on/off specified VLAN in the VLAN filter table. + * Disables multicast address in RAR and the use of the multicast hash table. **/ -s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, - bool vlan_on) +s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw) { - u32 VftaIndex; - u32 BitOffset; - u32 VftaReg; - u32 VftaByte; - - /* Determine 32-bit word position in array */ - VftaIndex = (vlan >> 5) & 0x7F; /* upper seven bits */ - - /* Determine the location of the (VMD) queue index */ - VftaByte = ((vlan >> 3) & 0x03); /* bits (4:3) indicating byte array */ - BitOffset = (vlan & 0x7) << 2; /* lower 3 bits indicate nibble */ - - /* Set the nibble for VMD queue index */ - VftaReg = IXGBE_READ_REG(hw, IXGBE_VFTAVIND(VftaByte, VftaIndex)); - VftaReg &= (~(0x0F << BitOffset)); - VftaReg |= (vind << BitOffset); - IXGBE_WRITE_REG(hw, IXGBE_VFTAVIND(VftaByte, VftaIndex), VftaReg); - - /* Determine the location of the bit for this VLAN id */ - BitOffset = vlan & 0x1F; /* lower five bits */ - - VftaReg = IXGBE_READ_REG(hw, IXGBE_VFTA(VftaIndex)); - if (vlan_on) - /* Turn on this VLAN id */ - VftaReg |= (1 << BitOffset); - else - /* Turn off this VLAN id */ - VftaReg &= ~(1 << BitOffset); - IXGBE_WRITE_REG(hw, IXGBE_VFTA(VftaIndex), VftaReg); - - return 0; -} - -/** - * ixgbe_setup_fc - Configure flow control settings - * @hw: pointer to hardware structure - * @packetbuf_num: packet buffer number (0-7) - * - * Configures the flow control settings based on SW configuration. - * This function is used for 802.3x flow control configuration only. - **/ -s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) -{ - u32 frctl_reg; - u32 rmcs_reg; - - if (packetbuf_num < 0 || packetbuf_num > 7) - hw_dbg(hw, "Invalid packet buffer number [%d], expected range " - "is 0-7\n", packetbuf_num); - - frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); - frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE); - - rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS); - rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X); - - /* - * 10 gig parts do not have a word in the EEPROM to determine the - * default flow control setting, so we explicitly set it to full. - */ - if (hw->fc.type == ixgbe_fc_default) - hw->fc.type = ixgbe_fc_full; - - /* - * We want to save off the original Flow Control configuration just in - * case we get disconnected and then reconnected into a different hub - * or switch with different Flow Control capabilities. - */ - hw->fc.type = hw->fc.original_type; - - /* - * The possible values of the "flow_control" parameter are: - * 0: Flow control is completely disabled - * 1: Rx flow control is enabled (we can receive pause frames but not - * send pause frames). - * 2: Tx flow control is enabled (we can send pause frames but we do not - * support receiving pause frames) - * 3: Both Rx and TX flow control (symmetric) are enabled. - * other: Invalid. - */ - switch (hw->fc.type) { - case ixgbe_fc_none: - break; - case ixgbe_fc_rx_pause: - /* - * RX Flow control is enabled, - * and TX Flow control is disabled. - */ - frctl_reg |= IXGBE_FCTRL_RFCE; - break; - case ixgbe_fc_tx_pause: - /* - * TX Flow control is enabled, and RX Flow control is disabled, - * by a software over-ride. - */ - rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; - break; - case ixgbe_fc_full: - /* - * Flow control (both RX and TX) is enabled by a software - * over-ride. - */ - frctl_reg |= IXGBE_FCTRL_RFCE; - rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; - break; - default: - /* We should never get here. The value should be 0-3. */ - hw_dbg(hw, "Flow control param set incorrectly\n"); - break; - } + u32 i; + u32 rar_entries = hw->mac.num_rar_entries; + struct ixgbe_addr_filter_info *a = &hw->addr_ctrl; - /* Enable 802.3x based flow control settings. */ - IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg); - IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg); + if (a->mc_addr_in_rar_count > 0) + for (i = (rar_entries - a->mc_addr_in_rar_count); + i < rar_entries; i++) + ixgbe_disable_rar(hw, i); - /* - * Check for invalid software configuration, zeros are completely - * invalid for all parameters used past this point, and if we enable - * flow control with zero water marks, we blast flow control packets. - */ - if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) { - hw_dbg(hw, "Flow control structure initialized incorrectly\n"); - return IXGBE_ERR_INVALID_LINK_SETTINGS; - } - - /* - * We need to set up the Receive Threshold high and low water - * marks as well as (optionally) enabling the transmission of - * XON frames. - */ - if (hw->fc.type & ixgbe_fc_tx_pause) { - if (hw->fc.send_xon) { - IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), - (hw->fc.low_water | IXGBE_FCRTL_XONE)); - } else { - IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), - hw->fc.low_water); - } - IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), - (hw->fc.high_water)|IXGBE_FCRTH_FCEN); - } - - IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time); - IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1)); + if (a->mta_in_use > 0) + IXGBE_WRITE_REG(hw, IXGBE_MCSTCTRL, hw->mac.mc_filter_type); return 0; } @@ -1167,13 +1500,24 @@ s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packetbuf_num) **/ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) { - u32 ctrl; - s32 i; + u32 i; + u32 reg_val; + u32 number_of_queues; s32 status = IXGBE_ERR_MASTER_REQUESTS_PENDING; - ctrl = IXGBE_READ_REG(hw, IXGBE_CTRL); - ctrl |= IXGBE_CTRL_GIO_DIS; - IXGBE_WRITE_REG(hw, IXGBE_CTRL, ctrl); + /* Disable the receive unit by stopping each queue */ + number_of_queues = hw->mac.max_rx_queues; + for (i = 0; i < number_of_queues; i++) { + reg_val = IXGBE_READ_REG(hw, IXGBE_RXDCTL(i)); + if (reg_val & IXGBE_RXDCTL_ENABLE) { + reg_val &= ~IXGBE_RXDCTL_ENABLE; + IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(i), reg_val); + } + } + + reg_val = IXGBE_READ_REG(hw, IXGBE_CTRL); + reg_val |= IXGBE_CTRL_GIO_DIS; + IXGBE_WRITE_REG(hw, IXGBE_CTRL, reg_val); for (i = 0; i < IXGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { if (!(IXGBE_READ_REG(hw, IXGBE_STATUS) & IXGBE_STATUS_GIO)) { @@ -1188,11 +1532,11 @@ s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw) /** - * ixgbe_acquire_swfw_sync - Aquire SWFW semaphore + * ixgbe_acquire_swfw_sync - Acquire SWFW semaphore * @hw: pointer to hardware structure - * @mask: Mask to specify wich semaphore to acquire + * @mask: Mask to specify which semaphore to acquire * - * Aquires the SWFW semaphore throught the GSSR register for the specified + * Acquires the SWFW semaphore thought the GSSR register for the specified * function (CSR, PHY0, PHY1, EEPROM, Flash) **/ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) @@ -1234,9 +1578,9 @@ s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask) /** * ixgbe_release_swfw_sync - Release SWFW semaphore * @hw: pointer to hardware structure - * @mask: Mask to specify wich semaphore to release + * @mask: Mask to specify which semaphore to release * - * Releases the SWFW semaphore throught the GSSR register for the specified + * Releases the SWFW semaphore thought the GSSR register for the specified * function (CSR, PHY0, PHY1, EEPROM, Flash) **/ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) @@ -1253,45 +1597,3 @@ void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask) ixgbe_release_eeprom_semaphore(hw); } -/** - * ixgbe_read_analog_reg8 - Reads 8 bit Atlas analog register - * @hw: pointer to hardware structure - * @reg: analog register to read - * @val: read value - * - * Performs write operation to analog register specified. - **/ -s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val) -{ - u32 atlas_ctl; - - IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, - IXGBE_ATLASCTL_WRITE_CMD | (reg << 8)); - IXGBE_WRITE_FLUSH(hw); - udelay(10); - atlas_ctl = IXGBE_READ_REG(hw, IXGBE_ATLASCTL); - *val = (u8)atlas_ctl; - - return 0; -} - -/** - * ixgbe_write_analog_reg8 - Writes 8 bit Atlas analog register - * @hw: pointer to hardware structure - * @reg: atlas register to write - * @val: value to write - * - * Performs write operation to Atlas analog register specified. - **/ -s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val) -{ - u32 atlas_ctl; - - atlas_ctl = (reg << 8) | val; - IXGBE_WRITE_REG(hw, IXGBE_ATLASCTL, atlas_ctl); - IXGBE_WRITE_FLUSH(hw); - udelay(10); - - return 0; -} - diff --git a/drivers/net/ixgbe/ixgbe_common.h b/drivers/net/ixgbe/ixgbe_common.h index c75ecba9ccd..192f8d01291 100644 --- a/drivers/net/ixgbe/ixgbe_common.h +++ b/drivers/net/ixgbe/ixgbe_common.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2007 Intel Corporation. + Copyright(c) 1999 - 2008 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -20,7 +20,6 @@ the file called "COPYING". Contact Information: - Linux NICS <linux.nics@intel.com> e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 @@ -31,36 +30,45 @@ #include "ixgbe_type.h" -s32 ixgbe_init_hw(struct ixgbe_hw *hw); -s32 ixgbe_start_hw(struct ixgbe_hw *hw); -s32 ixgbe_get_mac_addr(struct ixgbe_hw *hw, u8 *mac_addr); -s32 ixgbe_stop_adapter(struct ixgbe_hw *hw); -s32 ixgbe_read_part_num(struct ixgbe_hw *hw, u32 *part_num); - -s32 ixgbe_led_on(struct ixgbe_hw *hw, u32 index); -s32 ixgbe_led_off(struct ixgbe_hw *hw, u32 index); - -s32 ixgbe_init_eeprom(struct ixgbe_hw *hw); -s32 ixgbe_read_eeprom(struct ixgbe_hw *hw, u16 offset, u16 *data); -s32 ixgbe_validate_eeprom_checksum(struct ixgbe_hw *hw, u16 *checksum_val); - -s32 ixgbe_set_rar(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vind, - u32 enable_addr); -s32 ixgbe_update_mc_addr_list(struct ixgbe_hw *hw, u8 *mc_addr_list, - u32 mc_addr_count, ixgbe_mc_addr_itr next); -s32 ixgbe_update_uc_addr_list(struct ixgbe_hw *hw, u8 *uc_addr_list, - u32 mc_addr_count, ixgbe_mc_addr_itr next); -s32 ixgbe_set_vfta(struct ixgbe_hw *hw, u32 vlan, u32 vind, bool vlan_on); -s32 ixgbe_validate_mac_addr(u8 *mac_addr); - -s32 ixgbe_setup_fc(struct ixgbe_hw *hw, s32 packtetbuf_num); +s32 ixgbe_init_ops_generic(struct ixgbe_hw *hw); +s32 ixgbe_init_hw_generic(struct ixgbe_hw *hw); +s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw); +s32 ixgbe_clear_hw_cntrs_generic(struct ixgbe_hw *hw); +s32 ixgbe_read_pba_num_generic(struct ixgbe_hw *hw, u32 *pba_num); +s32 ixgbe_get_mac_addr_generic(struct ixgbe_hw *hw, u8 *mac_addr); +s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw); +s32 ixgbe_stop_adapter_generic(struct ixgbe_hw *hw); + +s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index); + +s32 ixgbe_init_eeprom_params_generic(struct ixgbe_hw *hw); +s32 ixgbe_read_eeprom_generic(struct ixgbe_hw *hw, u16 offset, u16 *data); +s32 ixgbe_read_eeprom_bit_bang_generic(struct ixgbe_hw *hw, u16 offset, + u16 *data); +s32 ixgbe_validate_eeprom_checksum_generic(struct ixgbe_hw *hw, + u16 *checksum_val); +s32 ixgbe_update_eeprom_checksum_generic(struct ixgbe_hw *hw); + +s32 ixgbe_set_rar_generic(struct ixgbe_hw *hw, u32 index, u8 *addr, u32 vmdq, + u32 enable_addr); +s32 ixgbe_clear_rar_generic(struct ixgbe_hw *hw, u32 index); +s32 ixgbe_init_rx_addrs_generic(struct ixgbe_hw *hw); +s32 ixgbe_update_mc_addr_list_generic(struct ixgbe_hw *hw, u8 *mc_addr_list, + u32 mc_addr_count, + ixgbe_mc_addr_itr func); +s32 ixgbe_update_uc_addr_list_generic(struct ixgbe_hw *hw, u8 *addr_list, + u32 addr_count, ixgbe_mc_addr_itr func); +s32 ixgbe_enable_mc_generic(struct ixgbe_hw *hw); +s32 ixgbe_disable_mc_generic(struct ixgbe_hw *hw); +s32 ixgbe_validate_mac_addr(u8 *mac_addr); s32 ixgbe_acquire_swfw_sync(struct ixgbe_hw *hw, u16 mask); void ixgbe_release_swfw_sync(struct ixgbe_hw *hw, u16 mask); s32 ixgbe_disable_pcie_master(struct ixgbe_hw *hw); -s32 ixgbe_read_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 *val); -s32 ixgbe_write_analog_reg8(struct ixgbe_hw *hw, u32 reg, u8 val); +s32 ixgbe_read_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 *val); +s32 ixgbe_write_analog_reg8_generic(struct ixgbe_hw *hw, u32 reg, u8 val); #define IXGBE_WRITE_REG(a, reg, value) writel((value), ((a)->hw_addr + (reg))) diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index 61c000e2309..81a9c4b8672 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2007 Intel Corporation. + Copyright(c) 1999 - 2008 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -20,7 +20,6 @@ the file called "COPYING". Contact Information: - Linux NICS <linux.nics@intel.com> e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 @@ -48,7 +47,7 @@ struct ixgbe_stats { }; #define IXGBE_STAT(m) sizeof(((struct ixgbe_adapter *)0)->m), \ - offsetof(struct ixgbe_adapter, m) + offsetof(struct ixgbe_adapter, m) static struct ixgbe_stats ixgbe_gstrings_stats[] = { {"rx_packets", IXGBE_STAT(net_stats.rx_packets)}, {"tx_packets", IXGBE_STAT(net_stats.tx_packets)}, @@ -95,14 +94,15 @@ static struct ixgbe_stats ixgbe_gstrings_stats[] = { }; #define IXGBE_QUEUE_STATS_LEN \ - ((((struct ixgbe_adapter *)netdev->priv)->num_tx_queues + \ - ((struct ixgbe_adapter *)netdev->priv)->num_rx_queues) * \ - (sizeof(struct ixgbe_queue_stats) / sizeof(u64))) -#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats) + ((((struct ixgbe_adapter *)netdev->priv)->num_tx_queues + \ + ((struct ixgbe_adapter *)netdev->priv)->num_rx_queues) * \ + (sizeof(struct ixgbe_queue_stats) / sizeof(u64))) +#define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN) +#define IXGBE_GLOBAL_STATS_LEN ARRAY_SIZE(ixgbe_gstrings_stats) #define IXGBE_STATS_LEN (IXGBE_GLOBAL_STATS_LEN + IXGBE_QUEUE_STATS_LEN) static int ixgbe_get_settings(struct net_device *netdev, - struct ethtool_cmd *ecmd) + struct ethtool_cmd *ecmd) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; @@ -114,7 +114,7 @@ static int ixgbe_get_settings(struct net_device *netdev, ecmd->transceiver = XCVR_EXTERNAL; if (hw->phy.media_type == ixgbe_media_type_copper) { ecmd->supported |= (SUPPORTED_1000baseT_Full | - SUPPORTED_TP | SUPPORTED_Autoneg); + SUPPORTED_TP | SUPPORTED_Autoneg); ecmd->advertising = (ADVERTISED_TP | ADVERTISED_Autoneg); if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL) @@ -126,14 +126,15 @@ static int ixgbe_get_settings(struct net_device *netdev, } else { ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising = (ADVERTISED_10000baseT_Full | - ADVERTISED_FIBRE); + ADVERTISED_FIBRE); ecmd->port = PORT_FIBRE; + ecmd->autoneg = AUTONEG_DISABLE; } - adapter->hw.mac.ops.check_link(hw, &(link_speed), &link_up); + hw->mac.ops.check_link(hw, &link_speed, &link_up, false); if (link_up) { ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ? - SPEED_10000 : SPEED_1000; + SPEED_10000 : SPEED_1000; ecmd->duplex = DUPLEX_FULL; } else { ecmd->speed = -1; @@ -144,7 +145,7 @@ static int ixgbe_get_settings(struct net_device *netdev, } static int ixgbe_set_settings(struct net_device *netdev, - struct ethtool_cmd *ecmd) + struct ethtool_cmd *ecmd) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; @@ -164,7 +165,7 @@ static int ixgbe_set_settings(struct net_device *netdev, } static void ixgbe_get_pauseparam(struct net_device *netdev, - struct ethtool_pauseparam *pause) + struct ethtool_pauseparam *pause) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; @@ -182,7 +183,7 @@ static void ixgbe_get_pauseparam(struct net_device *netdev, } static int ixgbe_set_pauseparam(struct net_device *netdev, - struct ethtool_pauseparam *pause) + struct ethtool_pauseparam *pause) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; @@ -241,7 +242,7 @@ static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data) if (data) netdev->features |= (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); else - netdev->features &= ~NETIF_F_IP_CSUM; + netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM); return 0; } @@ -281,7 +282,7 @@ static int ixgbe_get_regs_len(struct net_device *netdev) #define IXGBE_GET_STAT(_A_, _R_) _A_->stats._R_ static void ixgbe_get_regs(struct net_device *netdev, - struct ethtool_regs *regs, void *p) + struct ethtool_regs *regs, void *p) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; @@ -315,7 +316,9 @@ static void ixgbe_get_regs(struct net_device *netdev, regs_buff[17] = IXGBE_READ_REG(hw, IXGBE_GRC); /* Interrupt */ - regs_buff[18] = IXGBE_READ_REG(hw, IXGBE_EICR); + /* don't read EICR because it can clear interrupt causes, instead + * read EICS which is a shadow but doesn't clear EICR */ + regs_buff[18] = IXGBE_READ_REG(hw, IXGBE_EICS); regs_buff[19] = IXGBE_READ_REG(hw, IXGBE_EICS); regs_buff[20] = IXGBE_READ_REG(hw, IXGBE_EIMS); regs_buff[21] = IXGBE_READ_REG(hw, IXGBE_EIMC); @@ -325,7 +328,7 @@ static void ixgbe_get_regs(struct net_device *netdev, regs_buff[25] = IXGBE_READ_REG(hw, IXGBE_IVAR(0)); regs_buff[26] = IXGBE_READ_REG(hw, IXGBE_MSIXT); regs_buff[27] = IXGBE_READ_REG(hw, IXGBE_MSIXPBA); - regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_PBACL); + regs_buff[28] = IXGBE_READ_REG(hw, IXGBE_PBACL(0)); regs_buff[29] = IXGBE_READ_REG(hw, IXGBE_GPIE); /* Flow Control */ @@ -371,7 +374,7 @@ static void ixgbe_get_regs(struct net_device *netdev, regs_buff[482 + i] = IXGBE_READ_REG(hw, IXGBE_RAL(i)); for (i = 0; i < 16; i++) regs_buff[498 + i] = IXGBE_READ_REG(hw, IXGBE_RAH(i)); - regs_buff[514] = IXGBE_READ_REG(hw, IXGBE_PSRTYPE); + regs_buff[514] = IXGBE_READ_REG(hw, IXGBE_PSRTYPE(0)); regs_buff[515] = IXGBE_READ_REG(hw, IXGBE_FCTRL); regs_buff[516] = IXGBE_READ_REG(hw, IXGBE_VLNCTRL); regs_buff[517] = IXGBE_READ_REG(hw, IXGBE_MCSTCTRL); @@ -419,7 +422,6 @@ static void ixgbe_get_regs(struct net_device *netdev, regs_buff[827] = IXGBE_READ_REG(hw, IXGBE_WUPM); regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT); - /* DCE */ regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS); regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS); regs_buff[831] = IXGBE_READ_REG(hw, IXGBE_PDPMCS); @@ -539,21 +541,17 @@ static void ixgbe_get_regs(struct net_device *netdev, /* Diagnostic */ regs_buff[1071] = IXGBE_READ_REG(hw, IXGBE_RDSTATCTL); for (i = 0; i < 8; i++) - regs_buff[1072] = IXGBE_READ_REG(hw, IXGBE_RDSTAT(i)); + regs_buff[1072 + i] = IXGBE_READ_REG(hw, IXGBE_RDSTAT(i)); regs_buff[1080] = IXGBE_READ_REG(hw, IXGBE_RDHMPN); - regs_buff[1081] = IXGBE_READ_REG(hw, IXGBE_RIC_DW0); - regs_buff[1082] = IXGBE_READ_REG(hw, IXGBE_RIC_DW1); - regs_buff[1083] = IXGBE_READ_REG(hw, IXGBE_RIC_DW2); - regs_buff[1084] = IXGBE_READ_REG(hw, IXGBE_RIC_DW3); + for (i = 0; i < 4; i++) + regs_buff[1081 + i] = IXGBE_READ_REG(hw, IXGBE_RIC_DW(i)); regs_buff[1085] = IXGBE_READ_REG(hw, IXGBE_RDPROBE); regs_buff[1086] = IXGBE_READ_REG(hw, IXGBE_TDSTATCTL); for (i = 0; i < 8; i++) - regs_buff[1087] = IXGBE_READ_REG(hw, IXGBE_TDSTAT(i)); + regs_buff[1087 + i] = IXGBE_READ_REG(hw, IXGBE_TDSTAT(i)); regs_buff[1095] = IXGBE_READ_REG(hw, IXGBE_TDHMPN); - regs_buff[1096] = IXGBE_READ_REG(hw, IXGBE_TIC_DW0); - regs_buff[1097] = IXGBE_READ_REG(hw, IXGBE_TIC_DW1); - regs_buff[1098] = IXGBE_READ_REG(hw, IXGBE_TIC_DW2); - regs_buff[1099] = IXGBE_READ_REG(hw, IXGBE_TIC_DW3); + for (i = 0; i < 4; i++) + regs_buff[1096 + i] = IXGBE_READ_REG(hw, IXGBE_TIC_DW(i)); regs_buff[1100] = IXGBE_READ_REG(hw, IXGBE_TDPROBE); regs_buff[1101] = IXGBE_READ_REG(hw, IXGBE_TXBUFCTRL); regs_buff[1102] = IXGBE_READ_REG(hw, IXGBE_TXBUFDATA0); @@ -566,7 +564,7 @@ static void ixgbe_get_regs(struct net_device *netdev, regs_buff[1109] = IXGBE_READ_REG(hw, IXGBE_RXBUFDATA2); regs_buff[1110] = IXGBE_READ_REG(hw, IXGBE_RXBUFDATA3); for (i = 0; i < 8; i++) - regs_buff[1111] = IXGBE_READ_REG(hw, IXGBE_PCIE_DIAG(i)); + regs_buff[1111 + i] = IXGBE_READ_REG(hw, IXGBE_PCIE_DIAG(i)); regs_buff[1119] = IXGBE_READ_REG(hw, IXGBE_RFVAL); regs_buff[1120] = IXGBE_READ_REG(hw, IXGBE_MDFTC1); regs_buff[1121] = IXGBE_READ_REG(hw, IXGBE_MDFTC2); @@ -585,7 +583,7 @@ static int ixgbe_get_eeprom_len(struct net_device *netdev) } static int ixgbe_get_eeprom(struct net_device *netdev, - struct ethtool_eeprom *eeprom, u8 *bytes) + struct ethtool_eeprom *eeprom, u8 *bytes) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_hw *hw = &adapter->hw; @@ -608,8 +606,8 @@ static int ixgbe_get_eeprom(struct net_device *netdev, return -ENOMEM; for (i = 0; i < eeprom_len; i++) { - if ((ret_val = ixgbe_read_eeprom(hw, first_word + i, - &eeprom_buff[i]))) + if ((ret_val = hw->eeprom.ops.read(hw, first_word + i, + &eeprom_buff[i]))) break; } @@ -624,7 +622,7 @@ static int ixgbe_get_eeprom(struct net_device *netdev, } static void ixgbe_get_drvinfo(struct net_device *netdev, - struct ethtool_drvinfo *drvinfo) + struct ethtool_drvinfo *drvinfo) { struct ixgbe_adapter *adapter = netdev_priv(netdev); @@ -637,7 +635,7 @@ static void ixgbe_get_drvinfo(struct net_device *netdev, } static void ixgbe_get_ringparam(struct net_device *netdev, - struct ethtool_ringparam *ring) + struct ethtool_ringparam *ring) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_ring *tx_ring = adapter->tx_ring; @@ -654,15 +652,12 @@ static void ixgbe_get_ringparam(struct net_device *netdev, } static int ixgbe_set_ringparam(struct net_device *netdev, - struct ethtool_ringparam *ring) + struct ethtool_ringparam *ring) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - struct ixgbe_tx_buffer *old_buf; - struct ixgbe_rx_buffer *old_rx_buf; - void *old_desc; + struct ixgbe_ring *temp_ring; int i, err; - u32 new_rx_count, new_tx_count, old_size; - dma_addr_t old_dma; + u32 new_rx_count, new_tx_count; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; @@ -681,6 +676,15 @@ static int ixgbe_set_ringparam(struct net_device *netdev, return 0; } + if (adapter->num_tx_queues > adapter->num_rx_queues) + temp_ring = vmalloc(adapter->num_tx_queues * + sizeof(struct ixgbe_ring)); + else + temp_ring = vmalloc(adapter->num_rx_queues * + sizeof(struct ixgbe_ring)); + if (!temp_ring) + return -ENOMEM; + while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) msleep(1); @@ -693,66 +697,61 @@ static int ixgbe_set_ringparam(struct net_device *netdev, * to the tx and rx ring structs. */ if (new_tx_count != adapter->tx_ring->count) { + memcpy(temp_ring, adapter->tx_ring, + adapter->num_tx_queues * sizeof(struct ixgbe_ring)); + for (i = 0; i < adapter->num_tx_queues; i++) { - /* Save existing descriptor ring */ - old_buf = adapter->tx_ring[i].tx_buffer_info; - old_desc = adapter->tx_ring[i].desc; - old_size = adapter->tx_ring[i].size; - old_dma = adapter->tx_ring[i].dma; - /* Try to allocate a new one */ - adapter->tx_ring[i].tx_buffer_info = NULL; - adapter->tx_ring[i].desc = NULL; - adapter->tx_ring[i].count = new_tx_count; - err = ixgbe_setup_tx_resources(adapter, - &adapter->tx_ring[i]); + temp_ring[i].count = new_tx_count; + err = ixgbe_setup_tx_resources(adapter, &temp_ring[i]); if (err) { - /* Restore the old one so at least - the adapter still works, even if - we failed the request */ - adapter->tx_ring[i].tx_buffer_info = old_buf; - adapter->tx_ring[i].desc = old_desc; - adapter->tx_ring[i].size = old_size; - adapter->tx_ring[i].dma = old_dma; + while (i) { + i--; + ixgbe_free_tx_resources(adapter, + &temp_ring[i]); + } goto err_setup; } - /* Free the old buffer manually */ - vfree(old_buf); - pci_free_consistent(adapter->pdev, old_size, - old_desc, old_dma); } + + for (i = 0; i < adapter->num_tx_queues; i++) + ixgbe_free_tx_resources(adapter, &adapter->tx_ring[i]); + + memcpy(adapter->tx_ring, temp_ring, + adapter->num_tx_queues * sizeof(struct ixgbe_ring)); + + adapter->tx_ring_count = new_tx_count; } if (new_rx_count != adapter->rx_ring->count) { - for (i = 0; i < adapter->num_rx_queues; i++) { + memcpy(temp_ring, adapter->rx_ring, + adapter->num_rx_queues * sizeof(struct ixgbe_ring)); - old_rx_buf = adapter->rx_ring[i].rx_buffer_info; - old_desc = adapter->rx_ring[i].desc; - old_size = adapter->rx_ring[i].size; - old_dma = adapter->rx_ring[i].dma; - - adapter->rx_ring[i].rx_buffer_info = NULL; - adapter->rx_ring[i].desc = NULL; - adapter->rx_ring[i].dma = 0; - adapter->rx_ring[i].count = new_rx_count; - err = ixgbe_setup_rx_resources(adapter, - &adapter->rx_ring[i]); + for (i = 0; i < adapter->num_rx_queues; i++) { + temp_ring[i].count = new_rx_count; + err = ixgbe_setup_rx_resources(adapter, &temp_ring[i]); if (err) { - adapter->rx_ring[i].rx_buffer_info = old_rx_buf; - adapter->rx_ring[i].desc = old_desc; - adapter->rx_ring[i].size = old_size; - adapter->rx_ring[i].dma = old_dma; + while (i) { + i--; + ixgbe_free_rx_resources(adapter, + &temp_ring[i]); + } goto err_setup; } - - vfree(old_rx_buf); - pci_free_consistent(adapter->pdev, old_size, old_desc, - old_dma); } + + for (i = 0; i < adapter->num_rx_queues; i++) + ixgbe_free_rx_resources(adapter, &adapter->rx_ring[i]); + + memcpy(adapter->rx_ring, temp_ring, + adapter->num_rx_queues * sizeof(struct ixgbe_ring)); + + adapter->rx_ring_count = new_rx_count; } + /* success! */ err = 0; err_setup: - if (netif_running(adapter->netdev)) + if (netif_running(netdev)) ixgbe_up(adapter); clear_bit(__IXGBE_RESETTING, &adapter->state); @@ -770,7 +769,7 @@ static int ixgbe_get_sset_count(struct net_device *netdev, int sset) } static void ixgbe_get_ethtool_stats(struct net_device *netdev, - struct ethtool_stats *stats, u64 *data) + struct ethtool_stats *stats, u64 *data) { struct ixgbe_adapter *adapter = netdev_priv(netdev); u64 *queue_stat; @@ -778,12 +777,20 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, int j, k; int i; u64 aggregated = 0, flushed = 0, no_desc = 0; + for (i = 0; i < adapter->num_rx_queues; i++) { + aggregated += adapter->rx_ring[i].lro_mgr.stats.aggregated; + flushed += adapter->rx_ring[i].lro_mgr.stats.flushed; + no_desc += adapter->rx_ring[i].lro_mgr.stats.no_desc; + } + adapter->lro_aggregated = aggregated; + adapter->lro_flushed = flushed; + adapter->lro_no_desc = no_desc; ixgbe_update_stats(adapter); for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { char *p = (char *)adapter + ixgbe_gstrings_stats[i].stat_offset; data[i] = (ixgbe_gstrings_stats[i].sizeof_stat == - sizeof(u64)) ? *(u64 *)p : *(u32 *)p; + sizeof(u64)) ? *(u64 *)p : *(u32 *)p; } for (j = 0; j < adapter->num_tx_queues; j++) { queue_stat = (u64 *)&adapter->tx_ring[j].stats; @@ -792,24 +799,18 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, i += k; } for (j = 0; j < adapter->num_rx_queues; j++) { - aggregated += adapter->rx_ring[j].lro_mgr.stats.aggregated; - flushed += adapter->rx_ring[j].lro_mgr.stats.flushed; - no_desc += adapter->rx_ring[j].lro_mgr.stats.no_desc; queue_stat = (u64 *)&adapter->rx_ring[j].stats; for (k = 0; k < stat_count; k++) data[i + k] = queue_stat[k]; i += k; } - adapter->lro_aggregated = aggregated; - adapter->lro_flushed = flushed; - adapter->lro_no_desc = no_desc; } static void ixgbe_get_strings(struct net_device *netdev, u32 stringset, - u8 *data) + u8 *data) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - u8 *p = data; + char *p = (char *)data; int i; switch (stringset) { @@ -831,14 +832,14 @@ static void ixgbe_get_strings(struct net_device *netdev, u32 stringset, sprintf(p, "rx_queue_%u_bytes", i); p += ETH_GSTRING_LEN; } -/* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */ + /* BUG_ON(p - data != IXGBE_STATS_LEN * ETH_GSTRING_LEN); */ break; } } static void ixgbe_get_wol(struct net_device *netdev, - struct ethtool_wolinfo *wol) + struct ethtool_wolinfo *wol) { wol->supported = 0; wol->wolopts = 0; @@ -859,16 +860,17 @@ static int ixgbe_nway_reset(struct net_device *netdev) static int ixgbe_phys_id(struct net_device *netdev, u32 data) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - u32 led_reg = IXGBE_READ_REG(&adapter->hw, IXGBE_LEDCTL); + struct ixgbe_hw *hw = &adapter->hw; + u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); u32 i; if (!data || data > 300) data = 300; for (i = 0; i < (data * 1000); i += 400) { - ixgbe_led_on(&adapter->hw, IXGBE_LED_ON); + hw->mac.ops.led_on(hw, IXGBE_LED_ON); msleep_interruptible(200); - ixgbe_led_off(&adapter->hw, IXGBE_LED_ON); + hw->mac.ops.led_off(hw, IXGBE_LED_ON); msleep_interruptible(200); } @@ -879,67 +881,75 @@ static int ixgbe_phys_id(struct net_device *netdev, u32 data) } static int ixgbe_get_coalesce(struct net_device *netdev, - struct ethtool_coalesce *ec) + struct ethtool_coalesce *ec) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS) - ec->rx_coalesce_usecs = adapter->rx_eitr; - else - ec->rx_coalesce_usecs = 1000000 / adapter->rx_eitr; - - if (adapter->tx_eitr < IXGBE_MIN_ITR_USECS) - ec->tx_coalesce_usecs = adapter->tx_eitr; - else - ec->tx_coalesce_usecs = 1000000 / adapter->tx_eitr; - ec->tx_max_coalesced_frames_irq = adapter->tx_ring[0].work_limit; + + /* only valid if in constant ITR mode */ + switch (adapter->itr_setting) { + case 0: + /* throttling disabled */ + ec->rx_coalesce_usecs = 0; + break; + case 1: + /* dynamic ITR mode */ + ec->rx_coalesce_usecs = 1; + break; + default: + /* fixed interrupt rate mode */ + ec->rx_coalesce_usecs = 1000000/adapter->eitr_param; + break; + } return 0; } static int ixgbe_set_coalesce(struct net_device *netdev, - struct ethtool_coalesce *ec) + struct ethtool_coalesce *ec) { struct ixgbe_adapter *adapter = netdev_priv(netdev); - - if ((ec->rx_coalesce_usecs > IXGBE_MAX_ITR_USECS) || - ((ec->rx_coalesce_usecs != 0) && - (ec->rx_coalesce_usecs != 1) && - (ec->rx_coalesce_usecs != 3) && - (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS))) - return -EINVAL; - if ((ec->tx_coalesce_usecs > IXGBE_MAX_ITR_USECS) || - ((ec->tx_coalesce_usecs != 0) && - (ec->tx_coalesce_usecs != 1) && - (ec->tx_coalesce_usecs != 3) && - (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS))) - return -EINVAL; - - /* convert to rate of irq's per second */ - if (ec->rx_coalesce_usecs < IXGBE_MIN_ITR_USECS) - adapter->rx_eitr = ec->rx_coalesce_usecs; - else - adapter->rx_eitr = (1000000 / ec->rx_coalesce_usecs); - - if (ec->tx_coalesce_usecs < IXGBE_MIN_ITR_USECS) - adapter->tx_eitr = ec->rx_coalesce_usecs; - else - adapter->tx_eitr = (1000000 / ec->tx_coalesce_usecs); + struct ixgbe_hw *hw = &adapter->hw; + int i; if (ec->tx_max_coalesced_frames_irq) - adapter->tx_ring[0].work_limit = - ec->tx_max_coalesced_frames_irq; + adapter->tx_ring[0].work_limit = ec->tx_max_coalesced_frames_irq; + + if (ec->rx_coalesce_usecs > 1) { + /* store the value in ints/second */ + adapter->eitr_param = 1000000/ec->rx_coalesce_usecs; + + /* static value of interrupt rate */ + adapter->itr_setting = adapter->eitr_param; + /* clear the lower bit */ + adapter->itr_setting &= ~1; + } else if (ec->rx_coalesce_usecs == 1) { + /* 1 means dynamic mode */ + adapter->eitr_param = 20000; + adapter->itr_setting = 1; + } else { + /* any other value means disable eitr, which is best + * served by setting the interrupt rate very high */ + adapter->eitr_param = 3000000; + adapter->itr_setting = 0; + } - if (netif_running(netdev)) { - ixgbe_down(adapter); - ixgbe_up(adapter); + for (i = 0; i < adapter->num_msix_vectors - NON_Q_VECTORS; i++) { + struct ixgbe_q_vector *q_vector = &adapter->q_vector[i]; + if (q_vector->txr_count && !q_vector->rxr_count) + q_vector->eitr = (adapter->eitr_param >> 1); + else + /* rx only or mixed */ + q_vector->eitr = adapter->eitr_param; + IXGBE_WRITE_REG(hw, IXGBE_EITR(i), + EITR_INTS_PER_SEC_TO_REG(q_vector->eitr)); } return 0; } -static struct ethtool_ops ixgbe_ethtool_ops = { +static const struct ethtool_ops ixgbe_ethtool_ops = { .get_settings = ixgbe_get_settings, .set_settings = ixgbe_set_settings, .get_drvinfo = ixgbe_get_drvinfo, @@ -966,7 +976,7 @@ static struct ethtool_ops ixgbe_ethtool_ops = { .set_tso = ixgbe_set_tso, .get_strings = ixgbe_get_strings, .phys_id = ixgbe_phys_id, - .get_sset_count = ixgbe_get_sset_count, + .get_sset_count = ixgbe_get_sset_count, .get_ethtool_stats = ixgbe_get_ethtool_stats, .get_coalesce = ixgbe_get_coalesce, .set_coalesce = ixgbe_set_coalesce, diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index 362541aa946..ca17af4349d 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2007 Intel Corporation. + Copyright(c) 1999 - 2008 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -20,7 +20,6 @@ the file called "COPYING". Contact Information: - Linux NICS <linux.nics@intel.com> e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 @@ -46,15 +45,14 @@ char ixgbe_driver_name[] = "ixgbe"; static const char ixgbe_driver_string[] = - "Intel(R) 10 Gigabit PCI Express Network Driver"; + "Intel(R) 10 Gigabit PCI Express Network Driver"; -#define DRV_VERSION "1.3.18-k4" +#define DRV_VERSION "1.3.30-k2" const char ixgbe_driver_version[] = DRV_VERSION; -static const char ixgbe_copyright[] = - "Copyright (c) 1999-2007 Intel Corporation."; +static char ixgbe_copyright[] = "Copyright (c) 1999-2007 Intel Corporation."; static const struct ixgbe_info *ixgbe_info_tbl[] = { - [board_82598] = &ixgbe_82598_info, + [board_82598] = &ixgbe_82598_info, }; /* ixgbe_pci_tbl - PCI Device ID Table @@ -74,15 +72,17 @@ static struct pci_device_id ixgbe_pci_tbl[] = { board_82598 }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT), board_82598 }, + {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_XF_LR), + board_82598 }, /* required last entry */ {0, } }; MODULE_DEVICE_TABLE(pci, ixgbe_pci_tbl); -#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE) +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) static int ixgbe_notify_dca(struct notifier_block *, unsigned long event, - void *p); + void *p); static struct notifier_block dca_notifier = { .notifier_call = ixgbe_notify_dca, .next = NULL, @@ -104,7 +104,7 @@ static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter) /* Let firmware take over control of h/w */ ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, - ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD); + ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD); } static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter) @@ -114,24 +114,11 @@ static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter) /* Let firmware know the driver has taken over */ ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT); IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT, - ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD); + ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD); } -#ifdef DEBUG -/** - * ixgbe_get_hw_dev_name - return device name string - * used by hardware layer to print debugging information - **/ -char *ixgbe_get_hw_dev_name(struct ixgbe_hw *hw) -{ - struct ixgbe_adapter *adapter = hw->back; - struct net_device *netdev = adapter->netdev; - return netdev->name; -} -#endif - static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, u16 int_alloc_entry, - u8 msix_vector) + u8 msix_vector) { u32 ivar, index; @@ -144,12 +131,12 @@ static void ixgbe_set_ivar(struct ixgbe_adapter *adapter, u16 int_alloc_entry, } static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, - struct ixgbe_tx_buffer - *tx_buffer_info) + struct ixgbe_tx_buffer + *tx_buffer_info) { if (tx_buffer_info->dma) { pci_unmap_page(adapter->pdev, tx_buffer_info->dma, - tx_buffer_info->length, PCI_DMA_TODEVICE); + tx_buffer_info->length, PCI_DMA_TODEVICE); tx_buffer_info->dma = 0; } if (tx_buffer_info->skb) { @@ -160,8 +147,8 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, } static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - unsigned int eop) + struct ixgbe_ring *tx_ring, + unsigned int eop) { struct ixgbe_hw *hw = &adapter->hw; u32 head, tail; @@ -196,14 +183,14 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter, return false; } -#define IXGBE_MAX_TXD_PWR 14 -#define IXGBE_MAX_DATA_PER_TXD (1 << IXGBE_MAX_TXD_PWR) +#define IXGBE_MAX_TXD_PWR 14 +#define IXGBE_MAX_DATA_PER_TXD (1 << IXGBE_MAX_TXD_PWR) /* Tx Descriptors needed, worst case */ #define TXD_USE_COUNT(S) (((S) >> IXGBE_MAX_TXD_PWR) + \ (((S) & (IXGBE_MAX_DATA_PER_TXD - 1)) ? 1 : 0)) #define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \ - MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */ + MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1) /* for context */ #define GET_TX_HEAD_FROM_RING(ring) (\ *(volatile u32 *) \ @@ -309,9 +296,9 @@ done_cleaning: return (total_packets ? true : false); } -#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE) +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring) { u32 rxctrl; int cpu = get_cpu(); @@ -330,7 +317,7 @@ static void ixgbe_update_rx_dca(struct ixgbe_adapter *adapter, } static void ixgbe_update_tx_dca(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { u32 txctrl; int cpu = get_cpu(); @@ -406,8 +393,8 @@ static int __ixgbe_notify_dca(struct device *dev, void *data) * @rx_desc: rx descriptor **/ static void ixgbe_receive_skb(struct ixgbe_adapter *adapter, - struct sk_buff *skb, u8 status, - struct ixgbe_ring *ring, + struct sk_buff *skb, u8 status, + struct ixgbe_ring *ring, union ixgbe_adv_rx_desc *rx_desc) { bool is_vlan = (status & IXGBE_RXD_STAT_VP); @@ -480,7 +467,6 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, struct ixgbe_ring *rx_ring, int cleaned_count) { - struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; union ixgbe_adv_rx_desc *rx_desc; struct ixgbe_rx_buffer *bi; @@ -493,20 +479,29 @@ static void ixgbe_alloc_rx_buffers(struct ixgbe_adapter *adapter, while (cleaned_count--) { rx_desc = IXGBE_RX_DESC_ADV(*rx_ring, i); - if (!bi->page && + if (!bi->page_dma && (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED)) { - bi->page = alloc_page(GFP_ATOMIC); if (!bi->page) { - adapter->alloc_rx_page_failed++; - goto no_buffers; + bi->page = alloc_page(GFP_ATOMIC); + if (!bi->page) { + adapter->alloc_rx_page_failed++; + goto no_buffers; + } + bi->page_offset = 0; + } else { + /* use a half page if we're re-using */ + bi->page_offset ^= (PAGE_SIZE / 2); } - bi->page_dma = pci_map_page(pdev, bi->page, 0, - PAGE_SIZE, - PCI_DMA_FROMDEVICE); + + bi->page_dma = pci_map_page(pdev, bi->page, + bi->page_offset, + (PAGE_SIZE / 2), + PCI_DMA_FROMDEVICE); } if (!bi->skb) { - struct sk_buff *skb = netdev_alloc_skb(netdev, bufsz); + struct sk_buff *skb = netdev_alloc_skb(adapter->netdev, + bufsz); if (!skb) { adapter->alloc_rx_buff_failed++; @@ -567,10 +562,9 @@ static inline u16 ixgbe_get_pkt_info(union ixgbe_adv_rx_desc *rx_desc) } static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring, - int *work_done, int work_to_do) + struct ixgbe_ring *rx_ring, + int *work_done, int work_to_do) { - struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; union ixgbe_adv_rx_desc *rx_desc, *next_rxd; struct ixgbe_rx_buffer *rx_buffer_info, *next_buffer; @@ -596,7 +590,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter, if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { hdr_info = le16_to_cpu(ixgbe_get_hdr_info(rx_desc)); len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >> - IXGBE_RXDADV_HDRBUFLEN_SHIFT; + IXGBE_RXDADV_HDRBUFLEN_SHIFT; if (hdr_info & IXGBE_RXDADV_SPH) adapter->rx_hdr_split++; if (len > IXGBE_RX_HDR_SIZE) @@ -613,18 +607,25 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter, if (len && !skb_shinfo(skb)->nr_frags) { pci_unmap_single(pdev, rx_buffer_info->dma, - rx_ring->rx_buf_len + NET_IP_ALIGN, - PCI_DMA_FROMDEVICE); + rx_ring->rx_buf_len + NET_IP_ALIGN, + PCI_DMA_FROMDEVICE); skb_put(skb, len); } if (upper_len) { pci_unmap_page(pdev, rx_buffer_info->page_dma, - PAGE_SIZE, PCI_DMA_FROMDEVICE); + PAGE_SIZE / 2, PCI_DMA_FROMDEVICE); rx_buffer_info->page_dma = 0; skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, - rx_buffer_info->page, 0, upper_len); - rx_buffer_info->page = NULL; + rx_buffer_info->page, + rx_buffer_info->page_offset, + upper_len); + + if ((rx_ring->rx_buf_len > (PAGE_SIZE / 2)) || + (page_count(rx_buffer_info->page) != 1)) + rx_buffer_info->page = NULL; + else + get_page(rx_buffer_info->page); skb->len += upper_len; skb->data_len += upper_len; @@ -647,6 +648,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter, rx_buffer_info->skb = next_buffer->skb; rx_buffer_info->dma = next_buffer->dma; next_buffer->skb = skb; + next_buffer->dma = 0; adapter->non_eop_descs++; goto next_desc; } @@ -662,9 +664,9 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter, total_rx_bytes += skb->len; total_rx_packets++; - skb->protocol = eth_type_trans(skb, netdev); + skb->protocol = eth_type_trans(skb, adapter->netdev); ixgbe_receive_skb(adapter, skb, staterr, rx_ring, rx_desc); - netdev->last_rx = jiffies; + adapter->netdev->last_rx = jiffies; next_desc: rx_desc->wb.upper.status_error = 0; @@ -724,43 +726,43 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter) q_vector = &adapter->q_vector[v_idx]; /* XXX for_each_bit(...) */ r_idx = find_first_bit(q_vector->rxr_idx, - adapter->num_rx_queues); + adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { j = adapter->rx_ring[r_idx].reg_idx; ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(j), v_idx); r_idx = find_next_bit(q_vector->rxr_idx, - adapter->num_rx_queues, - r_idx + 1); + adapter->num_rx_queues, + r_idx + 1); } r_idx = find_first_bit(q_vector->txr_idx, - adapter->num_tx_queues); + adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { j = adapter->tx_ring[r_idx].reg_idx; ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(j), v_idx); r_idx = find_next_bit(q_vector->txr_idx, - adapter->num_tx_queues, - r_idx + 1); + adapter->num_tx_queues, + r_idx + 1); } - /* if this is a tx only vector use half the irq (tx) rate */ + /* if this is a tx only vector halve the interrupt rate */ if (q_vector->txr_count && !q_vector->rxr_count) - q_vector->eitr = adapter->tx_eitr; + q_vector->eitr = (adapter->eitr_param >> 1); else - /* rx only or mixed */ - q_vector->eitr = adapter->rx_eitr; + /* rx only */ + q_vector->eitr = adapter->eitr_param; IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), - EITR_INTS_PER_SEC_TO_REG(q_vector->eitr)); + EITR_INTS_PER_SEC_TO_REG(q_vector->eitr)); } ixgbe_set_ivar(adapter, IXGBE_IVAR_OTHER_CAUSES_INDEX, v_idx); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EITR(v_idx), 1950); - /* set up to autoclear timer, lsc, and the vectors */ + /* set up to autoclear timer, and the vectors */ mask = IXGBE_EIMS_ENABLE_MASK; - mask &= ~IXGBE_EIMS_OTHER; + mask &= ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC); IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC, mask); } @@ -790,8 +792,8 @@ enum latency_range { * parameter (see ixgbe_param.c) **/ static u8 ixgbe_update_itr(struct ixgbe_adapter *adapter, - u32 eitr, u8 itr_setting, - int packets, int bytes) + u32 eitr, u8 itr_setting, + int packets, int bytes) { unsigned int retval = itr_setting; u32 timepassed_us; @@ -838,40 +840,40 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) u32 new_itr; u8 current_itr, ret_itr; int i, r_idx, v_idx = ((void *)q_vector - (void *)(adapter->q_vector)) / - sizeof(struct ixgbe_q_vector); + sizeof(struct ixgbe_q_vector); struct ixgbe_ring *rx_ring, *tx_ring; r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { tx_ring = &(adapter->tx_ring[r_idx]); ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, - q_vector->tx_eitr, - tx_ring->total_packets, - tx_ring->total_bytes); + q_vector->tx_itr, + tx_ring->total_packets, + tx_ring->total_bytes); /* if the result for this queue would decrease interrupt * rate for this vector then use that result */ - q_vector->tx_eitr = ((q_vector->tx_eitr > ret_itr) ? - q_vector->tx_eitr - 1 : ret_itr); + q_vector->tx_itr = ((q_vector->tx_itr > ret_itr) ? + q_vector->tx_itr - 1 : ret_itr); r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); + r_idx + 1); } r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); for (i = 0; i < q_vector->rxr_count; i++) { rx_ring = &(adapter->rx_ring[r_idx]); ret_itr = ixgbe_update_itr(adapter, q_vector->eitr, - q_vector->rx_eitr, - rx_ring->total_packets, - rx_ring->total_bytes); + q_vector->rx_itr, + rx_ring->total_packets, + rx_ring->total_bytes); /* if the result for this queue would decrease interrupt * rate for this vector then use that result */ - q_vector->rx_eitr = ((q_vector->rx_eitr > ret_itr) ? - q_vector->rx_eitr - 1 : ret_itr); + q_vector->rx_itr = ((q_vector->rx_itr > ret_itr) ? + q_vector->rx_itr - 1 : ret_itr); r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, - r_idx + 1); + r_idx + 1); } - current_itr = max(q_vector->rx_eitr, q_vector->tx_eitr); + current_itr = max(q_vector->rx_itr, q_vector->tx_itr); switch (current_itr) { /* counts and packets in update_itr are dependent on these numbers */ @@ -895,13 +897,27 @@ static void ixgbe_set_itr_msix(struct ixgbe_q_vector *q_vector) itr_reg = EITR_INTS_PER_SEC_TO_REG(new_itr); /* must write high and low 16 bits to reset counter */ DPRINTK(TX_ERR, DEBUG, "writing eitr(%d): %08X\n", v_idx, - itr_reg); + itr_reg); IXGBE_WRITE_REG(hw, IXGBE_EITR(v_idx), itr_reg | (itr_reg)<<16); } return; } + +static void ixgbe_check_lsc(struct ixgbe_adapter *adapter) +{ + struct ixgbe_hw *hw = &adapter->hw; + + adapter->lsc_int++; + adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; + adapter->link_check_timeout = jiffies; + if (!test_bit(__IXGBE_DOWN, &adapter->state)) { + IXGBE_WRITE_REG(hw, IXGBE_EIMC, IXGBE_EIMC_LSC); + schedule_work(&adapter->watchdog_task); + } +} + static irqreturn_t ixgbe_msix_lsc(int irq, void *data) { struct net_device *netdev = data; @@ -909,11 +925,8 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data) struct ixgbe_hw *hw = &adapter->hw; u32 eicr = IXGBE_READ_REG(hw, IXGBE_EICR); - if (eicr & IXGBE_EICR_LSC) { - adapter->lsc_int++; - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - mod_timer(&adapter->watchdog_timer, jiffies); - } + if (eicr & IXGBE_EICR_LSC) + ixgbe_check_lsc(adapter); if (!test_bit(__IXGBE_DOWN, &adapter->state)) IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER); @@ -934,7 +947,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data) r_idx = find_first_bit(q_vector->txr_idx, adapter->num_tx_queues); for (i = 0; i < q_vector->txr_count; i++) { tx_ring = &(adapter->tx_ring[r_idx]); -#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE) +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) ixgbe_update_tx_dca(adapter, tx_ring); #endif @@ -942,7 +955,7 @@ static irqreturn_t ixgbe_msix_clean_tx(int irq, void *data) tx_ring->total_packets = 0; ixgbe_clean_tx_irq(adapter, tx_ring); r_idx = find_next_bit(q_vector->txr_idx, adapter->num_tx_queues, - r_idx + 1); + r_idx + 1); } return IRQ_HANDLED; @@ -959,16 +972,24 @@ static irqreturn_t ixgbe_msix_clean_rx(int irq, void *data) struct ixgbe_adapter *adapter = q_vector->adapter; struct ixgbe_ring *rx_ring; int r_idx; + int i; r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rxr_count; i++) { + rx_ring = &(adapter->rx_ring[r_idx]); + rx_ring->total_bytes = 0; + rx_ring->total_packets = 0; + r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx + 1); + } + if (!q_vector->rxr_count) return IRQ_HANDLED; + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); rx_ring = &(adapter->rx_ring[r_idx]); /* disable interrupts on this vector only */ IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, rx_ring->v_idx); - rx_ring->total_bytes = 0; - rx_ring->total_packets = 0; netif_rx_schedule(adapter->netdev, &q_vector->napi); return IRQ_HANDLED; @@ -987,19 +1008,21 @@ static irqreturn_t ixgbe_msix_clean_many(int irq, void *data) * @napi: napi struct with our devices info in it * @budget: amount of work driver is allowed to do this pass, in packets * + * This function is optimized for cleaning one queue only on a single + * q_vector!!! **/ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) { struct ixgbe_q_vector *q_vector = - container_of(napi, struct ixgbe_q_vector, napi); + container_of(napi, struct ixgbe_q_vector, napi); struct ixgbe_adapter *adapter = q_vector->adapter; - struct ixgbe_ring *rx_ring; + struct ixgbe_ring *rx_ring = NULL; int work_done = 0; long r_idx; r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); rx_ring = &(adapter->rx_ring[r_idx]); -#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE) +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) ixgbe_update_rx_dca(adapter, rx_ring); #endif @@ -1009,7 +1032,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) /* If all Rx work done, exit the polling mode */ if (work_done < budget) { netif_rx_complete(adapter->netdev, napi); - if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS) + if (adapter->itr_setting & 3) ixgbe_set_itr_msix(q_vector); if (!test_bit(__IXGBE_DOWN, &adapter->state)) IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, rx_ring->v_idx); @@ -1018,8 +1041,57 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget) return work_done; } +/** + * ixgbe_clean_rxonly_many - msix (aka one shot) rx clean routine + * @napi: napi struct with our devices info in it + * @budget: amount of work driver is allowed to do this pass, in packets + * + * This function will clean more than one rx queue associated with a + * q_vector. + **/ +static int ixgbe_clean_rxonly_many(struct napi_struct *napi, int budget) +{ + struct ixgbe_q_vector *q_vector = + container_of(napi, struct ixgbe_q_vector, napi); + struct ixgbe_adapter *adapter = q_vector->adapter; + struct ixgbe_ring *rx_ring = NULL; + int work_done = 0, i; + long r_idx; + u16 enable_mask = 0; + + /* attempt to distribute budget to each queue fairly, but don't allow + * the budget to go below 1 because we'll exit polling */ + budget /= (q_vector->rxr_count ?: 1); + budget = max(budget, 1); + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + for (i = 0; i < q_vector->rxr_count; i++) { + rx_ring = &(adapter->rx_ring[r_idx]); +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) + if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) + ixgbe_update_rx_dca(adapter, rx_ring); +#endif + ixgbe_clean_rx_irq(adapter, rx_ring, &work_done, budget); + enable_mask |= rx_ring->v_idx; + r_idx = find_next_bit(q_vector->rxr_idx, adapter->num_rx_queues, + r_idx + 1); + } + + r_idx = find_first_bit(q_vector->rxr_idx, adapter->num_rx_queues); + rx_ring = &(adapter->rx_ring[r_idx]); + /* If all Rx work done, exit the polling mode */ + if (work_done < budget) { + netif_rx_complete(adapter->netdev, napi); + if (adapter->itr_setting & 3) + ixgbe_set_itr_msix(q_vector); + if (!test_bit(__IXGBE_DOWN, &adapter->state)) + IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, enable_mask); + return 0; + } + + return work_done; +} static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, - int r_idx) + int r_idx) { a->q_vector[v_idx].adapter = a; set_bit(r_idx, a->q_vector[v_idx].rxr_idx); @@ -1028,7 +1100,7 @@ static inline void map_vector_to_rxq(struct ixgbe_adapter *a, int v_idx, } static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, - int r_idx) + int r_idx) { a->q_vector[v_idx].adapter = a; set_bit(r_idx, a->q_vector[v_idx].txr_idx); @@ -1048,7 +1120,7 @@ static inline void map_vector_to_txq(struct ixgbe_adapter *a, int v_idx, * mapping configurations in here. **/ static int ixgbe_map_rings_to_vectors(struct ixgbe_adapter *adapter, - int vectors) + int vectors) { int v_start = 0; int rxr_idx = 0, txr_idx = 0; @@ -1125,28 +1197,28 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) goto out; #define SET_HANDLER(_v) ((!(_v)->rxr_count) ? &ixgbe_msix_clean_tx : \ - (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \ - &ixgbe_msix_clean_many) + (!(_v)->txr_count) ? &ixgbe_msix_clean_rx : \ + &ixgbe_msix_clean_many) for (vector = 0; vector < q_vectors; vector++) { handler = SET_HANDLER(&adapter->q_vector[vector]); sprintf(adapter->name[vector], "%s:v%d-%s", - netdev->name, vector, - (handler == &ixgbe_msix_clean_rx) ? "Rx" : - ((handler == &ixgbe_msix_clean_tx) ? "Tx" : "TxRx")); + netdev->name, vector, + (handler == &ixgbe_msix_clean_rx) ? "Rx" : + ((handler == &ixgbe_msix_clean_tx) ? "Tx" : "TxRx")); err = request_irq(adapter->msix_entries[vector].vector, - handler, 0, adapter->name[vector], - &(adapter->q_vector[vector])); + handler, 0, adapter->name[vector], + &(adapter->q_vector[vector])); if (err) { DPRINTK(PROBE, ERR, - "request_irq failed for MSIX interrupt " - "Error: %d\n", err); + "request_irq failed for MSIX interrupt " + "Error: %d\n", err); goto free_queue_irqs; } } sprintf(adapter->name[vector], "%s:lsc", netdev->name); err = request_irq(adapter->msix_entries[vector].vector, - &ixgbe_msix_lsc, 0, adapter->name[vector], netdev); + &ixgbe_msix_lsc, 0, adapter->name[vector], netdev); if (err) { DPRINTK(PROBE, ERR, "request_irq for msix_lsc failed: %d\n", err); @@ -1158,7 +1230,7 @@ static int ixgbe_request_msix_irqs(struct ixgbe_adapter *adapter) free_queue_irqs: for (i = vector - 1; i >= 0; i--) free_irq(adapter->msix_entries[--vector].vector, - &(adapter->q_vector[i])); + &(adapter->q_vector[i])); adapter->flags &= ~IXGBE_FLAG_MSIX_ENABLED; pci_disable_msix(adapter->pdev); kfree(adapter->msix_entries); @@ -1176,16 +1248,16 @@ static void ixgbe_set_itr(struct ixgbe_adapter *adapter) struct ixgbe_ring *rx_ring = &adapter->rx_ring[0]; struct ixgbe_ring *tx_ring = &adapter->tx_ring[0]; - q_vector->tx_eitr = ixgbe_update_itr(adapter, new_itr, - q_vector->tx_eitr, - tx_ring->total_packets, - tx_ring->total_bytes); - q_vector->rx_eitr = ixgbe_update_itr(adapter, new_itr, - q_vector->rx_eitr, - rx_ring->total_packets, - rx_ring->total_bytes); + q_vector->tx_itr = ixgbe_update_itr(adapter, new_itr, + q_vector->tx_itr, + tx_ring->total_packets, + tx_ring->total_bytes); + q_vector->rx_itr = ixgbe_update_itr(adapter, new_itr, + q_vector->rx_itr, + rx_ring->total_packets, + rx_ring->total_bytes); - current_itr = max(q_vector->rx_eitr, q_vector->tx_eitr); + current_itr = max(q_vector->rx_itr, q_vector->tx_itr); switch (current_itr) { /* counts and packets in update_itr are dependent on these numbers */ @@ -1230,19 +1302,19 @@ static irqreturn_t ixgbe_intr(int irq, void *data) struct ixgbe_hw *hw = &adapter->hw; u32 eicr; - /* for NAPI, using EIAM to auto-mask tx/rx interrupt bits on read * therefore no explict interrupt disable is necessary */ eicr = IXGBE_READ_REG(hw, IXGBE_EICR); - if (!eicr) + if (!eicr) { + /* shared interrupt alert! + * make sure interrupts are enabled because the read will + * have disabled interrupts due to EIAM */ + ixgbe_irq_enable(adapter); return IRQ_NONE; /* Not our interrupt */ - - if (eicr & IXGBE_EICR_LSC) { - adapter->lsc_int++; - if (!test_bit(__IXGBE_DOWN, &adapter->state)) - mod_timer(&adapter->watchdog_timer, jiffies); } + if (eicr & IXGBE_EICR_LSC) + ixgbe_check_lsc(adapter); if (netif_rx_schedule_prep(netdev, &adapter->q_vector[0].napi)) { adapter->tx_ring[0].total_packets = 0; @@ -1285,10 +1357,10 @@ static int ixgbe_request_irq(struct ixgbe_adapter *adapter) err = ixgbe_request_msix_irqs(adapter); } else if (adapter->flags & IXGBE_FLAG_MSI_ENABLED) { err = request_irq(adapter->pdev->irq, &ixgbe_intr, 0, - netdev->name, netdev); + netdev->name, netdev); } else { err = request_irq(adapter->pdev->irq, &ixgbe_intr, IRQF_SHARED, - netdev->name, netdev); + netdev->name, netdev); } if (err) @@ -1312,7 +1384,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter) i--; for (; i >= 0; i--) { free_irq(adapter->msix_entries[i].vector, - &(adapter->q_vector[i])); + &(adapter->q_vector[i])); } ixgbe_reset_q_vectors(adapter); @@ -1359,7 +1431,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter) struct ixgbe_hw *hw = &adapter->hw; IXGBE_WRITE_REG(hw, IXGBE_EITR(0), - EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr)); + EITR_INTS_PER_SEC_TO_REG(adapter->eitr_param)); ixgbe_set_ivar(adapter, IXGBE_IVAR_RX_QUEUE(0), 0); ixgbe_set_ivar(adapter, IXGBE_IVAR_TX_QUEUE(0), 0); @@ -1445,8 +1517,8 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index) srrctl |= IXGBE_RXBUFFER_2048 >> IXGBE_SRRCTL_BSIZEPKT_SHIFT; srrctl |= IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS; srrctl |= ((IXGBE_RX_HDR_SIZE << - IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) & - IXGBE_SRRCTL_BSIZEHDR_MASK); + IXGBE_SRRCTL_BSIZEHDRSIZE_SHIFT) & + IXGBE_SRRCTL_BSIZEHDR_MASK); } else { srrctl |= IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF; @@ -1463,7 +1535,7 @@ static void ixgbe_configure_srrctl(struct ixgbe_adapter *adapter, int index) /** * ixgbe_get_skb_hdr - helper function for LRO header processing * @skb: pointer to sk_buff to be added to LRO packet - * @iphdr: pointer to tcp header structure + * @iphdr: pointer to ip header structure * @tcph: pointer to tcp header structure * @hdr_flags: pointer to header flags * @priv: private data @@ -1488,7 +1560,7 @@ static int ixgbe_get_skb_hdr(struct sk_buff *skb, void **iphdr, void **tcph, } #define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \ - (((S) & (PAGE_SIZE - 1)) ? 1 : 0)) + (((S) & (PAGE_SIZE - 1)) ? 1 : 0)) /** * ixgbe_configure_rx - Configure 8259x Receive Unit after Reset @@ -1514,10 +1586,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) int rx_buf_len; /* Decide whether to use packet split mode or not */ - if (netdev->mtu > ETH_DATA_LEN) - adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED; - else - adapter->flags &= ~IXGBE_FLAG_RX_PS_ENABLED; + adapter->flags |= IXGBE_FLAG_RX_PS_ENABLED; /* Set the RX buffer length according to the mode */ if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) { @@ -1638,7 +1707,7 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter) } static void ixgbe_vlan_rx_register(struct net_device *netdev, - struct vlan_group *grp) + struct vlan_group *grp) { struct ixgbe_adapter *adapter = netdev_priv(netdev); u32 ctrl; @@ -1662,14 +1731,16 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev, static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; /* add VID to filter table */ - ixgbe_set_vfta(&adapter->hw, vid, 0, true); + hw->mac.ops.set_vfta(&adapter->hw, vid, 0, true); } static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_disable(adapter); @@ -1680,7 +1751,7 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid) ixgbe_irq_enable(adapter); /* remove VID from filter table */ - ixgbe_set_vfta(&adapter->hw, vid, 0, false); + hw->mac.ops.set_vfta(&adapter->hw, vid, 0, false); } static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) @@ -1756,15 +1827,15 @@ static void ixgbe_set_rx_mode(struct net_device *netdev) addr_count = netdev->uc_count; if (addr_count) addr_list = netdev->uc_list->dmi_addr; - ixgbe_update_uc_addr_list(hw, addr_list, addr_count, - ixgbe_addr_list_itr); + hw->mac.ops.update_uc_addr_list(hw, addr_list, addr_count, + ixgbe_addr_list_itr); /* reprogram multicast list */ addr_count = netdev->mc_count; if (addr_count) addr_list = netdev->mc_list->dmi_addr; - ixgbe_update_mc_addr_list(hw, addr_list, addr_count, - ixgbe_addr_list_itr); + hw->mac.ops.update_mc_addr_list(hw, addr_list, addr_count, + ixgbe_addr_list_itr); } static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) @@ -1778,10 +1849,16 @@ static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) q_vectors = 1; for (q_idx = 0; q_idx < q_vectors; q_idx++) { + struct napi_struct *napi; q_vector = &adapter->q_vector[q_idx]; if (!q_vector->rxr_count) continue; - napi_enable(&q_vector->napi); + napi = &q_vector->napi; + if ((adapter->flags & IXGBE_FLAG_MSIX_ENABLED) && + (q_vector->rxr_count > 1)) + napi->poll = &ixgbe_clean_rxonly_many; + + napi_enable(napi); } } @@ -1816,7 +1893,7 @@ static void ixgbe_configure(struct ixgbe_adapter *adapter) ixgbe_configure_rx(adapter); for (i = 0; i < adapter->num_rx_queues; i++) ixgbe_alloc_rx_buffers(adapter, &adapter->rx_ring[i], - (adapter->rx_ring[i].count - 1)); + (adapter->rx_ring[i].count - 1)); } static int ixgbe_up_complete(struct ixgbe_adapter *adapter) @@ -1834,7 +1911,7 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) (adapter->flags & IXGBE_FLAG_MSI_ENABLED)) { if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { gpie = (IXGBE_GPIE_MSIX_MODE | IXGBE_GPIE_EIAME | - IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD); + IXGBE_GPIE_PBA_SUPPORT | IXGBE_GPIE_OCD); } else { /* MSI only */ gpie = 0; @@ -1897,6 +1974,8 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter) /* bring the link up in the watchdog, this could race with our first * link up interrupt but shouldn't be a problem */ + adapter->flags |= IXGBE_FLAG_NEED_LINK_UPDATE; + adapter->link_check_timeout = jiffies; mod_timer(&adapter->watchdog_timer, jiffies); return 0; } @@ -1921,58 +2000,22 @@ int ixgbe_up(struct ixgbe_adapter *adapter) void ixgbe_reset(struct ixgbe_adapter *adapter) { - if (ixgbe_init_hw(&adapter->hw)) - DPRINTK(PROBE, ERR, "Hardware Error\n"); + struct ixgbe_hw *hw = &adapter->hw; + if (hw->mac.ops.init_hw(hw)) + dev_err(&adapter->pdev->dev, "Hardware Error\n"); /* reprogram the RAR[0] in case user changed it. */ - ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV); + hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); } -#ifdef CONFIG_PM -static int ixgbe_resume(struct pci_dev *pdev) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgbe_adapter *adapter = netdev_priv(netdev); - u32 err; - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - err = pci_enable_device(pdev); - if (err) { - printk(KERN_ERR "ixgbe: Cannot enable PCI device from " \ - "suspend\n"); - return err; - } - pci_set_master(pdev); - - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); - - if (netif_running(netdev)) { - err = ixgbe_request_irq(adapter); - if (err) - return err; - } - - ixgbe_reset(adapter); - - if (netif_running(netdev)) - ixgbe_up(adapter); - - netif_device_attach(netdev); - - return 0; -} -#endif - /** * ixgbe_clean_rx_ring - Free Rx Buffers per Queue * @adapter: board private structure * @rx_ring: ring to free buffers from **/ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring) { struct pci_dev *pdev = adapter->pdev; unsigned long size; @@ -1986,8 +2029,8 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, rx_buffer_info = &rx_ring->rx_buffer_info[i]; if (rx_buffer_info->dma) { pci_unmap_single(pdev, rx_buffer_info->dma, - rx_ring->rx_buf_len, - PCI_DMA_FROMDEVICE); + rx_ring->rx_buf_len, + PCI_DMA_FROMDEVICE); rx_buffer_info->dma = 0; } if (rx_buffer_info->skb) { @@ -1996,12 +2039,12 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, } if (!rx_buffer_info->page) continue; - pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE, - PCI_DMA_FROMDEVICE); + pci_unmap_page(pdev, rx_buffer_info->page_dma, PAGE_SIZE / 2, + PCI_DMA_FROMDEVICE); rx_buffer_info->page_dma = 0; - put_page(rx_buffer_info->page); rx_buffer_info->page = NULL; + rx_buffer_info->page_offset = 0; } size = sizeof(struct ixgbe_rx_buffer) * rx_ring->count; @@ -2023,7 +2066,7 @@ static void ixgbe_clean_rx_ring(struct ixgbe_adapter *adapter, * @tx_ring: ring to be cleaned **/ static void ixgbe_clean_tx_ring(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) + struct ixgbe_ring *tx_ring) { struct ixgbe_tx_buffer *tx_buffer_info; unsigned long size; @@ -2076,33 +2119,43 @@ static void ixgbe_clean_all_tx_rings(struct ixgbe_adapter *adapter) void ixgbe_down(struct ixgbe_adapter *adapter) { struct net_device *netdev = adapter->netdev; + struct ixgbe_hw *hw = &adapter->hw; u32 rxctrl; + u32 txdctl; + int i, j; /* signal that we are down to the interrupt handler */ set_bit(__IXGBE_DOWN, &adapter->state); /* disable receives */ - rxctrl = IXGBE_READ_REG(&adapter->hw, IXGBE_RXCTRL); - IXGBE_WRITE_REG(&adapter->hw, IXGBE_RXCTRL, - rxctrl & ~IXGBE_RXCTRL_RXEN); + rxctrl = IXGBE_READ_REG(hw, IXGBE_RXCTRL); + IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, rxctrl & ~IXGBE_RXCTRL_RXEN); netif_tx_disable(netdev); - /* disable transmits in the hardware */ - - /* flush both disables */ - IXGBE_WRITE_FLUSH(&adapter->hw); + IXGBE_WRITE_FLUSH(hw); msleep(10); + netif_tx_stop_all_queues(netdev); + ixgbe_irq_disable(adapter); ixgbe_napi_disable_all(adapter); + del_timer_sync(&adapter->watchdog_timer); + cancel_work_sync(&adapter->watchdog_task); + + /* disable transmits in the hardware now that interrupts are off */ + for (i = 0; i < adapter->num_tx_queues; i++) { + j = adapter->tx_ring[i].reg_idx; + txdctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(j)); + IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(j), + (txdctl & ~IXGBE_TXDCTL_ENABLE)); + } netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); -#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE) +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED; dca_remove_requester(&adapter->pdev->dev); @@ -2114,56 +2167,18 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ixgbe_clean_all_tx_rings(adapter); ixgbe_clean_all_rx_rings(adapter); -#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE) +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) /* since we reset the hardware DCA settings were cleared */ if (dca_add_requester(&adapter->pdev->dev) == 0) { adapter->flags |= IXGBE_FLAG_DCA_ENABLED; /* always use CB2 mode, difference is masked * in the CB driver */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2); + IXGBE_WRITE_REG(hw, IXGBE_DCA_CTRL, 2); ixgbe_setup_dca(adapter); } #endif } -static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *netdev = pci_get_drvdata(pdev); - struct ixgbe_adapter *adapter = netdev_priv(netdev); -#ifdef CONFIG_PM - int retval = 0; -#endif - - netif_device_detach(netdev); - - if (netif_running(netdev)) { - ixgbe_down(adapter); - ixgbe_free_irq(adapter); - } - -#ifdef CONFIG_PM - retval = pci_save_state(pdev); - if (retval) - return retval; -#endif - - pci_enable_wake(pdev, PCI_D3hot, 0); - pci_enable_wake(pdev, PCI_D3cold, 0); - - ixgbe_release_hw_control(adapter); - - pci_disable_device(pdev); - - pci_set_power_state(pdev, pci_choose_state(pdev, state)); - - return 0; -} - -static void ixgbe_shutdown(struct pci_dev *pdev) -{ - ixgbe_suspend(pdev, PMSG_SUSPEND); -} - /** * ixgbe_poll - NAPI Rx polling callback * @napi: structure for representing this polling device @@ -2174,11 +2189,11 @@ static void ixgbe_shutdown(struct pci_dev *pdev) static int ixgbe_poll(struct napi_struct *napi, int budget) { struct ixgbe_q_vector *q_vector = container_of(napi, - struct ixgbe_q_vector, napi); + struct ixgbe_q_vector, napi); struct ixgbe_adapter *adapter = q_vector->adapter; - int tx_cleaned = 0, work_done = 0; + int tx_cleaned, work_done = 0; -#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE) +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { ixgbe_update_tx_dca(adapter, adapter->tx_ring); ixgbe_update_rx_dca(adapter, adapter->rx_ring); @@ -2194,12 +2209,11 @@ static int ixgbe_poll(struct napi_struct *napi, int budget) /* If budget not fully consumed, exit the polling mode */ if (work_done < budget) { netif_rx_complete(adapter->netdev, napi); - if (adapter->rx_eitr < IXGBE_MIN_ITR_USECS) + if (adapter->itr_setting & 3) ixgbe_set_itr(adapter); if (!test_bit(__IXGBE_DOWN, &adapter->state)) ixgbe_irq_enable(adapter); } - return work_done; } @@ -2225,8 +2239,48 @@ static void ixgbe_reset_task(struct work_struct *work) ixgbe_reinit_locked(adapter); } +static void ixgbe_set_num_queues(struct ixgbe_adapter *adapter) +{ + int nrq = 1, ntq = 1; + int feature_mask = 0, rss_i, rss_m; + + /* Number of supported queues */ + switch (adapter->hw.mac.type) { + case ixgbe_mac_82598EB: + rss_i = adapter->ring_feature[RING_F_RSS].indices; + rss_m = 0; + feature_mask |= IXGBE_FLAG_RSS_ENABLED; + + switch (adapter->flags & feature_mask) { + case (IXGBE_FLAG_RSS_ENABLED): + rss_m = 0xF; + nrq = rss_i; + ntq = rss_i; + break; + case 0: + default: + rss_i = 0; + rss_m = 0; + nrq = 1; + ntq = 1; + break; + } + + adapter->ring_feature[RING_F_RSS].indices = rss_i; + adapter->ring_feature[RING_F_RSS].mask = rss_m; + break; + default: + nrq = 1; + ntq = 1; + break; + } + + adapter->num_rx_queues = nrq; + adapter->num_tx_queues = ntq; +} + static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, - int vectors) + int vectors) { int err, vector_threshold; @@ -2245,7 +2299,7 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, */ while (vectors >= vector_threshold) { err = pci_enable_msix(adapter->pdev, adapter->msix_entries, - vectors); + vectors); if (!err) /* Success in acquiring all requested vectors. */ break; else if (err < 0) @@ -2264,54 +2318,13 @@ static void ixgbe_acquire_msix_vectors(struct ixgbe_adapter *adapter, kfree(adapter->msix_entries); adapter->msix_entries = NULL; adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; - adapter->num_tx_queues = 1; - adapter->num_rx_queues = 1; + ixgbe_set_num_queues(adapter); } else { adapter->flags |= IXGBE_FLAG_MSIX_ENABLED; /* Woot! */ adapter->num_msix_vectors = vectors; } } -static void __devinit ixgbe_set_num_queues(struct ixgbe_adapter *adapter) -{ - int nrq, ntq; - int feature_mask = 0, rss_i, rss_m; - - /* Number of supported queues */ - switch (adapter->hw.mac.type) { - case ixgbe_mac_82598EB: - rss_i = adapter->ring_feature[RING_F_RSS].indices; - rss_m = 0; - feature_mask |= IXGBE_FLAG_RSS_ENABLED; - - switch (adapter->flags & feature_mask) { - case (IXGBE_FLAG_RSS_ENABLED): - rss_m = 0xF; - nrq = rss_i; - ntq = rss_i; - break; - case 0: - default: - rss_i = 0; - rss_m = 0; - nrq = 1; - ntq = 1; - break; - } - - adapter->ring_feature[RING_F_RSS].indices = rss_i; - adapter->ring_feature[RING_F_RSS].mask = rss_m; - break; - default: - nrq = 1; - ntq = 1; - break; - } - - adapter->num_rx_queues = nrq; - adapter->num_tx_queues = ntq; -} - /** * ixgbe_cache_ring_register - Descriptor ring to register mapping * @adapter: board private structure to initialize @@ -2321,9 +2334,6 @@ static void __devinit ixgbe_set_num_queues(struct ixgbe_adapter *adapter) **/ static void __devinit ixgbe_cache_ring_register(struct ixgbe_adapter *adapter) { - /* TODO: Remove all uses of the indices in the cases where multiple - * features are OR'd together, if the feature set makes sense. - */ int feature_mask = 0, rss_i; int i, txr_idx, rxr_idx; @@ -2364,21 +2374,22 @@ static int __devinit ixgbe_alloc_queues(struct ixgbe_adapter *adapter) int i; adapter->tx_ring = kcalloc(adapter->num_tx_queues, - sizeof(struct ixgbe_ring), GFP_KERNEL); + sizeof(struct ixgbe_ring), GFP_KERNEL); if (!adapter->tx_ring) goto err_tx_ring_allocation; adapter->rx_ring = kcalloc(adapter->num_rx_queues, - sizeof(struct ixgbe_ring), GFP_KERNEL); + sizeof(struct ixgbe_ring), GFP_KERNEL); if (!adapter->rx_ring) goto err_rx_ring_allocation; for (i = 0; i < adapter->num_tx_queues; i++) { - adapter->tx_ring[i].count = IXGBE_DEFAULT_TXD; + adapter->tx_ring[i].count = adapter->tx_ring_count; adapter->tx_ring[i].queue_index = i; } + for (i = 0; i < adapter->num_rx_queues; i++) { - adapter->rx_ring[i].count = IXGBE_DEFAULT_RXD; + adapter->rx_ring[i].count = adapter->rx_ring_count; adapter->rx_ring[i].queue_index = i; } @@ -2400,25 +2411,19 @@ err_tx_ring_allocation: * capabilities of the hardware and the kernel. **/ static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter - *adapter) + *adapter) { int err = 0; int vector, v_budget; /* - * Set the default interrupt throttle rate. - */ - adapter->rx_eitr = (1000000 / IXGBE_DEFAULT_ITR_RX_USECS); - adapter->tx_eitr = (1000000 / IXGBE_DEFAULT_ITR_TX_USECS); - - /* * It's easy to be greedy for MSI-X vectors, but it really * doesn't do us much good if we have a lot more vectors * than CPU's. So let's be conservative and only ask for * (roughly) twice the number of vectors as there are CPU's. */ v_budget = min(adapter->num_rx_queues + adapter->num_tx_queues, - (int)(num_online_cpus() * 2)) + NON_Q_VECTORS; + (int)(num_online_cpus() * 2)) + NON_Q_VECTORS; /* * At the same time, hardware can only support a maximum of @@ -2432,7 +2437,7 @@ static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter /* A failure in MSI-X entry allocation isn't fatal, but it does * mean we disable MSI-X capabilities of the adapter. */ adapter->msix_entries = kcalloc(v_budget, - sizeof(struct msix_entry), GFP_KERNEL); + sizeof(struct msix_entry), GFP_KERNEL); if (!adapter->msix_entries) { adapter->flags &= ~IXGBE_FLAG_RSS_ENABLED; ixgbe_set_num_queues(adapter); @@ -2441,7 +2446,7 @@ static int __devinit ixgbe_set_interrupt_capability(struct ixgbe_adapter err = ixgbe_alloc_queues(adapter); if (err) { DPRINTK(PROBE, ERR, "Unable to allocate memory " - "for queues\n"); + "for queues\n"); goto out; } @@ -2462,7 +2467,7 @@ try_msi: adapter->flags |= IXGBE_FLAG_MSI_ENABLED; } else { DPRINTK(HW, DEBUG, "Unable to allocate MSI interrupt, " - "falling back to legacy. Error: %d\n", err); + "falling back to legacy. Error: %d\n", err); /* reset err */ err = 0; } @@ -2518,9 +2523,9 @@ static int __devinit ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter) } DPRINTK(DRV, INFO, "Multiqueue %s: Rx Queue count = %u, " - "Tx Queue count = %u\n", - (adapter->num_rx_queues > 1) ? "Enabled" : - "Disabled", adapter->num_rx_queues, adapter->num_tx_queues); + "Tx Queue count = %u\n", + (adapter->num_rx_queues > 1) ? "Enabled" : + "Disabled", adapter->num_rx_queues, adapter->num_tx_queues); set_bit(__IXGBE_DOWN, &adapter->state); @@ -2547,15 +2552,19 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) struct pci_dev *pdev = adapter->pdev; unsigned int rss; + /* PCI config space info */ + + hw->vendor_id = pdev->vendor; + hw->device_id = pdev->device; + hw->revision_id = pdev->revision; + hw->subsystem_vendor_id = pdev->subsystem_vendor; + hw->subsystem_device_id = pdev->subsystem_device; + /* Set capability flags */ rss = min(IXGBE_MAX_RSS_INDICES, (int)num_online_cpus()); adapter->ring_feature[RING_F_RSS].indices = rss; adapter->flags |= IXGBE_FLAG_RSS_ENABLED; - /* Enable Dynamic interrupt throttling by default */ - adapter->rx_eitr = 1; - adapter->tx_eitr = 1; - /* default flow control settings */ hw->fc.original_type = ixgbe_fc_none; hw->fc.type = ixgbe_fc_none; @@ -2566,18 +2575,21 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter) /* select 10G link by default */ hw->mac.link_mode_select = IXGBE_AUTOC_LMS_10G_LINK_NO_AN; - if (hw->mac.ops.reset(hw)) { - dev_err(&pdev->dev, "HW Init failed\n"); - return -EIO; - } - if (hw->mac.ops.setup_link_speed(hw, IXGBE_LINK_SPEED_10GB_FULL, true, - false)) { - dev_err(&pdev->dev, "Link Speed setup failed\n"); - return -EIO; - } + + /* enable itr by default in dynamic mode */ + adapter->itr_setting = 1; + adapter->eitr_param = 20000; + + /* set defaults for eitr in MegaBytes */ + adapter->eitr_low = 10; + adapter->eitr_high = 20; + + /* set default ring sizes */ + adapter->tx_ring_count = IXGBE_DEFAULT_TXD; + adapter->rx_ring_count = IXGBE_DEFAULT_RXD; /* initialize eeprom parameters */ - if (ixgbe_init_eeprom(hw)) { + if (ixgbe_init_eeprom_params_generic(hw)) { dev_err(&pdev->dev, "EEPROM initialization failed\n"); return -EIO; } @@ -2633,6 +2645,31 @@ err: } /** + * ixgbe_setup_all_tx_resources - allocate all queues Tx resources + * @adapter: board private structure + * + * If this function returns with an error, then it's possible one or + * more of the rings is populated (while the rest are not). It is the + * callers duty to clean those orphaned rings. + * + * Return 0 on success, negative on failure + **/ +static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter) +{ + int i, err = 0; + + for (i = 0; i < adapter->num_tx_queues; i++) { + err = ixgbe_setup_tx_resources(adapter, &adapter->tx_ring[i]); + if (!err) + continue; + DPRINTK(PROBE, ERR, "Allocation for Tx Queue %u failed\n", i); + break; + } + + return err; +} + +/** * ixgbe_setup_rx_resources - allocate Rx resources (Descriptors) * @adapter: board private structure * @rx_ring: rx descriptor ring (for a specific queue) to setup @@ -2640,7 +2677,7 @@ err: * Returns 0 on success, negative on failure **/ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) + struct ixgbe_ring *rx_ring) { struct pci_dev *pdev = adapter->pdev; int size; @@ -2655,7 +2692,7 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter, rx_ring->rx_buffer_info = vmalloc(size); if (!rx_ring->rx_buffer_info) { DPRINTK(PROBE, ERR, - "vmalloc allocation failed for the rx desc ring\n"); + "vmalloc allocation failed for the rx desc ring\n"); goto alloc_failed; } memset(rx_ring->rx_buffer_info, 0, size); @@ -2668,7 +2705,7 @@ int ixgbe_setup_rx_resources(struct ixgbe_adapter *adapter, if (!rx_ring->desc) { DPRINTK(PROBE, ERR, - "Memory allocation failed for the rx desc ring\n"); + "Memory allocation failed for the rx desc ring\n"); vfree(rx_ring->rx_buffer_info); goto alloc_failed; } @@ -2685,14 +2722,40 @@ alloc_failed: } /** + * ixgbe_setup_all_rx_resources - allocate all queues Rx resources + * @adapter: board private structure + * + * If this function returns with an error, then it's possible one or + * more of the rings is populated (while the rest are not). It is the + * callers duty to clean those orphaned rings. + * + * Return 0 on success, negative on failure + **/ + +static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter) +{ + int i, err = 0; + + for (i = 0; i < adapter->num_rx_queues; i++) { + err = ixgbe_setup_rx_resources(adapter, &adapter->rx_ring[i]); + if (!err) + continue; + DPRINTK(PROBE, ERR, "Allocation for Rx Queue %u failed\n", i); + break; + } + + return err; +} + +/** * ixgbe_free_tx_resources - Free Tx Resources per Queue * @adapter: board private structure * @tx_ring: Tx descriptor ring for a specific queue * * Free all transmit software resources **/ -static void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring) +void ixgbe_free_tx_resources(struct ixgbe_adapter *adapter, + struct ixgbe_ring *tx_ring) { struct pci_dev *pdev = adapter->pdev; @@ -2727,8 +2790,8 @@ static void ixgbe_free_all_tx_resources(struct ixgbe_adapter *adapter) * * Free all receive software resources **/ -static void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter, - struct ixgbe_ring *rx_ring) +void ixgbe_free_rx_resources(struct ixgbe_adapter *adapter, + struct ixgbe_ring *rx_ring) { struct pci_dev *pdev = adapter->pdev; @@ -2760,59 +2823,6 @@ static void ixgbe_free_all_rx_resources(struct ixgbe_adapter *adapter) } /** - * ixgbe_setup_all_tx_resources - allocate all queues Tx resources - * @adapter: board private structure - * - * If this function returns with an error, then it's possible one or - * more of the rings is populated (while the rest are not). It is the - * callers duty to clean those orphaned rings. - * - * Return 0 on success, negative on failure - **/ -static int ixgbe_setup_all_tx_resources(struct ixgbe_adapter *adapter) -{ - int i, err = 0; - - for (i = 0; i < adapter->num_tx_queues; i++) { - err = ixgbe_setup_tx_resources(adapter, &adapter->tx_ring[i]); - if (err) { - DPRINTK(PROBE, ERR, - "Allocation for Tx Queue %u failed\n", i); - break; - } - } - - return err; -} - -/** - * ixgbe_setup_all_rx_resources - allocate all queues Rx resources - * @adapter: board private structure - * - * If this function returns with an error, then it's possible one or - * more of the rings is populated (while the rest are not). It is the - * callers duty to clean those orphaned rings. - * - * Return 0 on success, negative on failure - **/ - -static int ixgbe_setup_all_rx_resources(struct ixgbe_adapter *adapter) -{ - int i, err = 0; - - for (i = 0; i < adapter->num_rx_queues; i++) { - err = ixgbe_setup_rx_resources(adapter, &adapter->rx_ring[i]); - if (err) { - DPRINTK(PROBE, ERR, - "Allocation for Rx Queue %u failed\n", i); - break; - } - } - - return err; -} - -/** * ixgbe_change_mtu - Change the Maximum Transfer Unit * @netdev: network interface device structure * @new_mtu: new value for maximum frame size @@ -2824,12 +2834,12 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu) struct ixgbe_adapter *adapter = netdev_priv(netdev); int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; - if ((max_frame < (ETH_ZLEN + ETH_FCS_LEN)) || - (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE)) + /* MTU < 68 is an error and causes problems on some kernels */ + if ((new_mtu < 68) || (max_frame > IXGBE_MAX_JUMBO_FRAME_SIZE)) return -EINVAL; DPRINTK(PROBE, INFO, "changing MTU from %d to %d\n", - netdev->mtu, new_mtu); + netdev->mtu, new_mtu); /* must set new MTU before calling down or up */ netdev->mtu = new_mtu; @@ -2924,6 +2934,135 @@ static int ixgbe_close(struct net_device *netdev) } /** + * ixgbe_napi_add_all - prep napi structs for use + * @adapter: private struct + * helper function to napi_add each possible q_vector->napi + */ +static void ixgbe_napi_add_all(struct ixgbe_adapter *adapter) +{ + int q_idx, q_vectors; + int (*poll)(struct napi_struct *, int); + + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + poll = &ixgbe_clean_rxonly; + /* Only enable as many vectors as we have rx queues. */ + q_vectors = adapter->num_rx_queues; + } else { + poll = &ixgbe_poll; + /* only one q_vector for legacy modes */ + q_vectors = 1; + } + + for (q_idx = 0; q_idx < q_vectors; q_idx++) { + struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx]; + netif_napi_add(adapter->netdev, &q_vector->napi, (*poll), 64); + } +} + +static void ixgbe_napi_del_all(struct ixgbe_adapter *adapter) +{ + int q_idx; + int q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; + + /* legacy and MSI only use one vector */ + if (!(adapter->flags & IXGBE_FLAG_MSIX_ENABLED)) + q_vectors = 1; + + for (q_idx = 0; q_idx < q_vectors; q_idx++) { + struct ixgbe_q_vector *q_vector = &adapter->q_vector[q_idx]; + if (!q_vector->rxr_count) + continue; + netif_napi_del(&q_vector->napi); + } +} + +#ifdef CONFIG_PM +static int ixgbe_resume(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct ixgbe_adapter *adapter = netdev_priv(netdev); + u32 err; + + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + err = pci_enable_device(pdev); + if (err) { + printk(KERN_ERR "ixgbe: Cannot enable PCI device from " + "suspend\n"); + return err; + } + pci_set_master(pdev); + + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); + + err = ixgbe_init_interrupt_scheme(adapter); + if (err) { + printk(KERN_ERR "ixgbe: Cannot initialize interrupts for " + "device\n"); + return err; + } + + ixgbe_napi_add_all(adapter); + ixgbe_reset(adapter); + + if (netif_running(netdev)) { + err = ixgbe_open(adapter->netdev); + if (err) + return err; + } + + netif_device_attach(netdev); + + return 0; +} + +#endif /* CONFIG_PM */ +static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct ixgbe_adapter *adapter = netdev_priv(netdev); +#ifdef CONFIG_PM + int retval = 0; +#endif + + netif_device_detach(netdev); + + if (netif_running(netdev)) { + ixgbe_down(adapter); + ixgbe_free_irq(adapter); + ixgbe_free_all_tx_resources(adapter); + ixgbe_free_all_rx_resources(adapter); + } + ixgbe_reset_interrupt_capability(adapter); + ixgbe_napi_del_all(adapter); + kfree(adapter->tx_ring); + kfree(adapter->rx_ring); + +#ifdef CONFIG_PM + retval = pci_save_state(pdev); + if (retval) + return retval; +#endif + + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); + + ixgbe_release_hw_control(adapter); + + pci_disable_device(pdev); + + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + + return 0; +} + +static void ixgbe_shutdown(struct pci_dev *pdev) +{ + ixgbe_suspend(pdev, PMSG_SUSPEND); +} + +/** * ixgbe_update_stats - Update the board statistics counters. * @adapter: board private structure **/ @@ -2996,7 +3135,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) /* Rx Errors */ adapter->net_stats.rx_errors = adapter->stats.crcerrs + - adapter->stats.rlec; + adapter->stats.rlec; adapter->net_stats.rx_dropped = 0; adapter->net_stats.rx_length_errors = adapter->stats.rlec; adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs; @@ -3010,27 +3149,74 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) static void ixgbe_watchdog(unsigned long data) { struct ixgbe_adapter *adapter = (struct ixgbe_adapter *)data; - struct net_device *netdev = adapter->netdev; - bool link_up; - u32 link_speed = 0; + struct ixgbe_hw *hw = &adapter->hw; + + /* Do the watchdog outside of interrupt context due to the lovely + * delays that some of the newer hardware requires */ + if (!test_bit(__IXGBE_DOWN, &adapter->state)) { + /* Cause software interrupt to ensure rx rings are cleaned */ + if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { + u32 eics = + (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1; + IXGBE_WRITE_REG(hw, IXGBE_EICS, eics); + } else { + /* For legacy and MSI interrupts don't set any bits that + * are enabled for EIAM, because this operation would + * set *both* EIMS and EICS for any bit in EIAM */ + IXGBE_WRITE_REG(hw, IXGBE_EICS, + (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); + } + /* Reset the timer */ + mod_timer(&adapter->watchdog_timer, + round_jiffies(jiffies + 2 * HZ)); + } - adapter->hw.mac.ops.check_link(&adapter->hw, &(link_speed), &link_up); + schedule_work(&adapter->watchdog_task); +} + +/** + * ixgbe_watchdog_task - worker thread to bring link up + * @work: pointer to work_struct containing our data + **/ +static void ixgbe_watchdog_task(struct work_struct *work) +{ + struct ixgbe_adapter *adapter = container_of(work, + struct ixgbe_adapter, + watchdog_task); + struct net_device *netdev = adapter->netdev; + struct ixgbe_hw *hw = &adapter->hw; + u32 link_speed = adapter->link_speed; + bool link_up = adapter->link_up; + + adapter->flags |= IXGBE_FLAG_IN_WATCHDOG_TASK; + + if (adapter->flags & IXGBE_FLAG_NEED_LINK_UPDATE) { + hw->mac.ops.check_link(hw, &link_speed, &link_up, false); + if (link_up || + time_after(jiffies, (adapter->link_check_timeout + + IXGBE_TRY_LINK_TIMEOUT))) { + IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMC_LSC); + adapter->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE; + } + adapter->link_up = link_up; + adapter->link_speed = link_speed; + } if (link_up) { if (!netif_carrier_ok(netdev)) { - u32 frctl = IXGBE_READ_REG(&adapter->hw, IXGBE_FCTRL); - u32 rmcs = IXGBE_READ_REG(&adapter->hw, IXGBE_RMCS); + u32 frctl = IXGBE_READ_REG(hw, IXGBE_FCTRL); + u32 rmcs = IXGBE_READ_REG(hw, IXGBE_RMCS); #define FLOW_RX (frctl & IXGBE_FCTRL_RFCE) #define FLOW_TX (rmcs & IXGBE_RMCS_TFCE_802_3X) DPRINTK(LINK, INFO, "NIC Link is Up %s, " - "Flow Control: %s\n", - (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? - "10 Gbps" : - (link_speed == IXGBE_LINK_SPEED_1GB_FULL ? - "1 Gbps" : "unknown speed")), - ((FLOW_RX && FLOW_TX) ? "RX/TX" : - (FLOW_RX ? "RX" : - (FLOW_TX ? "TX" : "None")))); + "Flow Control: %s\n", + (link_speed == IXGBE_LINK_SPEED_10GB_FULL ? + "10 Gbps" : + (link_speed == IXGBE_LINK_SPEED_1GB_FULL ? + "1 Gbps" : "unknown speed")), + ((FLOW_RX && FLOW_TX) ? "RX/TX" : + (FLOW_RX ? "RX" : + (FLOW_TX ? "TX" : "None")))); netif_carrier_on(netdev); netif_tx_wake_all_queues(netdev); @@ -3039,6 +3225,8 @@ static void ixgbe_watchdog(unsigned long data) adapter->detect_tx_hung = true; } } else { + adapter->link_up = false; + adapter->link_speed = 0; if (netif_carrier_ok(netdev)) { DPRINTK(LINK, INFO, "NIC Link is Down\n"); netif_carrier_off(netdev); @@ -3047,36 +3235,19 @@ static void ixgbe_watchdog(unsigned long data) } ixgbe_update_stats(adapter); - - if (!test_bit(__IXGBE_DOWN, &adapter->state)) { - /* Cause software interrupt to ensure rx rings are cleaned */ - if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { - u32 eics = - (1 << (adapter->num_msix_vectors - NON_Q_VECTORS)) - 1; - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, eics); - } else { - /* for legacy and MSI interrupts don't set any bits that - * are enabled for EIAM, because this operation would - * set *both* EIMS and EICS for any bit in EIAM */ - IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, - (IXGBE_EICS_TCP_TIMER | IXGBE_EICS_OTHER)); - } - /* Reset the timer */ - mod_timer(&adapter->watchdog_timer, - round_jiffies(jiffies + 2 * HZ)); - } + adapter->flags &= ~IXGBE_FLAG_IN_WATCHDOG_TASK; } static int ixgbe_tso(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, struct sk_buff *skb, - u32 tx_flags, u8 *hdr_len) + struct ixgbe_ring *tx_ring, struct sk_buff *skb, + u32 tx_flags, u8 *hdr_len) { struct ixgbe_adv_tx_context_desc *context_desc; unsigned int i; int err; struct ixgbe_tx_buffer *tx_buffer_info; - u32 vlan_macip_lens = 0, type_tucmd_mlhl = 0; - u32 mss_l4len_idx = 0, l4len; + u32 vlan_macip_lens = 0, type_tucmd_mlhl; + u32 mss_l4len_idx, l4len; if (skb_is_gso(skb)) { if (skb_header_cloned(skb)) { @@ -3092,16 +3263,16 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, iph->tot_len = 0; iph->check = 0; tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr, - iph->daddr, 0, - IPPROTO_TCP, - 0); + iph->daddr, 0, + IPPROTO_TCP, + 0); adapter->hw_tso_ctxt++; } else if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV6) { ipv6_hdr(skb)->payload_len = 0; tcp_hdr(skb)->check = ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr, - &ipv6_hdr(skb)->daddr, - 0, IPPROTO_TCP, 0); + &ipv6_hdr(skb)->daddr, + 0, IPPROTO_TCP, 0); adapter->hw_tso6_ctxt++; } @@ -3115,7 +3286,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, vlan_macip_lens |= (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK); vlan_macip_lens |= ((skb_network_offset(skb)) << - IXGBE_ADVTXD_MACLEN_SHIFT); + IXGBE_ADVTXD_MACLEN_SHIFT); *hdr_len += skb_network_offset(skb); vlan_macip_lens |= (skb_transport_header(skb) - skb_network_header(skb)); @@ -3125,8 +3296,8 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, context_desc->seqnum_seed = 0; /* ADV DTYP TUCMD MKRLOC/ISCSIHEDLEN */ - type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT | - IXGBE_ADVTXD_DTYP_CTXT); + type_tucmd_mlhl = (IXGBE_TXD_CMD_DEXT | + IXGBE_ADVTXD_DTYP_CTXT); if (skb->protocol == htons(ETH_P_IP)) type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; @@ -3134,7 +3305,7 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, context_desc->type_tucmd_mlhl = cpu_to_le32(type_tucmd_mlhl); /* MSS L4LEN IDX */ - mss_l4len_idx |= + mss_l4len_idx = (skb_shinfo(skb)->gso_size << IXGBE_ADVTXD_MSS_SHIFT); mss_l4len_idx |= (l4len << IXGBE_ADVTXD_L4LEN_SHIFT); /* use index 1 for TSO */ @@ -3155,8 +3326,8 @@ static int ixgbe_tso(struct ixgbe_adapter *adapter, } static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - struct sk_buff *skb, u32 tx_flags) + struct ixgbe_ring *tx_ring, + struct sk_buff *skb, u32 tx_flags) { struct ixgbe_adv_tx_context_desc *context_desc; unsigned int i; @@ -3173,16 +3344,16 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, vlan_macip_lens |= (tx_flags & IXGBE_TX_FLAGS_VLAN_MASK); vlan_macip_lens |= (skb_network_offset(skb) << - IXGBE_ADVTXD_MACLEN_SHIFT); + IXGBE_ADVTXD_MACLEN_SHIFT); if (skb->ip_summed == CHECKSUM_PARTIAL) vlan_macip_lens |= (skb_transport_header(skb) - - skb_network_header(skb)); + skb_network_header(skb)); context_desc->vlan_macip_lens = cpu_to_le32(vlan_macip_lens); context_desc->seqnum_seed = 0; type_tucmd_mlhl |= (IXGBE_TXD_CMD_DEXT | - IXGBE_ADVTXD_DTYP_CTXT); + IXGBE_ADVTXD_DTYP_CTXT); if (skb->ip_summed == CHECKSUM_PARTIAL) { switch (skb->protocol) { @@ -3190,16 +3361,14 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, type_tucmd_mlhl |= IXGBE_ADVTXD_TUCMD_IPV4; if (ip_hdr(skb)->protocol == IPPROTO_TCP) type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_TCP; + IXGBE_ADVTXD_TUCMD_L4T_TCP; break; - case __constant_htons(ETH_P_IPV6): /* XXX what about other V6 headers?? */ if (ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) type_tucmd_mlhl |= - IXGBE_ADVTXD_TUCMD_L4T_TCP; + IXGBE_ADVTXD_TUCMD_L4T_TCP; break; - default: if (unlikely(net_ratelimit())) { DPRINTK(PROBE, WARNING, @@ -3216,6 +3385,7 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, tx_buffer_info->time_stamp = jiffies; tx_buffer_info->next_to_watch = i; + adapter->hw_csum_tx_good++; i++; if (i == tx_ring->count) @@ -3224,12 +3394,13 @@ static bool ixgbe_tx_csum(struct ixgbe_adapter *adapter, return true; } + return false; } static int ixgbe_tx_map(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - struct sk_buff *skb, unsigned int first) + struct ixgbe_ring *tx_ring, + struct sk_buff *skb, unsigned int first) { struct ixgbe_tx_buffer *tx_buffer_info; unsigned int len = skb->len; @@ -3247,8 +3418,8 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, tx_buffer_info->length = size; tx_buffer_info->dma = pci_map_single(adapter->pdev, - skb->data + offset, - size, PCI_DMA_TODEVICE); + skb->data + offset, + size, PCI_DMA_TODEVICE); tx_buffer_info->time_stamp = jiffies; tx_buffer_info->next_to_watch = i; @@ -3273,9 +3444,10 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, tx_buffer_info->length = size; tx_buffer_info->dma = pci_map_page(adapter->pdev, - frag->page, - offset, - size, PCI_DMA_TODEVICE); + frag->page, + offset, + size, + PCI_DMA_TODEVICE); tx_buffer_info->time_stamp = jiffies; tx_buffer_info->next_to_watch = i; @@ -3298,8 +3470,8 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter, } static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, - struct ixgbe_ring *tx_ring, - int tx_flags, int count, u32 paylen, u8 hdr_len) + struct ixgbe_ring *tx_ring, + int tx_flags, int count, u32 paylen, u8 hdr_len) { union ixgbe_adv_tx_desc *tx_desc = NULL; struct ixgbe_tx_buffer *tx_buffer_info; @@ -3318,17 +3490,17 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, cmd_type_len |= IXGBE_ADVTXD_DCMD_TSE; olinfo_status |= IXGBE_TXD_POPTS_TXSM << - IXGBE_ADVTXD_POPTS_SHIFT; + IXGBE_ADVTXD_POPTS_SHIFT; /* use index 1 context for tso */ olinfo_status |= (1 << IXGBE_ADVTXD_IDX_SHIFT); if (tx_flags & IXGBE_TX_FLAGS_IPV4) olinfo_status |= IXGBE_TXD_POPTS_IXSM << - IXGBE_ADVTXD_POPTS_SHIFT; + IXGBE_ADVTXD_POPTS_SHIFT; } else if (tx_flags & IXGBE_TX_FLAGS_CSUM) olinfo_status |= IXGBE_TXD_POPTS_TXSM << - IXGBE_ADVTXD_POPTS_SHIFT; + IXGBE_ADVTXD_POPTS_SHIFT; olinfo_status |= ((paylen - hdr_len) << IXGBE_ADVTXD_PAYLEN_SHIFT); @@ -3338,9 +3510,8 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i); tx_desc->read.buffer_addr = cpu_to_le64(tx_buffer_info->dma); tx_desc->read.cmd_type_len = - cpu_to_le32(cmd_type_len | tx_buffer_info->length); + cpu_to_le32(cmd_type_len | tx_buffer_info->length); tx_desc->read.olinfo_status = cpu_to_le32(olinfo_status); - i++; if (i == tx_ring->count) i = 0; @@ -3361,7 +3532,7 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter, } static int __ixgbe_maybe_stop_tx(struct net_device *netdev, - struct ixgbe_ring *tx_ring, int size) + struct ixgbe_ring *tx_ring, int size) { struct ixgbe_adapter *adapter = netdev_priv(netdev); @@ -3377,61 +3548,52 @@ static int __ixgbe_maybe_stop_tx(struct net_device *netdev, return -EBUSY; /* A reprieve! - use start_queue because it doesn't call schedule */ - netif_wake_subqueue(netdev, tx_ring->queue_index); + netif_start_subqueue(netdev, tx_ring->queue_index); ++adapter->restart_queue; return 0; } static int ixgbe_maybe_stop_tx(struct net_device *netdev, - struct ixgbe_ring *tx_ring, int size) + struct ixgbe_ring *tx_ring, int size) { if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size)) return 0; return __ixgbe_maybe_stop_tx(netdev, tx_ring, size); } - static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) { struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_ring *tx_ring; - unsigned int len = skb->len; unsigned int first; unsigned int tx_flags = 0; u8 hdr_len = 0; int r_idx = 0, tso; - unsigned int mss = 0; int count = 0; unsigned int f; - unsigned int nr_frags = skb_shinfo(skb)->nr_frags; - len -= skb->data_len; + r_idx = (adapter->num_tx_queues - 1) & skb->queue_mapping; tx_ring = &adapter->tx_ring[r_idx]; - - if (skb->len <= 0) { - dev_kfree_skb(skb); - return NETDEV_TX_OK; + if (adapter->vlgrp && vlan_tx_tag_present(skb)) { + tx_flags |= vlan_tx_tag_get(skb); + tx_flags <<= IXGBE_TX_FLAGS_VLAN_SHIFT; + tx_flags |= IXGBE_TX_FLAGS_VLAN; } - mss = skb_shinfo(skb)->gso_size; - - if (mss) - count++; - else if (skb->ip_summed == CHECKSUM_PARTIAL) + /* three things can cause us to need a context descriptor */ + if (skb_is_gso(skb) || + (skb->ip_summed == CHECKSUM_PARTIAL) || + (tx_flags & IXGBE_TX_FLAGS_VLAN)) count++; - count += TXD_USE_COUNT(len); - for (f = 0; f < nr_frags; f++) + count += TXD_USE_COUNT(skb_headlen(skb)); + for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size); if (ixgbe_maybe_stop_tx(netdev, tx_ring, count)) { adapter->tx_busy++; return NETDEV_TX_BUSY; } - if (adapter->vlgrp && vlan_tx_tag_present(skb)) { - tx_flags |= IXGBE_TX_FLAGS_VLAN; - tx_flags |= (vlan_tx_tag_get(skb) << IXGBE_TX_FLAGS_VLAN_SHIFT); - } if (skb->protocol == htons(ETH_P_IP)) tx_flags |= IXGBE_TX_FLAGS_IPV4; @@ -3445,12 +3607,12 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (tso) tx_flags |= IXGBE_TX_FLAGS_TSO; else if (ixgbe_tx_csum(adapter, tx_ring, skb, tx_flags) && - (skb->ip_summed == CHECKSUM_PARTIAL)) + (skb->ip_summed == CHECKSUM_PARTIAL)) tx_flags |= IXGBE_TX_FLAGS_CSUM; ixgbe_tx_queue(adapter, tx_ring, tx_flags, - ixgbe_tx_map(adapter, tx_ring, skb, first), - skb->len, hdr_len); + ixgbe_tx_map(adapter, tx_ring, skb, first), + skb->len, hdr_len); netdev->trans_start = jiffies; @@ -3484,15 +3646,16 @@ static struct net_device_stats *ixgbe_get_stats(struct net_device *netdev) static int ixgbe_set_mac(struct net_device *netdev, void *p) { struct ixgbe_adapter *adapter = netdev_priv(netdev); + struct ixgbe_hw *hw = &adapter->hw; struct sockaddr *addr = p; if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); - memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len); + memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len); - ixgbe_set_rar(&adapter->hw, 0, adapter->hw.mac.addr, 0, IXGBE_RAH_AV); + hw->mac.ops.set_rar(hw, 0, hw->mac.addr, 0, IXGBE_RAH_AV); return 0; } @@ -3516,28 +3679,19 @@ static void ixgbe_netpoll(struct net_device *netdev) #endif /** - * ixgbe_napi_add_all - prep napi structs for use - * @adapter: private struct - * helper function to napi_add each possible q_vector->napi - */ -static void ixgbe_napi_add_all(struct ixgbe_adapter *adapter) + * ixgbe_link_config - set up initial link with default speed and duplex + * @hw: pointer to private hardware struct + * + * Returns 0 on success, negative on failure + **/ +static int ixgbe_link_config(struct ixgbe_hw *hw) { - int i, q_vectors = adapter->num_msix_vectors - NON_Q_VECTORS; - int (*poll)(struct napi_struct *, int); + u32 autoneg = IXGBE_LINK_SPEED_10GB_FULL; - if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) { - poll = &ixgbe_clean_rxonly; - } else { - poll = &ixgbe_poll; - /* only one q_vector for legacy modes */ - q_vectors = 1; - } + /* must always autoneg for both 1G and 10G link */ + hw->mac.autoneg = true; - for (i = 0; i < q_vectors; i++) { - struct ixgbe_q_vector *q_vector = &adapter->q_vector[i]; - netif_napi_add(adapter->netdev, &q_vector->napi, - (*poll), 64); - } + return hw->mac.ops.setup_link_speed(hw, autoneg, true, true); } /** @@ -3552,17 +3706,16 @@ static void ixgbe_napi_add_all(struct ixgbe_adapter *adapter) * and a hardware reset occur. **/ static int __devinit ixgbe_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) + const struct pci_device_id *ent) { struct net_device *netdev; struct ixgbe_adapter *adapter = NULL; struct ixgbe_hw *hw; const struct ixgbe_info *ii = ixgbe_info_tbl[ent->driver_data]; - unsigned long mmio_start, mmio_len; static int cards_found; int i, err, pci_using_dac; u16 link_status, link_speed, link_width; - u32 part_num; + u32 part_num, eec; err = pci_enable_device(pdev); if (err) @@ -3577,7 +3730,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); if (err) { dev_err(&pdev->dev, "No usable DMA " - "configuration, aborting\n"); + "configuration, aborting\n"); goto err_dma; } } @@ -3610,10 +3763,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, hw->back = adapter; adapter->msg_enable = (1 << DEFAULT_DEBUG_LEVEL_SHIFT) - 1; - mmio_start = pci_resource_start(pdev, 0); - mmio_len = pci_resource_len(pdev, 0); - - hw->hw_addr = ioremap(mmio_start, mmio_len); + hw->hw_addr = ioremap(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); if (!hw->hw_addr) { err = -EIO; goto err_ioremap; @@ -3643,22 +3794,23 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, #endif strcpy(netdev->name, pci_name(pdev)); - netdev->mem_start = mmio_start; - netdev->mem_end = mmio_start + mmio_len; - adapter->bd_number = cards_found; - /* PCI config space info */ - hw->vendor_id = pdev->vendor; - hw->device_id = pdev->device; - hw->revision_id = pdev->revision; - hw->subsystem_vendor_id = pdev->subsystem_vendor; - hw->subsystem_device_id = pdev->subsystem_device; - /* Setup hw api */ memcpy(&hw->mac.ops, ii->mac_ops, sizeof(hw->mac.ops)); hw->mac.type = ii->mac; + /* EEPROM */ + memcpy(&hw->eeprom.ops, ii->eeprom_ops, sizeof(hw->eeprom.ops)); + eec = IXGBE_READ_REG(hw, IXGBE_EEC); + /* If EEPROM is valid (bit 8 = 1), use default otherwise use bit bang */ + if (!(eec & (1 << 8))) + hw->eeprom.ops.read = &ixgbe_read_eeprom_bit_bang_generic; + + /* PHY */ + memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops)); + /* phy->sfp_type = ixgbe_sfp_type_unknown; */ + err = ii->get_invariants(hw); if (err) goto err_hw_init; @@ -3668,11 +3820,18 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, if (err) goto err_sw_init; + /* reset_hw fills in the perm_addr as well */ + err = hw->mac.ops.reset_hw(hw); + if (err) { + dev_err(&adapter->pdev->dev, "HW Init failed: %d\n", err); + goto err_sw_init; + } + netdev->features = NETIF_F_SG | - NETIF_F_IP_CSUM | - NETIF_F_HW_VLAN_TX | - NETIF_F_HW_VLAN_RX | - NETIF_F_HW_VLAN_FILTER; + NETIF_F_IP_CSUM | + NETIF_F_HW_VLAN_TX | + NETIF_F_HW_VLAN_RX | + NETIF_F_HW_VLAN_FILTER; netdev->features |= NETIF_F_IPV6_CSUM; netdev->features |= NETIF_F_TSO; @@ -3688,7 +3847,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, netdev->features |= NETIF_F_HIGHDMA; /* make sure the EEPROM is good */ - if (ixgbe_validate_eeprom_checksum(hw, NULL) < 0) { + if (hw->eeprom.ops.validate_checksum(hw, NULL) < 0) { dev_err(&pdev->dev, "The EEPROM Checksum Is Not Valid\n"); err = -EIO; goto err_eeprom; @@ -3697,7 +3856,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, memcpy(netdev->dev_addr, hw->mac.perm_addr, netdev->addr_len); memcpy(netdev->perm_addr, hw->mac.perm_addr, netdev->addr_len); - if (ixgbe_validate_mac_addr(netdev->dev_addr)) { + if (ixgbe_validate_mac_addr(netdev->perm_addr)) { + dev_err(&pdev->dev, "invalid MAC address\n"); err = -EIO; goto err_eeprom; } @@ -3707,6 +3867,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, adapter->watchdog_timer.data = (unsigned long)adapter; INIT_WORK(&adapter->reset_task, ixgbe_reset_task); + INIT_WORK(&adapter->watchdog_task, ixgbe_watchdog_task); err = ixgbe_init_interrupt_scheme(adapter); if (err) @@ -3717,32 +3878,39 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, link_speed = link_status & IXGBE_PCI_LINK_SPEED; link_width = link_status & IXGBE_PCI_LINK_WIDTH; dev_info(&pdev->dev, "(PCI Express:%s:%s) " - "%02x:%02x:%02x:%02x:%02x:%02x\n", - ((link_speed == IXGBE_PCI_LINK_SPEED_5000) ? "5.0Gb/s" : - (link_speed == IXGBE_PCI_LINK_SPEED_2500) ? "2.5Gb/s" : - "Unknown"), - ((link_width == IXGBE_PCI_LINK_WIDTH_8) ? "Width x8" : - (link_width == IXGBE_PCI_LINK_WIDTH_4) ? "Width x4" : - (link_width == IXGBE_PCI_LINK_WIDTH_2) ? "Width x2" : - (link_width == IXGBE_PCI_LINK_WIDTH_1) ? "Width x1" : - "Unknown"), - netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], - netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); - ixgbe_read_part_num(hw, &part_num); + "%02x:%02x:%02x:%02x:%02x:%02x\n", + ((link_speed == IXGBE_PCI_LINK_SPEED_5000) ? "5.0Gb/s" : + (link_speed == IXGBE_PCI_LINK_SPEED_2500) ? "2.5Gb/s" : + "Unknown"), + ((link_width == IXGBE_PCI_LINK_WIDTH_8) ? "Width x8" : + (link_width == IXGBE_PCI_LINK_WIDTH_4) ? "Width x4" : + (link_width == IXGBE_PCI_LINK_WIDTH_2) ? "Width x2" : + (link_width == IXGBE_PCI_LINK_WIDTH_1) ? "Width x1" : + "Unknown"), + netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], + netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); + ixgbe_read_pba_num_generic(hw, &part_num); dev_info(&pdev->dev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n", - hw->mac.type, hw->phy.type, - (part_num >> 8), (part_num & 0xff)); + hw->mac.type, hw->phy.type, + (part_num >> 8), (part_num & 0xff)); if (link_width <= IXGBE_PCI_LINK_WIDTH_4) { dev_warn(&pdev->dev, "PCI-Express bandwidth available for " - "this card is not sufficient for optimal " - "performance.\n"); + "this card is not sufficient for optimal " + "performance.\n"); dev_warn(&pdev->dev, "For optimal performance a x8 " - "PCI-Express slot is required.\n"); + "PCI-Express slot is required.\n"); } /* reset the hardware with the new settings */ - ixgbe_start_hw(hw); + hw->mac.ops.start_hw(hw); + + /* link_config depends on start_hw being called at least once */ + err = ixgbe_link_config(hw); + if (err) { + dev_err(&pdev->dev, "setup_link_speed FAILED %d\n", err); + goto err_register; + } netif_carrier_off(netdev); netif_tx_stop_all_queues(netdev); @@ -3754,7 +3922,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, if (err) goto err_register; -#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE) +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (dca_add_requester(&pdev->dev) == 0) { adapter->flags |= IXGBE_FLAG_DCA_ENABLED; /* always use CB2 mode, difference is masked @@ -3804,7 +3972,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) flush_scheduled_work(); -#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE) +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) if (adapter->flags & IXGBE_FLAG_DCA_ENABLED) { adapter->flags &= ~IXGBE_FLAG_DCA_ENABLED; dca_remove_requester(&pdev->dev); @@ -3822,6 +3990,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) pci_release_regions(pdev); DPRINTK(PROBE, INFO, "complete\n"); + ixgbe_napi_del_all(adapter); kfree(adapter->tx_ring); kfree(adapter->rx_ring); @@ -3839,7 +4008,7 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev) * this device has been detected. */ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, - pci_channel_state_t state) + pci_channel_state_t state) { struct net_device *netdev = pci_get_drvdata(pdev); struct ixgbe_adapter *adapter = netdev->priv; @@ -3850,7 +4019,7 @@ static pci_ers_result_t ixgbe_io_error_detected(struct pci_dev *pdev, ixgbe_down(adapter); pci_disable_device(pdev); - /* Request a slot slot reset. */ + /* Request a slot reset. */ return PCI_ERS_RESULT_NEED_RESET; } @@ -3867,7 +4036,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev) if (pci_enable_device(pdev)) { DPRINTK(PROBE, ERR, - "Cannot re-enable PCI device after reset.\n"); + "Cannot re-enable PCI device after reset.\n"); return PCI_ERS_RESULT_DISCONNECT; } pci_set_master(pdev); @@ -3901,7 +4070,6 @@ static void ixgbe_io_resume(struct pci_dev *pdev) } netif_device_attach(netdev); - } static struct pci_error_handlers ixgbe_err_handler = { @@ -3937,13 +4105,14 @@ static int __init ixgbe_init_module(void) printk(KERN_INFO "%s: %s\n", ixgbe_driver_name, ixgbe_copyright); -#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE) +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) dca_register_notify(&dca_notifier); #endif ret = pci_register_driver(&ixgbe_driver); return ret; } + module_init(ixgbe_init_module); /** @@ -3954,20 +4123,20 @@ module_init(ixgbe_init_module); **/ static void __exit ixgbe_exit_module(void) { -#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE) +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) dca_unregister_notify(&dca_notifier); #endif pci_unregister_driver(&ixgbe_driver); } -#if defined(CONFIG_DCA) || defined (CONFIG_DCA_MODULE) +#if defined(CONFIG_DCA) || defined(CONFIG_DCA_MODULE) static int ixgbe_notify_dca(struct notifier_block *nb, unsigned long event, - void *p) + void *p) { int ret_val; ret_val = driver_for_each_device(&ixgbe_driver.driver, NULL, &event, - __ixgbe_notify_dca); + __ixgbe_notify_dca); return ret_val ? NOTIFY_BAD : NOTIFY_DONE; } diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 8002931ae82..764035a8c9a 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2007 Intel Corporation. + Copyright(c) 1999 - 2008 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -20,7 +20,6 @@ the file called "COPYING". Contact Information: - Linux NICS <linux.nics@intel.com> e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 @@ -33,32 +32,36 @@ #include "ixgbe_common.h" #include "ixgbe_phy.h" +static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr); static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id); static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw); -static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr); -static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, - u32 device_type, u16 phy_data); /** - * ixgbe_identify_phy - Get physical layer module + * ixgbe_identify_phy_generic - Get physical layer module * @hw: pointer to hardware structure * * Determines the physical layer module found on the current adapter. **/ -s32 ixgbe_identify_phy(struct ixgbe_hw *hw) +s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw) { s32 status = IXGBE_ERR_PHY_ADDR_INVALID; u32 phy_addr; - for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { - if (ixgbe_validate_phy_addr(hw, phy_addr)) { - hw->phy.addr = phy_addr; - ixgbe_get_phy_id(hw); - hw->phy.type = ixgbe_get_phy_type_from_id(hw->phy.id); - status = 0; - break; + if (hw->phy.type == ixgbe_phy_unknown) { + for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) { + if (ixgbe_validate_phy_addr(hw, phy_addr)) { + hw->phy.addr = phy_addr; + ixgbe_get_phy_id(hw); + hw->phy.type = + ixgbe_get_phy_type_from_id(hw->phy.id); + status = 0; + break; + } } + } else { + status = 0; } + return status; } @@ -73,10 +76,8 @@ static bool ixgbe_validate_phy_addr(struct ixgbe_hw *hw, u32 phy_addr) bool valid = false; hw->phy.addr = phy_addr; - ixgbe_read_phy_reg(hw, - IXGBE_MDIO_PHY_ID_HIGH, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, - &phy_id); + hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, &phy_id); if (phy_id != 0xFFFF && phy_id != 0x0) valid = true; @@ -95,21 +96,18 @@ static s32 ixgbe_get_phy_id(struct ixgbe_hw *hw) u16 phy_id_high = 0; u16 phy_id_low = 0; - status = ixgbe_read_phy_reg(hw, - IXGBE_MDIO_PHY_ID_HIGH, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, - &phy_id_high); + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_HIGH, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + &phy_id_high); if (status == 0) { hw->phy.id = (u32)(phy_id_high << 16); - status = ixgbe_read_phy_reg(hw, - IXGBE_MDIO_PHY_ID_LOW, - IXGBE_MDIO_PMA_PMD_DEV_TYPE, - &phy_id_low); + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_PHY_ID_LOW, + IXGBE_MDIO_PMA_PMD_DEV_TYPE, + &phy_id_low); hw->phy.id |= (u32)(phy_id_low & IXGBE_PHY_REVISION_MASK); hw->phy.revision = (u32)(phy_id_low & ~IXGBE_PHY_REVISION_MASK); } - return status; } @@ -123,9 +121,6 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) enum ixgbe_phy_type phy_type; switch (phy_id) { - case TN1010_PHY_ID: - phy_type = ixgbe_phy_tn; - break; case QT2022_PHY_ID: phy_type = ixgbe_phy_qt; break; @@ -138,32 +133,31 @@ static enum ixgbe_phy_type ixgbe_get_phy_type_from_id(u32 phy_id) } /** - * ixgbe_reset_phy - Performs a PHY reset + * ixgbe_reset_phy_generic - Performs a PHY reset * @hw: pointer to hardware structure **/ -s32 ixgbe_reset_phy(struct ixgbe_hw *hw) +s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw) { /* * Perform soft PHY reset to the PHY_XS. * This will cause a soft reset to the PHY */ - return ixgbe_write_phy_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, - IXGBE_MDIO_PHY_XS_DEV_TYPE, - IXGBE_MDIO_PHY_XS_RESET); + return hw->phy.ops.write_reg(hw, IXGBE_MDIO_PHY_XS_CONTROL, + IXGBE_MDIO_PHY_XS_DEV_TYPE, + IXGBE_MDIO_PHY_XS_RESET); } /** - * ixgbe_read_phy_reg - Reads a value from a specified PHY register + * ixgbe_read_phy_reg_generic - Reads a value from a specified PHY register * @hw: pointer to hardware structure * @reg_addr: 32 bit address of PHY register to read * @phy_data: Pointer to read data from PHY register **/ -s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, - u32 device_type, u16 *phy_data) +s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data) { u32 command; u32 i; - u32 timeout = 10; u32 data; s32 status = 0; u16 gssr; @@ -179,9 +173,9 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, if (status == 0) { /* Setup and write the address cycle command */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | - (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | - (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | - (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); + (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); @@ -190,7 +184,7 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, * The MDI Command bit will clear when the operation is * complete */ - for (i = 0; i < timeout; i++) { + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { udelay(10); command = IXGBE_READ_REG(hw, IXGBE_MSCA); @@ -210,9 +204,9 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, * command */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | - (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | - (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | - (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND)); + (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + (IXGBE_MSCA_READ | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); @@ -221,7 +215,7 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, * completed. The MDI Command bit will clear when the * operation is complete */ - for (i = 0; i < timeout; i++) { + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { udelay(10); command = IXGBE_READ_REG(hw, IXGBE_MSCA); @@ -231,8 +225,7 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, } if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { - hw_dbg(hw, - "PHY read command didn't complete\n"); + hw_dbg(hw, "PHY read command didn't complete\n"); status = IXGBE_ERR_PHY; } else { /* @@ -247,22 +240,22 @@ s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, ixgbe_release_swfw_sync(hw, gssr); } + return status; } /** - * ixgbe_write_phy_reg - Writes a value to specified PHY register + * ixgbe_write_phy_reg_generic - Writes a value to specified PHY register * @hw: pointer to hardware structure * @reg_addr: 32 bit PHY register to write * @device_type: 5 bit device type * @phy_data: Data to write to the PHY register **/ -static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, - u32 device_type, u16 phy_data) +s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data) { u32 command; u32 i; - u32 timeout = 10; s32 status = 0; u16 gssr; @@ -280,9 +273,9 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, /* Setup and write the address cycle command */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | - (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | - (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | - (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); + (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + (IXGBE_MSCA_ADDR_CYCLE | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); @@ -291,19 +284,19 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, * The MDI Command bit will clear when the operation is * complete */ - for (i = 0; i < timeout; i++) { + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { udelay(10); command = IXGBE_READ_REG(hw, IXGBE_MSCA); - if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) { - hw_dbg(hw, "PHY address cmd didn't complete\n"); + if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) break; - } } - if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) + if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { + hw_dbg(hw, "PHY address cmd didn't complete\n"); status = IXGBE_ERR_PHY; + } if (status == 0) { /* @@ -311,9 +304,9 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, * command */ command = ((reg_addr << IXGBE_MSCA_NP_ADDR_SHIFT) | - (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | - (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | - (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND)); + (device_type << IXGBE_MSCA_DEV_TYPE_SHIFT) | + (hw->phy.addr << IXGBE_MSCA_PHY_ADDR_SHIFT) | + (IXGBE_MSCA_WRITE | IXGBE_MSCA_MDI_COMMAND)); IXGBE_WRITE_REG(hw, IXGBE_MSCA, command); @@ -322,20 +315,19 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, * completed. The MDI Command bit will clear when the * operation is complete */ - for (i = 0; i < timeout; i++) { + for (i = 0; i < IXGBE_MDIO_COMMAND_TIMEOUT; i++) { udelay(10); command = IXGBE_READ_REG(hw, IXGBE_MSCA); - if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) { - hw_dbg(hw, "PHY write command did not " - "complete.\n"); + if ((command & IXGBE_MSCA_MDI_COMMAND) == 0) break; - } } - if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) + if ((command & IXGBE_MSCA_MDI_COMMAND) != 0) { + hw_dbg(hw, "PHY address cmd didn't complete\n"); status = IXGBE_ERR_PHY; + } } ixgbe_release_swfw_sync(hw, gssr); @@ -345,67 +337,54 @@ static s32 ixgbe_write_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, } /** - * ixgbe_setup_tnx_phy_link - Set and restart autoneg + * ixgbe_setup_phy_link_generic - Set and restart autoneg * @hw: pointer to hardware structure * * Restart autonegotiation and PHY and waits for completion. **/ -s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw) +s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) { s32 status = IXGBE_NOT_IMPLEMENTED; u32 time_out; u32 max_time_out = 10; - u16 autoneg_speed_selection_register = 0x10; - u16 autoneg_restart_mask = 0x0200; - u16 autoneg_complete_mask = 0x0020; - u16 autoneg_reg = 0; + u16 autoneg_reg = IXGBE_MII_AUTONEG_REG; /* * Set advertisement settings in PHY based on autoneg_advertised * settings. If autoneg_advertised = 0, then advertise default values - * txn devices cannot be "forced" to a autoneg 10G and fail. But can + * tnx devices cannot be "forced" to a autoneg 10G and fail. But can * for a 1G. */ - ixgbe_read_phy_reg(hw, - autoneg_speed_selection_register, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_reg); + hw->phy.ops.read_reg(hw, IXGBE_MII_SPEED_SELECTION_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); if (hw->phy.autoneg_advertised == IXGBE_LINK_SPEED_1GB_FULL) autoneg_reg &= 0xEFFF; /* 0 in bit 12 is 1G operation */ else autoneg_reg |= 0x1000; /* 1 in bit 12 is 10G/1G operation */ - ixgbe_write_phy_reg(hw, - autoneg_speed_selection_register, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - autoneg_reg); - + hw->phy.ops.write_reg(hw, IXGBE_MII_SPEED_SELECTION_REG, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); /* Restart PHY autonegotiation and wait for completion */ - ixgbe_read_phy_reg(hw, - IXGBE_MDIO_AUTO_NEG_CONTROL, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_reg); + hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, &autoneg_reg); - autoneg_reg |= autoneg_restart_mask; + autoneg_reg |= IXGBE_MII_RESTART; - ixgbe_write_phy_reg(hw, - IXGBE_MDIO_AUTO_NEG_CONTROL, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - autoneg_reg); + hw->phy.ops.write_reg(hw, IXGBE_MDIO_AUTO_NEG_CONTROL, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, autoneg_reg); /* Wait for autonegotiation to finish */ for (time_out = 0; time_out < max_time_out; time_out++) { udelay(10); /* Restart PHY autonegotiation and wait for completion */ - status = ixgbe_read_phy_reg(hw, - IXGBE_MDIO_AUTO_NEG_STATUS, - IXGBE_MDIO_AUTO_NEG_DEV_TYPE, - &autoneg_reg); + status = hw->phy.ops.read_reg(hw, IXGBE_MDIO_AUTO_NEG_STATUS, + IXGBE_MDIO_AUTO_NEG_DEV_TYPE, + &autoneg_reg); - autoneg_reg &= autoneg_complete_mask; - if (autoneg_reg == autoneg_complete_mask) { + autoneg_reg &= IXGBE_MII_AUTONEG_COMPLETE; + if (autoneg_reg == IXGBE_MII_AUTONEG_COMPLETE) { status = 0; break; } @@ -418,64 +397,17 @@ s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw) } /** - * ixgbe_check_tnx_phy_link - Determine link and speed status - * @hw: pointer to hardware structure - * - * Reads the VS1 register to determine if link is up and the current speed for - * the PHY. - **/ -s32 ixgbe_check_tnx_phy_link(struct ixgbe_hw *hw, u32 *speed, - bool *link_up) -{ - s32 status = 0; - u32 time_out; - u32 max_time_out = 10; - u16 phy_link = 0; - u16 phy_speed = 0; - u16 phy_data = 0; - - /* Initialize speed and link to default case */ - *link_up = false; - *speed = IXGBE_LINK_SPEED_10GB_FULL; - - /* - * Check current speed and link status of the PHY register. - * This is a vendor specific register and may have to - * be changed for other copper PHYs. - */ - for (time_out = 0; time_out < max_time_out; time_out++) { - udelay(10); - if (phy_link == IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS) { - *link_up = true; - if (phy_speed == - IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS) - *speed = IXGBE_LINK_SPEED_1GB_FULL; - break; - } else { - status = ixgbe_read_phy_reg(hw, - IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS, - IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE, - &phy_data); - phy_link = phy_data & - IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS; - phy_speed = phy_data & - IXGBE_MDIO_VENDOR_SPECIFIC_1_SPEED_STATUS; - } - } - - return status; -} - -/** - * ixgbe_setup_tnx_phy_link_speed - Sets the auto advertised capabilities + * ixgbe_setup_phy_link_speed_generic - Sets the auto advertised capabilities * @hw: pointer to hardware structure * @speed: new link speed * @autoneg: true if autonegotiation enabled **/ -s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, u32 speed, - bool autoneg, - bool autoneg_wait_to_complete) +s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg, + bool autoneg_wait_to_complete) { + /* * Clear autoneg_advertised and set new values based on input link * speed. @@ -484,11 +416,13 @@ s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, u32 speed, if (speed & IXGBE_LINK_SPEED_10GB_FULL) hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_10GB_FULL; + if (speed & IXGBE_LINK_SPEED_1GB_FULL) hw->phy.autoneg_advertised |= IXGBE_LINK_SPEED_1GB_FULL; /* Setup link based on the new speed settings */ - ixgbe_setup_tnx_phy_link(hw); + hw->phy.ops.setup_link(hw); return 0; } + diff --git a/drivers/net/ixgbe/ixgbe_phy.h b/drivers/net/ixgbe/ixgbe_phy.h index aa3ea72e678..9bfe3f2b1d8 100644 --- a/drivers/net/ixgbe/ixgbe_phy.h +++ b/drivers/net/ixgbe/ixgbe_phy.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2007 Intel Corporation. + Copyright(c) 1999 - 2008 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -20,7 +20,6 @@ the file called "COPYING". Contact Information: - Linux NICS <linux.nics@intel.com> e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 @@ -30,20 +29,52 @@ #define _IXGBE_PHY_H_ #include "ixgbe_type.h" +#define IXGBE_I2C_EEPROM_DEV_ADDR 0xA0 -s32 ixgbe_setup_phy_link(struct ixgbe_hw *hw); -s32 ixgbe_check_phy_link(struct ixgbe_hw *hw, u32 *speed, bool *link_up); -s32 ixgbe_setup_phy_link_speed(struct ixgbe_hw *hw, u32 speed, bool autoneg, - bool autoneg_wait_to_complete); -s32 ixgbe_identify_phy(struct ixgbe_hw *hw); -s32 ixgbe_reset_phy(struct ixgbe_hw *hw); -s32 ixgbe_read_phy_reg(struct ixgbe_hw *hw, u32 reg_addr, - u32 device_type, u16 *phy_data); - -/* PHY specific */ -s32 ixgbe_setup_tnx_phy_link(struct ixgbe_hw *hw); -s32 ixgbe_check_tnx_phy_link(struct ixgbe_hw *hw, u32 *speed, bool *link_up); -s32 ixgbe_setup_tnx_phy_link_speed(struct ixgbe_hw *hw, u32 speed, bool autoneg, - bool autoneg_wait_to_complete); +/* EEPROM byte offsets */ +#define IXGBE_SFF_IDENTIFIER 0x0 +#define IXGBE_SFF_IDENTIFIER_SFP 0x3 +#define IXGBE_SFF_VENDOR_OUI_BYTE0 0x25 +#define IXGBE_SFF_VENDOR_OUI_BYTE1 0x26 +#define IXGBE_SFF_VENDOR_OUI_BYTE2 0x27 +#define IXGBE_SFF_1GBE_COMP_CODES 0x6 +#define IXGBE_SFF_10GBE_COMP_CODES 0x3 +#define IXGBE_SFF_TRANSMISSION_MEDIA 0x9 + +/* Bitmasks */ +#define IXGBE_SFF_TWIN_AX_CAPABLE 0x80 +#define IXGBE_SFF_1GBASESX_CAPABLE 0x1 +#define IXGBE_SFF_10GBASESR_CAPABLE 0x10 +#define IXGBE_SFF_10GBASELR_CAPABLE 0x20 +#define IXGBE_I2C_EEPROM_READ_MASK 0x100 +#define IXGBE_I2C_EEPROM_STATUS_MASK 0x3 +#define IXGBE_I2C_EEPROM_STATUS_NO_OPERATION 0x0 +#define IXGBE_I2C_EEPROM_STATUS_PASS 0x1 +#define IXGBE_I2C_EEPROM_STATUS_FAIL 0x2 +#define IXGBE_I2C_EEPROM_STATUS_IN_PROGRESS 0x3 + +/* Bit-shift macros */ +#define IXGBE_SFF_VENDOR_OUI_BYTE0_SHIFT 12 +#define IXGBE_SFF_VENDOR_OUI_BYTE1_SHIFT 8 +#define IXGBE_SFF_VENDOR_OUI_BYTE2_SHIFT 4 + +/* Vendor OUIs: format of OUI is 0x[byte0][byte1][byte2][00] */ +#define IXGBE_SFF_VENDOR_OUI_TYCO 0x00407600 +#define IXGBE_SFF_VENDOR_OUI_FTL 0x00906500 +#define IXGBE_SFF_VENDOR_OUI_AVAGO 0x00176A00 + + +s32 ixgbe_init_phy_ops_generic(struct ixgbe_hw *hw); +s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw); +s32 ixgbe_reset_phy_generic(struct ixgbe_hw *hw); +s32 ixgbe_read_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 *phy_data); +s32 ixgbe_write_phy_reg_generic(struct ixgbe_hw *hw, u32 reg_addr, + u32 device_type, u16 phy_data); +s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw); +s32 ixgbe_setup_phy_link_speed_generic(struct ixgbe_hw *hw, + ixgbe_link_speed speed, + bool autoneg, + bool autoneg_wait_to_complete); #endif /* _IXGBE_PHY_H_ */ diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h index 3e9c483ad8e..c6f8fa1c4e5 100644 --- a/drivers/net/ixgbe/ixgbe_type.h +++ b/drivers/net/ixgbe/ixgbe_type.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel 10 Gigabit PCI Express Linux driver - Copyright(c) 1999 - 2007 Intel Corporation. + Copyright(c) 1999 - 2008 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -20,7 +20,6 @@ the file called "COPYING". Contact Information: - Linux NICS <linux.nics@intel.com> e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 @@ -37,9 +36,9 @@ /* Device IDs */ #define IXGBE_DEV_ID_82598AF_DUAL_PORT 0x10C6 #define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7 -#define IXGBE_DEV_ID_82598AT_DUAL_PORT 0x10C8 #define IXGBE_DEV_ID_82598EB_CX4 0x10DD #define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC +#define IXGBE_DEV_ID_82598EB_XF_LR 0x10F4 /* General Registers */ #define IXGBE_CTRL 0x00000 @@ -70,11 +69,11 @@ #define IXGBE_EIMC 0x00888 #define IXGBE_EIAC 0x00810 #define IXGBE_EIAM 0x00890 -#define IXGBE_EITR(_i) (0x00820 + ((_i) * 4)) /* 0x820-0x86c */ -#define IXGBE_IVAR(_i) (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */ +#define IXGBE_EITR(_i) (((_i) <= 23) ? (0x00820 + ((_i) * 4)) : (0x012300 + ((_i) * 4))) +#define IXGBE_IVAR(_i) (0x00900 + ((_i) * 4)) /* 24 at 0x900-0x960 */ #define IXGBE_MSIXT 0x00000 /* MSI-X Table. 0x0000 - 0x01C */ #define IXGBE_MSIXPBA 0x02000 /* MSI-X Pending bit array */ -#define IXGBE_PBACL 0x11068 +#define IXGBE_PBACL(_i) (((_i) == 0) ? (0x11068) : (0x110C0 + ((_i) * 4))) #define IXGBE_GPIE 0x00898 /* Flow Control Registers */ @@ -86,20 +85,33 @@ #define IXGBE_TFCS 0x0CE00 /* Receive DMA Registers */ -#define IXGBE_RDBAL(_i) (0x01000 + ((_i) * 0x40)) /* 64 of each (0-63)*/ -#define IXGBE_RDBAH(_i) (0x01004 + ((_i) * 0x40)) -#define IXGBE_RDLEN(_i) (0x01008 + ((_i) * 0x40)) -#define IXGBE_RDH(_i) (0x01010 + ((_i) * 0x40)) -#define IXGBE_RDT(_i) (0x01018 + ((_i) * 0x40)) -#define IXGBE_RXDCTL(_i) (0x01028 + ((_i) * 0x40)) -#define IXGBE_RSCCTL(_i) (0x0102C + ((_i) * 0x40)) -#define IXGBE_SRRCTL(_i) (0x02100 + ((_i) * 4)) - /* array of 16 (0x02100-0x0213C) */ -#define IXGBE_DCA_RXCTRL(_i) (0x02200 + ((_i) * 4)) - /* array of 16 (0x02200-0x0223C) */ -#define IXGBE_RDRXCTL 0x02F00 +#define IXGBE_RDBAL(_i) (((_i) < 64) ? (0x01000 + ((_i) * 0x40)) : (0x0D000 + ((_i - 64) * 0x40))) +#define IXGBE_RDBAH(_i) (((_i) < 64) ? (0x01004 + ((_i) * 0x40)) : (0x0D004 + ((_i - 64) * 0x40))) +#define IXGBE_RDLEN(_i) (((_i) < 64) ? (0x01008 + ((_i) * 0x40)) : (0x0D008 + ((_i - 64) * 0x40))) +#define IXGBE_RDH(_i) (((_i) < 64) ? (0x01010 + ((_i) * 0x40)) : (0x0D010 + ((_i - 64) * 0x40))) +#define IXGBE_RDT(_i) (((_i) < 64) ? (0x01018 + ((_i) * 0x40)) : (0x0D018 + ((_i - 64) * 0x40))) +#define IXGBE_RXDCTL(_i) (((_i) < 64) ? (0x01028 + ((_i) * 0x40)) : (0x0D028 + ((_i - 64) * 0x40))) +/* + * Split and Replication Receive Control Registers + * 00-15 : 0x02100 + n*4 + * 16-64 : 0x01014 + n*0x40 + * 64-127: 0x0D014 + (n-64)*0x40 + */ +#define IXGBE_SRRCTL(_i) (((_i) <= 15) ? (0x02100 + ((_i) * 4)) : \ + (((_i) < 64) ? (0x01014 + ((_i) * 0x40)) : \ + (0x0D014 + ((_i - 64) * 0x40)))) +/* + * Rx DCA Control Register: + * 00-15 : 0x02200 + n*4 + * 16-64 : 0x0100C + n*0x40 + * 64-127: 0x0D00C + (n-64)*0x40 + */ +#define IXGBE_DCA_RXCTRL(_i) (((_i) <= 15) ? (0x02200 + ((_i) * 4)) : \ + (((_i) < 64) ? (0x0100C + ((_i) * 0x40)) : \ + (0x0D00C + ((_i - 64) * 0x40)))) +#define IXGBE_RDRXCTL 0x02F00 #define IXGBE_RXPBSIZE(_i) (0x03C00 + ((_i) * 4)) - /* 8 of these 0x03C00 - 0x03C1C */ + /* 8 of these 0x03C00 - 0x03C1C */ #define IXGBE_RXCTRL 0x03000 #define IXGBE_DROPEN 0x03D04 #define IXGBE_RXPBSIZE_SHIFT 10 @@ -107,29 +119,32 @@ /* Receive Registers */ #define IXGBE_RXCSUM 0x05000 #define IXGBE_RFCTL 0x05008 +#define IXGBE_DRECCCTL 0x02F08 +#define IXGBE_DRECCCTL_DISABLE 0 +/* Multicast Table Array - 128 entries */ #define IXGBE_MTA(_i) (0x05200 + ((_i) * 4)) - /* Multicast Table Array - 128 entries */ -#define IXGBE_RAL(_i) (0x05400 + ((_i) * 8)) /* 16 of these (0-15) */ -#define IXGBE_RAH(_i) (0x05404 + ((_i) * 8)) /* 16 of these (0-15) */ -#define IXGBE_PSRTYPE 0x05480 - /* 0x5480-0x54BC Packet split receive type */ +#define IXGBE_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : (0x0A200 + ((_i) * 8))) +#define IXGBE_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : (0x0A204 + ((_i) * 8))) +/* Packet split receive type */ +#define IXGBE_PSRTYPE(_i) (((_i) <= 15) ? (0x05480 + ((_i) * 4)) : (0x0EA00 + ((_i) * 4))) +/* array of 4096 1-bit vlan filters */ #define IXGBE_VFTA(_i) (0x0A000 + ((_i) * 4)) - /* array of 4096 1-bit vlan filters */ +/*array of 4096 4-bit vlan vmdq indices */ #define IXGBE_VFTAVIND(_j, _i) (0x0A200 + ((_j) * 0x200) + ((_i) * 4)) - /*array of 4096 4-bit vlan vmdq indicies */ #define IXGBE_FCTRL 0x05080 #define IXGBE_VLNCTRL 0x05088 #define IXGBE_MCSTCTRL 0x05090 #define IXGBE_MRQC 0x05818 -#define IXGBE_VMD_CTL 0x0581C #define IXGBE_IMIR(_i) (0x05A80 + ((_i) * 4)) /* 8 of these (0-7) */ #define IXGBE_IMIREXT(_i) (0x05AA0 + ((_i) * 4)) /* 8 of these (0-7) */ #define IXGBE_IMIRVP 0x05AC0 +#define IXGBE_VMD_CTL 0x0581C #define IXGBE_RETA(_i) (0x05C00 + ((_i) * 4)) /* 32 of these (0-31) */ #define IXGBE_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* 10 of these (0-9) */ + /* Transmit DMA registers */ -#define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40))/* 32 of these (0-31)*/ +#define IXGBE_TDBAL(_i) (0x06000 + ((_i) * 0x40)) /* 32 of these (0-31)*/ #define IXGBE_TDBAH(_i) (0x06004 + ((_i) * 0x40)) #define IXGBE_TDLEN(_i) (0x06008 + ((_i) * 0x40)) #define IXGBE_TDH(_i) (0x06010 + ((_i) * 0x40)) @@ -138,11 +153,10 @@ #define IXGBE_TDWBAL(_i) (0x06038 + ((_i) * 0x40)) #define IXGBE_TDWBAH(_i) (0x0603C + ((_i) * 0x40)) #define IXGBE_DTXCTL 0x07E00 -#define IXGBE_DCA_TXCTRL(_i) (0x07200 + ((_i) * 4)) - /* there are 16 of these (0-15) */ + +#define IXGBE_DCA_TXCTRL(_i) (0x07200 + ((_i) * 4)) /* 16 of these (0-15) */ #define IXGBE_TIPG 0x0CB00 -#define IXGBE_TXPBSIZE(_i) (0x0CC00 + ((_i) *0x04)) - /* there are 8 of these */ +#define IXGBE_TXPBSIZE(_i) (0x0CC00 + ((_i) * 4)) /* 8 of these */ #define IXGBE_MNGTXMAP 0x0CD10 #define IXGBE_TIPG_FIBER_DEFAULT 3 #define IXGBE_TXPBSIZE_SHIFT 10 @@ -154,6 +168,7 @@ #define IXGBE_IPAV 0x05838 #define IXGBE_IP4AT 0x05840 /* IPv4 table 0x5840-0x5858 */ #define IXGBE_IP6AT 0x05880 /* IPv6 table 0x5880-0x588F */ + #define IXGBE_WUPL 0x05900 #define IXGBE_WUPM 0x05A00 /* wake up pkt memory 0x5A00-0x5A7C */ #define IXGBE_FHFT 0x09000 /* Flex host filter table 9000-93FC */ @@ -170,6 +185,8 @@ #define IXGBE_TDPT2TCCR(_i) (0x0CD20 + ((_i) * 4)) /* 8 of these (0-7) */ #define IXGBE_TDPT2TCSR(_i) (0x0CD40 + ((_i) * 4)) /* 8 of these (0-7) */ + + /* Stats registers */ #define IXGBE_CRCERRS 0x04000 #define IXGBE_ILLERRC 0x04004 @@ -224,7 +241,7 @@ #define IXGBE_XEC 0x04120 #define IXGBE_RQSMR(_i) (0x02300 + ((_i) * 4)) /* 16 of these */ -#define IXGBE_TQSMR(_i) (0x07300 + ((_i) * 4)) /* 8 of these */ +#define IXGBE_TQSMR(_i) (((_i) <= 7) ? (0x07300 + ((_i) * 4)) : (0x08600 + ((_i) * 4))) #define IXGBE_QPRC(_i) (0x01030 + ((_i) * 0x40)) /* 16 of these */ #define IXGBE_QPTC(_i) (0x06030 + ((_i) * 0x40)) /* 16 of these */ @@ -275,23 +292,17 @@ #define IXGBE_DCA_CTRL 0x11074 /* Diagnostic Registers */ -#define IXGBE_RDSTATCTL 0x02C20 -#define IXGBE_RDSTAT(_i) (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */ -#define IXGBE_RDHMPN 0x02F08 -#define IXGBE_RIC_DW0 0x02F10 -#define IXGBE_RIC_DW1 0x02F14 -#define IXGBE_RIC_DW2 0x02F18 -#define IXGBE_RIC_DW3 0x02F1C -#define IXGBE_RDPROBE 0x02F20 -#define IXGBE_TDSTATCTL 0x07C20 -#define IXGBE_TDSTAT(_i) (0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */ -#define IXGBE_TDHMPN 0x07F08 -#define IXGBE_TIC_DW0 0x07F10 -#define IXGBE_TIC_DW1 0x07F14 -#define IXGBE_TIC_DW2 0x07F18 -#define IXGBE_TIC_DW3 0x07F1C -#define IXGBE_TDPROBE 0x07F20 -#define IXGBE_TXBUFCTRL 0x0C600 +#define IXGBE_RDSTATCTL 0x02C20 +#define IXGBE_RDSTAT(_i) (0x02C00 + ((_i) * 4)) /* 0x02C00-0x02C1C */ +#define IXGBE_RDHMPN 0x02F08 +#define IXGBE_RIC_DW(_i) (0x02F10 + ((_i) * 4)) +#define IXGBE_RDPROBE 0x02F20 +#define IXGBE_TDSTATCTL 0x07C20 +#define IXGBE_TDSTAT(_i) (0x07C00 + ((_i) * 4)) /* 0x07C00 - 0x07C1C */ +#define IXGBE_TDHMPN 0x07F08 +#define IXGBE_TIC_DW(_i) (0x07F10 + ((_i) * 4)) +#define IXGBE_TDPROBE 0x07F20 +#define IXGBE_TXBUFCTRL 0x0C600 #define IXGBE_TXBUFDATA0 0x0C610 #define IXGBE_TXBUFDATA1 0x0C614 #define IXGBE_TXBUFDATA2 0x0C618 @@ -392,7 +403,7 @@ #define IXGBE_DCA_TXCTRL_CPUID_MASK 0x0000001F /* Tx CPUID Mask */ #define IXGBE_DCA_TXCTRL_DESC_DCA_EN (1 << 5) /* DCA Tx Desc enable */ -#define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* TX Desc writeback RO bit */ +#define IXGBE_DCA_TXCTRL_TX_WB_RO_EN (1 << 11) /* Tx Desc writeback RO bit */ #define IXGBE_DCA_MAX_QUEUES_82598 16 /* DCA regs only on 16 queues */ /* MSCA Bit Masks */ @@ -416,10 +427,10 @@ #define IXGBE_MSCA_MDI_IN_PROG_EN 0x80000000 /* MDI in progress enable */ /* MSRWD bit masks */ -#define IXGBE_MSRWD_WRITE_DATA_MASK 0x0000FFFF -#define IXGBE_MSRWD_WRITE_DATA_SHIFT 0 -#define IXGBE_MSRWD_READ_DATA_MASK 0xFFFF0000 -#define IXGBE_MSRWD_READ_DATA_SHIFT 16 +#define IXGBE_MSRWD_WRITE_DATA_MASK 0x0000FFFF +#define IXGBE_MSRWD_WRITE_DATA_SHIFT 0 +#define IXGBE_MSRWD_READ_DATA_MASK 0xFFFF0000 +#define IXGBE_MSRWD_READ_DATA_SHIFT 16 /* Atlas registers */ #define IXGBE_ATLAS_PDN_LPBK 0x24 @@ -434,6 +445,7 @@ #define IXGBE_ATLAS_PDN_TX_1G_QL_ALL 0xF0 #define IXGBE_ATLAS_PDN_TX_AN_QL_ALL 0xF0 + /* Device Type definitions for new protocol MDIO commands */ #define IXGBE_MDIO_PMA_PMD_DEV_TYPE 0x1 #define IXGBE_MDIO_PCS_DEV_TYPE 0x3 @@ -441,6 +453,8 @@ #define IXGBE_MDIO_AUTO_NEG_DEV_TYPE 0x7 #define IXGBE_MDIO_VENDOR_SPECIFIC_1_DEV_TYPE 0x1E /* Device 30 */ +#define IXGBE_MDIO_COMMAND_TIMEOUT 100 /* PHY Timeout for 1 GB mode */ + #define IXGBE_MDIO_VENDOR_SPECIFIC_1_CONTROL 0x0 /* VS1 Control Reg */ #define IXGBE_MDIO_VENDOR_SPECIFIC_1_STATUS 0x1 /* VS1 Status Reg */ #define IXGBE_MDIO_VENDOR_SPECIFIC_1_LINK_STATUS 0x0008 /* 1 = Link Up */ @@ -454,23 +468,39 @@ #define IXGBE_MDIO_PHY_XS_RESET 0x8000 /* PHY_XS Reset */ #define IXGBE_MDIO_PHY_ID_HIGH 0x2 /* PHY ID High Reg*/ #define IXGBE_MDIO_PHY_ID_LOW 0x3 /* PHY ID Low Reg*/ -#define IXGBE_MDIO_PHY_SPEED_ABILITY 0x4 /* Speed Abilty Reg */ +#define IXGBE_MDIO_PHY_SPEED_ABILITY 0x4 /* Speed Ability Reg */ #define IXGBE_MDIO_PHY_SPEED_10G 0x0001 /* 10G capable */ #define IXGBE_MDIO_PHY_SPEED_1G 0x0010 /* 1G capable */ +#define IXGBE_MDIO_PMA_PMD_SDA_SCL_ADDR 0xC30A /* PHY_XS SDA/SCL Address Reg */ +#define IXGBE_MDIO_PMA_PMD_SDA_SCL_DATA 0xC30B /* PHY_XS SDA/SCL Data Reg */ +#define IXGBE_MDIO_PMA_PMD_SDA_SCL_STAT 0xC30C /* PHY_XS SDA/SCL Status Reg */ + +/* MII clause 22/28 definitions */ +#define IXGBE_MDIO_PHY_LOW_POWER_MODE 0x0800 + +#define IXGBE_MII_SPEED_SELECTION_REG 0x10 +#define IXGBE_MII_RESTART 0x200 +#define IXGBE_MII_AUTONEG_COMPLETE 0x20 +#define IXGBE_MII_AUTONEG_REG 0x0 + #define IXGBE_PHY_REVISION_MASK 0xFFFFFFF0 #define IXGBE_MAX_PHY_ADDR 32 /* PHY IDs*/ -#define TN1010_PHY_ID 0x00A19410 #define QT2022_PHY_ID 0x0043A400 +/* PHY Types */ +#define IXGBE_M88E1145_E_PHY_ID 0x01410CD0 + /* General purpose Interrupt Enable */ -#define IXGBE_GPIE_MSIX_MODE 0x00000010 /* MSI-X mode */ -#define IXGBE_GPIE_OCD 0x00000020 /* Other Clear Disable */ -#define IXGBE_GPIE_EIMEN 0x00000040 /* Immediate Interrupt Enable */ -#define IXGBE_GPIE_EIAME 0x40000000 -#define IXGBE_GPIE_PBA_SUPPORT 0x80000000 +#define IXGBE_SDP0_GPIEN 0x00000001 /* SDP0 */ +#define IXGBE_SDP1_GPIEN 0x00000002 /* SDP1 */ +#define IXGBE_GPIE_MSIX_MODE 0x00000010 /* MSI-X mode */ +#define IXGBE_GPIE_OCD 0x00000020 /* Other Clear Disable */ +#define IXGBE_GPIE_EIMEN 0x00000040 /* Immediate Interrupt Enable */ +#define IXGBE_GPIE_EIAME 0x40000000 +#define IXGBE_GPIE_PBA_SUPPORT 0x80000000 /* Transmit Flow Control status */ #define IXGBE_TFCS_TXOFF 0x00000001 @@ -531,7 +561,7 @@ #define IXGBE_PAP_TXPAUSECNT_MASK 0x0000FFFF /* Pause counter mask */ /* RMCS Bit Masks */ -#define IXGBE_RMCS_RRM 0x00000002 /* Receive Recylce Mode enable */ +#define IXGBE_RMCS_RRM 0x00000002 /* Receive Recycle Mode enable */ /* Receive Arbitration Control: 0 Round Robin, 1 DFP */ #define IXGBE_RMCS_RAC 0x00000004 #define IXGBE_RMCS_DFP IXGBE_RMCS_RAC /* Deficit Fixed Priority ena */ @@ -539,12 +569,15 @@ #define IXGBE_RMCS_TFCE_PRIORITY 0x00000010 /* Tx Priority flow control ena */ #define IXGBE_RMCS_ARBDIS 0x00000040 /* Arbitration disable bit */ + /* Interrupt register bitmasks */ /* Extended Interrupt Cause Read */ #define IXGBE_EICR_RTX_QUEUE 0x0000FFFF /* RTx Queue Interrupt */ #define IXGBE_EICR_LSC 0x00100000 /* Link Status Change */ -#define IXGBE_EICR_MNG 0x00400000 /* Managability Event Interrupt */ +#define IXGBE_EICR_MNG 0x00400000 /* Manageability Event Interrupt */ +#define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */ +#define IXGBE_EICR_GPI_SDP1 0x02000000 /* Gen Purpose Interrupt on SDP1 */ #define IXGBE_EICR_PBUR 0x10000000 /* Packet Buffer Handler Error */ #define IXGBE_EICR_DHER 0x20000000 /* Descriptor Handler Error */ #define IXGBE_EICR_TCP_TIMER 0x40000000 /* TCP Timer */ @@ -552,11 +585,12 @@ /* Extended Interrupt Cause Set */ #define IXGBE_EICS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */ -#define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */ -#define IXGBE_EICR_GPI_SDP0 0x01000000 /* Gen Purpose Interrupt on SDP0 */ -#define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ -#define IXGBE_EICS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Error */ -#define IXGBE_EICS_DHER IXGBE_EICR_DHER /* Desc Handler Error */ +#define IXGBE_EICS_LSC IXGBE_EICR_LSC /* Link Status Change */ +#define IXGBE_EICS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ +#define IXGBE_EICS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ +#define IXGBE_EICS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ +#define IXGBE_EICS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */ +#define IXGBE_EICS_DHER IXGBE_EICR_DHER /* Desc Handler Error */ #define IXGBE_EICS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */ #define IXGBE_EICS_OTHER IXGBE_EICR_OTHER /* INT Cause Active */ @@ -564,7 +598,9 @@ #define IXGBE_EIMS_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */ #define IXGBE_EIMS_LSC IXGBE_EICR_LSC /* Link Status Change */ #define IXGBE_EIMS_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ -#define IXGBE_EIMS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Error */ +#define IXGBE_EIMS_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ +#define IXGBE_EIMS_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ +#define IXGBE_EIMS_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */ #define IXGBE_EIMS_DHER IXGBE_EICR_DHER /* Descr Handler Error */ #define IXGBE_EIMS_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */ #define IXGBE_EIMS_OTHER IXGBE_EICR_OTHER /* INT Cause Active */ @@ -573,18 +609,20 @@ #define IXGBE_EIMC_RTX_QUEUE IXGBE_EICR_RTX_QUEUE /* RTx Queue Interrupt */ #define IXGBE_EIMC_LSC IXGBE_EICR_LSC /* Link Status Change */ #define IXGBE_EIMC_MNG IXGBE_EICR_MNG /* MNG Event Interrupt */ -#define IXGBE_EIMC_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Error */ -#define IXGBE_EIMC_DHER IXGBE_EICR_DHER /* Desc Handler Error */ +#define IXGBE_EIMC_GPI_SDP0 IXGBE_EICR_GPI_SDP0 /* SDP0 Gen Purpose Int */ +#define IXGBE_EIMC_GPI_SDP1 IXGBE_EICR_GPI_SDP1 /* SDP1 Gen Purpose Int */ +#define IXGBE_EIMC_PBUR IXGBE_EICR_PBUR /* Pkt Buf Handler Err */ +#define IXGBE_EIMC_DHER IXGBE_EICR_DHER /* Desc Handler Err */ #define IXGBE_EIMC_TCP_TIMER IXGBE_EICR_TCP_TIMER /* TCP Timer */ #define IXGBE_EIMC_OTHER IXGBE_EICR_OTHER /* INT Cause Active */ -#define IXGBE_EIMS_ENABLE_MASK (\ - IXGBE_EIMS_RTX_QUEUE | \ - IXGBE_EIMS_LSC | \ - IXGBE_EIMS_TCP_TIMER | \ - IXGBE_EIMS_OTHER) +#define IXGBE_EIMS_ENABLE_MASK ( \ + IXGBE_EIMS_RTX_QUEUE | \ + IXGBE_EIMS_LSC | \ + IXGBE_EIMS_TCP_TIMER | \ + IXGBE_EIMS_OTHER) -/* Immediate Interrupt RX (A.K.A. Low Latency Interrupt) */ +/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */ #define IXGBE_IMIR_PORT_IM_EN 0x00010000 /* TCP port enable */ #define IXGBE_IMIR_PORT_BP 0x00020000 /* TCP port check bypass */ #define IXGBE_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */ @@ -621,6 +659,7 @@ #define IXGBE_VLNCTRL_VFE 0x40000000 /* bit 30 */ #define IXGBE_VLNCTRL_VME 0x80000000 /* bit 31 */ + #define IXGBE_ETHERNET_IEEE_VLAN_TYPE 0x8100 /* 802.1q protocol */ /* STATUS Bit Masks */ @@ -668,16 +707,16 @@ #define IXGBE_AUTOC_AN_RESTART 0x00001000 #define IXGBE_AUTOC_FLU 0x00000001 #define IXGBE_AUTOC_LMS_SHIFT 13 -#define IXGBE_AUTOC_LMS_MASK (0x7 << IXGBE_AUTOC_LMS_SHIFT) -#define IXGBE_AUTOC_LMS_1G_LINK_NO_AN (0x0 << IXGBE_AUTOC_LMS_SHIFT) -#define IXGBE_AUTOC_LMS_10G_LINK_NO_AN (0x1 << IXGBE_AUTOC_LMS_SHIFT) -#define IXGBE_AUTOC_LMS_1G_AN (0x2 << IXGBE_AUTOC_LMS_SHIFT) -#define IXGBE_AUTOC_LMS_KX4_AN (0x4 << IXGBE_AUTOC_LMS_SHIFT) -#define IXGBE_AUTOC_LMS_KX4_AN_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT) -#define IXGBE_AUTOC_LMS_ATTACH_TYPE (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT) - -#define IXGBE_AUTOC_1G_PMA_PMD 0x00000200 -#define IXGBE_AUTOC_10G_PMA_PMD 0x00000180 +#define IXGBE_AUTOC_LMS_MASK (0x7 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_1G_LINK_NO_AN (0x0 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_10G_LINK_NO_AN (0x1 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_1G_AN (0x2 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_KX4_AN (0x4 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_KX4_AN_1G_AN (0x6 << IXGBE_AUTOC_LMS_SHIFT) +#define IXGBE_AUTOC_LMS_ATTACH_TYPE (0x7 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT) + +#define IXGBE_AUTOC_1G_PMA_PMD 0x00000200 +#define IXGBE_AUTOC_10G_PMA_PMD 0x00000180 #define IXGBE_AUTOC_10G_PMA_PMD_SHIFT 7 #define IXGBE_AUTOC_1G_PMA_PMD_SHIFT 9 #define IXGBE_AUTOC_10G_XAUI (0x0 << IXGBE_AUTOC_10G_PMA_PMD_SHIFT) @@ -703,6 +742,7 @@ #define IXGBE_LINKS_TL_FAULT 0x00001000 #define IXGBE_LINKS_SIGNAL 0x00000F00 +#define IXGBE_LINK_UP_TIME 90 /* 9.0 Seconds */ #define IXGBE_AUTO_NEG_TIME 45 /* 4.5 Seconds */ /* SW Semaphore Register bitmasks */ @@ -757,6 +797,11 @@ #define IXGBE_PBANUM0_PTR 0x15 #define IXGBE_PBANUM1_PTR 0x16 +/* Legacy EEPROM word offsets */ +#define IXGBE_ISCSI_BOOT_CAPS 0x0033 +#define IXGBE_ISCSI_SETUP_PORT_0 0x0030 +#define IXGBE_ISCSI_SETUP_PORT_1 0x0034 + /* EEPROM Commands - SPI */ #define IXGBE_EEPROM_MAX_RETRY_SPI 5000 /* Max wait 5ms for RDY signal */ #define IXGBE_EEPROM_STATUS_RDY_SPI 0x01 @@ -764,7 +809,7 @@ #define IXGBE_EEPROM_WRITE_OPCODE_SPI 0x02 /* EEPROM write opcode */ #define IXGBE_EEPROM_A8_OPCODE_SPI 0x08 /* opcode bit-3 = addr bit-8 */ #define IXGBE_EEPROM_WREN_OPCODE_SPI 0x06 /* EEPROM set Write Ena latch */ -/* EEPROM reset Write Enbale latch */ +/* EEPROM reset Write Enable latch */ #define IXGBE_EEPROM_WRDI_OPCODE_SPI 0x04 #define IXGBE_EEPROM_RDSR_OPCODE_SPI 0x05 /* EEPROM read Status reg */ #define IXGBE_EEPROM_WRSR_OPCODE_SPI 0x01 /* EEPROM write Status reg */ @@ -803,22 +848,20 @@ /* Number of 100 microseconds we wait for PCI Express master disable */ #define IXGBE_PCI_MASTER_DISABLE_TIMEOUT 800 -/* PHY Types */ -#define IXGBE_M88E1145_E_PHY_ID 0x01410CD0 - /* Check whether address is multicast. This is little-endian specific check.*/ #define IXGBE_IS_MULTICAST(Address) \ - (bool)(((u8 *)(Address))[0] & ((u8)0x01)) + (bool)(((u8 *)(Address))[0] & ((u8)0x01)) /* Check whether an address is broadcast. */ #define IXGBE_IS_BROADCAST(Address) \ - ((((u8 *)(Address))[0] == ((u8)0xff)) && \ - (((u8 *)(Address))[1] == ((u8)0xff))) + ((((u8 *)(Address))[0] == ((u8)0xff)) && \ + (((u8 *)(Address))[1] == ((u8)0xff))) /* RAH */ #define IXGBE_RAH_VIND_MASK 0x003C0000 #define IXGBE_RAH_VIND_SHIFT 18 #define IXGBE_RAH_AV 0x80000000 +#define IXGBE_CLEAR_VMDQ_ALL 0xFFFFFFFF /* Header split receive */ #define IXGBE_RFCTL_ISCSI_DIS 0x00000001 @@ -847,7 +890,7 @@ #define IXGBE_MAX_FRAME_SZ 0x40040000 #define IXGBE_TDWBAL_HEAD_WB_ENABLE 0x1 /* Tx head write-back enable */ -#define IXGBE_TDWBAL_SEQNUM_WB_ENABLE 0x2 /* Tx seq. # write-back enable */ +#define IXGBE_TDWBAL_SEQNUM_WB_ENABLE 0x2 /* Tx seq# write-back enable */ /* Receive Config masks */ #define IXGBE_RXCTRL_RXEN 0x00000001 /* Enable Receiver */ @@ -860,7 +903,7 @@ #define IXGBE_FCTRL_BAM 0x00000400 /* Broadcast Accept Mode */ #define IXGBE_FCTRL_PMCF 0x00001000 /* Pass MAC Control Frames */ #define IXGBE_FCTRL_DPF 0x00002000 /* Discard Pause Frame */ -/* Receive Priority Flow Control Enbale */ +/* Receive Priority Flow Control Enable */ #define IXGBE_FCTRL_RPFCE 0x00004000 #define IXGBE_FCTRL_RFCE 0x00008000 /* Receive Flow Control Ena */ @@ -890,9 +933,8 @@ /* Receive Descriptor bit definitions */ #define IXGBE_RXD_STAT_DD 0x01 /* Descriptor Done */ #define IXGBE_RXD_STAT_EOP 0x02 /* End of Packet */ -#define IXGBE_RXD_STAT_IXSM 0x04 /* Ignore checksum */ #define IXGBE_RXD_STAT_VP 0x08 /* IEEE VLAN Packet */ -#define IXGBE_RXD_STAT_UDPCS 0x10 /* UDP xsum caculated */ +#define IXGBE_RXD_STAT_UDPCS 0x10 /* UDP xsum calculated */ #define IXGBE_RXD_STAT_L4CS 0x20 /* L4 xsum calculated */ #define IXGBE_RXD_STAT_IPCS 0x40 /* IP xsum calculated */ #define IXGBE_RXD_STAT_PIF 0x80 /* passed in-exact filter */ @@ -908,7 +950,7 @@ #define IXGBE_RXD_ERR_USE 0x20 /* Undersize Error */ #define IXGBE_RXD_ERR_TCPE 0x40 /* TCP/UDP Checksum Error */ #define IXGBE_RXD_ERR_IPE 0x80 /* IP Checksum Error */ -#define IXGBE_RXDADV_HBO 0x00800000 +#define IXGBE_RXDADV_ERR_HBO 0x00800000 /*Header Buffer Overflow */ #define IXGBE_RXDADV_ERR_CE 0x01000000 /* CRC Error */ #define IXGBE_RXDADV_ERR_LE 0x02000000 /* Length Error */ #define IXGBE_RXDADV_ERR_PE 0x08000000 /* Packet Error */ @@ -922,15 +964,17 @@ #define IXGBE_RXD_CFI_MASK 0x1000 /* CFI is bit 12 */ #define IXGBE_RXD_CFI_SHIFT 12 + /* SRRCTL bit definitions */ -#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */ -#define IXGBE_SRRCTL_BSIZEPKT_MASK 0x0000007F -#define IXGBE_SRRCTL_BSIZEHDR_MASK 0x00003F00 -#define IXGBE_SRRCTL_DESCTYPE_LEGACY 0x00000000 +#define IXGBE_SRRCTL_BSIZEPKT_SHIFT 10 /* so many KBs */ +#define IXGBE_SRRCTL_BSIZEPKT_MASK 0x0000007F +#define IXGBE_SRRCTL_BSIZEHDR_MASK 0x00003F00 +#define IXGBE_SRRCTL_DESCTYPE_LEGACY 0x00000000 #define IXGBE_SRRCTL_DESCTYPE_ADV_ONEBUF 0x02000000 #define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT 0x04000000 #define IXGBE_SRRCTL_DESCTYPE_HDR_REPLICATION_LARGE_PKT 0x08000000 #define IXGBE_SRRCTL_DESCTYPE_HDR_SPLIT_ALWAYS 0x0A000000 +#define IXGBE_SRRCTL_DESCTYPE_MASK 0x0E000000 #define IXGBE_RXDPS_HDRSTAT_HDRSP 0x00008000 #define IXGBE_RXDPS_HDRSTAT_HDRLEN_MASK 0x000003FF @@ -964,21 +1008,20 @@ #define IXGBE_RXDADV_PKTTYPE_UDP 0x00000200 /* UDP hdr present */ #define IXGBE_RXDADV_PKTTYPE_SCTP 0x00000400 /* SCTP hdr present */ #define IXGBE_RXDADV_PKTTYPE_NFS 0x00000800 /* NFS hdr present */ - /* Masks to determine if packets should be dropped due to frame errors */ -#define IXGBE_RXD_ERR_FRAME_ERR_MASK (\ - IXGBE_RXD_ERR_CE | \ - IXGBE_RXD_ERR_LE | \ - IXGBE_RXD_ERR_PE | \ - IXGBE_RXD_ERR_OSE | \ - IXGBE_RXD_ERR_USE) - -#define IXGBE_RXDADV_ERR_FRAME_ERR_MASK (\ - IXGBE_RXDADV_ERR_CE | \ - IXGBE_RXDADV_ERR_LE | \ - IXGBE_RXDADV_ERR_PE | \ - IXGBE_RXDADV_ERR_OSE | \ - IXGBE_RXDADV_ERR_USE) +#define IXGBE_RXD_ERR_FRAME_ERR_MASK ( \ + IXGBE_RXD_ERR_CE | \ + IXGBE_RXD_ERR_LE | \ + IXGBE_RXD_ERR_PE | \ + IXGBE_RXD_ERR_OSE | \ + IXGBE_RXD_ERR_USE) + +#define IXGBE_RXDADV_ERR_FRAME_ERR_MASK ( \ + IXGBE_RXDADV_ERR_CE | \ + IXGBE_RXDADV_ERR_LE | \ + IXGBE_RXDADV_ERR_PE | \ + IXGBE_RXDADV_ERR_OSE | \ + IXGBE_RXDADV_ERR_USE) /* Multicast bit mask */ #define IXGBE_MCSTCTRL_MFE 0x4 @@ -994,6 +1037,7 @@ #define IXGBE_RX_DESC_SPECIAL_PRI_SHIFT 0x000D /* Priority in upper 3 of 16 */ #define IXGBE_TX_DESC_SPECIAL_PRI_SHIFT IXGBE_RX_DESC_SPECIAL_PRI_SHIFT + /* Transmit Descriptor - Legacy */ struct ixgbe_legacy_tx_desc { u64 buffer_addr; /* Address of the descriptor's data buffer */ @@ -1008,8 +1052,8 @@ struct ixgbe_legacy_tx_desc { union { __le32 data; struct { - u8 status; /* Descriptor status */ - u8 css; /* Checksum start */ + u8 status; /* Descriptor status */ + u8 css; /* Checksum start */ __le16 vlan; } fields; } upper; @@ -1018,7 +1062,7 @@ struct ixgbe_legacy_tx_desc { /* Transmit Descriptor - Advanced */ union ixgbe_adv_tx_desc { struct { - __le64 buffer_addr; /* Address of descriptor's data buf */ + __le64 buffer_addr; /* Address of descriptor's data buf */ __le32 cmd_type_len; __le32 olinfo_status; } read; @@ -1050,8 +1094,8 @@ union ixgbe_adv_rx_desc { union { __le32 data; struct { - __le16 pkt_info; /* RSS type, Packet type */ - __le16 hdr_info; /* Split Header, header len */ + __le16 pkt_info; /* RSS, Pkt type */ + __le16 hdr_info; /* Splithdr, hdrlen */ } hs_rss; } lo_dword; union { @@ -1079,49 +1123,69 @@ struct ixgbe_adv_tx_context_desc { }; /* Adv Transmit Descriptor Config Masks */ -#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buffer length(bytes) */ +#define IXGBE_ADVTXD_DTALEN_MASK 0x0000FFFF /* Data buf length(bytes) */ #define IXGBE_ADVTXD_DTYP_MASK 0x00F00000 /* DTYP mask */ #define IXGBE_ADVTXD_DTYP_CTXT 0x00200000 /* Advanced Context Desc */ #define IXGBE_ADVTXD_DTYP_DATA 0x00300000 /* Advanced Data Descriptor */ #define IXGBE_ADVTXD_DCMD_EOP IXGBE_TXD_CMD_EOP /* End of Packet */ #define IXGBE_ADVTXD_DCMD_IFCS IXGBE_TXD_CMD_IFCS /* Insert FCS */ -#define IXGBE_ADVTXD_DCMD_RDMA 0x04000000 /* RDMA */ #define IXGBE_ADVTXD_DCMD_RS IXGBE_TXD_CMD_RS /* Report Status */ -#define IXGBE_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */ +#define IXGBE_ADVTXD_DCMD_DDTYP_ISCSI 0x10000000 /* DDP hdr type or iSCSI */ #define IXGBE_ADVTXD_DCMD_DEXT IXGBE_TXD_CMD_DEXT /* Desc ext (1=Adv) */ #define IXGBE_ADVTXD_DCMD_VLE IXGBE_TXD_CMD_VLE /* VLAN pkt enable */ #define IXGBE_ADVTXD_DCMD_TSE 0x80000000 /* TCP Seg enable */ #define IXGBE_ADVTXD_STAT_DD IXGBE_TXD_STAT_DD /* Descriptor Done */ -#define IXGBE_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED present in WB */ +#define IXGBE_ADVTXD_STAT_SN_CRC 0x00000002 /* NXTSEQ/SEED pres in WB */ #define IXGBE_ADVTXD_STAT_RSV 0x0000000C /* STA Reserved */ #define IXGBE_ADVTXD_IDX_SHIFT 4 /* Adv desc Index shift */ +#define IXGBE_ADVTXD_CC 0x00000080 /* Check Context */ #define IXGBE_ADVTXD_POPTS_SHIFT 8 /* Adv desc POPTS shift */ #define IXGBE_ADVTXD_POPTS_IXSM (IXGBE_TXD_POPTS_IXSM << \ - IXGBE_ADVTXD_POPTS_SHIFT) + IXGBE_ADVTXD_POPTS_SHIFT) #define IXGBE_ADVTXD_POPTS_TXSM (IXGBE_TXD_POPTS_TXSM << \ - IXGBE_ADVTXD_POPTS_SHIFT) -#define IXGBE_ADVTXD_POPTS_EOM 0x00000400 /* Enable L bit-RDMA DDP hdr */ -#define IXGBE_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */ -#define IXGBE_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */ -#define IXGBE_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */ -#define IXGBE_ADVTXD_POPTS_ISCO_FULL 0x00001800 /* 1st&Last TSO-full iSCSI PDU*/ -#define IXGBE_ADVTXD_POPTS_RSV 0x00002000 /* POPTS Reserved */ -#define IXGBE_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */ -#define IXGBE_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */ -#define IXGBE_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */ -#define IXGBE_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */ -#define IXGBE_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */ -#define IXGBE_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */ -#define IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ -#define IXGBE_ADVTXD_TUCMD_MKRREQ 0x00002000 /* Req requires Markers and CRC */ -#define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */ -#define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */ - + IXGBE_ADVTXD_POPTS_SHIFT) +#define IXGBE_ADVTXD_POPTS_ISCO_1ST 0x00000000 /* 1st TSO of iSCSI PDU */ +#define IXGBE_ADVTXD_POPTS_ISCO_MDL 0x00000800 /* Middle TSO of iSCSI PDU */ +#define IXGBE_ADVTXD_POPTS_ISCO_LAST 0x00001000 /* Last TSO of iSCSI PDU */ +#define IXGBE_ADVTXD_POPTS_ISCO_FULL 0x00001800 /* 1st&Last TSO-full iSCSI PDU */ +#define IXGBE_ADVTXD_POPTS_RSV 0x00002000 /* POPTS Reserved */ +#define IXGBE_ADVTXD_PAYLEN_SHIFT 14 /* Adv desc PAYLEN shift */ +#define IXGBE_ADVTXD_MACLEN_SHIFT 9 /* Adv ctxt desc mac len shift */ +#define IXGBE_ADVTXD_VLAN_SHIFT 16 /* Adv ctxt vlan tag shift */ +#define IXGBE_ADVTXD_TUCMD_IPV4 0x00000400 /* IP Packet Type: 1=IPv4 */ +#define IXGBE_ADVTXD_TUCMD_IPV6 0x00000000 /* IP Packet Type: 0=IPv6 */ +#define IXGBE_ADVTXD_TUCMD_L4T_UDP 0x00000000 /* L4 Packet TYPE of UDP */ +#define IXGBE_ADVTXD_TUCMD_L4T_TCP 0x00000800 /* L4 Packet TYPE of TCP */ +#define IXGBE_ADVTXD_TUCMD_L4T_SCTP 0x00001000 /* L4 Packet TYPE of SCTP */ +#define IXGBE_ADVTXD_TUCMD_MKRREQ 0x00002000 /*Req requires Markers and CRC*/ +#define IXGBE_ADVTXD_L4LEN_SHIFT 8 /* Adv ctxt L4LEN shift */ +#define IXGBE_ADVTXD_MSS_SHIFT 16 /* Adv ctxt MSS shift */ + +/* Autonegotiation advertised speeds */ +typedef u32 ixgbe_autoneg_advertised; /* Link speed */ +typedef u32 ixgbe_link_speed; #define IXGBE_LINK_SPEED_UNKNOWN 0 #define IXGBE_LINK_SPEED_100_FULL 0x0008 #define IXGBE_LINK_SPEED_1GB_FULL 0x0020 #define IXGBE_LINK_SPEED_10GB_FULL 0x0080 +#define IXGBE_LINK_SPEED_82598_AUTONEG (IXGBE_LINK_SPEED_1GB_FULL | \ + IXGBE_LINK_SPEED_10GB_FULL) + +/* Physical layer type */ +typedef u32 ixgbe_physical_layer; +#define IXGBE_PHYSICAL_LAYER_UNKNOWN 0 +#define IXGBE_PHYSICAL_LAYER_10GBASE_T 0x0001 +#define IXGBE_PHYSICAL_LAYER_1000BASE_T 0x0002 +#define IXGBE_PHYSICAL_LAYER_100BASE_T 0x0004 +#define IXGBE_PHYSICAL_LAYER_SFP_PLUS_CU 0x0008 +#define IXGBE_PHYSICAL_LAYER_10GBASE_LR 0x0010 +#define IXGBE_PHYSICAL_LAYER_10GBASE_LRM 0x0020 +#define IXGBE_PHYSICAL_LAYER_10GBASE_SR 0x0040 +#define IXGBE_PHYSICAL_LAYER_10GBASE_KX4 0x0080 +#define IXGBE_PHYSICAL_LAYER_10GBASE_CX4 0x0100 +#define IXGBE_PHYSICAL_LAYER_1000BASE_KX 0x0200 +#define IXGBE_PHYSICAL_LAYER_1000BASE_BX 0x0400 enum ixgbe_eeprom_type { @@ -1138,16 +1202,38 @@ enum ixgbe_mac_type { enum ixgbe_phy_type { ixgbe_phy_unknown = 0, - ixgbe_phy_tn, ixgbe_phy_qt, - ixgbe_phy_xaui + ixgbe_phy_xaui, + ixgbe_phy_tw_tyco, + ixgbe_phy_tw_unknown, + ixgbe_phy_sfp_avago, + ixgbe_phy_sfp_ftl, + ixgbe_phy_sfp_unknown, + ixgbe_phy_generic +}; + +/* + * SFP+ module type IDs: + * + * ID Module Type + * ============= + * 0 SFP_DA_CU + * 1 SFP_SR + * 2 SFP_LR + */ +enum ixgbe_sfp_type { + ixgbe_sfp_type_da_cu = 0, + ixgbe_sfp_type_sr = 1, + ixgbe_sfp_type_lr = 2, + ixgbe_sfp_type_unknown = 0xFFFF }; enum ixgbe_media_type { ixgbe_media_type_unknown = 0, ixgbe_media_type_fiber, ixgbe_media_type_copper, - ixgbe_media_type_backplane + ixgbe_media_type_backplane, + ixgbe_media_type_virtual }; /* Flow Control Settings */ @@ -1245,59 +1331,114 @@ struct ixgbe_hw; typedef u8* (*ixgbe_mc_addr_itr) (struct ixgbe_hw *hw, u8 **mc_addr_ptr, u32 *vmdq); +/* Function pointer table */ +struct ixgbe_eeprom_operations { + s32 (*init_params)(struct ixgbe_hw *); + s32 (*read)(struct ixgbe_hw *, u16, u16 *); + s32 (*write)(struct ixgbe_hw *, u16, u16); + s32 (*validate_checksum)(struct ixgbe_hw *, u16 *); + s32 (*update_checksum)(struct ixgbe_hw *); +}; + struct ixgbe_mac_operations { - s32 (*reset)(struct ixgbe_hw *); + s32 (*init_hw)(struct ixgbe_hw *); + s32 (*reset_hw)(struct ixgbe_hw *); + s32 (*start_hw)(struct ixgbe_hw *); + s32 (*clear_hw_cntrs)(struct ixgbe_hw *); enum ixgbe_media_type (*get_media_type)(struct ixgbe_hw *); + s32 (*get_supported_physical_layer)(struct ixgbe_hw *); + s32 (*get_mac_addr)(struct ixgbe_hw *, u8 *); + s32 (*stop_adapter)(struct ixgbe_hw *); + s32 (*get_bus_info)(struct ixgbe_hw *); + s32 (*read_analog_reg8)(struct ixgbe_hw*, u32, u8*); + s32 (*write_analog_reg8)(struct ixgbe_hw*, u32, u8); + + /* Link */ s32 (*setup_link)(struct ixgbe_hw *); - s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *); - s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool); - s32 (*get_link_settings)(struct ixgbe_hw *, u32 *, bool *); + s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool, + bool); + s32 (*check_link)(struct ixgbe_hw *, ixgbe_link_speed *, bool *, bool); + s32 (*get_link_capabilities)(struct ixgbe_hw *, ixgbe_link_speed *, + bool *); + + /* LED */ + s32 (*led_on)(struct ixgbe_hw *, u32); + s32 (*led_off)(struct ixgbe_hw *, u32); + s32 (*blink_led_start)(struct ixgbe_hw *, u32); + s32 (*blink_led_stop)(struct ixgbe_hw *, u32); + + /* RAR, Multicast, VLAN */ + s32 (*set_rar)(struct ixgbe_hw *, u32, u8 *, u32, u32); + s32 (*clear_rar)(struct ixgbe_hw *, u32); + s32 (*set_vmdq)(struct ixgbe_hw *, u32, u32); + s32 (*clear_vmdq)(struct ixgbe_hw *, u32, u32); + s32 (*init_rx_addrs)(struct ixgbe_hw *); + s32 (*update_uc_addr_list)(struct ixgbe_hw *, u8 *, u32, + ixgbe_mc_addr_itr); + s32 (*update_mc_addr_list)(struct ixgbe_hw *, u8 *, u32, + ixgbe_mc_addr_itr); + s32 (*enable_mc)(struct ixgbe_hw *); + s32 (*disable_mc)(struct ixgbe_hw *); + s32 (*clear_vfta)(struct ixgbe_hw *); + s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool); + s32 (*init_uta_tables)(struct ixgbe_hw *); + + /* Flow Control */ + s32 (*setup_fc)(struct ixgbe_hw *, s32); }; struct ixgbe_phy_operations { + s32 (*identify)(struct ixgbe_hw *); + s32 (*identify_sfp)(struct ixgbe_hw *); + s32 (*reset)(struct ixgbe_hw *); + s32 (*read_reg)(struct ixgbe_hw *, u32, u32, u16 *); + s32 (*write_reg)(struct ixgbe_hw *, u32, u32, u16); s32 (*setup_link)(struct ixgbe_hw *); - s32 (*check_link)(struct ixgbe_hw *, u32 *, bool *); - s32 (*setup_link_speed)(struct ixgbe_hw *, u32, bool, bool); -}; - -struct ixgbe_mac_info { - struct ixgbe_mac_operations ops; - enum ixgbe_mac_type type; - u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; - u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; - s32 mc_filter_type; - u32 mcft_size; - u32 vft_size; - u32 num_rar_entries; - u32 num_rx_queues; - u32 num_tx_queues; - u32 link_attach_type; - u32 link_mode_select; - bool link_settings_loaded; + s32 (*setup_link_speed)(struct ixgbe_hw *, ixgbe_link_speed, bool, + bool); + s32 (*read_i2c_byte)(struct ixgbe_hw *, u8, u8, u8 *); + s32 (*write_i2c_byte)(struct ixgbe_hw *, u8, u8, u8); + s32 (*read_i2c_eeprom)(struct ixgbe_hw *, u8 , u8 *); + s32 (*write_i2c_eeprom)(struct ixgbe_hw *, u8, u8); }; struct ixgbe_eeprom_info { - enum ixgbe_eeprom_type type; - u16 word_size; - u16 address_bits; + struct ixgbe_eeprom_operations ops; + enum ixgbe_eeprom_type type; + u32 semaphore_delay; + u16 word_size; + u16 address_bits; }; -struct ixgbe_phy_info { - struct ixgbe_phy_operations ops; - - enum ixgbe_phy_type type; - u32 addr; - u32 id; - u32 revision; - enum ixgbe_media_type media_type; - u32 autoneg_advertised; - bool autoneg_wait_to_complete; +struct ixgbe_mac_info { + struct ixgbe_mac_operations ops; + enum ixgbe_mac_type type; + u8 addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; + u8 perm_addr[IXGBE_ETH_LENGTH_OF_ADDRESS]; + s32 mc_filter_type; + u32 mcft_size; + u32 vft_size; + u32 num_rar_entries; + u32 max_tx_queues; + u32 max_rx_queues; + u32 link_attach_type; + u32 link_mode_select; + bool link_settings_loaded; + bool autoneg; + bool autoneg_failed; }; -struct ixgbe_info { - enum ixgbe_mac_type mac; - s32 (*get_invariants)(struct ixgbe_hw *); - struct ixgbe_mac_operations *mac_ops; +struct ixgbe_phy_info { + struct ixgbe_phy_operations ops; + enum ixgbe_phy_type type; + u32 addr; + u32 id; + enum ixgbe_sfp_type sfp_type; + u32 revision; + enum ixgbe_media_type media_type; + bool reset_disable; + ixgbe_autoneg_advertised autoneg_advertised; + bool autoneg_wait_to_complete; }; struct ixgbe_hw { @@ -1316,6 +1457,15 @@ struct ixgbe_hw { bool adapter_stopped; }; +struct ixgbe_info { + enum ixgbe_mac_type mac; + s32 (*get_invariants)(struct ixgbe_hw *); + struct ixgbe_mac_operations *mac_ops; + struct ixgbe_eeprom_operations *eeprom_ops; + struct ixgbe_phy_operations *phy_ops; +}; + + /* Error Codes */ #define IXGBE_ERR_EEPROM -1 #define IXGBE_ERR_EEPROM_CHECKSUM -2 @@ -1334,6 +1484,8 @@ struct ixgbe_hw { #define IXGBE_ERR_RESET_FAILED -15 #define IXGBE_ERR_SWFW_SYNC -16 #define IXGBE_ERR_PHY_ADDR_INVALID -17 +#define IXGBE_ERR_I2C -18 +#define IXGBE_ERR_SFP_NOT_SUPPORTED -19 #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF #endif /* _IXGBE_TYPE_H_ */ diff --git a/drivers/net/meth.c b/drivers/net/meth.c index 0a97c26df6a..a1e22ed1f6e 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c @@ -41,7 +41,7 @@ #endif #if MFE_DEBUG>=1 -#define DPRINTK(str,args...) printk(KERN_DEBUG "meth: %s: " str, __FUNCTION__ , ## args) +#define DPRINTK(str,args...) printk(KERN_DEBUG "meth: %s: " str, __func__ , ## args) #define MFE_RX_DEBUG 2 #else #define DPRINTK(str,args...) diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c index 6d343efb271..4e7a5faf035 100644 --- a/drivers/net/mipsnet.c +++ b/drivers/net/mipsnet.c @@ -203,7 +203,7 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id) out_badirq: printk(KERN_INFO "%s: %s(): irq %d for unknown device\n", - dev->name, __FUNCTION__, irq); + dev->name, __func__, irq); return ret; } diff --git a/drivers/net/mlx4/alloc.c b/drivers/net/mlx4/alloc.c index 096bca54bcf..b411b79d72a 100644 --- a/drivers/net/mlx4/alloc.c +++ b/drivers/net/mlx4/alloc.c @@ -33,6 +33,7 @@ #include <linux/errno.h> #include <linux/slab.h> +#include <linux/mm.h> #include <linux/bitmap.h> #include <linux/dma-mapping.h> #include <linux/vmalloc.h> diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c index 62071d9c4a5..d1dd5b48dbd 100644 --- a/drivers/net/mlx4/mr.c +++ b/drivers/net/mlx4/mr.c @@ -67,11 +67,10 @@ struct mlx4_mpt_entry { #define MLX4_MPT_FLAG_PHYSICAL (1 << 9) #define MLX4_MPT_FLAG_REGION (1 << 8) -#define MLX4_MPT_PD_FLAG_FAST_REG (1 << 26) +#define MLX4_MPT_PD_FLAG_FAST_REG (1 << 27) +#define MLX4_MPT_PD_FLAG_RAE (1 << 28) #define MLX4_MPT_PD_FLAG_EN_INV (3 << 24) -#define MLX4_MTT_FLAG_PRESENT 1 - #define MLX4_MPT_STATUS_SW 0xF0 #define MLX4_MPT_STATUS_HW 0x00 @@ -348,7 +347,10 @@ int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr) if (mr->mtt.order >= 0 && mr->mtt.page_shift == 0) { /* fast register MR in free state */ mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_FREE); - mpt_entry->pd_flags |= cpu_to_be32(MLX4_MPT_PD_FLAG_FAST_REG); + mpt_entry->pd_flags |= cpu_to_be32(MLX4_MPT_PD_FLAG_FAST_REG | + MLX4_MPT_PD_FLAG_RAE); + mpt_entry->mtt_sz = cpu_to_be32((1 << mr->mtt.order) * + MLX4_MTT_ENTRY_PER_SEG); } else { mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_SW_OWNS); } diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 0a18b9e96da..372811ade9f 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -48,30 +48,28 @@ #include <linux/kernel.h> #include <linux/spinlock.h> #include <linux/workqueue.h> -#include <linux/mii.h> +#include <linux/phy.h> #include <linux/mv643xx_eth.h> #include <asm/io.h> #include <asm/types.h> #include <asm/system.h> static char mv643xx_eth_driver_name[] = "mv643xx_eth"; -static char mv643xx_eth_driver_version[] = "1.3"; +static char mv643xx_eth_driver_version[] = "1.4"; -#define MV643XX_ETH_CHECKSUM_OFFLOAD_TX -#define MV643XX_ETH_NAPI -#define MV643XX_ETH_TX_FAST_REFILL - -#ifdef MV643XX_ETH_CHECKSUM_OFFLOAD_TX -#define MAX_DESCS_PER_SKB (MAX_SKB_FRAGS + 1) -#else -#define MAX_DESCS_PER_SKB 1 -#endif /* * Registers shared between all ports. */ #define PHY_ADDR 0x0000 #define SMI_REG 0x0004 +#define SMI_BUSY 0x10000000 +#define SMI_READ_VALID 0x08000000 +#define SMI_OPCODE_READ 0x04000000 +#define SMI_OPCODE_WRITE 0x00000000 +#define ERR_INT_CAUSE 0x0080 +#define ERR_INT_SMI_DONE 0x00000010 +#define ERR_INT_MASK 0x0084 #define WINDOW_BASE(w) (0x0200 + ((w) << 3)) #define WINDOW_SIZE(w) (0x0204 + ((w) << 3)) #define WINDOW_REMAP_HIGH(w) (0x0280 + ((w) << 2)) @@ -104,16 +102,12 @@ static char mv643xx_eth_driver_version[] = "1.3"; #define TX_BW_MTU(p) (0x0458 + ((p) << 10)) #define TX_BW_BURST(p) (0x045c + ((p) << 10)) #define INT_CAUSE(p) (0x0460 + ((p) << 10)) -#define INT_TX_END_0 0x00080000 #define INT_TX_END 0x07f80000 -#define INT_RX 0x0007fbfc +#define INT_RX 0x000003fc #define INT_EXT 0x00000002 #define INT_CAUSE_EXT(p) (0x0464 + ((p) << 10)) -#define INT_EXT_LINK 0x00100000 -#define INT_EXT_PHY 0x00010000 -#define INT_EXT_TX_ERROR_0 0x00000100 -#define INT_EXT_TX_0 0x00000001 -#define INT_EXT_TX 0x0000ffff +#define INT_EXT_LINK_PHY 0x00110000 +#define INT_EXT_TX 0x000000ff #define INT_MASK(p) (0x0468 + ((p) << 10)) #define INT_MASK_EXT(p) (0x046c + ((p) << 10)) #define TX_FIFO_URGENT_THRESHOLD(p) (0x0474 + ((p) << 10)) @@ -171,8 +165,8 @@ static char mv643xx_eth_driver_version[] = "1.3"; #define FORCE_LINK_PASS (1 << 1) #define SERIAL_PORT_ENABLE (1 << 0) -#define DEFAULT_RX_QUEUE_SIZE 400 -#define DEFAULT_TX_QUEUE_SIZE 800 +#define DEFAULT_RX_QUEUE_SIZE 128 +#define DEFAULT_TX_QUEUE_SIZE 256 /* @@ -249,9 +243,23 @@ struct mv643xx_eth_shared_private { void __iomem *base; /* - * Protects access to SMI_REG, which is shared between ports. + * Points at the right SMI instance to use. + */ + struct mv643xx_eth_shared_private *smi; + + /* + * Provides access to local SMI interface. + */ + struct mii_bus smi_bus; + + /* + * If we have access to the error interrupt pin (which is + * somewhat misnamed as it not only reflects internal errors + * but also reflects SMI completion), use that to wait for + * SMI access completion instead of polling the SMI busy bit. */ - spinlock_t phy_lock; + int err_interrupt; + wait_queue_head_t smi_busy_wait; /* * Per-port MBUS window access register value. @@ -263,9 +271,13 @@ struct mv643xx_eth_shared_private { */ unsigned int t_clk; int extended_rx_coal_limit; - int tx_bw_control_moved; + int tx_bw_control; }; +#define TX_BW_CONTROL_ABSENT 0 +#define TX_BW_CONTROL_OLD_LAYOUT 1 +#define TX_BW_CONTROL_NEW_LAYOUT 2 + /* per-port *****************************************************************/ struct mib_counters { @@ -314,8 +326,6 @@ struct rx_queue { dma_addr_t rx_desc_dma; int rx_desc_area_size; struct sk_buff **rx_skb; - - struct timer_list rx_oom; }; struct tx_queue { @@ -330,7 +340,12 @@ struct tx_queue { struct tx_desc *tx_desc_area; dma_addr_t tx_desc_dma; int tx_desc_area_size; - struct sk_buff **tx_skb; + + struct sk_buff_head tx_skb; + + unsigned long tx_packets; + unsigned long tx_bytes; + unsigned long tx_dropped; }; struct mv643xx_eth_private { @@ -339,14 +354,24 @@ struct mv643xx_eth_private { struct net_device *dev; - struct mv643xx_eth_shared_private *shared_smi; - int phy_addr; - - spinlock_t lock; + struct phy_device *phy; + struct timer_list mib_counters_timer; + spinlock_t mib_counters_lock; struct mib_counters mib_counters; + struct work_struct tx_timeout_task; - struct mii_if_info mii; + + struct napi_struct napi; + u8 work_link; + u8 work_tx; + u8 work_tx_end; + u8 work_rx; + u8 work_rx_refill; + u8 work_rx_oom; + + int skb_size; + struct sk_buff_head rx_recycle; /* * RX state. @@ -354,9 +379,8 @@ struct mv643xx_eth_private { int default_rx_ring_size; unsigned long rx_desc_sram_addr; int rx_desc_sram_size; - u8 rxq_mask; - int rxq_primary; - struct napi_struct napi; + int rxq_count; + struct timer_list rx_oom; struct rx_queue rxq[8]; /* @@ -365,12 +389,8 @@ struct mv643xx_eth_private { int default_tx_ring_size; unsigned long tx_desc_sram_addr; int tx_desc_sram_size; - u8 txq_mask; - int txq_primary; + int txq_count; struct tx_queue txq[8]; -#ifdef MV643XX_ETH_TX_FAST_REFILL - int tx_clean_threshold; -#endif }; @@ -440,94 +460,21 @@ static void txq_disable(struct tx_queue *txq) udelay(10); } -static void __txq_maybe_wake(struct tx_queue *txq) +static void txq_maybe_wake(struct tx_queue *txq) { struct mv643xx_eth_private *mp = txq_to_mp(txq); + struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index); - /* - * netif_{stop,wake}_queue() flow control only applies to - * the primary queue. - */ - BUG_ON(txq->index != mp->txq_primary); - - if (txq->tx_ring_size - txq->tx_desc_count >= MAX_DESCS_PER_SKB) - netif_wake_queue(mp->dev); -} - - -/* rx ***********************************************************************/ -static void txq_reclaim(struct tx_queue *txq, int force); - -static void rxq_refill(struct rx_queue *rxq) -{ - struct mv643xx_eth_private *mp = rxq_to_mp(rxq); - unsigned long flags; - - spin_lock_irqsave(&mp->lock, flags); - - while (rxq->rx_desc_count < rxq->rx_ring_size) { - int skb_size; - struct sk_buff *skb; - int unaligned; - int rx; - - /* - * Reserve 2+14 bytes for an ethernet header (the - * hardware automatically prepends 2 bytes of dummy - * data to each received packet), 16 bytes for up to - * four VLAN tags, and 4 bytes for the trailing FCS - * -- 36 bytes total. - */ - skb_size = mp->dev->mtu + 36; - - /* - * Make sure that the skb size is a multiple of 8 - * bytes, as the lower three bits of the receive - * descriptor's buffer size field are ignored by - * the hardware. - */ - skb_size = (skb_size + 7) & ~7; - - skb = dev_alloc_skb(skb_size + dma_get_cache_alignment() - 1); - if (skb == NULL) - break; - - unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1); - if (unaligned) - skb_reserve(skb, dma_get_cache_alignment() - unaligned); - - rxq->rx_desc_count++; - rx = rxq->rx_used_desc; - rxq->rx_used_desc = (rx + 1) % rxq->rx_ring_size; - - rxq->rx_desc_area[rx].buf_ptr = dma_map_single(NULL, skb->data, - skb_size, DMA_FROM_DEVICE); - rxq->rx_desc_area[rx].buf_size = skb_size; - rxq->rx_skb[rx] = skb; - wmb(); - rxq->rx_desc_area[rx].cmd_sts = BUFFER_OWNED_BY_DMA | - RX_ENABLE_INTERRUPT; - wmb(); - - /* - * The hardware automatically prepends 2 bytes of - * dummy data to each received packet, so that the - * IP header ends up 16-byte aligned. - */ - skb_reserve(skb, 2); + if (netif_tx_queue_stopped(nq)) { + __netif_tx_lock(nq, smp_processor_id()); + if (txq->tx_ring_size - txq->tx_desc_count >= MAX_SKB_FRAGS + 1) + netif_tx_wake_queue(nq); + __netif_tx_unlock(nq); } - - if (rxq->rx_desc_count != rxq->rx_ring_size) - mod_timer(&rxq->rx_oom, jiffies + (HZ / 10)); - - spin_unlock_irqrestore(&mp->lock, flags); } -static inline void rxq_refill_timer_wrapper(unsigned long data) -{ - rxq_refill((struct rx_queue *)data); -} +/* rx napi ******************************************************************/ static int rxq_process(struct rx_queue *rxq, int budget) { struct mv643xx_eth_private *mp = rxq_to_mp(rxq); @@ -539,31 +486,31 @@ static int rxq_process(struct rx_queue *rxq, int budget) struct rx_desc *rx_desc; unsigned int cmd_sts; struct sk_buff *skb; - unsigned long flags; - - spin_lock_irqsave(&mp->lock, flags); + u16 byte_cnt; rx_desc = &rxq->rx_desc_area[rxq->rx_curr_desc]; cmd_sts = rx_desc->cmd_sts; - if (cmd_sts & BUFFER_OWNED_BY_DMA) { - spin_unlock_irqrestore(&mp->lock, flags); + if (cmd_sts & BUFFER_OWNED_BY_DMA) break; - } rmb(); skb = rxq->rx_skb[rxq->rx_curr_desc]; rxq->rx_skb[rxq->rx_curr_desc] = NULL; - rxq->rx_curr_desc = (rxq->rx_curr_desc + 1) % rxq->rx_ring_size; - - spin_unlock_irqrestore(&mp->lock, flags); + rxq->rx_curr_desc++; + if (rxq->rx_curr_desc == rxq->rx_ring_size) + rxq->rx_curr_desc = 0; - dma_unmap_single(NULL, rx_desc->buf_ptr + 2, + dma_unmap_single(NULL, rx_desc->buf_ptr, rx_desc->buf_size, DMA_FROM_DEVICE); rxq->rx_desc_count--; rx++; + mp->work_rx_refill |= 1 << rxq->index; + + byte_cnt = rx_desc->byte_cnt; + /* * Update statistics. * @@ -573,7 +520,7 @@ static int rxq_process(struct rx_queue *rxq, int budget) * byte CRC at the end of the packet (which we do count). */ stats->rx_packets++; - stats->rx_bytes += rx_desc->byte_cnt - 2; + stats->rx_bytes += byte_cnt - 2; /* * In case we received a packet without first / last bits @@ -596,72 +543,84 @@ static int rxq_process(struct rx_queue *rxq, int budget) if (cmd_sts & ERROR_SUMMARY) stats->rx_errors++; - dev_kfree_skb_irq(skb); + dev_kfree_skb(skb); } else { /* * The -4 is for the CRC in the trailer of the * received packet */ - skb_put(skb, rx_desc->byte_cnt - 2 - 4); + skb_put(skb, byte_cnt - 2 - 4); - if (cmd_sts & LAYER_4_CHECKSUM_OK) { + if (cmd_sts & LAYER_4_CHECKSUM_OK) skb->ip_summed = CHECKSUM_UNNECESSARY; - skb->csum = htons( - (cmd_sts & 0x0007fff8) >> 3); - } skb->protocol = eth_type_trans(skb, mp->dev); -#ifdef MV643XX_ETH_NAPI netif_receive_skb(skb); -#else - netif_rx(skb); -#endif } mp->dev->last_rx = jiffies; } - rxq_refill(rxq); + if (rx < budget) + mp->work_rx &= ~(1 << rxq->index); return rx; } -#ifdef MV643XX_ETH_NAPI -static int mv643xx_eth_poll(struct napi_struct *napi, int budget) +static int rxq_refill(struct rx_queue *rxq, int budget) { - struct mv643xx_eth_private *mp; - int rx; - int i; + struct mv643xx_eth_private *mp = rxq_to_mp(rxq); + int refilled; - mp = container_of(napi, struct mv643xx_eth_private, napi); + refilled = 0; + while (refilled < budget && rxq->rx_desc_count < rxq->rx_ring_size) { + struct sk_buff *skb; + int unaligned; + int rx; + + skb = __skb_dequeue(&mp->rx_recycle); + if (skb == NULL) + skb = dev_alloc_skb(mp->skb_size + + dma_get_cache_alignment() - 1); -#ifdef MV643XX_ETH_TX_FAST_REFILL - if (++mp->tx_clean_threshold > 5) { - mp->tx_clean_threshold = 0; - for (i = 0; i < 8; i++) - if (mp->txq_mask & (1 << i)) - txq_reclaim(mp->txq + i, 0); - - if (netif_carrier_ok(mp->dev)) { - spin_lock_irq(&mp->lock); - __txq_maybe_wake(mp->txq + mp->txq_primary); - spin_unlock_irq(&mp->lock); + if (skb == NULL) { + mp->work_rx_oom |= 1 << rxq->index; + goto oom; } - } -#endif - rx = 0; - for (i = 7; rx < budget && i >= 0; i--) - if (mp->rxq_mask & (1 << i)) - rx += rxq_process(mp->rxq + i, budget - rx); + unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1); + if (unaligned) + skb_reserve(skb, dma_get_cache_alignment() - unaligned); - if (rx < budget) { - netif_rx_complete(mp->dev, napi); - wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT); + refilled++; + rxq->rx_desc_count++; + + rx = rxq->rx_used_desc++; + if (rxq->rx_used_desc == rxq->rx_ring_size) + rxq->rx_used_desc = 0; + + rxq->rx_desc_area[rx].buf_ptr = dma_map_single(NULL, skb->data, + mp->skb_size, DMA_FROM_DEVICE); + rxq->rx_desc_area[rx].buf_size = mp->skb_size; + rxq->rx_skb[rx] = skb; + wmb(); + rxq->rx_desc_area[rx].cmd_sts = BUFFER_OWNED_BY_DMA | + RX_ENABLE_INTERRUPT; + wmb(); + + /* + * The hardware automatically prepends 2 bytes of + * dummy data to each received packet, so that the + * IP header ends up 16-byte aligned. + */ + skb_reserve(skb, 2); } - return rx; + if (refilled < budget) + mp->work_rx_refill &= ~(1 << rxq->index); + +oom: + return refilled; } -#endif /* tx ***********************************************************************/ @@ -684,8 +643,9 @@ static int txq_alloc_desc_index(struct tx_queue *txq) BUG_ON(txq->tx_desc_count >= txq->tx_ring_size); - tx_desc_curr = txq->tx_curr_desc; - txq->tx_curr_desc = (tx_desc_curr + 1) % txq->tx_ring_size; + tx_desc_curr = txq->tx_curr_desc++; + if (txq->tx_curr_desc == txq->tx_ring_size) + txq->tx_curr_desc = 0; BUG_ON(txq->tx_curr_desc == txq->tx_used_desc); @@ -714,10 +674,8 @@ static void txq_submit_frag_skb(struct tx_queue *txq, struct sk_buff *skb) desc->cmd_sts = BUFFER_OWNED_BY_DMA | ZERO_PADDING | TX_LAST_DESC | TX_ENABLE_INTERRUPT; - txq->tx_skb[tx_index] = skb; } else { desc->cmd_sts = BUFFER_OWNED_BY_DMA; - txq->tx_skb[tx_index] = NULL; } desc->l4i_chk = 0; @@ -734,144 +692,228 @@ static inline __be16 sum16_as_be(__sum16 sum) return (__force __be16)sum; } -static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb) +static int txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb) { struct mv643xx_eth_private *mp = txq_to_mp(txq); int nr_frags = skb_shinfo(skb)->nr_frags; int tx_index; struct tx_desc *desc; u32 cmd_sts; + u16 l4i_chk; int length; cmd_sts = TX_FIRST_DESC | GEN_CRC | BUFFER_OWNED_BY_DMA; - - tx_index = txq_alloc_desc_index(txq); - desc = &txq->tx_desc_area[tx_index]; - - if (nr_frags) { - txq_submit_frag_skb(txq, skb); - - length = skb_headlen(skb); - txq->tx_skb[tx_index] = NULL; - } else { - cmd_sts |= ZERO_PADDING | TX_LAST_DESC | TX_ENABLE_INTERRUPT; - length = skb->len; - txq->tx_skb[tx_index] = skb; - } - - desc->byte_cnt = length; - desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); + l4i_chk = 0; if (skb->ip_summed == CHECKSUM_PARTIAL) { - int mac_hdr_len; + int tag_bytes; BUG_ON(skb->protocol != htons(ETH_P_IP) && skb->protocol != htons(ETH_P_8021Q)); - cmd_sts |= GEN_TCP_UDP_CHECKSUM | - GEN_IP_V4_CHECKSUM | - ip_hdr(skb)->ihl << TX_IHL_SHIFT; + tag_bytes = (void *)ip_hdr(skb) - (void *)skb->data - ETH_HLEN; + if (unlikely(tag_bytes & ~12)) { + if (skb_checksum_help(skb) == 0) + goto no_csum; + kfree_skb(skb); + return 1; + } - mac_hdr_len = (void *)ip_hdr(skb) - (void *)skb->data; - switch (mac_hdr_len - ETH_HLEN) { - case 0: - break; - case 4: - cmd_sts |= MAC_HDR_EXTRA_4_BYTES; - break; - case 8: - cmd_sts |= MAC_HDR_EXTRA_8_BYTES; - break; - case 12: + if (tag_bytes & 4) cmd_sts |= MAC_HDR_EXTRA_4_BYTES; + if (tag_bytes & 8) cmd_sts |= MAC_HDR_EXTRA_8_BYTES; - break; - default: - if (net_ratelimit()) - dev_printk(KERN_ERR, &txq_to_mp(txq)->dev->dev, - "mac header length is %d?!\n", mac_hdr_len); - break; - } + + cmd_sts |= GEN_TCP_UDP_CHECKSUM | + GEN_IP_V4_CHECKSUM | + ip_hdr(skb)->ihl << TX_IHL_SHIFT; switch (ip_hdr(skb)->protocol) { case IPPROTO_UDP: cmd_sts |= UDP_FRAME; - desc->l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check)); + l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check)); break; case IPPROTO_TCP: - desc->l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check)); + l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check)); break; default: BUG(); } } else { +no_csum: /* Errata BTS #50, IHL must be 5 if no HW checksum */ cmd_sts |= 5 << TX_IHL_SHIFT; - desc->l4i_chk = 0; } + tx_index = txq_alloc_desc_index(txq); + desc = &txq->tx_desc_area[tx_index]; + + if (nr_frags) { + txq_submit_frag_skb(txq, skb); + length = skb_headlen(skb); + } else { + cmd_sts |= ZERO_PADDING | TX_LAST_DESC | TX_ENABLE_INTERRUPT; + length = skb->len; + } + + desc->l4i_chk = l4i_chk; + desc->byte_cnt = length; + desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE); + + __skb_queue_tail(&txq->tx_skb, skb); + /* ensure all other descriptors are written before first cmd_sts */ wmb(); desc->cmd_sts = cmd_sts; - /* clear TX_END interrupt status */ - wrl(mp, INT_CAUSE(mp->port_num), ~(INT_TX_END_0 << txq->index)); - rdl(mp, INT_CAUSE(mp->port_num)); + /* clear TX_END status */ + mp->work_tx_end &= ~(1 << txq->index); /* ensure all descriptors are written before poking hardware */ wmb(); txq_enable(txq); txq->tx_desc_count += nr_frags + 1; + + return 0; } static int mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev) { struct mv643xx_eth_private *mp = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; + int queue; struct tx_queue *txq; - unsigned long flags; + struct netdev_queue *nq; + + queue = skb_get_queue_mapping(skb); + txq = mp->txq + queue; + nq = netdev_get_tx_queue(dev, queue); if (has_tiny_unaligned_frags(skb) && __skb_linearize(skb)) { - stats->tx_dropped++; + txq->tx_dropped++; dev_printk(KERN_DEBUG, &dev->dev, "failed to linearize skb with tiny " "unaligned fragment\n"); return NETDEV_TX_BUSY; } - spin_lock_irqsave(&mp->lock, flags); - - txq = mp->txq + mp->txq_primary; - - if (txq->tx_ring_size - txq->tx_desc_count < MAX_DESCS_PER_SKB) { - spin_unlock_irqrestore(&mp->lock, flags); - if (txq->index == mp->txq_primary && net_ratelimit()) - dev_printk(KERN_ERR, &dev->dev, - "primary tx queue full?!\n"); + if (txq->tx_ring_size - txq->tx_desc_count < MAX_SKB_FRAGS + 1) { + if (net_ratelimit()) + dev_printk(KERN_ERR, &dev->dev, "tx queue full?!\n"); kfree_skb(skb); return NETDEV_TX_OK; } - txq_submit_skb(txq, skb); - stats->tx_bytes += skb->len; - stats->tx_packets++; - dev->trans_start = jiffies; - - if (txq->index == mp->txq_primary) { + if (!txq_submit_skb(txq, skb)) { int entries_left; + txq->tx_bytes += skb->len; + txq->tx_packets++; + dev->trans_start = jiffies; + entries_left = txq->tx_ring_size - txq->tx_desc_count; - if (entries_left < MAX_DESCS_PER_SKB) - netif_stop_queue(dev); + if (entries_left < MAX_SKB_FRAGS + 1) + netif_tx_stop_queue(nq); } - spin_unlock_irqrestore(&mp->lock, flags); - return NETDEV_TX_OK; } +/* tx napi ******************************************************************/ +static void txq_kick(struct tx_queue *txq) +{ + struct mv643xx_eth_private *mp = txq_to_mp(txq); + struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index); + u32 hw_desc_ptr; + u32 expected_ptr; + + __netif_tx_lock(nq, smp_processor_id()); + + if (rdl(mp, TXQ_COMMAND(mp->port_num)) & (1 << txq->index)) + goto out; + + hw_desc_ptr = rdl(mp, TXQ_CURRENT_DESC_PTR(mp->port_num, txq->index)); + expected_ptr = (u32)txq->tx_desc_dma + + txq->tx_curr_desc * sizeof(struct tx_desc); + + if (hw_desc_ptr != expected_ptr) + txq_enable(txq); + +out: + __netif_tx_unlock(nq); + + mp->work_tx_end &= ~(1 << txq->index); +} + +static int txq_reclaim(struct tx_queue *txq, int budget, int force) +{ + struct mv643xx_eth_private *mp = txq_to_mp(txq); + struct netdev_queue *nq = netdev_get_tx_queue(mp->dev, txq->index); + int reclaimed; + + __netif_tx_lock(nq, smp_processor_id()); + + reclaimed = 0; + while (reclaimed < budget && txq->tx_desc_count > 0) { + int tx_index; + struct tx_desc *desc; + u32 cmd_sts; + struct sk_buff *skb; + + tx_index = txq->tx_used_desc; + desc = &txq->tx_desc_area[tx_index]; + cmd_sts = desc->cmd_sts; + + if (cmd_sts & BUFFER_OWNED_BY_DMA) { + if (!force) + break; + desc->cmd_sts = cmd_sts & ~BUFFER_OWNED_BY_DMA; + } + + txq->tx_used_desc = tx_index + 1; + if (txq->tx_used_desc == txq->tx_ring_size) + txq->tx_used_desc = 0; + + reclaimed++; + txq->tx_desc_count--; + + skb = NULL; + if (cmd_sts & TX_LAST_DESC) + skb = __skb_dequeue(&txq->tx_skb); + + if (cmd_sts & ERROR_SUMMARY) { + dev_printk(KERN_INFO, &mp->dev->dev, "tx error\n"); + mp->dev->stats.tx_errors++; + } + + if (cmd_sts & TX_FIRST_DESC) { + dma_unmap_single(NULL, desc->buf_ptr, + desc->byte_cnt, DMA_TO_DEVICE); + } else { + dma_unmap_page(NULL, desc->buf_ptr, + desc->byte_cnt, DMA_TO_DEVICE); + } + + if (skb != NULL) { + if (skb_queue_len(&mp->rx_recycle) < + mp->default_rx_ring_size && + skb_recycle_check(skb, mp->skb_size)) + __skb_queue_head(&mp->rx_recycle, skb); + else + dev_kfree_skb(skb); + } + } + + __netif_tx_unlock(nq); + + if (reclaimed < budget) + mp->work_tx &= ~(1 << txq->index); + + return reclaimed; +} + + /* tx rate control **********************************************************/ /* * Set total maximum TX rate (shared by all TX queues for this port) @@ -895,14 +937,17 @@ static void tx_set_rate(struct mv643xx_eth_private *mp, int rate, int burst) if (bucket_size > 65535) bucket_size = 65535; - if (mp->shared->tx_bw_control_moved) { - wrl(mp, TX_BW_RATE_MOVED(mp->port_num), token_rate); - wrl(mp, TX_BW_MTU_MOVED(mp->port_num), mtu); - wrl(mp, TX_BW_BURST_MOVED(mp->port_num), bucket_size); - } else { + switch (mp->shared->tx_bw_control) { + case TX_BW_CONTROL_OLD_LAYOUT: wrl(mp, TX_BW_RATE(mp->port_num), token_rate); wrl(mp, TX_BW_MTU(mp->port_num), mtu); wrl(mp, TX_BW_BURST(mp->port_num), bucket_size); + break; + case TX_BW_CONTROL_NEW_LAYOUT: + wrl(mp, TX_BW_RATE_MOVED(mp->port_num), token_rate); + wrl(mp, TX_BW_MTU_MOVED(mp->port_num), mtu); + wrl(mp, TX_BW_BURST_MOVED(mp->port_num), bucket_size); + break; } } @@ -934,14 +979,21 @@ static void txq_set_fixed_prio_mode(struct tx_queue *txq) /* * Turn on fixed priority mode. */ - if (mp->shared->tx_bw_control_moved) - off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num); - else + off = 0; + switch (mp->shared->tx_bw_control) { + case TX_BW_CONTROL_OLD_LAYOUT: off = TXQ_FIX_PRIO_CONF(mp->port_num); + break; + case TX_BW_CONTROL_NEW_LAYOUT: + off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num); + break; + } - val = rdl(mp, off); - val |= 1 << txq->index; - wrl(mp, off, val); + if (off) { + val = rdl(mp, off); + val |= 1 << txq->index; + wrl(mp, off, val); + } } static void txq_set_wrr(struct tx_queue *txq, int weight) @@ -953,95 +1005,147 @@ static void txq_set_wrr(struct tx_queue *txq, int weight) /* * Turn off fixed priority mode. */ - if (mp->shared->tx_bw_control_moved) - off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num); - else + off = 0; + switch (mp->shared->tx_bw_control) { + case TX_BW_CONTROL_OLD_LAYOUT: off = TXQ_FIX_PRIO_CONF(mp->port_num); + break; + case TX_BW_CONTROL_NEW_LAYOUT: + off = TXQ_FIX_PRIO_CONF_MOVED(mp->port_num); + break; + } - val = rdl(mp, off); - val &= ~(1 << txq->index); - wrl(mp, off, val); + if (off) { + val = rdl(mp, off); + val &= ~(1 << txq->index); + wrl(mp, off, val); - /* - * Configure WRR weight for this queue. - */ - off = TXQ_BW_WRR_CONF(mp->port_num, txq->index); + /* + * Configure WRR weight for this queue. + */ + off = TXQ_BW_WRR_CONF(mp->port_num, txq->index); - val = rdl(mp, off); - val = (val & ~0xff) | (weight & 0xff); - wrl(mp, off, val); + val = rdl(mp, off); + val = (val & ~0xff) | (weight & 0xff); + wrl(mp, off, val); + } } /* mii management interface *************************************************/ -#define SMI_BUSY 0x10000000 -#define SMI_READ_VALID 0x08000000 -#define SMI_OPCODE_READ 0x04000000 -#define SMI_OPCODE_WRITE 0x00000000 +static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id) +{ + struct mv643xx_eth_shared_private *msp = dev_id; + + if (readl(msp->base + ERR_INT_CAUSE) & ERR_INT_SMI_DONE) { + writel(~ERR_INT_SMI_DONE, msp->base + ERR_INT_CAUSE); + wake_up(&msp->smi_busy_wait); + return IRQ_HANDLED; + } + + return IRQ_NONE; +} -static void smi_reg_read(struct mv643xx_eth_private *mp, unsigned int addr, - unsigned int reg, unsigned int *value) +static int smi_is_done(struct mv643xx_eth_shared_private *msp) { - void __iomem *smi_reg = mp->shared_smi->base + SMI_REG; - unsigned long flags; - int i; + return !(readl(msp->base + SMI_REG) & SMI_BUSY); +} - /* the SMI register is a shared resource */ - spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); +static int smi_wait_ready(struct mv643xx_eth_shared_private *msp) +{ + if (msp->err_interrupt == NO_IRQ) { + int i; - /* wait for the SMI register to become available */ - for (i = 0; readl(smi_reg) & SMI_BUSY; i++) { - if (i == 1000) { - printk("%s: PHY busy timeout\n", mp->dev->name); - goto out; + for (i = 0; !smi_is_done(msp); i++) { + if (i == 10) + return -ETIMEDOUT; + msleep(10); } - udelay(10); + + return 0; + } + + if (!wait_event_timeout(msp->smi_busy_wait, smi_is_done(msp), + msecs_to_jiffies(100))) + return -ETIMEDOUT; + + return 0; +} + +static int smi_bus_read(struct mii_bus *bus, int addr, int reg) +{ + struct mv643xx_eth_shared_private *msp = bus->priv; + void __iomem *smi_reg = msp->base + SMI_REG; + int ret; + + if (smi_wait_ready(msp)) { + printk("mv643xx_eth: SMI bus busy timeout\n"); + return -ETIMEDOUT; } writel(SMI_OPCODE_READ | (reg << 21) | (addr << 16), smi_reg); - /* now wait for the data to be valid */ - for (i = 0; !(readl(smi_reg) & SMI_READ_VALID); i++) { - if (i == 1000) { - printk("%s: PHY read timeout\n", mp->dev->name); - goto out; - } - udelay(10); + if (smi_wait_ready(msp)) { + printk("mv643xx_eth: SMI bus busy timeout\n"); + return -ETIMEDOUT; } - *value = readl(smi_reg) & 0xffff; -out: - spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); + ret = readl(smi_reg); + if (!(ret & SMI_READ_VALID)) { + printk("mv643xx_eth: SMI bus read not valid\n"); + return -ENODEV; + } + + return ret & 0xffff; } -static void smi_reg_write(struct mv643xx_eth_private *mp, - unsigned int addr, - unsigned int reg, unsigned int value) +static int smi_bus_write(struct mii_bus *bus, int addr, int reg, u16 val) { - void __iomem *smi_reg = mp->shared_smi->base + SMI_REG; - unsigned long flags; - int i; - - /* the SMI register is a shared resource */ - spin_lock_irqsave(&mp->shared_smi->phy_lock, flags); + struct mv643xx_eth_shared_private *msp = bus->priv; + void __iomem *smi_reg = msp->base + SMI_REG; - /* wait for the SMI register to become available */ - for (i = 0; readl(smi_reg) & SMI_BUSY; i++) { - if (i == 1000) { - printk("%s: PHY busy timeout\n", mp->dev->name); - goto out; - } - udelay(10); + if (smi_wait_ready(msp)) { + printk("mv643xx_eth: SMI bus busy timeout\n"); + return -ETIMEDOUT; } writel(SMI_OPCODE_WRITE | (reg << 21) | - (addr << 16) | (value & 0xffff), smi_reg); -out: - spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags); + (addr << 16) | (val & 0xffff), smi_reg); + + if (smi_wait_ready(msp)) { + printk("mv643xx_eth: SMI bus busy timeout\n"); + return -ETIMEDOUT; + } + + return 0; } -/* mib counters *************************************************************/ +/* statistics ***************************************************************/ +static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev) +{ + struct mv643xx_eth_private *mp = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + unsigned long tx_packets = 0; + unsigned long tx_bytes = 0; + unsigned long tx_dropped = 0; + int i; + + for (i = 0; i < mp->txq_count; i++) { + struct tx_queue *txq = mp->txq + i; + + tx_packets += txq->tx_packets; + tx_bytes += txq->tx_bytes; + tx_dropped += txq->tx_dropped; + } + + stats->tx_packets = tx_packets; + stats->tx_bytes = tx_bytes; + stats->tx_dropped = tx_dropped; + + return stats; +} + static inline u32 mib_read(struct mv643xx_eth_private *mp, int offset) { return rdl(mp, MIB_COUNTERS(mp->port_num) + offset); @@ -1059,6 +1163,7 @@ static void mib_counters_update(struct mv643xx_eth_private *mp) { struct mib_counters *p = &mp->mib_counters; + spin_lock(&mp->mib_counters_lock); p->good_octets_received += mib_read(mp, 0x00); p->good_octets_received += (u64)mib_read(mp, 0x04) << 32; p->bad_octets_received += mib_read(mp, 0x08); @@ -1091,6 +1196,16 @@ static void mib_counters_update(struct mv643xx_eth_private *mp) p->bad_crc_event += mib_read(mp, 0x74); p->collision += mib_read(mp, 0x78); p->late_collision += mib_read(mp, 0x7c); + spin_unlock(&mp->mib_counters_lock); + + mod_timer(&mp->mib_counters_timer, jiffies + 30 * HZ); +} + +static void mib_counters_timer_wrapper(unsigned long _mp) +{ + struct mv643xx_eth_private *mp = (void *)_mp; + + mib_counters_update(mp); } @@ -1156,9 +1271,9 @@ static int mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd * struct mv643xx_eth_private *mp = netdev_priv(dev); int err; - spin_lock_irq(&mp->lock); - err = mii_ethtool_gset(&mp->mii, cmd); - spin_unlock_irq(&mp->lock); + err = phy_read_status(mp->phy); + if (err == 0) + err = phy_ethtool_gset(mp->phy, cmd); /* * The MAC does not support 1000baseT_Half. @@ -1206,18 +1321,13 @@ static int mv643xx_eth_get_settings_phyless(struct net_device *dev, struct ethto static int mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct mv643xx_eth_private *mp = netdev_priv(dev); - int err; /* * The MAC does not support 1000baseT_Half. */ cmd->advertising &= ~ADVERTISED_1000baseT_Half; - spin_lock_irq(&mp->lock); - err = mii_ethtool_sset(&mp->mii, cmd); - spin_unlock_irq(&mp->lock); - - return err; + return phy_ethtool_sset(mp->phy, cmd); } static int mv643xx_eth_set_settings_phyless(struct net_device *dev, struct ethtool_cmd *cmd) @@ -1239,7 +1349,7 @@ static int mv643xx_eth_nway_reset(struct net_device *dev) { struct mv643xx_eth_private *mp = netdev_priv(dev); - return mii_nway_restart(&mp->mii); + return genphy_restart_aneg(mp->phy); } static int mv643xx_eth_nway_reset_phyless(struct net_device *dev) @@ -1249,14 +1359,7 @@ static int mv643xx_eth_nway_reset_phyless(struct net_device *dev) static u32 mv643xx_eth_get_link(struct net_device *dev) { - struct mv643xx_eth_private *mp = netdev_priv(dev); - - return mii_link_ok(&mp->mii); -} - -static u32 mv643xx_eth_get_link_phyless(struct net_device *dev) -{ - return 1; + return !!netif_carrier_ok(dev); } static void mv643xx_eth_get_strings(struct net_device *dev, @@ -1277,9 +1380,10 @@ static void mv643xx_eth_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, uint64_t *data) { - struct mv643xx_eth_private *mp = dev->priv; + struct mv643xx_eth_private *mp = netdev_priv(dev); int i; + mv643xx_eth_get_stats(dev); mib_counters_update(mp); for (i = 0; i < ARRAY_SIZE(mv643xx_eth_stats); i++) { @@ -1323,7 +1427,7 @@ static const struct ethtool_ops mv643xx_eth_ethtool_ops_phyless = { .set_settings = mv643xx_eth_set_settings_phyless, .get_drvinfo = mv643xx_eth_get_drvinfo, .nway_reset = mv643xx_eth_nway_reset_phyless, - .get_link = mv643xx_eth_get_link_phyless, + .get_link = mv643xx_eth_get_link, .set_sg = ethtool_op_set_sg, .get_strings = mv643xx_eth_get_strings, .get_ethtool_stats = mv643xx_eth_get_ethtool_stats, @@ -1487,7 +1591,7 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index) size = rxq->rx_ring_size * sizeof(struct rx_desc); - if (index == mp->rxq_primary && size <= mp->rx_desc_sram_size) { + if (index == 0 && size <= mp->rx_desc_sram_size) { rxq->rx_desc_area = ioremap(mp->rx_desc_sram_addr, mp->rx_desc_sram_size); rxq->rx_desc_dma = mp->rx_desc_sram_addr; @@ -1515,20 +1619,21 @@ static int rxq_init(struct mv643xx_eth_private *mp, int index) rx_desc = (struct rx_desc *)rxq->rx_desc_area; for (i = 0; i < rxq->rx_ring_size; i++) { - int nexti = (i + 1) % rxq->rx_ring_size; + int nexti; + + nexti = i + 1; + if (nexti == rxq->rx_ring_size) + nexti = 0; + rx_desc[i].next_desc_ptr = rxq->rx_desc_dma + nexti * sizeof(struct rx_desc); } - init_timer(&rxq->rx_oom); - rxq->rx_oom.data = (unsigned long)rxq; - rxq->rx_oom.function = rxq_refill_timer_wrapper; - return 0; out_free: - if (index == mp->rxq_primary && size <= mp->rx_desc_sram_size) + if (index == 0 && size <= mp->rx_desc_sram_size) iounmap(rxq->rx_desc_area); else dma_free_coherent(NULL, size, @@ -1546,8 +1651,6 @@ static void rxq_deinit(struct rx_queue *rxq) rxq_disable(rxq); - del_timer_sync(&rxq->rx_oom); - for (i = 0; i < rxq->rx_ring_size; i++) { if (rxq->rx_skb[i]) { dev_kfree_skb(rxq->rx_skb[i]); @@ -1561,7 +1664,7 @@ static void rxq_deinit(struct rx_queue *rxq) rxq->rx_desc_count); } - if (rxq->index == mp->rxq_primary && + if (rxq->index == 0 && rxq->rx_desc_area_size <= mp->rx_desc_sram_size) iounmap(rxq->rx_desc_area); else @@ -1588,7 +1691,7 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) size = txq->tx_ring_size * sizeof(struct tx_desc); - if (index == mp->txq_primary && size <= mp->tx_desc_sram_size) { + if (index == 0 && size <= mp->tx_desc_sram_size) { txq->tx_desc_area = ioremap(mp->tx_desc_sram_addr, mp->tx_desc_sram_size); txq->tx_desc_dma = mp->tx_desc_sram_addr; @@ -1601,120 +1704,97 @@ static int txq_init(struct mv643xx_eth_private *mp, int index) if (txq->tx_desc_area == NULL) { dev_printk(KERN_ERR, &mp->dev->dev, "can't allocate tx ring (%d bytes)\n", size); - goto out; + return -ENOMEM; } memset(txq->tx_desc_area, 0, size); txq->tx_desc_area_size = size; - txq->tx_skb = kmalloc(txq->tx_ring_size * sizeof(*txq->tx_skb), - GFP_KERNEL); - if (txq->tx_skb == NULL) { - dev_printk(KERN_ERR, &mp->dev->dev, - "can't allocate tx skb ring\n"); - goto out_free; - } tx_desc = (struct tx_desc *)txq->tx_desc_area; for (i = 0; i < txq->tx_ring_size; i++) { struct tx_desc *txd = tx_desc + i; - int nexti = (i + 1) % txq->tx_ring_size; + int nexti; + + nexti = i + 1; + if (nexti == txq->tx_ring_size) + nexti = 0; txd->cmd_sts = 0; txd->next_desc_ptr = txq->tx_desc_dma + nexti * sizeof(struct tx_desc); } - return 0; - + skb_queue_head_init(&txq->tx_skb); -out_free: - if (index == mp->txq_primary && size <= mp->tx_desc_sram_size) - iounmap(txq->tx_desc_area); - else - dma_free_coherent(NULL, size, - txq->tx_desc_area, - txq->tx_desc_dma); - -out: - return -ENOMEM; + return 0; } -static void txq_reclaim(struct tx_queue *txq, int force) +static void txq_deinit(struct tx_queue *txq) { struct mv643xx_eth_private *mp = txq_to_mp(txq); - unsigned long flags; - spin_lock_irqsave(&mp->lock, flags); - while (txq->tx_desc_count > 0) { - int tx_index; - struct tx_desc *desc; - u32 cmd_sts; - struct sk_buff *skb; - dma_addr_t addr; - int count; - - tx_index = txq->tx_used_desc; - desc = &txq->tx_desc_area[tx_index]; - cmd_sts = desc->cmd_sts; + txq_disable(txq); + txq_reclaim(txq, txq->tx_ring_size, 1); - if (cmd_sts & BUFFER_OWNED_BY_DMA) { - if (!force) - break; - desc->cmd_sts = cmd_sts & ~BUFFER_OWNED_BY_DMA; - } + BUG_ON(txq->tx_used_desc != txq->tx_curr_desc); - txq->tx_used_desc = (tx_index + 1) % txq->tx_ring_size; - txq->tx_desc_count--; + if (txq->index == 0 && + txq->tx_desc_area_size <= mp->tx_desc_sram_size) + iounmap(txq->tx_desc_area); + else + dma_free_coherent(NULL, txq->tx_desc_area_size, + txq->tx_desc_area, txq->tx_desc_dma); +} - addr = desc->buf_ptr; - count = desc->byte_cnt; - skb = txq->tx_skb[tx_index]; - txq->tx_skb[tx_index] = NULL; - if (cmd_sts & ERROR_SUMMARY) { - dev_printk(KERN_INFO, &mp->dev->dev, "tx error\n"); - mp->dev->stats.tx_errors++; - } +/* netdev ops and related ***************************************************/ +static int mv643xx_eth_collect_events(struct mv643xx_eth_private *mp) +{ + u32 int_cause; + u32 int_cause_ext; - /* - * Drop mp->lock while we free the skb. - */ - spin_unlock_irqrestore(&mp->lock, flags); + int_cause = rdl(mp, INT_CAUSE(mp->port_num)) & + (INT_TX_END | INT_RX | INT_EXT); + if (int_cause == 0) + return 0; - if (cmd_sts & TX_FIRST_DESC) - dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE); - else - dma_unmap_page(NULL, addr, count, DMA_TO_DEVICE); + int_cause_ext = 0; + if (int_cause & INT_EXT) + int_cause_ext = rdl(mp, INT_CAUSE_EXT(mp->port_num)); - if (skb) - dev_kfree_skb_irq(skb); + int_cause &= INT_TX_END | INT_RX; + if (int_cause) { + wrl(mp, INT_CAUSE(mp->port_num), ~int_cause); + mp->work_tx_end |= ((int_cause & INT_TX_END) >> 19) & + ~(rdl(mp, TXQ_COMMAND(mp->port_num)) & 0xff); + mp->work_rx |= (int_cause & INT_RX) >> 2; + } - spin_lock_irqsave(&mp->lock, flags); + int_cause_ext &= INT_EXT_LINK_PHY | INT_EXT_TX; + if (int_cause_ext) { + wrl(mp, INT_CAUSE_EXT(mp->port_num), ~int_cause_ext); + if (int_cause_ext & INT_EXT_LINK_PHY) + mp->work_link = 1; + mp->work_tx |= int_cause_ext & INT_EXT_TX; } - spin_unlock_irqrestore(&mp->lock, flags); + + return 1; } -static void txq_deinit(struct tx_queue *txq) +static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id) { - struct mv643xx_eth_private *mp = txq_to_mp(txq); - - txq_disable(txq); - txq_reclaim(txq, 1); + struct net_device *dev = (struct net_device *)dev_id; + struct mv643xx_eth_private *mp = netdev_priv(dev); - BUG_ON(txq->tx_used_desc != txq->tx_curr_desc); + if (unlikely(!mv643xx_eth_collect_events(mp))) + return IRQ_NONE; - if (txq->index == mp->txq_primary && - txq->tx_desc_area_size <= mp->tx_desc_sram_size) - iounmap(txq->tx_desc_area); - else - dma_free_coherent(NULL, txq->tx_desc_area_size, - txq->tx_desc_area, txq->tx_desc_dma); + wrl(mp, INT_MASK(mp->port_num), 0); + napi_schedule(&mp->napi); - kfree(txq->tx_skb); + return IRQ_HANDLED; } - -/* netdev ops and related ***************************************************/ static void handle_link_event(struct mv643xx_eth_private *mp) { struct net_device *dev = mp->dev; @@ -1731,15 +1811,12 @@ static void handle_link_event(struct mv643xx_eth_private *mp) printk(KERN_INFO "%s: link down\n", dev->name); netif_carrier_off(dev); - netif_stop_queue(dev); - for (i = 0; i < 8; i++) { + for (i = 0; i < mp->txq_count; i++) { struct tx_queue *txq = mp->txq + i; - if (mp->txq_mask & (1 << i)) { - txq_reclaim(txq, 1); - txq_reset_hw_ptr(txq); - } + txq_reclaim(txq, txq->tx_ring_size, 1); + txq_reset_hw_ptr(txq); } } return; @@ -1767,119 +1844,93 @@ static void handle_link_event(struct mv643xx_eth_private *mp) speed, duplex ? "full" : "half", fc ? "en" : "dis"); - if (!netif_carrier_ok(dev)) { + if (!netif_carrier_ok(dev)) netif_carrier_on(dev); - netif_wake_queue(dev); - } } -static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id) +static int mv643xx_eth_poll(struct napi_struct *napi, int budget) { - struct net_device *dev = (struct net_device *)dev_id; - struct mv643xx_eth_private *mp = netdev_priv(dev); - u32 int_cause; - u32 int_cause_ext; - - int_cause = rdl(mp, INT_CAUSE(mp->port_num)) & - (INT_TX_END | INT_RX | INT_EXT); - if (int_cause == 0) - return IRQ_NONE; - - int_cause_ext = 0; - if (int_cause & INT_EXT) { - int_cause_ext = rdl(mp, INT_CAUSE_EXT(mp->port_num)) - & (INT_EXT_LINK | INT_EXT_PHY | INT_EXT_TX); - wrl(mp, INT_CAUSE_EXT(mp->port_num), ~int_cause_ext); - } + struct mv643xx_eth_private *mp; + int work_done; - if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK)) - handle_link_event(mp); + mp = container_of(napi, struct mv643xx_eth_private, napi); - /* - * RxBuffer or RxError set for any of the 8 queues? - */ -#ifdef MV643XX_ETH_NAPI - if (int_cause & INT_RX) { - wrl(mp, INT_CAUSE(mp->port_num), ~(int_cause & INT_RX)); - wrl(mp, INT_MASK(mp->port_num), 0x00000000); - rdl(mp, INT_MASK(mp->port_num)); + mp->work_rx_refill |= mp->work_rx_oom; + mp->work_rx_oom = 0; - netif_rx_schedule(dev, &mp->napi); - } -#else - if (int_cause & INT_RX) { - int i; + work_done = 0; + while (work_done < budget) { + u8 queue_mask; + int queue; + int work_tbd; - for (i = 7; i >= 0; i--) - if (mp->rxq_mask & (1 << i)) - rxq_process(mp->rxq + i, INT_MAX); - } -#endif - - /* - * TxBuffer or TxError set for any of the 8 queues? - */ - if (int_cause_ext & INT_EXT_TX) { - int i; + if (mp->work_link) { + mp->work_link = 0; + handle_link_event(mp); + continue; + } - for (i = 0; i < 8; i++) - if (mp->txq_mask & (1 << i)) - txq_reclaim(mp->txq + i, 0); + queue_mask = mp->work_tx | mp->work_tx_end | + mp->work_rx | mp->work_rx_refill; + if (!queue_mask) { + if (mv643xx_eth_collect_events(mp)) + continue; + break; + } - /* - * Enough space again in the primary TX queue for a - * full packet? - */ - if (netif_carrier_ok(dev)) { - spin_lock(&mp->lock); - __txq_maybe_wake(mp->txq + mp->txq_primary); - spin_unlock(&mp->lock); + queue = fls(queue_mask) - 1; + queue_mask = 1 << queue; + + work_tbd = budget - work_done; + if (work_tbd > 16) + work_tbd = 16; + + if (mp->work_tx_end & queue_mask) { + txq_kick(mp->txq + queue); + } else if (mp->work_tx & queue_mask) { + work_done += txq_reclaim(mp->txq + queue, work_tbd, 0); + txq_maybe_wake(mp->txq + queue); + } else if (mp->work_rx & queue_mask) { + work_done += rxq_process(mp->rxq + queue, work_tbd); + } else if (mp->work_rx_refill & queue_mask) { + work_done += rxq_refill(mp->rxq + queue, work_tbd); + } else { + BUG(); } } - /* - * Any TxEnd interrupts? - */ - if (int_cause & INT_TX_END) { - int i; - - wrl(mp, INT_CAUSE(mp->port_num), ~(int_cause & INT_TX_END)); - - spin_lock(&mp->lock); - for (i = 0; i < 8; i++) { - struct tx_queue *txq = mp->txq + i; - u32 hw_desc_ptr; - u32 expected_ptr; - - if ((int_cause & (INT_TX_END_0 << i)) == 0) - continue; + if (work_done < budget) { + if (mp->work_rx_oom) + mod_timer(&mp->rx_oom, jiffies + (HZ / 10)); + napi_complete(napi); + wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT); + } - hw_desc_ptr = - rdl(mp, TXQ_CURRENT_DESC_PTR(mp->port_num, i)); - expected_ptr = (u32)txq->tx_desc_dma + - txq->tx_curr_desc * sizeof(struct tx_desc); + return work_done; +} - if (hw_desc_ptr != expected_ptr) - txq_enable(txq); - } - spin_unlock(&mp->lock); - } +static inline void oom_timer_wrapper(unsigned long data) +{ + struct mv643xx_eth_private *mp = (void *)data; - return IRQ_HANDLED; + napi_schedule(&mp->napi); } static void phy_reset(struct mv643xx_eth_private *mp) { - unsigned int data; + int data; + + data = phy_read(mp->phy, MII_BMCR); + if (data < 0) + return; - smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data); data |= BMCR_RESET; - smi_reg_write(mp, mp->phy_addr, MII_BMCR, data); + if (phy_write(mp->phy, MII_BMCR, data) < 0) + return; do { - udelay(1); - smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data); - } while (data & BMCR_RESET); + data = phy_read(mp->phy, MII_BMCR); + } while (data >= 0 && data & BMCR_RESET); } static void port_start(struct mv643xx_eth_private *mp) @@ -1890,7 +1941,7 @@ static void port_start(struct mv643xx_eth_private *mp) /* * Perform PHY reset, if there is a PHY. */ - if (mp->phy_addr != -1) { + if (mp->phy != NULL) { struct ethtool_cmd cmd; mv643xx_eth_get_settings(mp->dev, &cmd); @@ -1907,7 +1958,7 @@ static void port_start(struct mv643xx_eth_private *mp) wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr); pscr |= DO_NOT_FORCE_LINK_FAIL; - if (mp->phy_addr == -1) + if (mp->phy == NULL) pscr |= FORCE_LINK_PASS; wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr); @@ -1917,12 +1968,9 @@ static void port_start(struct mv643xx_eth_private *mp) * Configure TX path and queues. */ tx_set_rate(mp, 1000000000, 16777216); - for (i = 0; i < 8; i++) { + for (i = 0; i < mp->txq_count; i++) { struct tx_queue *txq = mp->txq + i; - if ((mp->txq_mask & (1 << i)) == 0) - continue; - txq_reset_hw_ptr(txq); txq_set_rate(txq, 1000000000, 16777216); txq_set_fixed_prio_mode(txq); @@ -1935,9 +1983,10 @@ static void port_start(struct mv643xx_eth_private *mp) /* * Receive all unmatched unicast, TCP, UDP, BPDU and broadcast - * frames to RX queue #0. + * frames to RX queue #0, and include the pseudo-header when + * calculating receive checksums. */ - wrl(mp, PORT_CONFIG(mp->port_num), 0x00000000); + wrl(mp, PORT_CONFIG(mp->port_num), 0x02000000); /* * Treat BPDUs as normal multicasts, and disable partition mode. @@ -1947,14 +1996,11 @@ static void port_start(struct mv643xx_eth_private *mp) /* * Enable the receive queues. */ - for (i = 0; i < 8; i++) { + for (i = 0; i < mp->rxq_count; i++) { struct rx_queue *rxq = mp->rxq + i; int off = RXQ_CURRENT_DESC_PTR(mp->port_num, i); u32 addr; - if ((mp->rxq_mask & (1 << i)) == 0) - continue; - addr = (u32)rxq->rx_desc_dma; addr += rxq->rx_curr_desc * sizeof(struct rx_desc); wrl(mp, off, addr); @@ -1993,6 +2039,26 @@ static void set_tx_coal(struct mv643xx_eth_private *mp, unsigned int delay) wrl(mp, TX_FIFO_URGENT_THRESHOLD(mp->port_num), (coal & 0x3fff) << 4); } +static void mv643xx_eth_recalc_skb_size(struct mv643xx_eth_private *mp) +{ + int skb_size; + + /* + * Reserve 2+14 bytes for an ethernet header (the hardware + * automatically prepends 2 bytes of dummy data to each + * received packet), 16 bytes for up to four VLAN tags, and + * 4 bytes for the trailing FCS -- 36 bytes total. + */ + skb_size = mp->dev->mtu + 36; + + /* + * Make sure that the skb size is a multiple of 8 bytes, as + * the lower three bits of the receive descriptor's buffer + * size field are ignored by the hardware. + */ + mp->skb_size = (skb_size + 7) & ~7; +} + static int mv643xx_eth_open(struct net_device *dev) { struct mv643xx_eth_private *mp = netdev_priv(dev); @@ -2004,8 +2070,7 @@ static int mv643xx_eth_open(struct net_device *dev) rdl(mp, INT_CAUSE_EXT(mp->port_num)); err = request_irq(dev->irq, mv643xx_eth_irq, - IRQF_SHARED | IRQF_SAMPLE_RANDOM, - dev->name, dev); + IRQF_SHARED, dev->name, dev); if (err) { dev_printk(KERN_ERR, &dev->dev, "can't assign irq\n"); return -EAGAIN; @@ -2013,58 +2078,53 @@ static int mv643xx_eth_open(struct net_device *dev) init_mac_tables(mp); - for (i = 0; i < 8; i++) { - if ((mp->rxq_mask & (1 << i)) == 0) - continue; + mv643xx_eth_recalc_skb_size(mp); + napi_enable(&mp->napi); + + skb_queue_head_init(&mp->rx_recycle); + + for (i = 0; i < mp->rxq_count; i++) { err = rxq_init(mp, i); if (err) { while (--i >= 0) - if (mp->rxq_mask & (1 << i)) - rxq_deinit(mp->rxq + i); + rxq_deinit(mp->rxq + i); goto out; } - rxq_refill(mp->rxq + i); + rxq_refill(mp->rxq + i, INT_MAX); } - for (i = 0; i < 8; i++) { - if ((mp->txq_mask & (1 << i)) == 0) - continue; + if (mp->work_rx_oom) { + mp->rx_oom.expires = jiffies + (HZ / 10); + add_timer(&mp->rx_oom); + } + for (i = 0; i < mp->txq_count; i++) { err = txq_init(mp, i); if (err) { while (--i >= 0) - if (mp->txq_mask & (1 << i)) - txq_deinit(mp->txq + i); + txq_deinit(mp->txq + i); goto out_free; } } -#ifdef MV643XX_ETH_NAPI - napi_enable(&mp->napi); -#endif - netif_carrier_off(dev); - netif_stop_queue(dev); port_start(mp); set_rx_coal(mp, 0); set_tx_coal(mp, 0); - wrl(mp, INT_MASK_EXT(mp->port_num), - INT_EXT_LINK | INT_EXT_PHY | INT_EXT_TX); - + wrl(mp, INT_MASK_EXT(mp->port_num), INT_EXT_LINK_PHY | INT_EXT_TX); wrl(mp, INT_MASK(mp->port_num), INT_TX_END | INT_RX | INT_EXT); return 0; out_free: - for (i = 0; i < 8; i++) - if (mp->rxq_mask & (1 << i)) - rxq_deinit(mp->rxq + i); + for (i = 0; i < mp->rxq_count; i++) + rxq_deinit(mp->rxq + i); out: free_irq(dev->irq, dev); @@ -2076,12 +2136,10 @@ static void port_reset(struct mv643xx_eth_private *mp) unsigned int data; int i; - for (i = 0; i < 8; i++) { - if (mp->rxq_mask & (1 << i)) - rxq_disable(mp->rxq + i); - if (mp->txq_mask & (1 << i)) - txq_disable(mp->txq + i); - } + for (i = 0; i < mp->rxq_count; i++) + rxq_disable(mp->rxq + i); + for (i = 0; i < mp->txq_count; i++) + txq_disable(mp->txq + i); while (1) { u32 ps = rdl(mp, PORT_STATUS(mp->port_num)); @@ -2107,23 +2165,26 @@ static int mv643xx_eth_stop(struct net_device *dev) wrl(mp, INT_MASK(mp->port_num), 0x00000000); rdl(mp, INT_MASK(mp->port_num)); -#ifdef MV643XX_ETH_NAPI + del_timer_sync(&mp->mib_counters_timer); + napi_disable(&mp->napi); -#endif + + del_timer_sync(&mp->rx_oom); + netif_carrier_off(dev); - netif_stop_queue(dev); free_irq(dev->irq, dev); port_reset(mp); + mv643xx_eth_get_stats(dev); mib_counters_update(mp); - for (i = 0; i < 8; i++) { - if (mp->rxq_mask & (1 << i)) - rxq_deinit(mp->rxq + i); - if (mp->txq_mask & (1 << i)) - txq_deinit(mp->txq + i); - } + skb_queue_purge(&mp->rx_recycle); + + for (i = 0; i < mp->rxq_count; i++) + rxq_deinit(mp->rxq + i); + for (i = 0; i < mp->txq_count; i++) + txq_deinit(mp->txq + i); return 0; } @@ -2132,8 +2193,8 @@ static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct mv643xx_eth_private *mp = netdev_priv(dev); - if (mp->phy_addr != -1) - return generic_mii_ioctl(&mp->mii, if_mii(ifr), cmd, NULL); + if (mp->phy != NULL) + return phy_mii_ioctl(mp->phy, if_mii(ifr), cmd); return -EOPNOTSUPP; } @@ -2146,6 +2207,7 @@ static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu) return -EINVAL; dev->mtu = new_mtu; + mv643xx_eth_recalc_skb_size(mp); tx_set_rate(mp, 1000000000, 16777216); if (!netif_running(dev)) @@ -2173,12 +2235,10 @@ static void tx_timeout_task(struct work_struct *ugly) mp = container_of(ugly, struct mv643xx_eth_private, tx_timeout_task); if (netif_running(mp->dev)) { - netif_stop_queue(mp->dev); - + netif_tx_stop_all_queues(mp->dev); port_reset(mp); port_start(mp); - - __txq_maybe_wake(mp->txq + mp->txq_primary); + netif_tx_wake_all_queues(mp->dev); } } @@ -2205,22 +2265,6 @@ static void mv643xx_eth_netpoll(struct net_device *dev) } #endif -static int mv643xx_eth_mdio_read(struct net_device *dev, int addr, int reg) -{ - struct mv643xx_eth_private *mp = netdev_priv(dev); - int val; - - smi_reg_read(mp, addr, reg, &val); - - return val; -} - -static void mv643xx_eth_mdio_write(struct net_device *dev, int addr, int reg, int val) -{ - struct mv643xx_eth_private *mp = netdev_priv(dev); - smi_reg_write(mp, addr, reg, val); -} - /* platform glue ************************************************************/ static void @@ -2272,14 +2316,20 @@ static void infer_hw_params(struct mv643xx_eth_shared_private *msp) msp->extended_rx_coal_limit = 0; /* - * Check whether the TX rate control registers are in the - * old or the new place. + * Check whether the MAC supports TX rate control, and if + * yes, whether its associated registers are in the old or + * the new place. */ writel(1, msp->base + TX_BW_MTU_MOVED(0)); - if (readl(msp->base + TX_BW_MTU_MOVED(0)) & 1) - msp->tx_bw_control_moved = 1; - else - msp->tx_bw_control_moved = 0; + if (readl(msp->base + TX_BW_MTU_MOVED(0)) & 1) { + msp->tx_bw_control = TX_BW_CONTROL_NEW_LAYOUT; + } else { + writel(7, msp->base + TX_BW_RATE(0)); + if (readl(msp->base + TX_BW_RATE(0)) & 7) + msp->tx_bw_control = TX_BW_CONTROL_OLD_LAYOUT; + else + msp->tx_bw_control = TX_BW_CONTROL_ABSENT; + } } static int mv643xx_eth_shared_probe(struct platform_device *pdev) @@ -2309,7 +2359,41 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) if (msp->base == NULL) goto out_free; - spin_lock_init(&msp->phy_lock); + /* + * Set up and register SMI bus. + */ + if (pd == NULL || pd->shared_smi == NULL) { + msp->smi_bus.priv = msp; + msp->smi_bus.name = "mv643xx_eth smi"; + msp->smi_bus.read = smi_bus_read; + msp->smi_bus.write = smi_bus_write, + snprintf(msp->smi_bus.id, MII_BUS_ID_SIZE, "%d", pdev->id); + msp->smi_bus.dev = &pdev->dev; + msp->smi_bus.phy_mask = 0xffffffff; + if (mdiobus_register(&msp->smi_bus) < 0) + goto out_unmap; + msp->smi = msp; + } else { + msp->smi = platform_get_drvdata(pd->shared_smi); + } + + msp->err_interrupt = NO_IRQ; + init_waitqueue_head(&msp->smi_busy_wait); + + /* + * Check whether the error interrupt is hooked up. + */ + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (res != NULL) { + int err; + + err = request_irq(res->start, mv643xx_eth_err_irq, + IRQF_SHARED, "mv643xx_eth", msp); + if (!err) { + writel(ERR_INT_SMI_DONE, msp->base + ERR_INT_MASK); + msp->err_interrupt = res->start; + } + } /* * (Re-)program MBUS remapping windows if we are asked to. @@ -2327,6 +2411,8 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev) return 0; +out_unmap: + iounmap(msp->base); out_free: kfree(msp); out: @@ -2336,7 +2422,12 @@ out: static int mv643xx_eth_shared_remove(struct platform_device *pdev) { struct mv643xx_eth_shared_private *msp = platform_get_drvdata(pdev); + struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data; + if (pd == NULL || pd->shared_smi == NULL) + mdiobus_unregister(&msp->smi_bus); + if (msp->err_interrupt != NO_IRQ) + free_irq(msp->err_interrupt, msp); iounmap(msp->base); kfree(msp); @@ -2382,33 +2473,13 @@ static void set_params(struct mv643xx_eth_private *mp, else uc_addr_get(mp, dev->dev_addr); - if (pd->phy_addr == -1) { - mp->shared_smi = NULL; - mp->phy_addr = -1; - } else { - mp->shared_smi = mp->shared; - if (pd->shared_smi != NULL) - mp->shared_smi = platform_get_drvdata(pd->shared_smi); - - if (pd->force_phy_addr || pd->phy_addr) { - mp->phy_addr = pd->phy_addr & 0x3f; - phy_addr_set(mp, mp->phy_addr); - } else { - mp->phy_addr = phy_addr_get(mp); - } - } - mp->default_rx_ring_size = DEFAULT_RX_QUEUE_SIZE; if (pd->rx_queue_size) mp->default_rx_ring_size = pd->rx_queue_size; mp->rx_desc_sram_addr = pd->rx_sram_addr; mp->rx_desc_sram_size = pd->rx_sram_size; - if (pd->rx_queue_mask) - mp->rxq_mask = pd->rx_queue_mask; - else - mp->rxq_mask = 0x01; - mp->rxq_primary = fls(mp->rxq_mask) - 1; + mp->rxq_count = pd->rx_queue_count ? : 1; mp->default_tx_ring_size = DEFAULT_TX_QUEUE_SIZE; if (pd->tx_queue_size) @@ -2416,76 +2487,63 @@ static void set_params(struct mv643xx_eth_private *mp, mp->tx_desc_sram_addr = pd->tx_sram_addr; mp->tx_desc_sram_size = pd->tx_sram_size; - if (pd->tx_queue_mask) - mp->txq_mask = pd->tx_queue_mask; - else - mp->txq_mask = 0x01; - mp->txq_primary = fls(mp->txq_mask) - 1; + mp->txq_count = pd->tx_queue_count ? : 1; } -static int phy_detect(struct mv643xx_eth_private *mp) +static struct phy_device *phy_scan(struct mv643xx_eth_private *mp, + int phy_addr) { - unsigned int data; - unsigned int data2; + struct mii_bus *bus = &mp->shared->smi->smi_bus; + struct phy_device *phydev; + int start; + int num; + int i; + + if (phy_addr == MV643XX_ETH_PHY_ADDR_DEFAULT) { + start = phy_addr_get(mp) & 0x1f; + num = 32; + } else { + start = phy_addr & 0x1f; + num = 1; + } - smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data); - smi_reg_write(mp, mp->phy_addr, MII_BMCR, data ^ BMCR_ANENABLE); + phydev = NULL; + for (i = 0; i < num; i++) { + int addr = (start + i) & 0x1f; - smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data2); - if (((data ^ data2) & BMCR_ANENABLE) == 0) - return -ENODEV; + if (bus->phy_map[addr] == NULL) + mdiobus_scan(bus, addr); - smi_reg_write(mp, mp->phy_addr, MII_BMCR, data); + if (phydev == NULL) { + phydev = bus->phy_map[addr]; + if (phydev != NULL) + phy_addr_set(mp, addr); + } + } - return 0; + return phydev; } -static int phy_init(struct mv643xx_eth_private *mp, - struct mv643xx_eth_platform_data *pd) +static void phy_init(struct mv643xx_eth_private *mp, int speed, int duplex) { - struct ethtool_cmd cmd; - int err; + struct phy_device *phy = mp->phy; - err = phy_detect(mp); - if (err) { - dev_printk(KERN_INFO, &mp->dev->dev, - "no PHY detected at addr %d\n", mp->phy_addr); - return err; - } phy_reset(mp); - mp->mii.phy_id = mp->phy_addr; - mp->mii.phy_id_mask = 0x3f; - mp->mii.reg_num_mask = 0x1f; - mp->mii.dev = mp->dev; - mp->mii.mdio_read = mv643xx_eth_mdio_read; - mp->mii.mdio_write = mv643xx_eth_mdio_write; - - mp->mii.supports_gmii = mii_check_gmii_support(&mp->mii); - - memset(&cmd, 0, sizeof(cmd)); - - cmd.port = PORT_MII; - cmd.transceiver = XCVR_INTERNAL; - cmd.phy_address = mp->phy_addr; - if (pd->speed == 0) { - cmd.autoneg = AUTONEG_ENABLE; - cmd.speed = SPEED_100; - cmd.advertising = ADVERTISED_10baseT_Half | - ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | - ADVERTISED_100baseT_Full; - if (mp->mii.supports_gmii) - cmd.advertising |= ADVERTISED_1000baseT_Full; + phy_attach(mp->dev, phy->dev.bus_id, 0, PHY_INTERFACE_MODE_GMII); + + if (speed == 0) { + phy->autoneg = AUTONEG_ENABLE; + phy->speed = 0; + phy->duplex = 0; + phy->advertising = phy->supported | ADVERTISED_Autoneg; } else { - cmd.autoneg = AUTONEG_DISABLE; - cmd.speed = pd->speed; - cmd.duplex = pd->duplex; + phy->autoneg = AUTONEG_DISABLE; + phy->advertising = 0; + phy->speed = speed; + phy->duplex = duplex; } - - mv643xx_eth_set_settings(mp->dev, &cmd); - - return 0; + phy_start_aneg(phy); } static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex) @@ -2499,7 +2557,7 @@ static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex) } pscr = MAX_RX_PACKET_9700BYTE | SERIAL_PORT_CONTROL_RESERVED; - if (mp->phy_addr == -1) { + if (mp->phy == NULL) { pscr |= DISABLE_AUTO_NEG_SPEED_GMII; if (speed == SPEED_1000) pscr |= SET_GMII_SPEED_TO_1000; @@ -2538,7 +2596,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev) return -ENODEV; } - dev = alloc_etherdev(sizeof(struct mv643xx_eth_private)); + dev = alloc_etherdev_mq(sizeof(struct mv643xx_eth_private), 8); if (!dev) return -ENOMEM; @@ -2549,33 +2607,47 @@ static int mv643xx_eth_probe(struct platform_device *pdev) mp->port_num = pd->port_number; mp->dev = dev; -#ifdef MV643XX_ETH_NAPI - netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, 64); -#endif set_params(mp, pd); + dev->real_num_tx_queues = mp->txq_count; - spin_lock_init(&mp->lock); - - mib_counters_clear(mp); - INIT_WORK(&mp->tx_timeout_task, tx_timeout_task); - - if (mp->phy_addr != -1) { - err = phy_init(mp, pd); - if (err) - goto out; + if (pd->phy_addr != MV643XX_ETH_PHY_NONE) + mp->phy = phy_scan(mp, pd->phy_addr); + if (mp->phy != NULL) { + phy_init(mp, pd->speed, pd->duplex); SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops); } else { SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops_phyless); } + init_pscr(mp, pd->speed, pd->duplex); + mib_counters_clear(mp); + + init_timer(&mp->mib_counters_timer); + mp->mib_counters_timer.data = (unsigned long)mp; + mp->mib_counters_timer.function = mib_counters_timer_wrapper; + mp->mib_counters_timer.expires = jiffies + 30 * HZ; + add_timer(&mp->mib_counters_timer); + + spin_lock_init(&mp->mib_counters_lock); + + INIT_WORK(&mp->tx_timeout_task, tx_timeout_task); + + netif_napi_add(dev, &mp->napi, mv643xx_eth_poll, 128); + + init_timer(&mp->rx_oom); + mp->rx_oom.data = (unsigned long)mp; + mp->rx_oom.function = oom_timer_wrapper; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); BUG_ON(!res); dev->irq = res->start; + dev->get_stats = mv643xx_eth_get_stats; dev->hard_start_xmit = mv643xx_eth_xmit; dev->open = mv643xx_eth_open; dev->stop = mv643xx_eth_stop; @@ -2590,14 +2662,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev) dev->watchdog_timeo = 2 * HZ; dev->base_addr = 0; -#ifdef MV643XX_ETH_CHECKSUM_OFFLOAD_TX - /* - * Zero copy can only work if we use Discovery II memory. Else, we will - * have to map the buffers to ISA memory which is only 16 MB - */ dev->features = NETIF_F_SG | NETIF_F_IP_CSUM; dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM; -#endif SET_NETDEV_DEV(dev, &pdev->dev); @@ -2611,16 +2677,6 @@ static int mv643xx_eth_probe(struct platform_device *pdev) dev_printk(KERN_NOTICE, &dev->dev, "port %d with MAC address %s\n", mp->port_num, print_mac(mac, dev->dev_addr)); - if (dev->features & NETIF_F_SG) - dev_printk(KERN_NOTICE, &dev->dev, "scatter/gather enabled\n"); - - if (dev->features & NETIF_F_IP_CSUM) - dev_printk(KERN_NOTICE, &dev->dev, "tx checksum offload\n"); - -#ifdef MV643XX_ETH_NAPI - dev_printk(KERN_NOTICE, &dev->dev, "napi enabled\n"); -#endif - if (mp->tx_desc_sram_size > 0) dev_printk(KERN_NOTICE, &dev->dev, "configured with sram\n"); @@ -2637,6 +2693,8 @@ static int mv643xx_eth_remove(struct platform_device *pdev) struct mv643xx_eth_private *mp = platform_get_drvdata(pdev); unregister_netdev(mp->dev); + if (mp->phy != NULL) + phy_detach(mp->phy); flush_scheduled_work(); free_netdev(mp->dev); diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index d6524db321a..005f2aa7501 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -183,7 +183,7 @@ struct myri10ge_slice_state { dma_addr_t fw_stats_bus; int watchdog_tx_done; int watchdog_tx_req; -#ifdef CONFIG_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) int cached_dca_tag; int cpu; __be32 __iomem *dca_tag; @@ -215,7 +215,7 @@ struct myri10ge_priv { int msi_enabled; int msix_enabled; struct msix_entry *msix_vectors; -#ifdef CONFIG_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) int dca_enabled; #endif u32 link_state; @@ -891,7 +891,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) struct myri10ge_slice_state *ss; int i, status; size_t bytes; -#ifdef CONFIG_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) unsigned long dca_tag_off; #endif @@ -986,7 +986,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) } put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); -#ifdef CONFIG_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_DCA_OFFSET, &cmd, 0); dca_tag_off = cmd.data0; for (i = 0; i < mgp->num_slices; i++) { @@ -1025,7 +1025,7 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) return status; } -#ifdef CONFIG_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) static void myri10ge_write_dca(struct myri10ge_slice_state *ss, int cpu, int tag) { @@ -1060,8 +1060,9 @@ static void myri10ge_setup_dca(struct myri10ge_priv *mgp) } err = dca_add_requester(&pdev->dev); if (err) { - dev_err(&pdev->dev, - "dca_add_requester() failed, err=%d\n", err); + if (err != -ENODEV) + dev_err(&pdev->dev, + "dca_add_requester() failed, err=%d\n", err); return; } mgp->dca_enabled = 1; @@ -1457,7 +1458,7 @@ static int myri10ge_poll(struct napi_struct *napi, int budget) struct net_device *netdev = ss->mgp->dev; int work_done; -#ifdef CONFIG_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) if (ss->mgp->dca_enabled) myri10ge_update_dca(ss); #endif @@ -1686,8 +1687,8 @@ static const char myri10ge_gstrings_main_stats[][ETH_GSTRING_LEN] = { "tx_boundary", "WC", "irq", "MSI", "MSIX", "read_dma_bw_MBs", "write_dma_bw_MBs", "read_write_dma_bw_MBs", "serial_number", "watchdog_resets", -#ifdef CONFIG_DCA - "dca_capable", "dca_enabled", +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) + "dca_capable_firmware", "dca_device_present", #endif "link_changes", "link_up", "dropped_link_overflow", "dropped_link_error_or_filtered", @@ -1765,7 +1766,7 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, data[i++] = (unsigned int)mgp->read_write_dma; data[i++] = (unsigned int)mgp->serial_number; data[i++] = (unsigned int)mgp->watchdog_resets; -#ifdef CONFIG_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) data[i++] = (unsigned int)(mgp->ss[0].dca_tag != NULL); data[i++] = (unsigned int)(mgp->dca_enabled); #endif @@ -3763,7 +3764,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_err(&pdev->dev, "failed reset\n"); goto abort_with_slices; } -#ifdef CONFIG_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) myri10ge_setup_dca(mgp); #endif pci_set_drvdata(pdev, mgp); @@ -3866,7 +3867,7 @@ static void myri10ge_remove(struct pci_dev *pdev) netdev = mgp->dev; unregister_netdev(netdev); -#ifdef CONFIG_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) myri10ge_teardown_dca(mgp); #endif myri10ge_dummy_rdma(mgp, 0); @@ -3911,7 +3912,7 @@ static struct pci_driver myri10ge_driver = { #endif }; -#ifdef CONFIG_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) static int myri10ge_notify_dca(struct notifier_block *nb, unsigned long event, void *p) { @@ -3943,7 +3944,7 @@ static __init int myri10ge_init_module(void) myri10ge_driver.name, myri10ge_rss_hash); myri10ge_rss_hash = MXGEFW_RSS_HASH_TYPE_SRC_PORT; } -#ifdef CONFIG_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) dca_register_notify(&myri10ge_dca_notifier); #endif @@ -3954,7 +3955,7 @@ module_init(myri10ge_init_module); static __exit void myri10ge_cleanup_module(void) { -#ifdef CONFIG_DCA +#if (defined CONFIG_DCA) || (defined CONFIG_DCA_MODULE) dca_unregister_notify(&myri10ge_dca_notifier); #endif pci_unregister_driver(&myri10ge_driver); diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index 656a260fc95..06e682334c7 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -1118,7 +1118,7 @@ static int __devexit myri_sbus_remove(struct of_device *dev) struct myri_eth *mp = dev_get_drvdata(&dev->dev); struct net_device *net_dev = mp->dev; - unregister_netdevice(net_dev); + unregister_netdev(net_dev); free_irq(net_dev->irq, net_dev); diff --git a/drivers/net/ne.c b/drivers/net/ne.c index fa3ceca4e15..eb681c0d51b 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -64,6 +64,25 @@ static const char version2[] = /* Do we support clones that don't adhere to 14,15 of the SAprom ? */ #define SUPPORT_NE_BAD_CLONES +/* 0xbad = bad sig or no reset ack */ +#define BAD 0xbad + +#define MAX_NE_CARDS 4 /* Max number of NE cards per module */ +static struct platform_device *pdev_ne[MAX_NE_CARDS]; +static int io[MAX_NE_CARDS]; +static int irq[MAX_NE_CARDS]; +static int bad[MAX_NE_CARDS]; + +#ifdef MODULE +module_param_array(io, int, NULL, 0); +module_param_array(irq, int, NULL, 0); +module_param_array(bad, int, NULL, 0); +MODULE_PARM_DESC(io, "I/O base address(es),required"); +MODULE_PARM_DESC(irq, "IRQ number(s)"); +MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures"); +MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver"); +MODULE_LICENSE("GPL"); +#endif /* MODULE */ /* Do we perform extra sanity checks on stuff ? */ /* #define NE_SANITY_CHECK */ @@ -74,6 +93,10 @@ static const char version2[] = /* Do we have a non std. amount of memory? (in units of 256 byte pages) */ /* #define PACKETBUF_MEMSIZE 0x40 */ +/* This is set up so that no ISA autoprobe takes place. We can't guarantee +that the ne2k probe is the last 8390 based probe to take place (as it +is at boot) and so the probe will get confused by any other 8390 cards. +ISA device autoprobes on a running machine are not recommended anyway. */ #if !defined(MODULE) && (defined(CONFIG_ISA) || defined(CONFIG_M32R)) /* Do we need a portlist for the ISA auto-probe ? */ #define NEEDS_PORTLIST @@ -192,8 +215,13 @@ static int __init do_ne_probe(struct net_device *dev) #endif /* First check any supplied i/o locations. User knows best. <cough> */ - if (base_addr > 0x1ff) /* Check a single specified location. */ - return ne_probe1(dev, base_addr); + if (base_addr > 0x1ff) { /* Check a single specified location. */ + int ret = ne_probe1(dev, base_addr); + if (ret) + printk(KERN_WARNING "ne.c: No NE*000 card found at " + "i/o = %#lx\n", base_addr); + return ret; + } else if (base_addr != 0) /* Don't probe at all. */ return -ENXIO; @@ -214,28 +242,6 @@ static int __init do_ne_probe(struct net_device *dev) return -ENODEV; } -#ifndef MODULE -struct net_device * __init ne_probe(int unit) -{ - struct net_device *dev = alloc_eip_netdev(); - int err; - - if (!dev) - return ERR_PTR(-ENOMEM); - - sprintf(dev->name, "eth%d", unit); - netdev_boot_setup_check(dev); - - err = do_ne_probe(dev); - if (err) - goto out; - return dev; -out: - free_netdev(dev); - return ERR_PTR(err); -} -#endif - static int __init ne_probe_isapnp(struct net_device *dev) { int i; @@ -329,7 +335,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) with an otherwise unused dev->mem_end value of "0xBAD" will cause the driver to skip these parts of the probe. */ - bad_card = ((dev->base_addr != 0) && (dev->mem_end == 0xbad)); + bad_card = ((dev->base_addr != 0) && (dev->mem_end == BAD)); /* Reset card. Who knows what dain-bramaged state it was left in. */ @@ -806,46 +812,95 @@ retry: static int __init ne_drv_probe(struct platform_device *pdev) { struct net_device *dev; + int err, this_dev = pdev->id; struct resource *res; - int err, irq; - - res = platform_get_resource(pdev, IORESOURCE_IO, 0); - irq = platform_get_irq(pdev, 0); - if (!res || irq < 0) - return -ENODEV; dev = alloc_eip_netdev(); if (!dev) return -ENOMEM; - dev->irq = irq; - dev->base_addr = res->start; + + /* ne.c doesn't populate resources in platform_device, but + * rbtx4927_ne_init and rbtx4938_ne_init do register devices + * with resources. + */ + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (res) { + dev->base_addr = res->start; + dev->irq = platform_get_irq(pdev, 0); + } else { + if (this_dev < 0 || this_dev >= MAX_NE_CARDS) + return -EINVAL; + dev->base_addr = io[this_dev]; + dev->irq = irq[this_dev]; + dev->mem_end = bad[this_dev]; + } err = do_ne_probe(dev); if (err) { free_netdev(dev); return err; } platform_set_drvdata(pdev, dev); + + /* Update with any values found by probing, don't update if + * resources were specified. + */ + if (!res) { + io[this_dev] = dev->base_addr; + irq[this_dev] = dev->irq; + } return 0; } -static int __exit ne_drv_remove(struct platform_device *pdev) +static int ne_drv_remove(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); - unregister_netdev(dev); - free_irq(dev->irq, dev); - release_region(dev->base_addr, NE_IO_EXTENT); - free_netdev(dev); + if (dev) { + struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; + netif_device_detach(dev); + unregister_netdev(dev); + if (idev) + pnp_device_detach(idev); + /* Careful ne_drv_remove can be called twice, once from + * the platform_driver.remove and again when the + * platform_device is being removed. + */ + ei_status.priv = 0; + free_irq(dev->irq, dev); + release_region(dev->base_addr, NE_IO_EXTENT); + free_netdev(dev); + platform_set_drvdata(pdev, NULL); + } return 0; } +/* Remove unused devices or all if true. */ +static void ne_loop_rm_unreg(int all) +{ + int this_dev; + struct platform_device *pdev; + for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { + pdev = pdev_ne[this_dev]; + /* No network device == unused */ + if (pdev && (!platform_get_drvdata(pdev) || all)) { + ne_drv_remove(pdev); + platform_device_unregister(pdev); + pdev_ne[this_dev] = NULL; + } + } +} + #ifdef CONFIG_PM static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state) { struct net_device *dev = platform_get_drvdata(pdev); - if (netif_running(dev)) + if (netif_running(dev)) { + struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; netif_device_detach(dev); + if (idev) + pnp_stop_dev(idev); + } return 0; } @@ -854,6 +909,9 @@ static int ne_drv_resume(struct platform_device *pdev) struct net_device *dev = platform_get_drvdata(pdev); if (netif_running(dev)) { + struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; + if (idev) + pnp_start_dev(idev); ne_reset_8390(dev); NS8390p_init(dev, 1); netif_device_attach(dev); @@ -866,7 +924,7 @@ static int ne_drv_resume(struct platform_device *pdev) #endif static struct platform_driver ne_driver = { - .remove = __exit_p(ne_drv_remove), + .remove = ne_drv_remove, .suspend = ne_drv_suspend, .resume = ne_drv_resume, .driver = { @@ -875,91 +933,96 @@ static struct platform_driver ne_driver = { }, }; -static int __init ne_init(void) +static void __init ne_add_devices(void) { - return platform_driver_probe(&ne_driver, ne_drv_probe); -} + int this_dev; + struct platform_device *pdev; -static void __exit ne_exit(void) -{ - platform_driver_unregister(&ne_driver); + for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { + if (pdev_ne[this_dev]) + continue; + pdev = platform_device_register_simple( + DRV_NAME, this_dev, NULL, 0); + if (IS_ERR(pdev)) + continue; + pdev_ne[this_dev] = pdev; + } } #ifdef MODULE -#define MAX_NE_CARDS 4 /* Max number of NE cards per module */ -static struct net_device *dev_ne[MAX_NE_CARDS]; -static int io[MAX_NE_CARDS]; -static int irq[MAX_NE_CARDS]; -static int bad[MAX_NE_CARDS]; /* 0xbad = bad sig or no reset ack */ - -module_param_array(io, int, NULL, 0); -module_param_array(irq, int, NULL, 0); -module_param_array(bad, int, NULL, 0); -MODULE_PARM_DESC(io, "I/O base address(es),required"); -MODULE_PARM_DESC(irq, "IRQ number(s)"); -MODULE_PARM_DESC(bad, "Accept card(s) with bad signatures"); -MODULE_DESCRIPTION("NE1000/NE2000 ISA/PnP Ethernet driver"); -MODULE_LICENSE("GPL"); - -/* This is set up so that no ISA autoprobe takes place. We can't guarantee -that the ne2k probe is the last 8390 based probe to take place (as it -is at boot) and so the probe will get confused by any other 8390 cards. -ISA device autoprobes on a running machine are not recommended anyway. */ - -int __init init_module(void) +int __init init_module() { - int this_dev, found = 0; - int plat_found = !ne_init(); - - for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct net_device *dev = alloc_eip_netdev(); - if (!dev) - break; - dev->irq = irq[this_dev]; - dev->mem_end = bad[this_dev]; - dev->base_addr = io[this_dev]; - if (do_ne_probe(dev) == 0) { - dev_ne[found++] = dev; - continue; - } - free_netdev(dev); - if (found || plat_found) - break; - if (io[this_dev] != 0) - printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]); - else - printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n"); - return -ENXIO; + int retval; + ne_add_devices(); + retval = platform_driver_probe(&ne_driver, ne_drv_probe); + if (retval) { + if (io[0] == 0) + printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\"" + " value(s) for ISA cards.\n"); + ne_loop_rm_unreg(1); + return retval; } - if (found || plat_found) - return 0; - return -ENODEV; -} -static void cleanup_card(struct net_device *dev) + /* Unregister unused platform_devices. */ + ne_loop_rm_unreg(0); + return retval; +} +#else /* MODULE */ +static int __init ne_init(void) { - struct pnp_dev *idev = (struct pnp_dev *)ei_status.priv; - if (idev) - pnp_device_detach(idev); - free_irq(dev->irq, dev); - release_region(dev->base_addr, NE_IO_EXTENT); + int retval = platform_driver_probe(&ne_driver, ne_drv_probe); + + /* Unregister unused platform_devices. */ + ne_loop_rm_unreg(0); + return retval; } +module_init(ne_init); -void __exit cleanup_module(void) +struct net_device * __init ne_probe(int unit) { int this_dev; + struct net_device *dev; + + /* Find an empty slot, that is no net_device and zero io port. */ + this_dev = 0; + while ((pdev_ne[this_dev] && platform_get_drvdata(pdev_ne[this_dev])) || + io[this_dev]) { + if (++this_dev == MAX_NE_CARDS) + return ERR_PTR(-ENOMEM); + } + + /* Get irq, io from kernel command line */ + dev = alloc_eip_netdev(); + if (!dev) + return ERR_PTR(-ENOMEM); - ne_exit(); + sprintf(dev->name, "eth%d", unit); + netdev_boot_setup_check(dev); + + io[this_dev] = dev->base_addr; + irq[this_dev] = dev->irq; + bad[this_dev] = dev->mem_end; + + free_netdev(dev); + + ne_add_devices(); + + /* return the first device found */ for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { - struct net_device *dev = dev_ne[this_dev]; - if (dev) { - unregister_netdev(dev); - cleanup_card(dev); - free_netdev(dev); + if (pdev_ne[this_dev]) { + dev = platform_get_drvdata(pdev_ne[this_dev]); + if (dev) + return dev; } } + + return ERR_PTR(-ENODEV); } -#else /* MODULE */ -module_init(ne_init); -module_exit(ne_exit); #endif /* MODULE */ + +static void __exit ne_exit(void) +{ + platform_driver_unregister(&ne_driver); + ne_loop_rm_unreg(1); +} +module_exit(ne_exit); diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c index 3f9af759cb9..b9bed82e1d2 100644 --- a/drivers/net/netx-eth.c +++ b/drivers/net/netx-eth.c @@ -189,7 +189,7 @@ netx_eth_interrupt(int irq, void *dev_id) if ((status & ISR_CON_HI) || (status & ISR_IND_HI)) printk("%s: unexpected status: 0x%08x\n", - __FUNCTION__, status); + __func__, status); fill_level = readl(NETX_PFIFO_FILL_LEVEL(IND_FIFO_PORT_LO(priv->id))); diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 244ab49c433..f8e601c51da 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -742,7 +742,7 @@ extern char netxen_nic_driver_name[]; } while (0) #else #define DPRINTK(klevel, fmt, args...) do { \ - printk(KERN_##klevel PFX "%s: %s: " fmt, __FUNCTION__,\ + printk(KERN_##klevel PFX "%s: %s: " fmt, __func__,\ (adapter != NULL && adapter->netdev != NULL) ? \ adapter->netdev->name : NULL, \ ## args); } while(0) diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 008fd6618a5..6ef3f0d84bc 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -77,18 +77,18 @@ static irqreturn_t netxen_msi_intr(int irq, void *data); /* PCI Device ID Table */ #define ENTRY(device) \ - {PCI_DEVICE(0x4040, (device)), \ + {PCI_DEVICE(PCI_VENDOR_ID_NETXEN, (device)), \ .class = PCI_CLASS_NETWORK_ETHERNET << 8, .class_mask = ~0} static struct pci_device_id netxen_pci_tbl[] __devinitdata = { - ENTRY(0x0001), - ENTRY(0x0002), - ENTRY(0x0003), - ENTRY(0x0004), - ENTRY(0x0005), - ENTRY(0x0024), - ENTRY(0x0025), - ENTRY(0x0100), + ENTRY(PCI_DEVICE_ID_NX2031_10GXSR), + ENTRY(PCI_DEVICE_ID_NX2031_10GCX4), + ENTRY(PCI_DEVICE_ID_NX2031_4GCU), + ENTRY(PCI_DEVICE_ID_NX2031_IMEZ), + ENTRY(PCI_DEVICE_ID_NX2031_HMEZ), + ENTRY(PCI_DEVICE_ID_NX2031_XG_MGMT), + ENTRY(PCI_DEVICE_ID_NX2031_XG_MGMT2), + ENTRY(PCI_DEVICE_ID_NX3031), {0,} }; @@ -241,7 +241,7 @@ static void netxen_check_options(struct netxen_adapter *adapter) case NETXEN_BRDTYPE_P3_REF_QG: case NETXEN_BRDTYPE_P3_4_GB: case NETXEN_BRDTYPE_P3_4_GB_MM: - adapter->msix_supported = 0; + adapter->msix_supported = !!use_msi_x; adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G; break; diff --git a/drivers/net/niu.c b/drivers/net/niu.c index e4765b713ab..e3be81eba8a 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -5984,6 +5984,56 @@ static void niu_netif_start(struct niu *np) niu_enable_interrupts(np, 1); } +static void niu_reset_buffers(struct niu *np) +{ + int i, j, k, err; + + if (np->rx_rings) { + for (i = 0; i < np->num_rx_rings; i++) { + struct rx_ring_info *rp = &np->rx_rings[i]; + + for (j = 0, k = 0; j < MAX_RBR_RING_SIZE; j++) { + struct page *page; + + page = rp->rxhash[j]; + while (page) { + struct page *next = + (struct page *) page->mapping; + u64 base = page->index; + base = base >> RBR_DESCR_ADDR_SHIFT; + rp->rbr[k++] = cpu_to_le32(base); + page = next; + } + } + for (; k < MAX_RBR_RING_SIZE; k++) { + err = niu_rbr_add_page(np, rp, GFP_ATOMIC, k); + if (unlikely(err)) + break; + } + + rp->rbr_index = rp->rbr_table_size - 1; + rp->rcr_index = 0; + rp->rbr_pending = 0; + rp->rbr_refill_pending = 0; + } + } + if (np->tx_rings) { + for (i = 0; i < np->num_tx_rings; i++) { + struct tx_ring_info *rp = &np->tx_rings[i]; + + for (j = 0; j < MAX_TX_RING_SIZE; j++) { + if (rp->tx_buffs[j].skb) + (void) release_tx_packet(np, rp, j); + } + + rp->pending = MAX_TX_RING_SIZE; + rp->prod = 0; + rp->cons = 0; + rp->wrap_bit = 0; + } + } +} + static void niu_reset_task(struct work_struct *work) { struct niu *np = container_of(work, struct niu, reset_task); @@ -6006,6 +6056,12 @@ static void niu_reset_task(struct work_struct *work) niu_stop_hw(np); + spin_unlock_irqrestore(&np->lock, flags); + + niu_reset_buffers(np); + + spin_lock_irqsave(&np->lock, flags); + err = niu_init_hw(np); if (!err) { np->timer.expires = jiffies + HZ; diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index 53451c3b2c0..0a575fef29e 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c @@ -119,7 +119,7 @@ KERN_INFO " Support available from http://foo.com/bar/baz.html\n"; #ifdef NETDRV_DEBUG /* note: prints function name for you */ -# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) +# define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args) #else # define DPRINTK(fmt, args...) #endif @@ -130,7 +130,7 @@ KERN_INFO " Support available from http://foo.com/bar/baz.html\n"; # define assert(expr) \ if(!(expr)) { \ printk( "Assertion failed! %s,%s,%s,line=%d\n", \ - #expr,__FILE__,__FUNCTION__,__LINE__); \ + #expr,__FILE__,__func__,__LINE__); \ } #endif diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c index 94e0b7ed76f..e7508c10887 100644 --- a/drivers/net/phy/mdio_bus.c +++ b/drivers/net/phy/mdio_bus.c @@ -60,49 +60,14 @@ int mdiobus_register(struct mii_bus *bus) bus->reset(bus); for (i = 0; i < PHY_MAX_ADDR; i++) { - struct phy_device *phydev; + bus->phy_map[i] = NULL; + if ((bus->phy_mask & (1 << i)) == 0) { + struct phy_device *phydev; - if (bus->phy_mask & (1 << i)) { - bus->phy_map[i] = NULL; - continue; + phydev = mdiobus_scan(bus, i); + if (IS_ERR(phydev)) + err = PTR_ERR(phydev); } - - phydev = get_phy_device(bus, i); - - if (IS_ERR(phydev)) - return PTR_ERR(phydev); - - /* There's a PHY at this address - * We need to set: - * 1) IRQ - * 2) bus_id - * 3) parent - * 4) bus - * 5) mii_bus - * And, we need to register it */ - if (phydev) { - phydev->irq = bus->irq[i]; - - phydev->dev.parent = bus->dev; - phydev->dev.bus = &mdio_bus_type; - snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, i); - - phydev->bus = bus; - - /* Run all of the fixups for this PHY */ - phy_scan_fixups(phydev); - - err = device_register(&phydev->dev); - - if (err) { - printk(KERN_ERR "phy %d failed to register\n", - i); - phy_device_free(phydev); - phydev = NULL; - } - } - - bus->phy_map[i] = phydev; } pr_info("%s: probed\n", bus->name); @@ -122,6 +87,48 @@ void mdiobus_unregister(struct mii_bus *bus) } EXPORT_SYMBOL(mdiobus_unregister); +struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr) +{ + struct phy_device *phydev; + int err; + + phydev = get_phy_device(bus, addr); + if (IS_ERR(phydev) || phydev == NULL) + return phydev; + + /* There's a PHY at this address + * We need to set: + * 1) IRQ + * 2) bus_id + * 3) parent + * 4) bus + * 5) mii_bus + * And, we need to register it */ + + phydev->irq = bus->irq != NULL ? bus->irq[addr] : PHY_POLL; + + phydev->dev.parent = bus->dev; + phydev->dev.bus = &mdio_bus_type; + snprintf(phydev->dev.bus_id, BUS_ID_SIZE, PHY_ID_FMT, bus->id, addr); + + phydev->bus = bus; + + /* Run all of the fixups for this PHY */ + phy_scan_fixups(phydev); + + err = device_register(&phydev->dev); + if (err) { + printk(KERN_ERR "phy %d failed to register\n", addr); + phy_device_free(phydev); + phydev = NULL; + } + + bus->phy_map[addr] = phydev; + + return phydev; +} +EXPORT_SYMBOL(mdiobus_scan); + /** * mdio_bus_match - determine if given PHY driver supports the given PHY device * @dev: target PHY device diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index ddccc074a76..5d4d21516a6 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1833,9 +1833,11 @@ ppp_receive_mp_frame(struct ppp *ppp, struct sk_buff *skb, struct channel *pch) /* If the queue is getting long, don't wait any longer for packets before the start of the queue. */ - if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN - && seq_before(ppp->minseq, ppp->mrq.next->sequence)) - ppp->minseq = ppp->mrq.next->sequence; + if (skb_queue_len(&ppp->mrq) >= PPP_MP_MAX_QLEN) { + struct sk_buff *skb = skb_peek(&ppp->mrq); + if (seq_before(ppp->minseq, skb->sequence)) + ppp->minseq = skb->sequence; + } /* Pull completed packets off the queue and receive them. */ while ((skb = ppp_mp_reconstruct(ppp))) @@ -1864,7 +1866,7 @@ ppp_mp_insert(struct ppp *ppp, struct sk_buff *skb) for (p = list->next; p != (struct sk_buff *)list; p = p->next) if (seq_before(seq, p->sequence)) break; - __skb_insert(skb, p->prev, p, list); + __skb_queue_before(list, p, skb); } /* diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c index ff175e8f36b..185b1dff10a 100644 --- a/drivers/net/pppol2tp.c +++ b/drivers/net/pppol2tp.c @@ -353,7 +353,7 @@ static void pppol2tp_recv_queue_skb(struct pppol2tp_session *session, struct sk_ spin_lock_bh(&session->reorder_q.lock); skb_queue_walk_safe(&session->reorder_q, skbp, tmp) { if (PPPOL2TP_SKB_CB(skbp)->ns > ns) { - __skb_insert(skb, skbp->prev, skbp, &session->reorder_q); + __skb_queue_before(&session->reorder_q, skbp, skb); PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG, "%s: pkt %hu, inserted before %hu, reorder_q len=%d\n", session->name, ns, PPPOL2TP_SKB_CB(skbp)->ns, diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 5d86281d936..34fe7ef8e5e 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c @@ -265,7 +265,7 @@ static void r6040_free_txbufs(struct net_device *dev) le32_to_cpu(lp->tx_insert_ptr->buf), MAX_BUF_SIZE, PCI_DMA_TODEVICE); dev_kfree_skb(lp->tx_insert_ptr->skb_ptr); - lp->rx_insert_ptr->skb_ptr = NULL; + lp->tx_insert_ptr->skb_ptr = NULL; } lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp; } @@ -370,7 +370,7 @@ static void r6040_init_mac_regs(struct net_device *dev) /* Reset internal state machine */ iowrite16(2, ioaddr + MAC_SM); iowrite16(0, ioaddr + MAC_SM); - udelay(5000); + mdelay(5); /* MAC Bus Control Register */ iowrite16(MBCR_DEFAULT, ioaddr + MBCR); @@ -806,7 +806,7 @@ static void r6040_mac_address(struct net_device *dev) iowrite16(0x01, ioaddr + MCR1); /* Reset MAC */ iowrite16(2, ioaddr + MAC_SM); /* Reset internal state machine */ iowrite16(0, ioaddr + MAC_SM); - udelay(5000); + mdelay(5); /* Restore MAC Address */ adrp = (u16 *) dev->dev_addr; diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 1822491f19c..fb899c675f4 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -36,7 +36,7 @@ #define assert(expr) \ if (!(expr)) { \ printk( "Assertion failed! %s,%s,%s,line=%d\n", \ - #expr,__FILE__,__FUNCTION__,__LINE__); \ + #expr,__FILE__,__func__,__LINE__); \ } #define dprintk(fmt, args...) \ do { printk(KERN_DEBUG PFX fmt, ## args); } while (0) @@ -2286,8 +2286,6 @@ static void rtl_hw_start_8168(struct net_device *dev) RTL_R8(IntrMask); - RTL_W32(RxMissed, 0); - rtl_set_rx_mode(dev); RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); @@ -2412,8 +2410,6 @@ static void rtl_hw_start_8101(struct net_device *dev) RTL_R8(IntrMask); - RTL_W32(RxMissed, 0); - rtl_set_rx_mode(dev); RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); @@ -3191,6 +3187,17 @@ static int rtl8169_poll(struct napi_struct *napi, int budget) return work_done; } +static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr) +{ + struct rtl8169_private *tp = netdev_priv(dev); + + if (tp->mac_version > RTL_GIGA_MAC_VER_06) + return; + + dev->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff); + RTL_W32(RxMissed, 0); +} + static void rtl8169_down(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -3208,9 +3215,7 @@ core_down: rtl8169_asic_down(ioaddr); - /* Update the error counts. */ - dev->stats.rx_missed_errors += RTL_R32(RxMissed); - RTL_W32(RxMissed, 0); + rtl8169_rx_missed(dev, ioaddr); spin_unlock_irq(&tp->lock); @@ -3332,8 +3337,7 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev) if (netif_running(dev)) { spin_lock_irqsave(&tp->lock, flags); - dev->stats.rx_missed_errors += RTL_R32(RxMissed); - RTL_W32(RxMissed, 0); + rtl8169_rx_missed(dev, ioaddr); spin_unlock_irqrestore(&tp->lock, flags); } @@ -3358,8 +3362,7 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state) rtl8169_asic_down(ioaddr); - dev->stats.rx_missed_errors += RTL_R32(RxMissed); - RTL_W32(RxMissed, 0); + rtl8169_rx_missed(dev, ioaddr); spin_unlock_irq(&tp->lock); diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 243db33042a..6a1375f9cbb 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -371,9 +371,6 @@ static void s2io_vlan_rx_register(struct net_device *dev, flags[i]); } -/* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */ -static int vlan_strip_flag; - /* Unregister the vlan */ static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid) { @@ -2303,7 +2300,7 @@ static int start_nic(struct s2io_nic *nic) val64 = readq(&bar0->rx_pa_cfg); val64 &= ~RX_PA_CFG_STRIP_VLAN_TAG; writeq(val64, &bar0->rx_pa_cfg); - vlan_strip_flag = 0; + nic->vlan_strip_flag = 0; } /* @@ -3136,7 +3133,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data) if (skb == NULL) { spin_unlock_irqrestore(&fifo_data->tx_lock, flags); DBG_PRINT(ERR_DBG, "%s: Null skb ", - __FUNCTION__); + __func__); DBG_PRINT(ERR_DBG, "in Tx Free Intr\n"); return; } @@ -3496,7 +3493,7 @@ static void s2io_reset(struct s2io_nic * sp) unsigned long long mem_alloc_cnt, mem_free_cnt, watchdog_cnt; DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n", - __FUNCTION__, sp->dev->name); + __func__, sp->dev->name); /* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */ pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd)); @@ -3518,7 +3515,7 @@ static void s2io_reset(struct s2io_nic * sp) } if (check_pci_device_id(val16) == (u16)PCI_ANY_ID) { - DBG_PRINT(ERR_DBG,"%s SW_Reset failed!\n", __FUNCTION__); + DBG_PRINT(ERR_DBG,"%s SW_Reset failed!\n", __func__); } pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, pci_cmd); @@ -3768,7 +3765,7 @@ static void restore_xmsi_data(struct s2io_nic *nic) val64 = (s2BIT(7) | s2BIT(15) | vBIT(msix_index, 26, 6)); writeq(val64, &bar0->xmsi_access); if (wait_for_msix_trans(nic, msix_index)) { - DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); + DBG_PRINT(ERR_DBG, "failed in %s\n", __func__); continue; } } @@ -3789,7 +3786,7 @@ static void store_xmsi_data(struct s2io_nic *nic) val64 = (s2BIT(15) | vBIT(msix_index, 26, 6)); writeq(val64, &bar0->xmsi_access); if (wait_for_msix_trans(nic, msix_index)) { - DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); + DBG_PRINT(ERR_DBG, "failed in %s\n", __func__); continue; } addr = readq(&bar0->xmsi_address); @@ -3812,7 +3809,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) GFP_KERNEL); if (!nic->entries) { DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \ - __FUNCTION__); + __func__); nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; return -ENOMEM; } @@ -3826,7 +3823,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) GFP_KERNEL); if (!nic->s2io_entries) { DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", - __FUNCTION__); + __func__); nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; kfree(nic->entries); nic->mac_control.stats_info->sw_stat.mem_freed @@ -5010,7 +5007,7 @@ static void s2io_set_multicast(struct net_device *dev) val64 = readq(&bar0->rx_pa_cfg); val64 &= ~RX_PA_CFG_STRIP_VLAN_TAG; writeq(val64, &bar0->rx_pa_cfg); - vlan_strip_flag = 0; + sp->vlan_strip_flag = 0; } val64 = readq(&bar0->mac_cfg); @@ -5032,7 +5029,7 @@ static void s2io_set_multicast(struct net_device *dev) val64 = readq(&bar0->rx_pa_cfg); val64 |= RX_PA_CFG_STRIP_VLAN_TAG; writeq(val64, &bar0->rx_pa_cfg); - vlan_strip_flag = 1; + sp->vlan_strip_flag = 1; } val64 = readq(&bar0->mac_cfg); @@ -6746,7 +6743,7 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) ret = s2io_card_up(sp); if (ret) { DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", - __FUNCTION__); + __func__); return ret; } s2io_wake_all_tx_queue(sp); @@ -7530,7 +7527,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) default: DBG_PRINT(ERR_DBG, "%s: Samadhana!!\n", - __FUNCTION__); + __func__); BUG(); } } @@ -7781,7 +7778,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) return -ENOMEM; } if ((ret = pci_request_regions(pdev, s2io_driver_name))) { - DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __FUNCTION__, ret); + DBG_PRINT(ERR_DBG, "%s: Request Regions failed - %x \n", __func__, ret); pci_disable_device(pdev); return -ENODEV; } @@ -7998,7 +7995,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) if (sp->device_type & XFRAME_II_DEVICE) { mode = s2io_verify_pci_mode(sp); if (mode < 0) { - DBG_PRINT(ERR_DBG, "%s: ", __FUNCTION__); + DBG_PRINT(ERR_DBG, "%s: ", __func__); DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode\n"); ret = -EBADSLT; goto set_swap_failed; @@ -8206,6 +8203,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) /* Initialize device name */ sprintf(sp->name, "%s Neterion %s", dev->name, sp->product_name); + if (vlan_tag_strip) + sp->vlan_strip_flag = 1; + else + sp->vlan_strip_flag = 0; + /* * Make Link state as off at this point, when the Link change * interrupt comes the state will be automatically changed to @@ -8299,7 +8301,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, if (!(rxdp->Control_1 & RXD_FRAME_PROTO_TCP)) { DBG_PRINT(INIT_DBG,"%s: Non-TCP frames not supported for LRO\n", - __FUNCTION__); + __func__); return -1; } @@ -8311,7 +8313,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, * If vlan stripping is disabled and the frame is VLAN tagged, * shift the offset by the VLAN header size bytes. */ - if ((!vlan_strip_flag) && + if ((!sp->vlan_strip_flag) && (rxdp->Control_1 & RXD_FRAME_VLAN_TAG)) ip_off += HEADER_VLAN_SIZE; } else { @@ -8330,7 +8332,7 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, static int check_for_socket_match(struct lro *lro, struct iphdr *ip, struct tcphdr *tcp) { - DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); + DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__); if ((lro->iph->saddr != ip->saddr) || (lro->iph->daddr != ip->daddr) || (lro->tcph->source != tcp->source) || (lro->tcph->dest != tcp->dest)) return -1; @@ -8345,7 +8347,7 @@ static inline int get_l4_pyld_length(struct iphdr *ip, struct tcphdr *tcp) static void initiate_new_session(struct lro *lro, u8 *l2h, struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len, u16 vlan_tag) { - DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); + DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__); lro->l2h = l2h; lro->iph = ip; lro->tcph = tcp; @@ -8375,7 +8377,7 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro) struct tcphdr *tcp = lro->tcph; __sum16 nchk; struct stat_block *statinfo = sp->mac_control.stats_info; - DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); + DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__); /* Update L3 header */ ip->tot_len = htons(lro->total_len); @@ -8403,7 +8405,7 @@ static void update_L3L4_header(struct s2io_nic *sp, struct lro *lro) static void aggregate_new_rx(struct lro *lro, struct iphdr *ip, struct tcphdr *tcp, u32 l4_pyld) { - DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); + DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__); lro->total_len += l4_pyld; lro->frags_len += l4_pyld; lro->tcp_next_seq += l4_pyld; @@ -8427,7 +8429,7 @@ static int verify_l3_l4_lro_capable(struct lro *l_lro, struct iphdr *ip, { u8 *ptr; - DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); + DBG_PRINT(INFO_DBG,"%s: Been here...\n", __func__); if (!tcp_pyld_len) { /* Runt frame or a pure ack */ @@ -8509,7 +8511,7 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp, if ((*lro)->tcp_next_seq != ntohl(tcph->seq)) { DBG_PRINT(INFO_DBG, "%s:Out of order. expected " - "0x%x, actual 0x%x\n", __FUNCTION__, + "0x%x, actual 0x%x\n", __func__, (*lro)->tcp_next_seq, ntohl(tcph->seq)); @@ -8549,7 +8551,7 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp, if (ret == 0) { /* sessions exceeded */ DBG_PRINT(INFO_DBG,"%s:All LRO sessions already in use\n", - __FUNCTION__); + __func__); *lro = NULL; return ret; } @@ -8571,7 +8573,7 @@ s2io_club_tcp_session(struct ring_info *ring_data, u8 *buffer, u8 **tcp, break; default: DBG_PRINT(ERR_DBG,"%s:Dont know, can't say!!\n", - __FUNCTION__); + __func__); break; } @@ -8592,7 +8594,7 @@ static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag) skb->protocol = eth_type_trans(skb, dev); if (sp->vlgrp && vlan_tag - && (vlan_strip_flag)) { + && (sp->vlan_strip_flag)) { /* Queueing the vlan frame to the upper layer */ if (sp->config.napi) vlan_hwaccel_receive_skb(skb, sp->vlgrp, vlan_tag); diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 6722a2f7d09..55cb943f23f 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h @@ -962,6 +962,7 @@ struct s2io_nic { int task_flag; unsigned long long start_time; struct vlan_group *vlgrp; + int vlan_strip_flag; #define MSIX_FLG 0xA5 int num_entries; struct msix_entry *entries; diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index fe41e4ec21e..ce10cfa1ee5 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -2069,9 +2069,10 @@ static irqreturn_t sbmac_intr(int irq,void *dev_instance) static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev) { struct sbmac_softc *sc = netdev_priv(dev); + unsigned long flags; /* lock eth irq */ - spin_lock_irq (&sc->sbm_lock); + spin_lock_irqsave(&sc->sbm_lock, flags); /* * Put the buffer on the transmit ring. If we @@ -2081,14 +2082,14 @@ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev) if (sbdma_add_txbuffer(&(sc->sbm_txdma),skb)) { /* XXX save skb that we could not send */ netif_stop_queue(dev); - spin_unlock_irq(&sc->sbm_lock); + spin_unlock_irqrestore(&sc->sbm_lock, flags); return 1; } dev->trans_start = jiffies; - spin_unlock_irq (&sc->sbm_lock); + spin_unlock_irqrestore(&sc->sbm_lock, flags); return 0; } @@ -2568,14 +2569,15 @@ static void sbmac_mii_poll(struct net_device *dev) static void sbmac_tx_timeout (struct net_device *dev) { struct sbmac_softc *sc = netdev_priv(dev); + unsigned long flags; - spin_lock_irq (&sc->sbm_lock); + spin_lock_irqsave(&sc->sbm_lock, flags); dev->trans_start = jiffies; dev->stats.tx_errors++; - spin_unlock_irq (&sc->sbm_lock); + spin_unlock_irqrestore(&sc->sbm_lock, flags); printk (KERN_WARNING "%s: Transmit timed out\n",dev->name); } diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 0d47d6ffe68..06ea71c7e34 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c @@ -445,10 +445,17 @@ static void efx_fini_channels(struct efx_nic *efx) struct efx_channel *channel; struct efx_tx_queue *tx_queue; struct efx_rx_queue *rx_queue; + int rc; EFX_ASSERT_RESET_SERIALISED(efx); BUG_ON(efx->port_enabled); + rc = falcon_flush_queues(efx); + if (rc) + EFX_ERR(efx, "failed to flush queues\n"); + else + EFX_LOG(efx, "successfully flushed all queues\n"); + efx_for_each_channel(channel, efx) { EFX_LOG(channel->efx, "shut down chan %d\n", channel->channel); @@ -456,13 +463,6 @@ static void efx_fini_channels(struct efx_nic *efx) efx_fini_rx_queue(rx_queue); efx_for_each_channel_tx_queue(tx_queue, channel) efx_fini_tx_queue(tx_queue); - } - - /* Do the event queues last so that we can handle flush events - * for all DMA queues. */ - efx_for_each_channel(channel, efx) { - EFX_LOG(channel->efx, "shut down evq %d\n", channel->channel); - efx_fini_eventq(channel); } } @@ -780,7 +780,7 @@ static int efx_init_io(struct efx_nic *efx) return 0; fail4: - release_mem_region(efx->membase_phys, efx->type->mem_map_size); + pci_release_region(efx->pci_dev, efx->type->mem_bar); fail3: efx->membase_phys = 0; fail2: @@ -1092,7 +1092,6 @@ static void efx_stop_all(struct efx_nic *efx) /* Isolate the MAC from the TX and RX engines, so that queue * flushes will complete in a timely fashion. */ - falcon_deconfigure_mac_wrapper(efx); falcon_drain_tx_fifo(efx); /* Stop the kernel transmit interface late, so the watchdog @@ -1750,7 +1749,6 @@ static struct efx_phy_operations efx_dummy_phy_operations = { .check_hw = efx_port_dummy_op_int, .fini = efx_port_dummy_op_void, .clear_interrupt = efx_port_dummy_op_void, - .reset_xaui = efx_port_dummy_op_void, }; static struct efx_board efx_dummy_board_info = { diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index e0c0b23f94e..31ed1f49de0 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -108,10 +108,10 @@ MODULE_PARM_DESC(rx_xon_thresh_bytes, "RX fifo XON threshold"); /* Max number of internal errors. After this resets will not be performed */ #define FALCON_MAX_INT_ERRORS 4 -/* Maximum period that we wait for flush events. If the flush event - * doesn't arrive in this period of time then we check if the queue - * was disabled anyway. */ -#define FALCON_FLUSH_TIMEOUT 10 /* 10ms */ +/* We poll for events every FLUSH_INTERVAL ms, and check FLUSH_POLL_COUNT times + */ +#define FALCON_FLUSH_INTERVAL 10 +#define FALCON_FLUSH_POLL_COUNT 100 /************************************************************************** * @@ -452,6 +452,8 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue) efx_oword_t tx_desc_ptr; struct efx_nic *efx = tx_queue->efx; + tx_queue->flushed = false; + /* Pin TX descriptor ring */ falcon_init_special_buffer(efx, &tx_queue->txd); @@ -492,60 +494,16 @@ void falcon_init_tx(struct efx_tx_queue *tx_queue) } } -static int falcon_flush_tx_queue(struct efx_tx_queue *tx_queue) +static void falcon_flush_tx_queue(struct efx_tx_queue *tx_queue) { struct efx_nic *efx = tx_queue->efx; - struct efx_channel *channel = &efx->channel[0]; efx_oword_t tx_flush_descq; - unsigned int read_ptr, i; /* Post a flush command */ EFX_POPULATE_OWORD_2(tx_flush_descq, TX_FLUSH_DESCQ_CMD, 1, TX_FLUSH_DESCQ, tx_queue->queue); falcon_write(efx, &tx_flush_descq, TX_FLUSH_DESCQ_REG_KER); - msleep(FALCON_FLUSH_TIMEOUT); - - if (EFX_WORKAROUND_7803(efx)) - return 0; - - /* Look for a flush completed event */ - read_ptr = channel->eventq_read_ptr; - for (i = 0; i < FALCON_EVQ_SIZE; ++i) { - efx_qword_t *event = falcon_event(channel, read_ptr); - int ev_code, ev_sub_code, ev_queue; - if (!falcon_event_present(event)) - break; - - ev_code = EFX_QWORD_FIELD(*event, EV_CODE); - ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE); - ev_queue = EFX_QWORD_FIELD(*event, DRIVER_EV_TX_DESCQ_ID); - if ((ev_sub_code == TX_DESCQ_FLS_DONE_EV_DECODE) && - (ev_queue == tx_queue->queue)) { - EFX_LOG(efx, "tx queue %d flush command succesful\n", - tx_queue->queue); - return 0; - } - - read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK; - } - - if (EFX_WORKAROUND_11557(efx)) { - efx_oword_t reg; - bool enabled; - - falcon_read_table(efx, ®, efx->type->txd_ptr_tbl_base, - tx_queue->queue); - enabled = EFX_OWORD_FIELD(reg, TX_DESCQ_EN); - if (!enabled) { - EFX_LOG(efx, "tx queue %d disabled without a " - "flush event seen\n", tx_queue->queue); - return 0; - } - } - - EFX_ERR(efx, "tx queue %d flush command timed out\n", tx_queue->queue); - return -ETIMEDOUT; } void falcon_fini_tx(struct efx_tx_queue *tx_queue) @@ -553,9 +511,8 @@ void falcon_fini_tx(struct efx_tx_queue *tx_queue) struct efx_nic *efx = tx_queue->efx; efx_oword_t tx_desc_ptr; - /* Stop the hardware using the queue */ - if (falcon_flush_tx_queue(tx_queue)) - EFX_ERR(efx, "failed to flush tx queue %d\n", tx_queue->queue); + /* The queue should have been flushed */ + WARN_ON(!tx_queue->flushed); /* Remove TX descriptor ring from card */ EFX_ZERO_OWORD(tx_desc_ptr); @@ -643,6 +600,8 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue) rx_queue->queue, rx_queue->rxd.index, rx_queue->rxd.index + rx_queue->rxd.entries - 1); + rx_queue->flushed = false; + /* Pin RX descriptor ring */ falcon_init_special_buffer(efx, &rx_queue->rxd); @@ -663,11 +622,9 @@ void falcon_init_rx(struct efx_rx_queue *rx_queue) rx_queue->queue); } -static int falcon_flush_rx_queue(struct efx_rx_queue *rx_queue) +static void falcon_flush_rx_queue(struct efx_rx_queue *rx_queue) { struct efx_nic *efx = rx_queue->efx; - struct efx_channel *channel = &efx->channel[0]; - unsigned int read_ptr, i; efx_oword_t rx_flush_descq; /* Post a flush command */ @@ -675,76 +632,15 @@ static int falcon_flush_rx_queue(struct efx_rx_queue *rx_queue) RX_FLUSH_DESCQ_CMD, 1, RX_FLUSH_DESCQ, rx_queue->queue); falcon_write(efx, &rx_flush_descq, RX_FLUSH_DESCQ_REG_KER); - msleep(FALCON_FLUSH_TIMEOUT); - - if (EFX_WORKAROUND_7803(efx)) - return 0; - - /* Look for a flush completed event */ - read_ptr = channel->eventq_read_ptr; - for (i = 0; i < FALCON_EVQ_SIZE; ++i) { - efx_qword_t *event = falcon_event(channel, read_ptr); - int ev_code, ev_sub_code, ev_queue; - bool ev_failed; - if (!falcon_event_present(event)) - break; - - ev_code = EFX_QWORD_FIELD(*event, EV_CODE); - ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE); - ev_queue = EFX_QWORD_FIELD(*event, DRIVER_EV_RX_DESCQ_ID); - ev_failed = EFX_QWORD_FIELD(*event, DRIVER_EV_RX_FLUSH_FAIL); - - if ((ev_sub_code == RX_DESCQ_FLS_DONE_EV_DECODE) && - (ev_queue == rx_queue->queue)) { - if (ev_failed) { - EFX_INFO(efx, "rx queue %d flush command " - "failed\n", rx_queue->queue); - return -EAGAIN; - } else { - EFX_LOG(efx, "rx queue %d flush command " - "succesful\n", rx_queue->queue); - return 0; - } - } - - read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK; - } - - if (EFX_WORKAROUND_11557(efx)) { - efx_oword_t reg; - bool enabled; - - falcon_read_table(efx, ®, efx->type->rxd_ptr_tbl_base, - rx_queue->queue); - enabled = EFX_OWORD_FIELD(reg, RX_DESCQ_EN); - if (!enabled) { - EFX_LOG(efx, "rx queue %d disabled without a " - "flush event seen\n", rx_queue->queue); - return 0; - } - } - - EFX_ERR(efx, "rx queue %d flush command timed out\n", rx_queue->queue); - return -ETIMEDOUT; } void falcon_fini_rx(struct efx_rx_queue *rx_queue) { efx_oword_t rx_desc_ptr; struct efx_nic *efx = rx_queue->efx; - int i, rc; - /* Try and flush the rx queue. This may need to be repeated */ - for (i = 0; i < 5; i++) { - rc = falcon_flush_rx_queue(rx_queue); - if (rc == -EAGAIN) - continue; - break; - } - if (rc) { - EFX_ERR(efx, "failed to flush rx queue %d\n", rx_queue->queue); - efx_schedule_reset(efx, RESET_TYPE_INVISIBLE); - } + /* The queue should already have been flushed */ + WARN_ON(!rx_queue->flushed); /* Remove RX descriptor ring from card */ EFX_ZERO_OWORD(rx_desc_ptr); @@ -1007,7 +903,7 @@ static void falcon_handle_global_event(struct efx_channel *channel, is_phy_event = true; if ((falcon_rev(efx) >= FALCON_REV_B0) && - EFX_OWORD_FIELD(*event, XG_MNT_INTR_B0)) + EFX_QWORD_FIELD(*event, XG_MNT_INTR_B0)) is_phy_event = true; if (is_phy_event) { @@ -1255,6 +1151,121 @@ void falcon_generate_test_event(struct efx_channel *channel, unsigned int magic) falcon_generate_event(channel, &test_event); } +/************************************************************************** + * + * Flush handling + * + **************************************************************************/ + + +static void falcon_poll_flush_events(struct efx_nic *efx) +{ + struct efx_channel *channel = &efx->channel[0]; + struct efx_tx_queue *tx_queue; + struct efx_rx_queue *rx_queue; + unsigned int read_ptr, i; + + read_ptr = channel->eventq_read_ptr; + for (i = 0; i < FALCON_EVQ_SIZE; ++i) { + efx_qword_t *event = falcon_event(channel, read_ptr); + int ev_code, ev_sub_code, ev_queue; + bool ev_failed; + if (!falcon_event_present(event)) + break; + + ev_code = EFX_QWORD_FIELD(*event, EV_CODE); + if (ev_code != DRIVER_EV_DECODE) + continue; + + ev_sub_code = EFX_QWORD_FIELD(*event, DRIVER_EV_SUB_CODE); + switch (ev_sub_code) { + case TX_DESCQ_FLS_DONE_EV_DECODE: + ev_queue = EFX_QWORD_FIELD(*event, + DRIVER_EV_TX_DESCQ_ID); + if (ev_queue < EFX_TX_QUEUE_COUNT) { + tx_queue = efx->tx_queue + ev_queue; + tx_queue->flushed = true; + } + break; + case RX_DESCQ_FLS_DONE_EV_DECODE: + ev_queue = EFX_QWORD_FIELD(*event, + DRIVER_EV_RX_DESCQ_ID); + ev_failed = EFX_QWORD_FIELD(*event, + DRIVER_EV_RX_FLUSH_FAIL); + if (ev_queue < efx->n_rx_queues) { + rx_queue = efx->rx_queue + ev_queue; + + /* retry the rx flush */ + if (ev_failed) + falcon_flush_rx_queue(rx_queue); + else + rx_queue->flushed = true; + } + break; + } + + read_ptr = (read_ptr + 1) & FALCON_EVQ_MASK; + } +} + +/* Handle tx and rx flushes at the same time, since they run in + * parallel in the hardware and there's no reason for us to + * serialise them */ +int falcon_flush_queues(struct efx_nic *efx) +{ + struct efx_rx_queue *rx_queue; + struct efx_tx_queue *tx_queue; + int i; + bool outstanding; + + /* Issue flush requests */ + efx_for_each_tx_queue(tx_queue, efx) { + tx_queue->flushed = false; + falcon_flush_tx_queue(tx_queue); + } + efx_for_each_rx_queue(rx_queue, efx) { + rx_queue->flushed = false; + falcon_flush_rx_queue(rx_queue); + } + + /* Poll the evq looking for flush completions. Since we're not pushing + * any more rx or tx descriptors at this point, we're in no danger of + * overflowing the evq whilst we wait */ + for (i = 0; i < FALCON_FLUSH_POLL_COUNT; ++i) { + msleep(FALCON_FLUSH_INTERVAL); + falcon_poll_flush_events(efx); + + /* Check if every queue has been succesfully flushed */ + outstanding = false; + efx_for_each_tx_queue(tx_queue, efx) + outstanding |= !tx_queue->flushed; + efx_for_each_rx_queue(rx_queue, efx) + outstanding |= !rx_queue->flushed; + if (!outstanding) + return 0; + } + + /* Mark the queues as all flushed. We're going to return failure + * leading to a reset, or fake up success anyway. "flushed" now + * indicates that we tried to flush. */ + efx_for_each_tx_queue(tx_queue, efx) { + if (!tx_queue->flushed) + EFX_ERR(efx, "tx queue %d flush command timed out\n", + tx_queue->queue); + tx_queue->flushed = true; + } + efx_for_each_rx_queue(rx_queue, efx) { + if (!rx_queue->flushed) + EFX_ERR(efx, "rx queue %d flush command timed out\n", + rx_queue->queue); + rx_queue->flushed = true; + } + + if (EFX_WORKAROUND_7803(efx)) + return 0; + + return -ETIMEDOUT; +} /************************************************************************** * @@ -1363,10 +1374,11 @@ static irqreturn_t falcon_fatal_interrupt(struct efx_nic *efx) EFX_OWORD_FMT "\n", EFX_OWORD_VAL(reg)); } - /* Disable DMA bus mastering on both devices */ + /* Disable both devices */ pci_disable_device(efx->pci_dev); if (FALCON_IS_DUAL_FUNC(efx)) pci_disable_device(nic_data->pci_dev2); + falcon_disable_interrupts(efx); if (++n_int_errors < FALCON_MAX_INT_ERRORS) { EFX_ERR(efx, "SYSTEM ERROR - reset scheduled\n"); @@ -1593,7 +1605,7 @@ void falcon_fini_interrupt(struct efx_nic *efx) ************************************************************************** */ -#define FALCON_SPI_MAX_LEN sizeof(efx_oword_t) +#define FALCON_SPI_MAX_LEN ((unsigned) sizeof(efx_oword_t)) /* Wait for SPI command completion */ static int falcon_spi_wait(struct efx_nic *efx) @@ -1942,8 +1954,10 @@ int falcon_dma_stats(struct efx_nic *efx, unsigned int done_offset) /* Wait for transfer to complete */ for (i = 0; i < 400; i++) { - if (*(volatile u32 *)dma_done == FALCON_STATS_DONE) + if (*(volatile u32 *)dma_done == FALCON_STATS_DONE) { + rmb(); /* Ensure the stats are valid. */ return 0; + } udelay(10); } @@ -2758,6 +2772,8 @@ int falcon_probe_nic(struct efx_nic *efx) /* Allocate storage for hardware specific data */ nic_data = kzalloc(sizeof(*nic_data), GFP_KERNEL); + if (!nic_data) + return -ENOMEM; efx->nic_data = nic_data; /* Determine number of ports etc. */ diff --git a/drivers/net/sfc/falcon.h b/drivers/net/sfc/falcon.h index 30d61e48ac6..be025ba7a6c 100644 --- a/drivers/net/sfc/falcon.h +++ b/drivers/net/sfc/falcon.h @@ -86,6 +86,7 @@ extern void falcon_fini_interrupt(struct efx_nic *efx); extern int falcon_probe_nic(struct efx_nic *efx); extern int falcon_probe_resources(struct efx_nic *efx); extern int falcon_init_nic(struct efx_nic *efx); +extern int falcon_flush_queues(struct efx_nic *efx); extern int falcon_reset_hw(struct efx_nic *efx, enum reset_type method); extern void falcon_remove_resources(struct efx_nic *efx); extern void falcon_remove_nic(struct efx_nic *efx); diff --git a/drivers/net/sfc/falcon_hwdefs.h b/drivers/net/sfc/falcon_hwdefs.h index e319fd64d07..5d584b0dbb5 100644 --- a/drivers/net/sfc/falcon_hwdefs.h +++ b/drivers/net/sfc/falcon_hwdefs.h @@ -117,7 +117,6 @@ #define SF_PRST_WIDTH 1 #define EE_PRST_LBN 8 #define EE_PRST_WIDTH 1 -/* See pic_mode_t for decoding of this field */ /* These bit definitions are extrapolated from the list of numerical * values for STRAP_PINS. */ diff --git a/drivers/net/sfc/falcon_io.h b/drivers/net/sfc/falcon_io.h index 6670cdfc41a..c16da3149fa 100644 --- a/drivers/net/sfc/falcon_io.h +++ b/drivers/net/sfc/falcon_io.h @@ -13,7 +13,6 @@ #include <linux/io.h> #include <linux/spinlock.h> -#include "net_driver.h" /************************************************************************** * diff --git a/drivers/net/sfc/falcon_xmac.c b/drivers/net/sfc/falcon_xmac.c index 0d9f68ff71e..d4012314dd0 100644 --- a/drivers/net/sfc/falcon_xmac.c +++ b/drivers/net/sfc/falcon_xmac.c @@ -78,79 +78,7 @@ static void falcon_setup_xaui(struct efx_nic *efx) falcon_write(efx, &txdrv, XX_TXDRV_CTL_REG); } -static void falcon_hold_xaui_in_rst(struct efx_nic *efx) -{ - efx_oword_t reg; - - EFX_ZERO_OWORD(reg); - EFX_SET_OWORD_FIELD(reg, XX_PWRDNA_EN, 1); - EFX_SET_OWORD_FIELD(reg, XX_PWRDNB_EN, 1); - EFX_SET_OWORD_FIELD(reg, XX_PWRDNC_EN, 1); - EFX_SET_OWORD_FIELD(reg, XX_PWRDND_EN, 1); - EFX_SET_OWORD_FIELD(reg, XX_RSTPLLAB_EN, 1); - EFX_SET_OWORD_FIELD(reg, XX_RSTPLLCD_EN, 1); - EFX_SET_OWORD_FIELD(reg, XX_RESETA_EN, 1); - EFX_SET_OWORD_FIELD(reg, XX_RESETB_EN, 1); - EFX_SET_OWORD_FIELD(reg, XX_RESETC_EN, 1); - EFX_SET_OWORD_FIELD(reg, XX_RESETD_EN, 1); - EFX_SET_OWORD_FIELD(reg, XX_RSTXGXSRX_EN, 1); - EFX_SET_OWORD_FIELD(reg, XX_RSTXGXSTX_EN, 1); - falcon_write(efx, ®, XX_PWR_RST_REG); - udelay(10); -} - -static int _falcon_reset_xaui_a(struct efx_nic *efx) -{ - efx_oword_t reg; - - falcon_hold_xaui_in_rst(efx); - falcon_read(efx, ®, XX_PWR_RST_REG); - - /* Follow the RAMBUS XAUI data reset sequencing - * Channels A and B first: power down, reset PLL, reset, clear - */ - EFX_SET_OWORD_FIELD(reg, XX_PWRDNA_EN, 0); - EFX_SET_OWORD_FIELD(reg, XX_PWRDNB_EN, 0); - falcon_write(efx, ®, XX_PWR_RST_REG); - udelay(10); - - EFX_SET_OWORD_FIELD(reg, XX_RSTPLLAB_EN, 0); - falcon_write(efx, ®, XX_PWR_RST_REG); - udelay(10); - - EFX_SET_OWORD_FIELD(reg, XX_RESETA_EN, 0); - EFX_SET_OWORD_FIELD(reg, XX_RESETB_EN, 0); - falcon_write(efx, ®, XX_PWR_RST_REG); - udelay(10); - - /* Channels C and D: power down, reset PLL, reset, clear */ - EFX_SET_OWORD_FIELD(reg, XX_PWRDNC_EN, 0); - EFX_SET_OWORD_FIELD(reg, XX_PWRDND_EN, 0); - falcon_write(efx, ®, XX_PWR_RST_REG); - udelay(10); - - EFX_SET_OWORD_FIELD(reg, XX_RSTPLLCD_EN, 0); - falcon_write(efx, ®, XX_PWR_RST_REG); - udelay(10); - - EFX_SET_OWORD_FIELD(reg, XX_RESETC_EN, 0); - EFX_SET_OWORD_FIELD(reg, XX_RESETD_EN, 0); - falcon_write(efx, ®, XX_PWR_RST_REG); - udelay(10); - - /* Setup XAUI */ - falcon_setup_xaui(efx); - udelay(10); - - /* Take XGXS out of reset */ - EFX_ZERO_OWORD(reg); - falcon_write(efx, ®, XX_PWR_RST_REG); - udelay(10); - - return 0; -} - -static int _falcon_reset_xaui_b(struct efx_nic *efx) +int falcon_reset_xaui(struct efx_nic *efx) { efx_oword_t reg; int count; @@ -171,20 +99,6 @@ static int _falcon_reset_xaui_b(struct efx_nic *efx) return -ETIMEDOUT; } -int falcon_reset_xaui(struct efx_nic *efx) -{ - int rc; - - if (EFX_WORKAROUND_9388(efx)) { - falcon_hold_xaui_in_rst(efx); - efx->phy_op->reset_xaui(efx); - rc = _falcon_reset_xaui_a(efx); - } else { - rc = _falcon_reset_xaui_b(efx); - } - return rc; -} - static bool falcon_xgmii_status(struct efx_nic *efx) { efx_oword_t reg; diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 567df00090f..cdb11fad605 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h @@ -160,6 +160,7 @@ struct efx_tx_buffer { * @channel: The associated channel * @buffer: The software buffer ring * @txd: The hardware descriptor ring + * @flushed: Used when handling queue flushing * @read_count: Current read pointer. * This is the number of buffers that have been removed from both rings. * @stopped: Stopped count. @@ -192,6 +193,7 @@ struct efx_tx_queue { struct efx_nic *nic; struct efx_tx_buffer *buffer; struct efx_special_buffer txd; + bool flushed; /* Members used mainly on the completion path */ unsigned int read_count ____cacheline_aligned_in_smp; @@ -260,6 +262,7 @@ struct efx_rx_buffer { * the remaining space in the allocation. * @buf_dma_addr: Page's DMA address. * @buf_data: Page's host address. + * @flushed: Use when handling queue flushing */ struct efx_rx_queue { struct efx_nic *efx; @@ -285,6 +288,7 @@ struct efx_rx_queue { struct page *buf_page; dma_addr_t buf_dma_addr; char *buf_data; + bool flushed; }; /** @@ -470,7 +474,7 @@ enum nic_state { * This is the equivalent of NET_IP_ALIGN [which controls the alignment * of the skb->head for hardware DMA]. */ -#if defined(__i386__) || defined(__x86_64__) +#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS #define EFX_PAGE_IP_ALIGN 0 #else #define EFX_PAGE_IP_ALIGN NET_IP_ALIGN @@ -503,7 +507,6 @@ enum efx_fc_type { * @clear_interrupt: Clear down interrupt * @blink: Blink LEDs * @check_hw: Check hardware - * @reset_xaui: Reset XAUI side of PHY for (software sequenced reset) * @mmds: MMD presence mask * @loopbacks: Supported loopback modes mask */ @@ -513,7 +516,6 @@ struct efx_phy_operations { void (*reconfigure) (struct efx_nic *efx); void (*clear_interrupt) (struct efx_nic *efx); int (*check_hw) (struct efx_nic *efx); - void (*reset_xaui) (struct efx_nic *efx); int (*test) (struct efx_nic *efx); int mmds; unsigned loopbacks; diff --git a/drivers/net/sfc/sfe4001.c b/drivers/net/sfc/sfe4001.c index b7005da55d5..fe4e3fd2233 100644 --- a/drivers/net/sfc/sfe4001.c +++ b/drivers/net/sfc/sfe4001.c @@ -129,18 +129,6 @@ static int sfe4001_poweron(struct efx_nic *efx) unsigned int i, j; int rc; u8 out; - efx_oword_t reg; - - /* Ensure that XGXS and XAUI SerDes are held in reset */ - EFX_POPULATE_OWORD_7(reg, XX_PWRDNA_EN, 1, - XX_PWRDNB_EN, 1, - XX_RSTPLLAB_EN, 1, - XX_RESETA_EN, 1, - XX_RESETB_EN, 1, - XX_RSTXGXSRX_EN, 1, - XX_RSTXGXSTX_EN, 1); - falcon_write(efx, ®, XX_PWR_RST_REG); - udelay(10); /* Clear any previous over-temperature alert */ rc = i2c_smbus_read_byte_data(hwmon_client, RSL); diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c index 8412dbe1e8f..d507c93d666 100644 --- a/drivers/net/sfc/tenxpress.c +++ b/drivers/net/sfc/tenxpress.c @@ -146,8 +146,6 @@ static int tenxpress_phy_check(struct efx_nic *efx) return 0; } -static void tenxpress_reset_xaui(struct efx_nic *efx); - static int tenxpress_init(struct efx_nic *efx) { int rc, reg; @@ -216,7 +214,10 @@ static int tenxpress_special_reset(struct efx_nic *efx) { int rc, reg; - EFX_TRACE(efx, "%s\n", __func__); + /* The XGMAC clock is driven from the SFC7101/SFT9001 312MHz clock, so + * a special software reset can glitch the XGMAC sufficiently for stats + * requests to fail. Since we don't ofen special_reset, just lock. */ + spin_lock(&efx->stats_lock); /* Initiate reset */ reg = mdio_clause45_read(efx, efx->mii.phy_id, @@ -225,20 +226,22 @@ static int tenxpress_special_reset(struct efx_nic *efx) mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD, PMA_PMD_EXT_CTRL_REG, reg); - msleep(200); + mdelay(200); /* Wait for the blocks to come out of reset */ rc = mdio_clause45_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); if (rc < 0) - return rc; + goto unlock; /* Try and reconfigure the device */ rc = tenxpress_init(efx); if (rc < 0) - return rc; + goto unlock; - return 0; +unlock: + spin_unlock(&efx->stats_lock); + return rc; } static void tenxpress_set_bad_lp(struct efx_nic *efx, bool bad_lp) @@ -374,8 +377,7 @@ static int tenxpress_phy_check_hw(struct efx_nic *efx) struct tenxpress_phy_data *phy_data = efx->phy_data; bool link_ok; - link_ok = (phy_data->phy_mode == PHY_MODE_NORMAL && - tenxpress_link_ok(efx, true)); + link_ok = tenxpress_link_ok(efx, true); if (link_ok != efx->link_up) falcon_xmac_sim_phy_event(efx); @@ -428,54 +430,6 @@ void tenxpress_phy_blink(struct efx_nic *efx, bool blink) PMA_PMD_LED_OVERR_REG, reg); } -static void tenxpress_reset_xaui(struct efx_nic *efx) -{ - int phy = efx->mii.phy_id; - int clk_ctrl, test_select, soft_rst2; - - /* Real work is done on clock_ctrl other resets are thought to be - * optional but make the reset more reliable - */ - - /* Read */ - clk_ctrl = mdio_clause45_read(efx, phy, MDIO_MMD_PCS, - PCS_CLOCK_CTRL_REG); - test_select = mdio_clause45_read(efx, phy, MDIO_MMD_PCS, - PCS_TEST_SELECT_REG); - soft_rst2 = mdio_clause45_read(efx, phy, MDIO_MMD_PCS, - PCS_SOFT_RST2_REG); - - /* Put in reset */ - test_select &= ~(1 << CLK312_EN_LBN); - mdio_clause45_write(efx, phy, MDIO_MMD_PCS, - PCS_TEST_SELECT_REG, test_select); - - soft_rst2 &= ~((1 << XGXS_RST_N_LBN) | (1 << SERDES_RST_N_LBN)); - mdio_clause45_write(efx, phy, MDIO_MMD_PCS, - PCS_SOFT_RST2_REG, soft_rst2); - - clk_ctrl &= ~(1 << PLL312_RST_N_LBN); - mdio_clause45_write(efx, phy, MDIO_MMD_PCS, - PCS_CLOCK_CTRL_REG, clk_ctrl); - udelay(10); - - /* Remove reset */ - clk_ctrl |= (1 << PLL312_RST_N_LBN); - mdio_clause45_write(efx, phy, MDIO_MMD_PCS, - PCS_CLOCK_CTRL_REG, clk_ctrl); - udelay(10); - - soft_rst2 |= ((1 << XGXS_RST_N_LBN) | (1 << SERDES_RST_N_LBN)); - mdio_clause45_write(efx, phy, MDIO_MMD_PCS, - PCS_SOFT_RST2_REG, soft_rst2); - udelay(10); - - test_select |= (1 << CLK312_EN_LBN); - mdio_clause45_write(efx, phy, MDIO_MMD_PCS, - PCS_TEST_SELECT_REG, test_select); - udelay(10); -} - static int tenxpress_phy_test(struct efx_nic *efx) { /* BIST is automatically run after a special software reset */ @@ -488,7 +442,6 @@ struct efx_phy_operations falcon_tenxpress_phy_ops = { .check_hw = tenxpress_phy_check_hw, .fini = tenxpress_phy_fini, .clear_interrupt = tenxpress_phy_clear_interrupt, - .reset_xaui = tenxpress_reset_xaui, .test = tenxpress_phy_test, .mmds = TENXPRESS_REQUIRED_DEVS, .loopbacks = TENXPRESS_LOOPBACKS, diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index cdee7c200d6..da3e9ff339f 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -516,7 +516,7 @@ void efx_remove_tx_queue(struct efx_tx_queue *tx_queue) /* Number of bytes inserted at the start of a TSO header buffer, * similar to NET_IP_ALIGN. */ -#if defined(__i386__) || defined(__x86_64__) +#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS #define TSOH_OFFSET 0 #else #define TSOH_OFFSET NET_IP_ALIGN diff --git a/drivers/net/sfc/workarounds.h b/drivers/net/sfc/workarounds.h index a824f5998c0..fa7b49d6928 100644 --- a/drivers/net/sfc/workarounds.h +++ b/drivers/net/sfc/workarounds.h @@ -24,8 +24,6 @@ #define EFX_WORKAROUND_7575 EFX_WORKAROUND_ALWAYS /* TX pkt parser problem with <= 16 byte TXes */ #define EFX_WORKAROUND_9141 EFX_WORKAROUND_ALWAYS -/* XGXS and XAUI reset sequencing in SW */ -#define EFX_WORKAROUND_9388 EFX_WORKAROUND_ALWAYS /* Low rate CRC errors require XAUI reset */ #define EFX_WORKAROUND_10750 EFX_WORKAROUND_ALWAYS /* TX_EV_PKT_ERR can be caused by a dangling TX descriptor diff --git a/drivers/net/sfc/xfp_phy.c b/drivers/net/sfc/xfp_phy.c index f6edecc2e58..276151df3a7 100644 --- a/drivers/net/sfc/xfp_phy.c +++ b/drivers/net/sfc/xfp_phy.c @@ -165,7 +165,6 @@ struct efx_phy_operations falcon_xfp_phy_ops = { .check_hw = xfp_phy_check_hw, .fini = xfp_phy_fini, .clear_interrupt = xfp_phy_clear_interrupt, - .reset_xaui = efx_port_dummy_op_void, .mmds = XFP_REQUIRED_DEVS, .loopbacks = XFP_LOOPBACKS, }; diff --git a/drivers/net/skfp/pmf.c b/drivers/net/skfp/pmf.c index ea85de91823..79e665e0853 100644 --- a/drivers/net/skfp/pmf.c +++ b/drivers/net/skfp/pmf.c @@ -44,17 +44,10 @@ static SMbuf *smt_build_pmf_response(struct s_smc *smc, struct smt_header *req, int set, int local); static int port_to_mib(struct s_smc *smc, int p); -#define MOFFSS(e) ((int)&(((struct fddi_mib *)0)->e)) -#define MOFFSA(e) ((int) (((struct fddi_mib *)0)->e)) - -#define MOFFMS(e) ((int)&(((struct fddi_mib_m *)0)->e)) -#define MOFFMA(e) ((int) (((struct fddi_mib_m *)0)->e)) - -#define MOFFAS(e) ((int)&(((struct fddi_mib_a *)0)->e)) -#define MOFFAA(e) ((int) (((struct fddi_mib_a *)0)->e)) - -#define MOFFPS(e) ((int)&(((struct fddi_mib_p *)0)->e)) -#define MOFFPA(e) ((int) (((struct fddi_mib_p *)0)->e)) +#define MOFFSS(e) offsetof(struct fddi_mib, e) +#define MOFFMS(e) offsetof(struct fddi_mib_m, e) +#define MOFFAS(e) offsetof(struct fddi_mib_a, e) +#define MOFFPS(e) offsetof(struct fddi_mib_p, e) #define AC_G 0x01 /* Get */ @@ -87,8 +80,8 @@ static const struct s_p_tab { { SMT_P100D,AC_G, MOFFSS(fddiSMTOpVersionId), "S" } , { SMT_P100E,AC_G, MOFFSS(fddiSMTHiVersionId), "S" } , { SMT_P100F,AC_G, MOFFSS(fddiSMTLoVersionId), "S" } , - { SMT_P1010,AC_G, MOFFSA(fddiSMTManufacturerData), "D" } , - { SMT_P1011,AC_GR, MOFFSA(fddiSMTUserData), "D" } , + { SMT_P1010,AC_G, MOFFSS(fddiSMTManufacturerData), "D" } , + { SMT_P1011,AC_GR, MOFFSS(fddiSMTUserData), "D" } , { SMT_P1012,AC_G, MOFFSS(fddiSMTMIBVersionId), "S" } , /* StationConfigGrp */ @@ -103,7 +96,7 @@ static const struct s_p_tab { { SMT_P101D,AC_GR, MOFFSS(fddiSMTTT_Notify), "wS" } , { SMT_P101E,AC_GR, MOFFSS(fddiSMTStatRptPolicy), "bB" } , { SMT_P101F,AC_GR, MOFFSS(fddiSMTTrace_MaxExpiration),"lL" } , - { SMT_P1020,AC_G, MOFFSA(fddiSMTPORTIndexes), "II" } , + { SMT_P1020,AC_G, MOFFSS(fddiSMTPORTIndexes), "II" } , { SMT_P1021,AC_G, MOFFSS(fddiSMTMACIndexes), "I" } , { SMT_P1022,AC_G, MOFFSS(fddiSMTBypassPresent), "F" } , @@ -117,8 +110,8 @@ static const struct s_p_tab { /* MIBOperationGrp */ { SMT_P1032,AC_GROUP } , - { SMT_P1033,AC_G, MOFFSA(fddiSMTTimeStamp),"P" } , - { SMT_P1034,AC_G, MOFFSA(fddiSMTTransitionTimeStamp),"P" } , + { SMT_P1033,AC_G, MOFFSS(fddiSMTTimeStamp),"P" } , + { SMT_P1034,AC_G, MOFFSS(fddiSMTTransitionTimeStamp),"P" } , /* NOTE : SMT_P1035 is already swapped ! SMT_P_SETCOUNT */ { SMT_P1035,AC_G, MOFFSS(fddiSMTSetCount),"4P" } , { SMT_P1036,AC_G, MOFFSS(fddiSMTLastSetStationId),"8" } , @@ -129,7 +122,7 @@ static const struct s_p_tab { * PRIVATE EXTENSIONS * only accessible locally to get/set passwd */ - { SMT_P10F0,AC_GR, MOFFSA(fddiPRPMFPasswd), "8" } , + { SMT_P10F0,AC_GR, MOFFSS(fddiPRPMFPasswd), "8" } , { SMT_P10F1,AC_GR, MOFFSS(fddiPRPMFStation), "8" } , #ifdef ESS { SMT_P10F2,AC_GR, MOFFSS(fddiESSPayload), "lL" } , @@ -245,7 +238,7 @@ static const struct s_p_tab { { SMT_P400E,AC_GR, MOFFPS(fddiPORTConnectionPolicies),"bB" } , { SMT_P400F,AC_G, MOFFPS(fddiPORTMacIndicated), "2" } , { SMT_P4010,AC_G, MOFFPS(fddiPORTCurrentPath), "E" } , - { SMT_P4011,AC_GR, MOFFPA(fddiPORTRequestedPaths), "l4" } , + { SMT_P4011,AC_GR, MOFFPS(fddiPORTRequestedPaths), "l4" } , { SMT_P4012,AC_G, MOFFPS(fddiPORTMACPlacement), "S" } , { SMT_P4013,AC_G, MOFFPS(fddiPORTAvailablePaths), "B" } , { SMT_P4016,AC_G, MOFFPS(fddiPORTPMDClass), "E" } , diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index c5871624f97..02cc064c2c8 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -183,7 +183,7 @@ static void smc911x_reset(struct net_device *dev) unsigned int reg, timeout=0, resets=1; unsigned long flags; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); /* Take out of PM setting first */ if ((SMC_GET_PMT_CTRL(lp) & PMT_CTRL_READY_) == 0) { @@ -272,7 +272,7 @@ static void smc911x_enable(struct net_device *dev) unsigned mask, cfg, cr; unsigned long flags; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); SMC_SET_MAC_ADDR(lp, dev->dev_addr); @@ -329,7 +329,7 @@ static void smc911x_shutdown(struct net_device *dev) unsigned cr; unsigned long flags; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", CARDNAME, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", CARDNAME, __func__); /* Disable IRQ's */ SMC_SET_INT_EN(lp, 0); @@ -348,7 +348,7 @@ static inline void smc911x_drop_pkt(struct net_device *dev) struct smc911x_local *lp = netdev_priv(dev); unsigned int fifo_count, timeout, reg; - DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", CARDNAME, __FUNCTION__); + DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", CARDNAME, __func__); fifo_count = SMC_GET_RX_FIFO_INF(lp) & 0xFFFF; if (fifo_count <= 4) { /* Manually dump the packet data */ @@ -382,7 +382,7 @@ static inline void smc911x_rcv(struct net_device *dev) unsigned char *data; DBG(SMC_DEBUG_FUNC | SMC_DEBUG_RX, "%s: --> %s\n", - dev->name, __FUNCTION__); + dev->name, __func__); status = SMC_GET_RX_STS_FIFO(lp); DBG(SMC_DEBUG_RX, "%s: Rx pkt len %d status 0x%08x \n", dev->name, (status & 0x3fff0000) >> 16, status & 0xc000ffff); @@ -460,7 +460,7 @@ static void smc911x_hardware_send_pkt(struct net_device *dev) unsigned char *buf; unsigned long flags; - DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", dev->name, __func__); BUG_ON(lp->pending_tx_skb == NULL); skb = lp->pending_tx_skb; @@ -524,7 +524,7 @@ static int smc911x_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) unsigned long flags; DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", - dev->name, __FUNCTION__); + dev->name, __func__); BUG_ON(lp->pending_tx_skb != NULL); @@ -596,7 +596,7 @@ static void smc911x_tx(struct net_device *dev) unsigned int tx_status; DBG(SMC_DEBUG_FUNC | SMC_DEBUG_TX, "%s: --> %s\n", - dev->name, __FUNCTION__); + dev->name, __func__); /* Collect the TX status */ while (((SMC_GET_TX_FIFO_INF(lp) & TX_FIFO_INF_TSUSED_) >> 16) != 0) { @@ -647,7 +647,7 @@ static int smc911x_phy_read(struct net_device *dev, int phyaddr, int phyreg) SMC_GET_MII(lp, phyreg, phyaddr, phydata); DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%02x, phydata=0x%04x\n", - __FUNCTION__, phyaddr, phyreg, phydata); + __func__, phyaddr, phyreg, phydata); return phydata; } @@ -661,7 +661,7 @@ static void smc911x_phy_write(struct net_device *dev, int phyaddr, int phyreg, struct smc911x_local *lp = netdev_priv(dev); DBG(SMC_DEBUG_MISC, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", - __FUNCTION__, phyaddr, phyreg, phydata); + __func__, phyaddr, phyreg, phydata); SMC_SET_MII(lp, phyreg, phyaddr, phydata); } @@ -676,7 +676,7 @@ static void smc911x_phy_detect(struct net_device *dev) int phyaddr; unsigned int cfg, id1, id2; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); lp->phy_type = 0; @@ -746,7 +746,7 @@ static int smc911x_phy_fixed(struct net_device *dev) int phyaddr = lp->mii.phy_id; int bmcr; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); /* Enter Link Disable state */ SMC_GET_PHY_BMCR(lp, phyaddr, bmcr); @@ -793,7 +793,7 @@ static int smc911x_phy_reset(struct net_device *dev, int phy) unsigned long flags; unsigned int reg; - DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __func__); spin_lock_irqsave(&lp->lock, flags); reg = SMC_GET_PMT_CTRL(lp); @@ -852,7 +852,7 @@ static void smc911x_phy_check_media(struct net_device *dev, int init) int phyaddr = lp->mii.phy_id; unsigned int bmcr, cr; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); if (mii_check_media(&lp->mii, netif_msg_link(lp), init)) { /* duplex state has changed */ @@ -892,7 +892,7 @@ static void smc911x_phy_configure(struct work_struct *work) int status; unsigned long flags; - DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s()\n", dev->name, __func__); /* * We should not be called if phy_type is zero. @@ -985,7 +985,7 @@ static void smc911x_phy_interrupt(struct net_device *dev) int phyaddr = lp->mii.phy_id; int status; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); if (lp->phy_type == 0) return; @@ -1013,7 +1013,7 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id) unsigned int rx_overrun=0, cr, pkts; unsigned long flags; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); spin_lock_irqsave(&lp->lock, flags); @@ -1174,8 +1174,6 @@ static irqreturn_t smc911x_interrupt(int irq, void *dev_id) spin_unlock_irqrestore(&lp->lock, flags); - DBG(3, "%s: Interrupt done (%d loops)\n", dev->name, 8-timeout); - return IRQ_HANDLED; } @@ -1188,7 +1186,7 @@ smc911x_tx_dma_irq(int dma, void *data) struct sk_buff *skb = lp->current_tx_skb; unsigned long flags; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); DBG(SMC_DEBUG_TX | SMC_DEBUG_DMA, "%s: TX DMA irq handler\n", dev->name); /* Clear the DMA interrupt sources */ @@ -1224,7 +1222,7 @@ smc911x_rx_dma_irq(int dma, void *data) unsigned long flags; unsigned int pkts; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, "%s: RX DMA irq handler\n", dev->name); /* Clear the DMA interrupt sources */ SMC_DMA_ACK_IRQ(dev, dma); @@ -1272,7 +1270,7 @@ static void smc911x_timeout(struct net_device *dev) int status, mask; unsigned long flags; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); spin_lock_irqsave(&lp->lock, flags); status = SMC_GET_INT(lp); @@ -1310,7 +1308,7 @@ static void smc911x_set_multicast_list(struct net_device *dev) unsigned int mcr, update_multicast = 0; unsigned long flags; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); spin_lock_irqsave(&lp->lock, flags); SMC_GET_MAC_CR(lp, mcr); @@ -1412,7 +1410,7 @@ smc911x_open(struct net_device *dev) { struct smc911x_local *lp = netdev_priv(dev); - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); /* * Check that the address is valid. If its not, refuse @@ -1420,7 +1418,7 @@ smc911x_open(struct net_device *dev) * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx */ if (!is_valid_ether_addr(dev->dev_addr)) { - PRINTK("%s: no valid ethernet hw addr\n", __FUNCTION__); + PRINTK("%s: no valid ethernet hw addr\n", __func__); return -EINVAL; } @@ -1449,7 +1447,7 @@ static int smc911x_close(struct net_device *dev) { struct smc911x_local *lp = netdev_priv(dev); - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); netif_stop_queue(dev); netif_carrier_off(dev); @@ -1483,7 +1481,7 @@ smc911x_ethtool_getsettings(struct net_device *dev, struct ethtool_cmd *cmd) int ret, status; unsigned long flags; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); cmd->maxtxpkt = 1; cmd->maxrxpkt = 1; @@ -1621,7 +1619,7 @@ static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev) for(timeout=10;(e2p_cmd & E2P_CMD_EPC_BUSY_) && timeout; timeout--) { if (e2p_cmd & E2P_CMD_EPC_TIMEOUT_) { PRINTK("%s: %s timeout waiting for EEPROM to respond\n", - dev->name, __FUNCTION__); + dev->name, __func__); return -EFAULT; } mdelay(1); @@ -1629,7 +1627,7 @@ static int smc911x_ethtool_wait_eeprom_ready(struct net_device *dev) } if (timeout == 0) { PRINTK("%s: %s timeout waiting for EEPROM CMD not busy\n", - dev->name, __FUNCTION__); + dev->name, __func__); return -ETIMEDOUT; } return 0; @@ -1742,7 +1740,7 @@ static int __init smc911x_findirq(struct net_device *dev) int timeout = 20; unsigned long cookie; - DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__); cookie = probe_irq_on(); @@ -1808,7 +1806,7 @@ static int __init smc911x_probe(struct net_device *dev) const char *version_string; unsigned long irq_flags; - DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __func__); /* First, see if the endian word is recognized */ val = SMC_GET_BYTE_TEST(lp); @@ -2058,7 +2056,7 @@ static int smc911x_drv_probe(struct platform_device *pdev) unsigned int *addr; int ret; - DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { ret = -ENODEV; @@ -2129,7 +2127,7 @@ static int smc911x_drv_remove(struct platform_device *pdev) struct smc911x_local *lp = netdev_priv(ndev); struct resource *res; - DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__); platform_set_drvdata(pdev, NULL); unregister_netdev(ndev); @@ -2159,7 +2157,7 @@ static int smc911x_drv_suspend(struct platform_device *dev, pm_message_t state) struct net_device *ndev = platform_get_drvdata(dev); struct smc911x_local *lp = netdev_priv(ndev); - DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__); if (ndev) { if (netif_running(ndev)) { netif_device_detach(ndev); @@ -2177,7 +2175,7 @@ static int smc911x_drv_resume(struct platform_device *dev) { struct net_device *ndev = platform_get_drvdata(dev); - DBG(SMC_DEBUG_FUNC, "--> %s\n", __FUNCTION__); + DBG(SMC_DEBUG_FUNC, "--> %s\n", __func__); if (ndev) { struct smc911x_local *lp = netdev_priv(ndev); diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 24768c10cad..ef5ce8845c9 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -270,7 +270,7 @@ static void smc_reset(struct net_device *dev) unsigned int ctl, cfg; struct sk_buff *pending_skb; - DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + DBG(2, "%s: %s\n", dev->name, __func__); /* Disable all interrupts, block TX tasklet */ spin_lock_irq(&lp->lock); @@ -363,7 +363,7 @@ static void smc_enable(struct net_device *dev) void __iomem *ioaddr = lp->base; int mask; - DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + DBG(2, "%s: %s\n", dev->name, __func__); /* see the header file for options in TCR/RCR DEFAULT */ SMC_SELECT_BANK(lp, 0); @@ -397,7 +397,7 @@ static void smc_shutdown(struct net_device *dev) void __iomem *ioaddr = lp->base; struct sk_buff *pending_skb; - DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__); + DBG(2, "%s: %s\n", CARDNAME, __func__); /* no more interrupts for me */ spin_lock_irq(&lp->lock); @@ -430,7 +430,7 @@ static inline void smc_rcv(struct net_device *dev) void __iomem *ioaddr = lp->base; unsigned int packet_number, status, packet_len; - DBG(3, "%s: %s\n", dev->name, __FUNCTION__); + DBG(3, "%s: %s\n", dev->name, __func__); packet_number = SMC_GET_RXFIFO(lp); if (unlikely(packet_number & RXFIFO_REMPTY)) { @@ -577,7 +577,7 @@ static void smc_hardware_send_pkt(unsigned long data) unsigned int packet_no, len; unsigned char *buf; - DBG(3, "%s: %s\n", dev->name, __FUNCTION__); + DBG(3, "%s: %s\n", dev->name, __func__); if (!smc_special_trylock(&lp->lock)) { netif_stop_queue(dev); @@ -662,7 +662,7 @@ static int smc_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) void __iomem *ioaddr = lp->base; unsigned int numPages, poll_count, status; - DBG(3, "%s: %s\n", dev->name, __FUNCTION__); + DBG(3, "%s: %s\n", dev->name, __func__); BUG_ON(lp->pending_tx_skb != NULL); @@ -734,7 +734,7 @@ static void smc_tx(struct net_device *dev) void __iomem *ioaddr = lp->base; unsigned int saved_packet, packet_no, tx_status, pkt_len; - DBG(3, "%s: %s\n", dev->name, __FUNCTION__); + DBG(3, "%s: %s\n", dev->name, __func__); /* If the TX FIFO is empty then nothing to do */ packet_no = SMC_GET_TXFIFO(lp); @@ -856,7 +856,7 @@ static int smc_phy_read(struct net_device *dev, int phyaddr, int phyreg) SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO)); DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", - __FUNCTION__, phyaddr, phyreg, phydata); + __func__, phyaddr, phyreg, phydata); SMC_SELECT_BANK(lp, 2); return phydata; @@ -883,7 +883,7 @@ static void smc_phy_write(struct net_device *dev, int phyaddr, int phyreg, SMC_SET_MII(lp, SMC_GET_MII(lp) & ~(MII_MCLK|MII_MDOE|MII_MDO)); DBG(3, "%s: phyaddr=0x%x, phyreg=0x%x, phydata=0x%x\n", - __FUNCTION__, phyaddr, phyreg, phydata); + __func__, phyaddr, phyreg, phydata); SMC_SELECT_BANK(lp, 2); } @@ -896,7 +896,7 @@ static void smc_phy_detect(struct net_device *dev) struct smc_local *lp = netdev_priv(dev); int phyaddr; - DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + DBG(2, "%s: %s\n", dev->name, __func__); lp->phy_type = 0; @@ -935,7 +935,7 @@ static int smc_phy_fixed(struct net_device *dev) int phyaddr = lp->mii.phy_id; int bmcr, cfg1; - DBG(3, "%s: %s\n", dev->name, __FUNCTION__); + DBG(3, "%s: %s\n", dev->name, __func__); /* Enter Link Disable state */ cfg1 = smc_phy_read(dev, phyaddr, PHY_CFG1_REG); @@ -1168,7 +1168,7 @@ static void smc_phy_interrupt(struct net_device *dev) int phyaddr = lp->mii.phy_id; int phy18; - DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + DBG(2, "%s: %s\n", dev->name, __func__); if (lp->phy_type == 0) return; @@ -1236,7 +1236,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id) int status, mask, timeout, card_stats; int saved_pointer; - DBG(3, "%s: %s\n", dev->name, __FUNCTION__); + DBG(3, "%s: %s\n", dev->name, __func__); spin_lock(&lp->lock); @@ -1358,7 +1358,7 @@ static void smc_timeout(struct net_device *dev) void __iomem *ioaddr = lp->base; int status, mask, eph_st, meminfo, fifo; - DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + DBG(2, "%s: %s\n", dev->name, __func__); spin_lock_irq(&lp->lock); status = SMC_GET_INT(lp); @@ -1402,7 +1402,7 @@ static void smc_set_multicast_list(struct net_device *dev) unsigned char multicast_table[8]; int update_multicast = 0; - DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + DBG(2, "%s: %s\n", dev->name, __func__); if (dev->flags & IFF_PROMISC) { DBG(2, "%s: RCR_PRMS\n", dev->name); @@ -1505,7 +1505,7 @@ smc_open(struct net_device *dev) { struct smc_local *lp = netdev_priv(dev); - DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + DBG(2, "%s: %s\n", dev->name, __func__); /* * Check that the address is valid. If its not, refuse @@ -1513,7 +1513,7 @@ smc_open(struct net_device *dev) * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx */ if (!is_valid_ether_addr(dev->dev_addr)) { - PRINTK("%s: no valid ethernet hw addr\n", __FUNCTION__); + PRINTK("%s: no valid ethernet hw addr\n", __func__); return -EINVAL; } @@ -1557,7 +1557,7 @@ static int smc_close(struct net_device *dev) { struct smc_local *lp = netdev_priv(dev); - DBG(2, "%s: %s\n", dev->name, __FUNCTION__); + DBG(2, "%s: %s\n", dev->name, __func__); netif_stop_queue(dev); netif_carrier_off(dev); @@ -1700,7 +1700,7 @@ static int __init smc_findirq(struct smc_local *lp) int timeout = 20; unsigned long cookie; - DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__); + DBG(2, "%s: %s\n", CARDNAME, __func__); cookie = probe_irq_on(); @@ -1778,7 +1778,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr, const char *version_string; DECLARE_MAC_BUF(mac); - DBG(2, "%s: %s\n", CARDNAME, __FUNCTION__); + DBG(2, "%s: %s\n", CARDNAME, __func__); /* First, see if the high byte is 0x33 */ val = SMC_CURRENT_BANK(lp); @@ -1961,7 +1961,8 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr, if (dev->dma != (unsigned char)-1) printk(" DMA %d", dev->dma); - printk("%s%s\n", nowait ? " [nowait]" : "", + printk("%s%s\n", + lp->cfg.flags & SMC91X_NOWAIT ? " [nowait]" : "", THROTTLE_TX_PKTS ? " [throttle_tx]" : ""); if (!is_valid_ether_addr(dev->dev_addr)) { diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 997e7f1d5c6..edea0732f14 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -446,6 +446,8 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r, #define SMC_CAN_USE_32BIT 1 #define SMC_NOWAIT 1 +#define SMC_IO_SHIFT (lp->io_shift) + #define SMC_inb(a, r) readb((a) + (r)) #define SMC_inw(a, r) readw((a) + (r)) #define SMC_inl(a, r) readl((a) + (r)) diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index 0e4a88d1632..31e7384e312 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1274,7 +1274,7 @@ static int __devexit bigmac_sbus_remove(struct of_device *dev) struct bigmac *bp = dev_get_drvdata(&dev->dev); struct net_device *net_dev = bp->dev; - unregister_netdevice(net_dev); + unregister_netdev(net_dev); sbus_iounmap(bp->gregs, GLOB_REG_SIZE); sbus_iounmap(bp->creg, CREG_REG_SIZE); diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 7d5561b8241..f860ea15039 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -409,6 +409,7 @@ static int change_mtu(struct net_device *dev, int new_mtu); static int eeprom_read(void __iomem *ioaddr, int location); static int mdio_read(struct net_device *dev, int phy_id, int location); static void mdio_write(struct net_device *dev, int phy_id, int location, int value); +static int mdio_wait_link(struct net_device *dev, int wait); static int netdev_open(struct net_device *dev); static void check_duplex(struct net_device *dev); static void netdev_timer(unsigned long data); @@ -785,6 +786,24 @@ static void mdio_write(struct net_device *dev, int phy_id, int location, int val return; } +static int mdio_wait_link(struct net_device *dev, int wait) +{ + int bmsr; + int phy_id; + struct netdev_private *np; + + np = netdev_priv(dev); + phy_id = np->phys[0]; + + do { + bmsr = mdio_read(dev, phy_id, MII_BMSR); + if (bmsr & 0x0004) + return 0; + mdelay(1); + } while (--wait > 0); + return -1; +} + static int netdev_open(struct net_device *dev) { struct netdev_private *np = netdev_priv(dev); @@ -1393,41 +1412,51 @@ static void netdev_error(struct net_device *dev, int intr_status) int speed; if (intr_status & LinkChange) { - if (np->an_enable) { - mii_advertise = mdio_read (dev, np->phys[0], MII_ADVERTISE); - mii_lpa= mdio_read (dev, np->phys[0], MII_LPA); - mii_advertise &= mii_lpa; - printk (KERN_INFO "%s: Link changed: ", dev->name); - if (mii_advertise & ADVERTISE_100FULL) { - np->speed = 100; - printk ("100Mbps, full duplex\n"); - } else if (mii_advertise & ADVERTISE_100HALF) { - np->speed = 100; - printk ("100Mbps, half duplex\n"); - } else if (mii_advertise & ADVERTISE_10FULL) { - np->speed = 10; - printk ("10Mbps, full duplex\n"); - } else if (mii_advertise & ADVERTISE_10HALF) { - np->speed = 10; - printk ("10Mbps, half duplex\n"); - } else - printk ("\n"); + if (mdio_wait_link(dev, 10) == 0) { + printk(KERN_INFO "%s: Link up\n", dev->name); + if (np->an_enable) { + mii_advertise = mdio_read(dev, np->phys[0], + MII_ADVERTISE); + mii_lpa = mdio_read(dev, np->phys[0], MII_LPA); + mii_advertise &= mii_lpa; + printk(KERN_INFO "%s: Link changed: ", + dev->name); + if (mii_advertise & ADVERTISE_100FULL) { + np->speed = 100; + printk("100Mbps, full duplex\n"); + } else if (mii_advertise & ADVERTISE_100HALF) { + np->speed = 100; + printk("100Mbps, half duplex\n"); + } else if (mii_advertise & ADVERTISE_10FULL) { + np->speed = 10; + printk("10Mbps, full duplex\n"); + } else if (mii_advertise & ADVERTISE_10HALF) { + np->speed = 10; + printk("10Mbps, half duplex\n"); + } else + printk("\n"); + } else { + mii_ctl = mdio_read(dev, np->phys[0], MII_BMCR); + speed = (mii_ctl & BMCR_SPEED100) ? 100 : 10; + np->speed = speed; + printk(KERN_INFO "%s: Link changed: %dMbps ,", + dev->name, speed); + printk("%s duplex.\n", + (mii_ctl & BMCR_FULLDPLX) ? + "full" : "half"); + } + check_duplex(dev); + if (np->flowctrl && np->mii_if.full_duplex) { + iowrite16(ioread16(ioaddr + MulticastFilter1+2) | 0x0200, + ioaddr + MulticastFilter1+2); + iowrite16(ioread16(ioaddr + MACCtrl0) | EnbFlowCtrl, + ioaddr + MACCtrl0); + } + netif_carrier_on(dev); } else { - mii_ctl = mdio_read (dev, np->phys[0], MII_BMCR); - speed = (mii_ctl & BMCR_SPEED100) ? 100 : 10; - np->speed = speed; - printk (KERN_INFO "%s: Link changed: %dMbps ,", - dev->name, speed); - printk ("%s duplex.\n", (mii_ctl & BMCR_FULLDPLX) ? - "full" : "half"); - } - check_duplex (dev); - if (np->flowctrl && np->mii_if.full_duplex) { - iowrite16(ioread16(ioaddr + MulticastFilter1+2) | 0x0200, - ioaddr + MulticastFilter1+2); - iowrite16(ioread16(ioaddr + MACCtrl0) | EnbFlowCtrl, - ioaddr + MACCtrl0); + printk(KERN_INFO "%s: Link down\n", dev->name); + netif_carrier_off(dev); } } if (intr_status & StatsMax) { diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h index 7db48f1cd94..efaf84d9757 100644 --- a/drivers/net/tehuti.h +++ b/drivers/net/tehuti.h @@ -539,22 +539,22 @@ struct txd_desc { #define ERR(fmt, args...) printk(KERN_ERR fmt, ## args) #define DBG2(fmt, args...) \ - printk(KERN_ERR "%s:%-5d: " fmt, __FUNCTION__, __LINE__, ## args) + printk(KERN_ERR "%s:%-5d: " fmt, __func__, __LINE__, ## args) #define BDX_ASSERT(x) BUG_ON(x) #ifdef DEBUG #define ENTER do { \ - printk(KERN_ERR "%s:%-5d: ENTER\n", __FUNCTION__, __LINE__); \ + printk(KERN_ERR "%s:%-5d: ENTER\n", __func__, __LINE__); \ } while (0) #define RET(args...) do { \ - printk(KERN_ERR "%s:%-5d: RETURN\n", __FUNCTION__, __LINE__); \ + printk(KERN_ERR "%s:%-5d: RETURN\n", __func__, __LINE__); \ return args; } while (0) #define DBG(fmt, args...) \ - printk(KERN_ERR "%s:%-5d: " fmt, __FUNCTION__, __LINE__, ## args) + printk(KERN_ERR "%s:%-5d: " fmt, __func__, __LINE__, ## args) #else #define ENTER do { } while (0) #define RET(args...) return args diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index 43fde99b24a..eb1da6f0b08 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -263,7 +263,7 @@ static inline void tsi108_write_tbi(struct tsi108_prv_data *data, return; udelay(10); } - printk(KERN_ERR "%s function time out \n", __FUNCTION__); + printk(KERN_ERR "%s function time out \n", __func__); } static int mii_speed(struct mii_if_info *mii) @@ -1059,7 +1059,7 @@ static void tsi108_stop_ethernet(struct net_device *dev) return; udelay(10); } - printk(KERN_ERR "%s function time out \n", __FUNCTION__); + printk(KERN_ERR "%s function time out \n", __func__); } static void tsi108_reset_ether(struct tsi108_prv_data * data) @@ -1244,7 +1244,7 @@ static void tsi108_init_phy(struct net_device *dev) udelay(10); } if (i == 0) - printk(KERN_ERR "%s function time out \n", __FUNCTION__); + printk(KERN_ERR "%s function time out \n", __func__); if (data->phy_type == TSI108_PHY_BCM54XX) { tsi108_write_mii(data, 0x09, 0x0300); diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 9281d06d5aa..f54c45049d5 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -1418,7 +1418,6 @@ static int de_close (struct net_device *dev) de_free_rings(de); de_adapter_sleep(de); - pci_disable_device(de->pdev); return 0; } diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c index 617ef41bdfe..6444cbec0bd 100644 --- a/drivers/net/tulip/de4x5.c +++ b/drivers/net/tulip/de4x5.c @@ -832,7 +832,7 @@ struct de4x5_private { s32 csr14; /* Saved SIA TX/RX Register */ s32 csr15; /* Saved SIA General Register */ int save_cnt; /* Flag if state already saved */ - struct sk_buff *skb; /* Save the (re-ordered) skb's */ + struct sk_buff_head queue; /* Save the (re-ordered) skb's */ } cache; struct de4x5_srom srom; /* A copy of the SROM */ int cfrv; /* Card CFRV copy */ @@ -1128,6 +1128,7 @@ de4x5_hw_init(struct net_device *dev, u_long iobase, struct device *gendev) printk(" which has an Ethernet PROM CRC error.\n"); return -ENXIO; } else { + skb_queue_head_init(&lp->cache.queue); lp->cache.gepc = GEP_INIT; lp->asBit = GEP_SLNK; lp->asPolarity = GEP_SLNK; @@ -1487,7 +1488,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct net_device *dev) } } else if (skb->len > 0) { /* If we already have stuff queued locally, use that first */ - if (lp->cache.skb && !lp->interrupt) { + if (!skb_queue_empty(&lp->cache.queue) && !lp->interrupt) { de4x5_put_cache(dev, skb); skb = de4x5_get_cache(dev); } @@ -1580,7 +1581,7 @@ de4x5_interrupt(int irq, void *dev_id) /* Load the TX ring with any locally stored packets */ if (!test_and_set_bit(0, (void *)&lp->cache.lock)) { - while (lp->cache.skb && !netif_queue_stopped(dev) && lp->tx_enable) { + while (!skb_queue_empty(&lp->cache.queue) && !netif_queue_stopped(dev) && lp->tx_enable) { de4x5_queue_pkt(de4x5_get_cache(dev), dev); } lp->cache.lock = 0; @@ -3679,11 +3680,7 @@ de4x5_free_tx_buffs(struct net_device *dev) } /* Unload the locally queued packets */ - while (lp->cache.skb) { - dev_kfree_skb(de4x5_get_cache(dev)); - } - - return; + __skb_queue_purge(&lp->cache.queue); } /* @@ -3781,43 +3778,24 @@ static void de4x5_put_cache(struct net_device *dev, struct sk_buff *skb) { struct de4x5_private *lp = netdev_priv(dev); - struct sk_buff *p; - - if (lp->cache.skb) { - for (p=lp->cache.skb; p->next; p=p->next); - p->next = skb; - } else { - lp->cache.skb = skb; - } - skb->next = NULL; - return; + __skb_queue_tail(&lp->cache.queue, skb); } static void de4x5_putb_cache(struct net_device *dev, struct sk_buff *skb) { struct de4x5_private *lp = netdev_priv(dev); - struct sk_buff *p = lp->cache.skb; - - lp->cache.skb = skb; - skb->next = p; - return; + __skb_queue_head(&lp->cache.queue, skb); } static struct sk_buff * de4x5_get_cache(struct net_device *dev) { struct de4x5_private *lp = netdev_priv(dev); - struct sk_buff *p = lp->cache.skb; - if (p) { - lp->cache.skb = p->next; - p->next = NULL; - } - - return p; + return __skb_dequeue(&lp->cache.queue); } /* diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 8f944e57fd5..c87747bb24c 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -400,7 +400,7 @@ static struct enet_addr_container *get_enet_addr_container(void) enet_addr_cont = kmalloc(sizeof(struct enet_addr_container), GFP_KERNEL); if (!enet_addr_cont) { ugeth_err("%s: No memory for enet_addr_container object.", - __FUNCTION__); + __func__); return NULL; } @@ -427,7 +427,7 @@ static int hw_add_addr_in_paddr(struct ucc_geth_private *ugeth, struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt; if (!(paddr_num < NUM_OF_PADDRS)) { - ugeth_warn("%s: Illegal paddr_num.", __FUNCTION__); + ugeth_warn("%s: Illegal paddr_num.", __func__); return -EINVAL; } @@ -447,7 +447,7 @@ static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num) struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt; if (!(paddr_num < NUM_OF_PADDRS)) { - ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__); + ugeth_warn("%s: Illagel paddr_num.", __func__); return -EINVAL; } @@ -1441,7 +1441,7 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth) u32 upsmr, maccfg2, tbiBaseAddress; u16 value; - ugeth_vdbg("%s: IN", __FUNCTION__); + ugeth_vdbg("%s: IN", __func__); ug_info = ugeth->ug_info; ug_regs = ugeth->ug_regs; @@ -1504,7 +1504,7 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth) if (ret_val != 0) { if (netif_msg_probe(ugeth)) ugeth_err("%s: Preamble length must be between 3 and 7 inclusive.", - __FUNCTION__); + __func__); return ret_val; } @@ -1744,7 +1744,7 @@ static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode) /* check if the UCC number is in range. */ if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) { if (netif_msg_probe(ugeth)) - ugeth_err("%s: ucc_num out of range.", __FUNCTION__); + ugeth_err("%s: ucc_num out of range.", __func__); return -EINVAL; } @@ -1773,7 +1773,7 @@ static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode) /* check if the UCC number is in range. */ if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) { if (netif_msg_probe(ugeth)) - ugeth_err("%s: ucc_num out of range.", __FUNCTION__); + ugeth_err("%s: ucc_num out of range.", __func__); return -EINVAL; } @@ -2062,7 +2062,7 @@ static int ugeth_82xx_filtering_add_addr_in_paddr(struct ucc_geth_private *ugeth ugeth_warn ("%s: multicast address added to paddr will have no " "effect - is this what you wanted?", - __FUNCTION__); + __func__); ugeth->indAddrRegUsed[paddr_num] = 1; /* mark this paddr as used */ /* store address in our database */ @@ -2278,7 +2278,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth) struct phy_device *phydev = ugeth->phydev; u32 tempval; - ugeth_vdbg("%s: IN", __FUNCTION__); + ugeth_vdbg("%s: IN", __func__); /* Disable the controller */ ugeth_disable(ugeth, COMM_DIR_RX_AND_TX); @@ -2315,7 +2315,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) (uf_info->bd_mem_part == MEM_PART_MURAM))) { if (netif_msg_probe(ugeth)) ugeth_err("%s: Bad memory partition value.", - __FUNCTION__); + __func__); return -EINVAL; } @@ -2327,7 +2327,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) if (netif_msg_probe(ugeth)) ugeth_err ("%s: Rx BD ring length must be multiple of 4, no smaller than 8.", - __FUNCTION__); + __func__); return -EINVAL; } } @@ -2338,7 +2338,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) if (netif_msg_probe(ugeth)) ugeth_err ("%s: Tx BD ring length must be no smaller than 2.", - __FUNCTION__); + __func__); return -EINVAL; } } @@ -2349,21 +2349,21 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) if (netif_msg_probe(ugeth)) ugeth_err ("%s: max_rx_buf_length must be non-zero multiple of 128.", - __FUNCTION__); + __func__); return -EINVAL; } /* num Tx queues */ if (ug_info->numQueuesTx > NUM_TX_QUEUES) { if (netif_msg_probe(ugeth)) - ugeth_err("%s: number of tx queues too large.", __FUNCTION__); + ugeth_err("%s: number of tx queues too large.", __func__); return -EINVAL; } /* num Rx queues */ if (ug_info->numQueuesRx > NUM_RX_QUEUES) { if (netif_msg_probe(ugeth)) - ugeth_err("%s: number of rx queues too large.", __FUNCTION__); + ugeth_err("%s: number of rx queues too large.", __func__); return -EINVAL; } @@ -2374,7 +2374,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) ugeth_err ("%s: VLAN priority table entry must not be" " larger than number of Rx queues.", - __FUNCTION__); + __func__); return -EINVAL; } } @@ -2386,7 +2386,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) ugeth_err ("%s: IP priority table entry must not be" " larger than number of Rx queues.", - __FUNCTION__); + __func__); return -EINVAL; } } @@ -2394,7 +2394,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) if (ug_info->cam && !ug_info->ecamptr) { if (netif_msg_probe(ugeth)) ugeth_err("%s: If cam mode is chosen, must supply cam ptr.", - __FUNCTION__); + __func__); return -EINVAL; } @@ -2404,7 +2404,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) if (netif_msg_probe(ugeth)) ugeth_err("%s: Number of station addresses greater than 1 " "not allowed in extended parsing mode.", - __FUNCTION__); + __func__); return -EINVAL; } @@ -2418,7 +2418,7 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth) /* Initialize the general fast UCC block. */ if (ucc_fast_init(uf_info, &ugeth->uccf)) { if (netif_msg_probe(ugeth)) - ugeth_err("%s: Failed to init uccf.", __FUNCTION__); + ugeth_err("%s: Failed to init uccf.", __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -2448,7 +2448,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) u8 __iomem *endOfRing; u8 numThreadsRxNumerical, numThreadsTxNumerical; - ugeth_vdbg("%s: IN", __FUNCTION__); + ugeth_vdbg("%s: IN", __func__); uccf = ugeth->uccf; ug_info = ugeth->ug_info; uf_info = &ug_info->uf_info; @@ -2474,7 +2474,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) default: if (netif_msg_ifup(ugeth)) ugeth_err("%s: Bad number of Rx threads value.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -EINVAL; break; @@ -2499,7 +2499,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) default: if (netif_msg_ifup(ugeth)) ugeth_err("%s: Bad number of Tx threads value.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -EINVAL; break; @@ -2553,7 +2553,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (ret_val != 0) { if (netif_msg_ifup(ugeth)) ugeth_err("%s: IPGIFG initialization parameter too large.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return ret_val; } @@ -2571,7 +2571,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (ret_val != 0) { if (netif_msg_ifup(ugeth)) ugeth_err("%s: Half Duplex initialization parameter too large.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return ret_val; } @@ -2626,7 +2626,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate memory for Tx bd rings.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -2662,7 +2662,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate memory for Rx bd rings.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -2678,7 +2678,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (ugeth->tx_skbuff[j] == NULL) { if (netif_msg_ifup(ugeth)) ugeth_err("%s: Could not allocate tx_skbuff", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -2710,7 +2710,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (ugeth->rx_skbuff[j] == NULL) { if (netif_msg_ifup(ugeth)) ugeth_err("%s: Could not allocate rx_skbuff", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -2744,7 +2744,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate DPRAM memory for p_tx_glbl_pram.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -2767,7 +2767,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate DPRAM memory for p_thread_data_tx.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -2797,7 +2797,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate DPRAM memory for p_send_q_mem_reg.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -2841,7 +2841,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate DPRAM memory for p_scheduler.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -2892,7 +2892,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) ugeth_err ("%s: Can not allocate DPRAM memory for" " p_tx_fw_statistics_pram.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -2932,7 +2932,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate DPRAM memory for p_rx_glbl_pram.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -2954,7 +2954,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate DPRAM memory for p_thread_data_rx.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -2978,7 +2978,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate DPRAM memory for" - " p_rx_fw_statistics_pram.", __FUNCTION__); + " p_rx_fw_statistics_pram.", __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -3001,7 +3001,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate DPRAM memory for" - " p_rx_irq_coalescing_tbl.", __FUNCTION__); + " p_rx_irq_coalescing_tbl.", __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -3070,7 +3070,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate DPRAM memory for p_rx_bd_qs_tbl.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -3147,7 +3147,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (!ug_info->extendedFilteringChainPointer) { if (netif_msg_ifup(ugeth)) ugeth_err("%s: Null Extended Filtering Chain Pointer.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -EINVAL; } @@ -3161,7 +3161,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate DPRAM memory for" - " p_exf_glbl_param.", __FUNCTION__); + " p_exf_glbl_param.", __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -3209,7 +3209,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate memory for" - " p_UccInitEnetParamShadows.", __FUNCTION__); + " p_UccInitEnetParamShadows.", __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -3244,7 +3244,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)) { if (netif_msg_ifup(ugeth)) ugeth_err("%s: Invalid largest External Lookup Key Size.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -EINVAL; } @@ -3271,7 +3271,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) ug_info->riscRx, 1)) != 0) { if (netif_msg_ifup(ugeth)) ugeth_err("%s: Can not fill p_init_enet_param_shadow.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return ret_val; } @@ -3287,7 +3287,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) ug_info->riscTx, 0)) != 0) { if (netif_msg_ifup(ugeth)) ugeth_err("%s: Can not fill p_init_enet_param_shadow.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return ret_val; } @@ -3297,7 +3297,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if ((ret_val = rx_bd_buffer_set(ugeth, (u8) i)) != 0) { if (netif_msg_ifup(ugeth)) ugeth_err("%s: Can not fill Rx bds with buffers.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return ret_val; } @@ -3309,7 +3309,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) if (netif_msg_ifup(ugeth)) ugeth_err ("%s: Can not allocate DPRAM memory for p_init_enet_pram.", - __FUNCTION__); + __func__); ucc_geth_memclean(ugeth); return -ENOMEM; } @@ -3360,7 +3360,7 @@ static void ucc_geth_timeout(struct net_device *dev) { struct ucc_geth_private *ugeth = netdev_priv(dev); - ugeth_vdbg("%s: IN", __FUNCTION__); + ugeth_vdbg("%s: IN", __func__); dev->stats.tx_errors++; @@ -3386,7 +3386,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev) u32 bd_status; u8 txQ = 0; - ugeth_vdbg("%s: IN", __FUNCTION__); + ugeth_vdbg("%s: IN", __func__); spin_lock_irq(&ugeth->lock); @@ -3459,7 +3459,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit u8 *bdBuffer; struct net_device *dev; - ugeth_vdbg("%s: IN", __FUNCTION__); + ugeth_vdbg("%s: IN", __func__); dev = ugeth->dev; @@ -3481,7 +3481,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit (bd_status & R_ERRORS_FATAL)) { if (netif_msg_rx_err(ugeth)) ugeth_err("%s, %d: ERROR!!! skb - 0x%08x", - __FUNCTION__, __LINE__, (u32) skb); + __func__, __LINE__, (u32) skb); if (skb) dev_kfree_skb_any(skb); @@ -3507,7 +3507,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit skb = get_new_skb(ugeth, bd); if (!skb) { if (netif_msg_rx_err(ugeth)) - ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__); + ugeth_warn("%s: No Rx Data Buffer", __func__); dev->stats.rx_dropped++; break; } @@ -3613,7 +3613,7 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info) register u32 tx_mask; u8 i; - ugeth_vdbg("%s: IN", __FUNCTION__); + ugeth_vdbg("%s: IN", __func__); uccf = ugeth->uccf; ug_info = ugeth->ug_info; @@ -3683,13 +3683,13 @@ static int ucc_geth_open(struct net_device *dev) struct ucc_geth_private *ugeth = netdev_priv(dev); int err; - ugeth_vdbg("%s: IN", __FUNCTION__); + ugeth_vdbg("%s: IN", __func__); /* Test station address */ if (dev->dev_addr[0] & ENET_GROUP_ADDR) { if (netif_msg_ifup(ugeth)) ugeth_err("%s: Multicast address used for station address" - " - is this what you wanted?", __FUNCTION__); + " - is this what you wanted?", __func__); return -EINVAL; } @@ -3772,7 +3772,7 @@ static int ucc_geth_close(struct net_device *dev) { struct ucc_geth_private *ugeth = netdev_priv(dev); - ugeth_vdbg("%s: IN", __FUNCTION__); + ugeth_vdbg("%s: IN", __func__); napi_disable(&ugeth->napi); @@ -3840,7 +3840,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI, }; - ugeth_vdbg("%s: IN", __FUNCTION__); + ugeth_vdbg("%s: IN", __func__); prop = of_get_property(np, "cell-index", NULL); if (!prop) { @@ -3857,7 +3857,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma if (ug_info == NULL) { if (netif_msg_probe(&debug)) ugeth_err("%s: [%d] Missing additional data!", - __FUNCTION__, ucc_num); + __func__, ucc_num); return -ENODEV; } diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 6e42b5a8c22..1164c52e2c0 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -92,9 +92,6 @@ #define HSO_NET_TX_TIMEOUT (HZ*10) -/* Serial port defines and structs. */ -#define HSO_SERIAL_FLAG_RX_SENT 0 - #define HSO_SERIAL_MAGIC 0x48534f31 /* Number of ttys to handle */ @@ -179,6 +176,12 @@ struct hso_net { unsigned long flags; }; +enum rx_ctrl_state{ + RX_IDLE, + RX_SENT, + RX_PENDING +}; + struct hso_serial { struct hso_device *parent; int magic; @@ -205,7 +208,7 @@ struct hso_serial { struct usb_endpoint_descriptor *in_endp; struct usb_endpoint_descriptor *out_endp; - unsigned long flags; + enum rx_ctrl_state rx_state; u8 rts_state; u8 dtr_state; unsigned tx_urb_used:1; @@ -216,6 +219,15 @@ struct hso_serial { spinlock_t serial_lock; int (*write_data) (struct hso_serial *serial); + /* Hacks required to get flow control + * working on the serial receive buffers + * so as not to drop characters on the floor. + */ + int curr_rx_urb_idx; + u16 curr_rx_urb_offset; + u8 rx_urb_filled[MAX_RX_URBS]; + struct tasklet_struct unthrottle_tasklet; + struct work_struct retry_unthrottle_workqueue; }; struct hso_device { @@ -271,7 +283,7 @@ struct hso_device { static int hso_serial_tiocmset(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); static void ctrl_callback(struct urb *urb); -static void put_rxbuf_data(struct urb *urb, struct hso_serial *serial); +static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial); static void hso_kick_transmit(struct hso_serial *serial); /* Helper functions */ static int hso_mux_submit_intr_urb(struct hso_shared_int *mux_int, @@ -287,6 +299,8 @@ static int hso_start_net_device(struct hso_device *hso_dev); static void hso_free_shared_int(struct hso_shared_int *shared_int); static int hso_stop_net_device(struct hso_device *hso_dev); static void hso_serial_ref_free(struct kref *ref); +static void hso_std_serial_read_bulk_callback(struct urb *urb); +static int hso_mux_serial_read(struct hso_serial *serial); static void async_get_intf(struct work_struct *data); static void async_put_intf(struct work_struct *data); static int hso_put_activity(struct hso_device *hso_dev); @@ -458,6 +472,17 @@ static ssize_t hso_sysfs_show_porttype(struct device *dev, } static DEVICE_ATTR(hsotype, S_IRUGO, hso_sysfs_show_porttype, NULL); +static int hso_urb_to_index(struct hso_serial *serial, struct urb *urb) +{ + int idx; + + for (idx = 0; idx < serial->num_rx_urbs; idx++) + if (serial->rx_urb[idx] == urb) + return idx; + dev_err(serial->parent->dev, "hso_urb_to_index failed\n"); + return -1; +} + /* converts mux value to a port spec value */ static u32 hso_mux_to_port(int mux) { @@ -1039,6 +1064,158 @@ static void _hso_serial_set_termios(struct tty_struct *tty, return; } +static void hso_resubmit_rx_bulk_urb(struct hso_serial *serial, struct urb *urb) +{ + int result; +#ifdef CONFIG_HSO_AUTOPM + usb_mark_last_busy(urb->dev); +#endif + /* We are done with this URB, resubmit it. Prep the USB to wait for + * another frame */ + usb_fill_bulk_urb(urb, serial->parent->usb, + usb_rcvbulkpipe(serial->parent->usb, + serial->in_endp-> + bEndpointAddress & 0x7F), + urb->transfer_buffer, serial->rx_data_length, + hso_std_serial_read_bulk_callback, serial); + /* Give this to the USB subsystem so it can tell us when more data + * arrives. */ + result = usb_submit_urb(urb, GFP_ATOMIC); + if (result) { + dev_err(&urb->dev->dev, "%s failed submit serial rx_urb %d\n", + __func__, result); + } +} + + + + +static void put_rxbuf_data_and_resubmit_bulk_urb(struct hso_serial *serial) +{ + int count; + struct urb *curr_urb; + + while (serial->rx_urb_filled[serial->curr_rx_urb_idx]) { + curr_urb = serial->rx_urb[serial->curr_rx_urb_idx]; + count = put_rxbuf_data(curr_urb, serial); + if (count == -1) + return; + if (count == 0) { + serial->curr_rx_urb_idx++; + if (serial->curr_rx_urb_idx >= serial->num_rx_urbs) + serial->curr_rx_urb_idx = 0; + hso_resubmit_rx_bulk_urb(serial, curr_urb); + } + } +} + +static void put_rxbuf_data_and_resubmit_ctrl_urb(struct hso_serial *serial) +{ + int count = 0; + struct urb *urb; + + urb = serial->rx_urb[0]; + if (serial->open_count > 0) { + count = put_rxbuf_data(urb, serial); + if (count == -1) + return; + } + /* Re issue a read as long as we receive data. */ + + if (count == 0 && ((urb->actual_length != 0) || + (serial->rx_state == RX_PENDING))) { + serial->rx_state = RX_SENT; + hso_mux_serial_read(serial); + } else + serial->rx_state = RX_IDLE; +} + + +/* read callback for Diag and CS port */ +static void hso_std_serial_read_bulk_callback(struct urb *urb) +{ + struct hso_serial *serial = urb->context; + int status = urb->status; + + /* sanity check */ + if (!serial) { + D1("serial == NULL"); + return; + } else if (status) { + log_usb_status(status, __func__); + return; + } + + D4("\n--- Got serial_read_bulk callback %02x ---", status); + D1("Actual length = %d\n", urb->actual_length); + DUMP1(urb->transfer_buffer, urb->actual_length); + + /* Anyone listening? */ + if (serial->open_count == 0) + return; + + if (status == 0) { + if (serial->parent->port_spec & HSO_INFO_CRC_BUG) { + u32 rest; + u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; + rest = + urb->actual_length % + serial->in_endp->wMaxPacketSize; + if (((rest == 5) || (rest == 6)) + && !memcmp(((u8 *) urb->transfer_buffer) + + urb->actual_length - 4, crc_check, 4)) { + urb->actual_length -= 4; + } + } + /* Valid data, handle RX data */ + spin_lock(&serial->serial_lock); + serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 1; + put_rxbuf_data_and_resubmit_bulk_urb(serial); + spin_unlock(&serial->serial_lock); + } else if (status == -ENOENT || status == -ECONNRESET) { + /* Unlinked - check for throttled port. */ + D2("Port %d, successfully unlinked urb", serial->minor); + spin_lock(&serial->serial_lock); + serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; + hso_resubmit_rx_bulk_urb(serial, urb); + spin_unlock(&serial->serial_lock); + } else { + D2("Port %d, status = %d for read urb", serial->minor, status); + return; + } +} + +/* + * This needs to be a tasklet otherwise we will + * end up recursively calling this function. + */ +void hso_unthrottle_tasklet(struct hso_serial *serial) +{ + unsigned long flags; + + spin_lock_irqsave(&serial->serial_lock, flags); + if ((serial->parent->port_spec & HSO_INTF_MUX)) + put_rxbuf_data_and_resubmit_ctrl_urb(serial); + else + put_rxbuf_data_and_resubmit_bulk_urb(serial); + spin_unlock_irqrestore(&serial->serial_lock, flags); +} + +static void hso_unthrottle(struct tty_struct *tty) +{ + struct hso_serial *serial = get_serial_by_tty(tty); + + tasklet_hi_schedule(&serial->unthrottle_tasklet); +} + +void hso_unthrottle_workfunc(struct work_struct *work) +{ + struct hso_serial *serial = + container_of(work, struct hso_serial, + retry_unthrottle_workqueue); + hso_unthrottle_tasklet(serial); +} + /* open the requested serial port */ static int hso_serial_open(struct tty_struct *tty, struct file *filp) { @@ -1064,13 +1241,18 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) tty->driver_data = serial; serial->tty = tty; - /* check for port allready opened, if not set the termios */ + /* check for port already opened, if not set the termios */ serial->open_count++; if (serial->open_count == 1) { tty->low_latency = 1; - serial->flags = 0; + serial->rx_state = RX_IDLE; /* Force default termio settings */ _hso_serial_set_termios(tty, NULL); + tasklet_init(&serial->unthrottle_tasklet, + (void (*)(unsigned long))hso_unthrottle_tasklet, + (unsigned long)serial); + INIT_WORK(&serial->retry_unthrottle_workqueue, + hso_unthrottle_workfunc); result = hso_start_serial_device(serial->parent, GFP_KERNEL); if (result) { hso_stop_serial_device(serial->parent); @@ -1117,9 +1299,13 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) } if (!usb_gone) hso_stop_serial_device(serial->parent); + tasklet_kill(&serial->unthrottle_tasklet); + cancel_work_sync(&serial->retry_unthrottle_workqueue); } + if (!usb_gone) usb_autopm_put_interface(serial->parent->interface); + mutex_unlock(&serial->parent->mutex); } @@ -1422,15 +1608,21 @@ static void intr_callback(struct urb *urb) (1 << i)); if (serial != NULL) { D1("Pending read interrupt on port %d\n", i); - if (!test_and_set_bit(HSO_SERIAL_FLAG_RX_SENT, - &serial->flags)) { + spin_lock(&serial->serial_lock); + if (serial->rx_state == RX_IDLE) { /* Setup and send a ctrl req read on * port i */ - hso_mux_serial_read(serial); + if (!serial->rx_urb_filled[0]) { + serial->rx_state = RX_SENT; + hso_mux_serial_read(serial); + } else + serial->rx_state = RX_PENDING; + } else { D1("Already pending a read on " "port %d\n", i); } + spin_unlock(&serial->serial_lock); } } } @@ -1532,16 +1724,10 @@ static void ctrl_callback(struct urb *urb) if (req->bRequestType == (USB_DIR_IN | USB_TYPE_OPTION_VENDOR | USB_RECIP_INTERFACE)) { /* response to a read command */ - if (serial->open_count > 0) { - /* handle RX data the normal way */ - put_rxbuf_data(urb, serial); - } - - /* Re issue a read as long as we receive data. */ - if (urb->actual_length != 0) - hso_mux_serial_read(serial); - else - clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags); + serial->rx_urb_filled[0] = 1; + spin_lock(&serial->serial_lock); + put_rxbuf_data_and_resubmit_ctrl_urb(serial); + spin_unlock(&serial->serial_lock); } else { hso_put_activity(serial->parent); if (serial->tty) @@ -1552,91 +1738,42 @@ static void ctrl_callback(struct urb *urb) } /* handle RX data for serial port */ -static void put_rxbuf_data(struct urb *urb, struct hso_serial *serial) +static int put_rxbuf_data(struct urb *urb, struct hso_serial *serial) { struct tty_struct *tty = serial->tty; - + int write_length_remaining = 0; + int curr_write_len; /* Sanity check */ if (urb == NULL || serial == NULL) { D1("serial = NULL"); - return; + return -2; } /* Push data to tty */ - if (tty && urb->actual_length) { + if (tty) { + write_length_remaining = urb->actual_length - + serial->curr_rx_urb_offset; D1("data to push to tty"); - tty_insert_flip_string(tty, urb->transfer_buffer, - urb->actual_length); - tty_flip_buffer_push(tty); - } -} - -/* read callback for Diag and CS port */ -static void hso_std_serial_read_bulk_callback(struct urb *urb) -{ - struct hso_serial *serial = urb->context; - int result; - int status = urb->status; - - /* sanity check */ - if (!serial) { - D1("serial == NULL"); - return; - } else if (status) { - log_usb_status(status, __func__); - return; - } - - D4("\n--- Got serial_read_bulk callback %02x ---", status); - D1("Actual length = %d\n", urb->actual_length); - DUMP1(urb->transfer_buffer, urb->actual_length); - - /* Anyone listening? */ - if (serial->open_count == 0) - return; - - if (status == 0) { - if (serial->parent->port_spec & HSO_INFO_CRC_BUG) { - u32 rest; - u8 crc_check[4] = { 0xDE, 0xAD, 0xBE, 0xEF }; - rest = - urb->actual_length % - serial->in_endp->wMaxPacketSize; - if (((rest == 5) || (rest == 6)) - && !memcmp(((u8 *) urb->transfer_buffer) + - urb->actual_length - 4, crc_check, 4)) { - urb->actual_length -= 4; - } + while (write_length_remaining) { + if (test_bit(TTY_THROTTLED, &tty->flags)) + return -1; + curr_write_len = tty_insert_flip_string + (tty, urb->transfer_buffer + + serial->curr_rx_urb_offset, + write_length_remaining); + serial->curr_rx_urb_offset += curr_write_len; + write_length_remaining -= curr_write_len; + tty_flip_buffer_push(tty); } - /* Valid data, handle RX data */ - put_rxbuf_data(urb, serial); - } else if (status == -ENOENT || status == -ECONNRESET) { - /* Unlinked - check for throttled port. */ - D2("Port %d, successfully unlinked urb", serial->minor); - } else { - D2("Port %d, status = %d for read urb", serial->minor, status); - return; } - - usb_mark_last_busy(urb->dev); - - /* We are done with this URB, resubmit it. Prep the USB to wait for - * another frame */ - usb_fill_bulk_urb(urb, serial->parent->usb, - usb_rcvbulkpipe(serial->parent->usb, - serial->in_endp-> - bEndpointAddress & 0x7F), - urb->transfer_buffer, serial->rx_data_length, - hso_std_serial_read_bulk_callback, serial); - /* Give this to the USB subsystem so it can tell us when more data - * arrives. */ - result = usb_submit_urb(urb, GFP_ATOMIC); - if (result) { - dev_err(&urb->dev->dev, "%s failed submit serial rx_urb %d", - __func__, result); + if (write_length_remaining == 0) { + serial->curr_rx_urb_offset = 0; + serial->rx_urb_filled[hso_urb_to_index(serial, urb)] = 0; } + return write_length_remaining; } + /* Base driver functions */ static void hso_log_port(struct hso_device *hso_dev) @@ -1794,9 +1931,13 @@ static int hso_stop_serial_device(struct hso_device *hso_dev) return -ENODEV; for (i = 0; i < serial->num_rx_urbs; i++) { - if (serial->rx_urb[i]) + if (serial->rx_urb[i]) { usb_kill_urb(serial->rx_urb[i]); + serial->rx_urb_filled[i] = 0; + } } + serial->curr_rx_urb_idx = 0; + serial->curr_rx_urb_offset = 0; if (serial->tx_urb) usb_kill_urb(serial->tx_urb); @@ -2211,14 +2352,14 @@ static struct hso_device *hso_create_bulk_serial_device( USB_DIR_IN); if (!serial->in_endp) { dev_err(&interface->dev, "Failed to find BULK IN ep\n"); - goto exit; + goto exit2; } if (! (serial->out_endp = hso_get_ep(interface, USB_ENDPOINT_XFER_BULK, USB_DIR_OUT))) { dev_err(&interface->dev, "Failed to find BULK IN ep\n"); - goto exit; + goto exit2; } serial->write_data = hso_std_serial_write_data; @@ -2231,9 +2372,10 @@ static struct hso_device *hso_create_bulk_serial_device( /* done, return it */ return hso_dev; + +exit2: + hso_serial_common_free(serial); exit: - if (hso_dev && serial) - hso_serial_common_free(serial); kfree(serial); hso_free_device(hso_dev); return NULL; @@ -2740,6 +2882,7 @@ static const struct tty_operations hso_serial_ops = { .chars_in_buffer = hso_serial_chars_in_buffer, .tiocmget = hso_serial_tiocmget, .tiocmset = hso_serial_tiocmset, + .unthrottle = hso_unthrottle }; static struct usb_driver hso_driver = { diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index ca9d00c1194..b5143509e8b 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c @@ -118,7 +118,7 @@ static void mcs7830_async_cmd_callback(struct urb *urb) if (urb->status < 0) printk(KERN_DEBUG "%s() failed with %d\n", - __FUNCTION__, urb->status); + __func__, urb->status); kfree(req); usb_free_urb(urb); diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 8c19307e504..38b90e7a7ed 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -119,7 +119,7 @@ static void ctrl_callback(struct urb *urb) default: if (netif_msg_drv(pegasus) && printk_ratelimit()) dev_dbg(&pegasus->intf->dev, "%s, status %d\n", - __FUNCTION__, urb->status); + __func__, urb->status); } pegasus->flags &= ~ETH_REGS_CHANGED; wake_up(&pegasus->ctrl_wait); @@ -136,7 +136,7 @@ static int get_registers(pegasus_t * pegasus, __u16 indx, __u16 size, if (!buffer) { if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "out of memory in %s\n", - __FUNCTION__); + __func__); return -ENOMEM; } add_wait_queue(&pegasus->ctrl_wait, &wait); @@ -224,7 +224,7 @@ static int set_registers(pegasus_t * pegasus, __u16 indx, __u16 size, netif_device_detach(pegasus->net); if (netif_msg_drv(pegasus)) dev_err(&pegasus->intf->dev, "%s, status %d\n", - __FUNCTION__, ret); + __func__, ret); goto out; } @@ -246,7 +246,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) if (!tmp) { if (netif_msg_drv(pegasus)) dev_warn(&pegasus->intf->dev, "out of memory in %s\n", - __FUNCTION__); + __func__); return -ENOMEM; } memcpy(tmp, &data, 1); @@ -277,7 +277,7 @@ static int set_register(pegasus_t * pegasus, __u16 indx, __u8 data) netif_device_detach(pegasus->net); if (netif_msg_drv(pegasus) && printk_ratelimit()) dev_err(&pegasus->intf->dev, "%s, status %d\n", - __FUNCTION__, ret); + __func__, ret); goto out; } @@ -310,7 +310,7 @@ static int update_eth_regs_async(pegasus_t * pegasus) netif_device_detach(pegasus->net); if (netif_msg_drv(pegasus)) dev_err(&pegasus->intf->dev, "%s, status %d\n", - __FUNCTION__, ret); + __func__, ret); } return ret; @@ -341,7 +341,7 @@ static int read_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 * regd) } fail: if (netif_msg_drv(pegasus)) - dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__); + dev_warn(&pegasus->intf->dev, "%s failed\n", __func__); return ret; } @@ -378,7 +378,7 @@ static int write_mii_word(pegasus_t * pegasus, __u8 phy, __u8 indx, __u16 regd) fail: if (netif_msg_drv(pegasus)) - dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__); + dev_warn(&pegasus->intf->dev, "%s failed\n", __func__); return -ETIMEDOUT; } @@ -415,7 +415,7 @@ static int read_eprom_word(pegasus_t * pegasus, __u8 index, __u16 * retdata) fail: if (netif_msg_drv(pegasus)) - dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__); + dev_warn(&pegasus->intf->dev, "%s failed\n", __func__); return -ETIMEDOUT; } @@ -463,7 +463,7 @@ static int write_eprom_word(pegasus_t * pegasus, __u8 index, __u16 data) return ret; fail: if (netif_msg_drv(pegasus)) - dev_warn(&pegasus->intf->dev, "%s failed\n", __FUNCTION__); + dev_warn(&pegasus->intf->dev, "%s failed\n", __func__); return -ETIMEDOUT; } #endif /* PEGASUS_WRITE_EEPROM */ diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 8463efb9e0b..02d25c74399 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -512,14 +512,13 @@ static int unlink_urbs (struct usbnet *dev, struct sk_buff_head *q) int count = 0; spin_lock_irqsave (&q->lock, flags); - for (skb = q->next; skb != (struct sk_buff *) q; skb = skbnext) { + skb_queue_walk_safe(q, skb, skbnext) { struct skb_data *entry; struct urb *urb; int retval; entry = (struct skb_data *) skb->cb; urb = entry->urb; - skbnext = skb->next; // during some PM-driven resume scenarios, // these (async) unlinks complete immediately diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h index 1b95b04c925..29a33090d3d 100644 --- a/drivers/net/via-velocity.h +++ b/drivers/net/via-velocity.h @@ -1381,7 +1381,7 @@ enum velocity_msg_level { #define ASSERT(x) { \ if (!(x)) { \ printk(KERN_ERR "assertion %s failed: file %s line %d\n", #x,\ - __FUNCTION__, __LINE__);\ + __func__, __LINE__);\ BUG(); \ }\ } diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c index d14e6678dee..a5ddc6c8963 100644 --- a/drivers/net/wan/cycx_drv.c +++ b/drivers/net/wan/cycx_drv.c @@ -407,7 +407,7 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len) if (cfm->version != CFM_VERSION) { printk(KERN_ERR "%s:%s: firmware format %u rejected! " "Expecting %u.\n", - modname, __FUNCTION__, cfm->version, CFM_VERSION); + modname, __func__, cfm->version, CFM_VERSION); return -EINVAL; } @@ -420,7 +420,7 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len) */ if (cksum != cfm->checksum) { printk(KERN_ERR "%s:%s: firmware corrupted!\n", - modname, __FUNCTION__); + modname, __func__); printk(KERN_ERR " cdsize = 0x%x (expected 0x%lx)\n", len - (int)sizeof(struct cycx_firmware) - 1, cfm->info.codesize); @@ -432,7 +432,7 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len) /* If everything is ok, set reset, data and code pointers */ img_hdr = (struct cycx_fw_header *)&cfm->image; #ifdef FIRMWARE_DEBUG - printk(KERN_INFO "%s:%s: image sizes\n", __FUNCTION__, modname); + printk(KERN_INFO "%s:%s: image sizes\n", __func__, modname); printk(KERN_INFO " reset=%lu\n", img_hdr->reset_size); printk(KERN_INFO " data=%lu\n", img_hdr->data_size); printk(KERN_INFO " code=%lu\n", img_hdr->code_size); diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c index d3b28b01b9f..5a7303dc096 100644 --- a/drivers/net/wan/cycx_x25.c +++ b/drivers/net/wan/cycx_x25.c @@ -874,7 +874,7 @@ static void cycx_x25_irq_connect(struct cycx_device *card, nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1); dprintk(1, KERN_INFO "%s:lcn=%d, local=%s, remote=%s\n", - __FUNCTION__, lcn, loc, rem); + __func__, lcn, loc, rem); dev = cycx_x25_get_dev_by_dte_addr(wandev, rem); if (!dev) { @@ -902,7 +902,7 @@ static void cycx_x25_irq_connect_confirm(struct cycx_device *card, cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn)); cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key)); dprintk(1, KERN_INFO "%s: %s:lcn=%d, key=%d\n", - card->devname, __FUNCTION__, lcn, key); + card->devname, __func__, lcn, key); dev = cycx_x25_get_dev_by_lcn(wandev, -key); if (!dev) { @@ -929,7 +929,7 @@ static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card, cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn)); dprintk(1, KERN_INFO "%s: %s:lcn=%d\n", - card->devname, __FUNCTION__, lcn); + card->devname, __func__, lcn); dev = cycx_x25_get_dev_by_lcn(wandev, lcn); if (!dev) { /* Invalid channel, discard packet */ @@ -950,7 +950,7 @@ static void cycx_x25_irq_disconnect(struct cycx_device *card, u8 lcn; cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn)); - dprintk(1, KERN_INFO "%s:lcn=%d\n", __FUNCTION__, lcn); + dprintk(1, KERN_INFO "%s:lcn=%d\n", __func__, lcn); dev = cycx_x25_get_dev_by_lcn(wandev, lcn); if (dev) { @@ -1381,7 +1381,7 @@ static void cycx_x25_chan_timer(unsigned long d) cycx_x25_chan_disconnect(dev); else printk(KERN_ERR "%s: %s for svc (%s) not connected!\n", - chan->card->devname, __FUNCTION__, dev->name); + chan->card->devname, __func__, dev->name); } /* Set logical channel state. */ @@ -1485,7 +1485,7 @@ static void cycx_x25_chan_send_event(struct net_device *dev, u8 event) unsigned char *ptr; if ((skb = dev_alloc_skb(1)) == NULL) { - printk(KERN_ERR "%s: out of memory\n", __FUNCTION__); + printk(KERN_ERR "%s: out of memory\n", __func__); return; } diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index f5d55ad0226..5f1ccb2b08b 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c @@ -647,7 +647,7 @@ static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv, skb = dpriv->rx_skbuff[dpriv->rx_current++%RX_RING_SIZE]; if (!skb) { - printk(KERN_DEBUG "%s: skb=0 (%s)\n", dev->name, __FUNCTION__); + printk(KERN_DEBUG "%s: skb=0 (%s)\n", dev->name, __func__); goto refill; } pkt_len = TO_SIZE(le32_to_cpu(rx_fd->state2)); diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c index 8b7e5d2e2ac..cbcbf6f0414 100644 --- a/drivers/net/wan/hdlc_x25.c +++ b/drivers/net/wan/hdlc_x25.c @@ -163,15 +163,17 @@ static void x25_close(struct net_device *dev) static int x25_rx(struct sk_buff *skb) { + struct net_device *dev = skb->dev; + if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { - skb->dev->stats.rx_dropped++; + dev->stats.rx_dropped++; return NET_RX_DROP; } - if (lapb_data_received(skb->dev, skb) == LAPB_OK) + if (lapb_data_received(dev, skb) == LAPB_OK) return NET_RX_SUCCESS; - skb->dev->stats.rx_errors++; + dev->stats.rx_errors++; dev_kfree_skb_any(skb); return NET_RX_DROP; } diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index 4518d0aa248..4917a94943b 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c @@ -548,7 +548,7 @@ static int pc300_tiocmset(struct tty_struct *tty, struct file *file, { st_cpc_tty_area *cpc_tty; - CPC_TTY_DBG("%s: set:%x clear:%x\n", __FUNCTION__, set, clear); + CPC_TTY_DBG("%s: set:%x clear:%x\n", __func__, set, clear); if (!tty || !tty->driver_data ) { CPC_TTY_DBG("hdlcX-tty: no TTY to chars in buffer\n"); diff --git a/drivers/net/wan/sbni.c b/drivers/net/wan/sbni.c index 6596cd0742b..f972fef87c9 100644 --- a/drivers/net/wan/sbni.c +++ b/drivers/net/wan/sbni.c @@ -856,7 +856,7 @@ prepare_to_send( struct sk_buff *skb, struct net_device *dev ) len = SBNI_MIN_LEN; nl->tx_buf_p = skb; - nl->tx_frameno = (len + nl->maxframe - 1) / nl->maxframe; + nl->tx_frameno = DIV_ROUND_UP(len, nl->maxframe); nl->framelen = len < nl->maxframe ? len : nl->maxframe; outb( inb( dev->base_addr + CSR0 ) | TR_REQ, dev->base_addr + CSR0 ); diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index ae58a12befd..370133e492d 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c @@ -7107,7 +7107,7 @@ static int airo_get_aplist(struct net_device *dev, */ static int airo_set_scan(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, + struct iw_point *dwrq, char *extra) { struct airo_info *ai = dev->priv; diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index f12355398fe..fd72e427cb2 100644 --- a/drivers/net/wireless/airo_cs.c +++ b/drivers/net/wireless/airo_cs.c @@ -147,7 +147,7 @@ static int airo_probe(struct pcmcia_device *p_dev) DEBUG(0, "airo_attach()\n"); /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; p_dev->irq.Handler = NULL; diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h index 20018869051..7134c40d6a6 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath5k/ath5k.h @@ -281,7 +281,9 @@ enum ath5k_radio { AR5K_RF5112 = 2, AR5K_RF2413 = 3, AR5K_RF5413 = 4, - AR5K_RF2425 = 5, + AR5K_RF2316 = 5, + AR5K_RF2317 = 6, + AR5K_RF2425 = 7, }; /* @@ -289,7 +291,7 @@ enum ath5k_radio { */ enum ath5k_srev_type { - AR5K_VERSION_VER, + AR5K_VERSION_MAC, AR5K_VERSION_RAD, }; @@ -301,23 +303,24 @@ struct ath5k_srev_name { #define AR5K_SREV_UNKNOWN 0xffff -#define AR5K_SREV_VER_AR5210 0x00 -#define AR5K_SREV_VER_AR5311 0x10 -#define AR5K_SREV_VER_AR5311A 0x20 -#define AR5K_SREV_VER_AR5311B 0x30 -#define AR5K_SREV_VER_AR5211 0x40 -#define AR5K_SREV_VER_AR5212 0x50 -#define AR5K_SREV_VER_AR5213 0x55 -#define AR5K_SREV_VER_AR5213A 0x59 -#define AR5K_SREV_VER_AR2413 0x78 -#define AR5K_SREV_VER_AR2414 0x79 -#define AR5K_SREV_VER_AR2424 0xa0 /* PCI-E */ -#define AR5K_SREV_VER_AR5424 0xa3 /* PCI-E */ -#define AR5K_SREV_VER_AR5413 0xa4 -#define AR5K_SREV_VER_AR5414 0xa5 -#define AR5K_SREV_VER_AR5416 0xc0 /* PCI-E */ -#define AR5K_SREV_VER_AR5418 0xca /* PCI-E */ -#define AR5K_SREV_VER_AR2425 0xe2 /* PCI-E */ +#define AR5K_SREV_AR5210 0x00 /* Crete */ +#define AR5K_SREV_AR5311 0x10 /* Maui 1 */ +#define AR5K_SREV_AR5311A 0x20 /* Maui 2 */ +#define AR5K_SREV_AR5311B 0x30 /* Spirit */ +#define AR5K_SREV_AR5211 0x40 /* Oahu */ +#define AR5K_SREV_AR5212 0x50 /* Venice */ +#define AR5K_SREV_AR5213 0x55 /* ??? */ +#define AR5K_SREV_AR5213A 0x59 /* Hainan */ +#define AR5K_SREV_AR2413 0x78 /* Griffin lite */ +#define AR5K_SREV_AR2414 0x70 /* Griffin */ +#define AR5K_SREV_AR5424 0x90 /* Condor */ +#define AR5K_SREV_AR5413 0xa4 /* Eagle lite */ +#define AR5K_SREV_AR5414 0xa0 /* Eagle */ +#define AR5K_SREV_AR2415 0xb0 /* Cobra */ +#define AR5K_SREV_AR5416 0xc0 /* PCI-E */ +#define AR5K_SREV_AR5418 0xca /* PCI-E */ +#define AR5K_SREV_AR2425 0xe0 /* Swan */ +#define AR5K_SREV_AR2417 0xf0 /* Nala */ #define AR5K_SREV_RAD_5110 0x00 #define AR5K_SREV_RAD_5111 0x10 @@ -329,10 +332,20 @@ struct ath5k_srev_name { #define AR5K_SREV_RAD_2112 0x40 #define AR5K_SREV_RAD_2112A 0x45 #define AR5K_SREV_RAD_2112B 0x46 -#define AR5K_SREV_RAD_SC0 0x50 /* Found on 2413/2414 */ -#define AR5K_SREV_RAD_SC1 0x60 /* Found on 5413/5414 */ -#define AR5K_SREV_RAD_SC2 0xa0 /* Found on 2424-5/5424 */ -#define AR5K_SREV_RAD_5133 0xc0 /* MIMO found on 5418 */ +#define AR5K_SREV_RAD_2413 0x50 +#define AR5K_SREV_RAD_5413 0x60 +#define AR5K_SREV_RAD_2316 0x70 +#define AR5K_SREV_RAD_2317 0x80 +#define AR5K_SREV_RAD_5424 0xa0 /* Mostly same as 5413 */ +#define AR5K_SREV_RAD_2425 0xa2 +#define AR5K_SREV_RAD_5133 0xc0 + +#define AR5K_SREV_PHY_5211 0x30 +#define AR5K_SREV_PHY_5212 0x41 +#define AR5K_SREV_PHY_2112B 0x43 +#define AR5K_SREV_PHY_2413 0x45 +#define AR5K_SREV_PHY_5413 0x61 +#define AR5K_SREV_PHY_2425 0x70 /* IEEE defs */ #define IEEE80211_MAX_LEN 2500 diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath5k/attach.c index 153c4111fab..51d569883cd 100644 --- a/drivers/net/wireless/ath5k/attach.c +++ b/drivers/net/wireless/ath5k/attach.c @@ -137,7 +137,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY; /* - * Set the mac revision based on the pci id + * Set the mac version based on the pci id */ ah->ah_version = mac_version; @@ -160,87 +160,132 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) 0xffffffff; ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, CHANNEL_5GHZ); + ah->ah_phy = AR5K_PHY(0); - if (ah->ah_version == AR5K_AR5210) - ah->ah_radio_2ghz_revision = 0; - else - ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, - CHANNEL_2GHZ); - - /* Return on unsuported chips (unsupported eeprom etc) */ - if ((srev >= AR5K_SREV_VER_AR5416) && - (srev < AR5K_SREV_VER_AR2425)) { - ATH5K_ERR(sc, "Device not yet supported.\n"); - ret = -ENODEV; - goto err_free; - } else if (srev == AR5K_SREV_VER_AR2425) { - ATH5K_WARN(sc, "Support for RF2425 is under development.\n"); - } - - /* Identify single chip solutions */ - if (((srev <= AR5K_SREV_VER_AR5414) && - (srev >= AR5K_SREV_VER_AR2413)) || - (srev == AR5K_SREV_VER_AR2425)) { - ah->ah_single_chip = true; - } else { - ah->ah_single_chip = false; - } - - /* Single chip radio */ - if (ah->ah_radio_2ghz_revision == ah->ah_radio_5ghz_revision) - ah->ah_radio_2ghz_revision = 0; - - /* Identify the radio chip*/ - if (ah->ah_version == AR5K_AR5210) { - ah->ah_radio = AR5K_RF5110; - /* - * Register returns 0x0/0x04 for radio revision - * so ath5k_hw_radio_revision doesn't parse the value - * correctly. For now we are based on mac's srev to - * identify RF2425 radio. - */ - } else if (srev == AR5K_SREV_VER_AR2425) { - ah->ah_radio = AR5K_RF2425; - ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425; - } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) { + /* Try to identify radio chip based on it's srev */ + switch (ah->ah_radio_5ghz_revision & 0xf0) { + case AR5K_SREV_RAD_5111: ah->ah_radio = AR5K_RF5111; + ah->ah_single_chip = false; + ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, + CHANNEL_2GHZ); ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111; - } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) { + break; + case AR5K_SREV_RAD_5112: + case AR5K_SREV_RAD_2112: ah->ah_radio = AR5K_RF5112; + ah->ah_single_chip = false; + ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, + CHANNEL_2GHZ); ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112; - } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) { + break; + case AR5K_SREV_RAD_2413: ah->ah_radio = AR5K_RF2413; + ah->ah_single_chip = true; ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; - } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) { + break; + case AR5K_SREV_RAD_5413: ah->ah_radio = AR5K_RF5413; + ah->ah_single_chip = true; ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; - } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) { - /* AR5424 */ - if (srev >= AR5K_SREV_VER_AR5424) { + break; + case AR5K_SREV_RAD_2316: + ah->ah_radio = AR5K_RF2316; + ah->ah_single_chip = true; + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316; + break; + case AR5K_SREV_RAD_2317: + ah->ah_radio = AR5K_RF2317; + ah->ah_single_chip = true; + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2317; + break; + case AR5K_SREV_RAD_5424: + if (ah->ah_mac_version == AR5K_SREV_AR2425 || + ah->ah_mac_version == AR5K_SREV_AR2417){ + ah->ah_radio = AR5K_RF2425; + ah->ah_single_chip = true; + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425; + } else { ah->ah_radio = AR5K_RF5413; + ah->ah_single_chip = true; ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; - /* AR2424 */ - } else { - ah->ah_radio = AR5K_RF2413; /* For testing */ + } + break; + default: + /* Identify radio based on mac/phy srev */ + if (ah->ah_version == AR5K_AR5210) { + ah->ah_radio = AR5K_RF5110; + ah->ah_single_chip = false; + } else if (ah->ah_version == AR5K_AR5211) { + ah->ah_radio = AR5K_RF5111; + ah->ah_single_chip = false; + ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, + CHANNEL_2GHZ); + } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) || + ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) || + ah->ah_phy_revision == AR5K_SREV_PHY_2425) { + ah->ah_radio = AR5K_RF2425; + ah->ah_single_chip = true; + ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425; + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425; + } else if (srev == AR5K_SREV_AR5213A && + ah->ah_phy_revision == AR5K_SREV_PHY_2112B) { + ah->ah_radio = AR5K_RF5112; + ah->ah_single_chip = false; + ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2112B; + } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) { + ah->ah_radio = AR5K_RF2316; + ah->ah_single_chip = true; + ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316; + } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) || + ah->ah_phy_revision == AR5K_SREV_PHY_5413) { + ah->ah_radio = AR5K_RF5413; + ah->ah_single_chip = true; + ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413; + ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; + } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) || + ah->ah_phy_revision == AR5K_SREV_PHY_2413) { + ah->ah_radio = AR5K_RF2413; + ah->ah_single_chip = true; + ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413; ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; + } else { + ATH5K_ERR(sc, "Couldn't identify radio revision.\n"); + ret = -ENODEV; + goto err_free; } } - ah->ah_phy = AR5K_PHY(0); + + + /* Return on unsuported chips (unsupported eeprom etc) */ + if ((srev >= AR5K_SREV_AR5416) && + (srev < AR5K_SREV_AR2425)) { + ATH5K_ERR(sc, "Device not yet supported.\n"); + ret = -ENODEV; + goto err_free; + } /* * Write PCI-E power save settings */ if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) { - ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080); - ath5k_hw_reg_write(ah, 0x24924924, 0x4080); - ath5k_hw_reg_write(ah, 0x28000039, 0x4080); - ath5k_hw_reg_write(ah, 0x53160824, 0x4080); - ath5k_hw_reg_write(ah, 0xe5980579, 0x4080); - ath5k_hw_reg_write(ah, 0x001defff, 0x4080); - ath5k_hw_reg_write(ah, 0x1aaabe40, 0x4080); - ath5k_hw_reg_write(ah, 0xbe105554, 0x4080); - ath5k_hw_reg_write(ah, 0x000e3007, 0x4080); - ath5k_hw_reg_write(ah, 0x00000000, 0x4084); + ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES); + ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES); + /* Shut off RX when elecidle is asserted */ + ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES); + ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES); + /* TODO: EEPROM work */ + ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES); + /* Shut off PLL and CLKREQ active in L1 */ + ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES); + /* Preserce other settings */ + ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES); + ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES); + ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES); + /* Reset SERDES to load new settings */ + ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET); + mdelay(1); } /* @@ -250,14 +295,13 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) if (ret) goto err_free; - /* Write AR5K_PCICFG_UNK on 2112B and later chips */ - if (ah->ah_radio_5ghz_revision > AR5K_SREV_RAD_2112B || - srev > AR5K_SREV_VER_AR2413) { - ath5k_hw_reg_write(ah, AR5K_PCICFG_UNK, AR5K_PCICFG); - } + /* Enable pci core retry fix on Hainan (5213A) and later chips */ + if (srev >= AR5K_SREV_AR5213A) + ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG); /* - * Get card capabilities, values, ... + * Get card capabilities, calibration values etc + * TODO: EEPROM work */ ret = ath5k_eeprom_init(ah); if (ret) { @@ -273,7 +317,7 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) goto err_free; } - /* Get MAC address */ + /* Set MAC address */ ret = ath5k_eeprom_read_mac(ah, mac); if (ret) { ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index e09ed2ce675..c151588aa48 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -72,7 +72,7 @@ MODULE_AUTHOR("Nick Kossifidis"); MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_VERSION("0.5.0 (EXPERIMENTAL)"); +MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); /* Known PCI ids */ @@ -93,41 +93,48 @@ static struct pci_device_id ath5k_pci_id_table[] __devinitdata = { { PCI_VDEVICE(ATHEROS, 0x0019), .driver_data = AR5K_AR5212 }, /* 5212 combatible */ { PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */ { PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */ - { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* 5424 Condor (PCI-E)*/ + { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* PCI-E cards */ + { PCI_VDEVICE(ATHEROS, 0x001d), .driver_data = AR5K_AR5212 }, /* 2417 Nala */ { 0 } }; MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); /* Known SREVs */ static struct ath5k_srev_name srev_names[] = { - { "5210", AR5K_VERSION_VER, AR5K_SREV_VER_AR5210 }, - { "5311", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311 }, - { "5311A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311A }, - { "5311B", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311B }, - { "5211", AR5K_VERSION_VER, AR5K_SREV_VER_AR5211 }, - { "5212", AR5K_VERSION_VER, AR5K_SREV_VER_AR5212 }, - { "5213", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213 }, - { "5213A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213A }, - { "2413", AR5K_VERSION_VER, AR5K_SREV_VER_AR2413 }, - { "2414", AR5K_VERSION_VER, AR5K_SREV_VER_AR2414 }, - { "2424", AR5K_VERSION_VER, AR5K_SREV_VER_AR2424 }, - { "5424", AR5K_VERSION_VER, AR5K_SREV_VER_AR5424 }, - { "5413", AR5K_VERSION_VER, AR5K_SREV_VER_AR5413 }, - { "5414", AR5K_VERSION_VER, AR5K_SREV_VER_AR5414 }, - { "5416", AR5K_VERSION_VER, AR5K_SREV_VER_AR5416 }, - { "5418", AR5K_VERSION_VER, AR5K_SREV_VER_AR5418 }, - { "2425", AR5K_VERSION_VER, AR5K_SREV_VER_AR2425 }, - { "xxxxx", AR5K_VERSION_VER, AR5K_SREV_UNKNOWN }, + { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, + { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, + { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, + { "5311B", AR5K_VERSION_MAC, AR5K_SREV_AR5311B }, + { "5211", AR5K_VERSION_MAC, AR5K_SREV_AR5211 }, + { "5212", AR5K_VERSION_MAC, AR5K_SREV_AR5212 }, + { "5213", AR5K_VERSION_MAC, AR5K_SREV_AR5213 }, + { "5213A", AR5K_VERSION_MAC, AR5K_SREV_AR5213A }, + { "2413", AR5K_VERSION_MAC, AR5K_SREV_AR2413 }, + { "2414", AR5K_VERSION_MAC, AR5K_SREV_AR2414 }, + { "5424", AR5K_VERSION_MAC, AR5K_SREV_AR5424 }, + { "5413", AR5K_VERSION_MAC, AR5K_SREV_AR5413 }, + { "5414", AR5K_VERSION_MAC, AR5K_SREV_AR5414 }, + { "2415", AR5K_VERSION_MAC, AR5K_SREV_AR2415 }, + { "5416", AR5K_VERSION_MAC, AR5K_SREV_AR5416 }, + { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, + { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, + { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, + { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, + { "5111A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111A }, { "2111", AR5K_VERSION_RAD, AR5K_SREV_RAD_2111 }, { "5112", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112 }, { "5112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A }, + { "5112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112B }, { "2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112 }, { "2112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A }, - { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC0 }, - { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC1 }, - { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC2 }, + { "2112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112B }, + { "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 }, + { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, + { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 }, + { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 }, + { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, }; @@ -390,7 +397,11 @@ ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) for (i = 0; i < ARRAY_SIZE(srev_names); i++) { if (srev_names[i].sr_type != type) continue; - if ((val & 0xff) < srev_names[i + 1].sr_val) { + + if ((val & 0xf0) == srev_names[i].sr_val) + name = srev_names[i].sr_name; + + if ((val & 0xff) == srev_names[i].sr_val) { name = srev_names[i].sr_name; break; } @@ -536,7 +547,7 @@ ath5k_pci_probe(struct pci_dev *pdev, goto err_ah; ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", - ath5k_chip_name(AR5K_VERSION_VER,sc->ah->ah_mac_srev), + ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), sc->ah->ah_mac_srev, sc->ah->ah_phy_revision); diff --git a/drivers/net/wireless/ath5k/dma.c b/drivers/net/wireless/ath5k/dma.c index a28090be960..7adceb2c7fa 100644 --- a/drivers/net/wireless/ath5k/dma.c +++ b/drivers/net/wireless/ath5k/dma.c @@ -68,7 +68,7 @@ int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) /* * It may take some time to disable the DMA receive unit */ - for (i = 2000; i > 0 && + for (i = 1000; i > 0 && (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0; i--) udelay(10); @@ -182,11 +182,10 @@ int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue) * have any pending frames. Returns -EBUSY if we still have pending frames, * -EINVAL if queue number is out of range. * - * TODO: Test queue drain code */ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) { - unsigned int i = 100; + unsigned int i = 40; u32 tx_queue, pending; ATH5K_TRACE(ah->ah_sc); @@ -233,13 +232,53 @@ int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) udelay(100); } while (--i && pending); + /* For 2413+ order PCU to drop packets using + * QUIET mechanism */ + if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) && + pending){ + /* Set periodicity and duration */ + ath5k_hw_reg_write(ah, + AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)| + AR5K_REG_SM(10, AR5K_QUIET_CTL2_QT_DUR), + AR5K_QUIET_CTL2); + + /* Enable quiet period for current TSF */ + ath5k_hw_reg_write(ah, + AR5K_QUIET_CTL1_QT_EN | + AR5K_REG_SM(ath5k_hw_reg_read(ah, + AR5K_TSF_L32_5211) >> 10, + AR5K_QUIET_CTL1_NEXT_QT_TSF), + AR5K_QUIET_CTL1); + + /* Force channel idle high */ + AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, + AR5K_DIAG_SW_CHANEL_IDLE_HIGH); + + /* Wait a while and disable mechanism */ + udelay(200); + AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1, + AR5K_QUIET_CTL1_QT_EN); + + /* Re-check for pending frames */ + i = 40; + do { + pending = ath5k_hw_reg_read(ah, + AR5K_QUEUE_STATUS(queue)) & + AR5K_QCU_STS_FRMPENDCNT; + udelay(100); + } while (--i && pending); + + AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211, + AR5K_DIAG_SW_CHANEL_IDLE_HIGH); + } + /* Clear register */ ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD); if (pending) return -EBUSY; } - /* TODO: Check for success else return error */ + /* TODO: Check for success on 5210 else return error */ return 0; } @@ -415,7 +454,7 @@ done: bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah) { ATH5K_TRACE(ah->ah_sc); - return ath5k_hw_reg_read(ah, AR5K_INTPEND); + return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0; } /** diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c index c77cee2a558..a47df9a24aa 100644 --- a/drivers/net/wireless/ath5k/pcu.c +++ b/drivers/net/wireless/ath5k/pcu.c @@ -633,8 +633,20 @@ u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) */ void ath5k_hw_reset_tsf(struct ath5k_hw *ah) { + u32 val; + ATH5K_TRACE(ah->ah_sc); - AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_RESET_TSF); + + val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF; + + /* + * Each write to the RESET_TSF bit toggles a hardware internal + * signal to reset TSF, but if left high it will cause a TSF reset + * on the next chip reset as well. Thus we always write the value + * twice to clear the signal. + */ + ath5k_hw_reg_write(ah, val, AR5K_BEACON); + ath5k_hw_reg_write(ah, val, AR5K_BEACON); } /* diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c index 1ea8ed962d2..e43f6563e61 100644 --- a/drivers/net/wireless/ath5k/phy.c +++ b/drivers/net/wireless/ath5k/phy.c @@ -2124,7 +2124,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210); ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210); - udelay(2300); + mdelay(2); /* * Set the channel (with AGC turned off) diff --git a/drivers/net/wireless/ath5k/qcu.c b/drivers/net/wireless/ath5k/qcu.c index 2e20f7816ca..01bf09176d2 100644 --- a/drivers/net/wireless/ath5k/qcu.c +++ b/drivers/net/wireless/ath5k/qcu.c @@ -375,7 +375,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) case AR5K_TX_QUEUE_BEACON: AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), AR5K_QCU_MISC_FRSHED_DBA_GT | - AR5K_QCU_MISC_CBREXP_BCN | + AR5K_QCU_MISC_CBREXP_BCN_DIS | AR5K_QCU_MISC_BCN_ENABLE); AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), @@ -395,8 +395,8 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) case AR5K_TX_QUEUE_CAB: AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), AR5K_QCU_MISC_FRSHED_DBA_GT | - AR5K_QCU_MISC_CBREXP | - AR5K_QCU_MISC_CBREXP_BCN); + AR5K_QCU_MISC_CBREXP_DIS | + AR5K_QCU_MISC_CBREXP_BCN_DIS); AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << @@ -405,7 +405,7 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) case AR5K_TX_QUEUE_UAPSD: AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), - AR5K_QCU_MISC_CBREXP); + AR5K_QCU_MISC_CBREXP_DIS); break; case AR5K_TX_QUEUE_DATA: diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h index a9883236444..e557fe178bb 100644 --- a/drivers/net/wireless/ath5k/reg.h +++ b/drivers/net/wireless/ath5k/reg.h @@ -29,6 +29,10 @@ * http://www.it.iitb.ac.in/~janak/wifire/01222734.pdf * * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf + * + * This file also contains register values found on a memory dump of + * Atheros's ART program (Atheros Radio Test), on ath9k, on legacy-hal + * released by Atheros and on various debug messages found on the net. */ @@ -295,7 +299,7 @@ #define AR5K_ISR_RXPHY 0x00004000 /* PHY error */ #define AR5K_ISR_RXKCM 0x00008000 /* RX Key cache miss */ #define AR5K_ISR_SWBA 0x00010000 /* Software beacon alert */ -#define AR5K_ISR_BRSSI 0x00020000 +#define AR5K_ISR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */ #define AR5K_ISR_BMISS 0x00040000 /* Beacon missed */ #define AR5K_ISR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */ #define AR5K_ISR_BNR 0x00100000 /* Beacon not ready [5211+] */ @@ -303,46 +307,56 @@ #define AR5K_ISR_RXCHIRP 0x00200000 /* CHIRP Received [5212+] */ #define AR5K_ISR_SSERR 0x00200000 /* Signaled System Error [5210] */ #define AR5K_ISR_DPERR 0x00400000 /* Det par Error (?) [5210] */ -#define AR5K_ISR_TIM 0x00800000 /* [5210] */ -#define AR5K_ISR_BCNMISC 0x00800000 /* [5212+] */ -#define AR5K_ISR_GPIO 0x01000000 /* GPIO (rf kill)*/ -#define AR5K_ISR_QCBRORN 0x02000000 /* CBR overrun (?) [5211+] */ -#define AR5K_ISR_QCBRURN 0x04000000 /* CBR underrun (?) [5211+] */ -#define AR5K_ISR_QTRIG 0x08000000 /* [5211+] */ +#define AR5K_ISR_RXDOPPLER 0x00400000 /* Doppler chirp received [5212+] */ +#define AR5K_ISR_TIM 0x00800000 /* [5211+] */ +#define AR5K_ISR_BCNMISC 0x00800000 /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT, + CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */ +#define AR5K_ISR_GPIO 0x01000000 /* GPIO (rf kill) */ +#define AR5K_ISR_QCBRORN 0x02000000 /* QCU CBR overrun [5211+] */ +#define AR5K_ISR_QCBRURN 0x04000000 /* QCU CBR underrun [5211+] */ +#define AR5K_ISR_QTRIG 0x08000000 /* QCU scheduling trigger [5211+] */ /* * Secondary status registers [5211+] (0 - 4) * - * I guess from the names that these give the status for each - * queue, that's why only masks are defined here, haven't got - * any info about them (couldn't find them anywhere in ar5k code). + * These give the status for each QCU, only QCUs 0-9 are + * represented. */ #define AR5K_SISR0 0x0084 /* Register Address [5211+] */ #define AR5K_SISR0_QCU_TXOK 0x000003ff /* Mask for QCU_TXOK */ +#define AR5K_SISR0_QCU_TXOK_S 0 #define AR5K_SISR0_QCU_TXDESC 0x03ff0000 /* Mask for QCU_TXDESC */ +#define AR5K_SISR0_QCU_TXDESC_S 16 #define AR5K_SISR1 0x0088 /* Register Address [5211+] */ #define AR5K_SISR1_QCU_TXERR 0x000003ff /* Mask for QCU_TXERR */ +#define AR5K_SISR1_QCU_TXERR_S 0 #define AR5K_SISR1_QCU_TXEOL 0x03ff0000 /* Mask for QCU_TXEOL */ +#define AR5K_SISR1_QCU_TXEOL_S 16 #define AR5K_SISR2 0x008c /* Register Address [5211+] */ #define AR5K_SISR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */ +#define AR5K_SISR2_QCU_TXURN_S 0 #define AR5K_SISR2_MCABT 0x00100000 /* Master Cycle Abort */ #define AR5K_SISR2_SSERR 0x00200000 /* Signaled System Error */ -#define AR5K_SISR2_DPERR 0x00400000 /* Det par Error (?) */ +#define AR5K_SISR2_DPERR 0x00400000 /* Bus parity error */ #define AR5K_SISR2_TIM 0x01000000 /* [5212+] */ #define AR5K_SISR2_CAB_END 0x02000000 /* [5212+] */ #define AR5K_SISR2_DTIM_SYNC 0x04000000 /* DTIM sync lost [5212+] */ #define AR5K_SISR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */ #define AR5K_SISR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */ #define AR5K_SISR2_DTIM 0x20000000 /* [5212+] */ +#define AR5K_SISR2_TSFOOR 0x80000000 /* TSF OOR (?) */ #define AR5K_SISR3 0x0090 /* Register Address [5211+] */ #define AR5K_SISR3_QCBRORN 0x000003ff /* Mask for QCBRORN */ +#define AR5K_SISR3_QCBORN_S 0 #define AR5K_SISR3_QCBRURN 0x03ff0000 /* Mask for QCBRURN */ +#define AR5K_SISR3_QCBRURN_S 16 #define AR5K_SISR4 0x0094 /* Register Address [5211+] */ #define AR5K_SISR4_QTRIG 0x000003ff /* Mask for QTRIG */ +#define AR5K_SISR4_QTRIG_S 0 /* * Shadow read-and-clear interrupt status registers [5211+] @@ -379,7 +393,7 @@ #define AR5K_IMR_RXPHY 0x00004000 /* PHY error*/ #define AR5K_IMR_RXKCM 0x00008000 /* RX Key cache miss */ #define AR5K_IMR_SWBA 0x00010000 /* Software beacon alert*/ -#define AR5K_IMR_BRSSI 0x00020000 +#define AR5K_IMR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */ #define AR5K_IMR_BMISS 0x00040000 /* Beacon missed*/ #define AR5K_IMR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */ #define AR5K_IMR_BNR 0x00100000 /* Beacon not ready [5211+] */ @@ -387,12 +401,14 @@ #define AR5K_IMR_RXCHIRP 0x00200000 /* CHIRP Received [5212+]*/ #define AR5K_IMR_SSERR 0x00200000 /* Signaled System Error [5210] */ #define AR5K_IMR_DPERR 0x00400000 /* Det par Error (?) [5210] */ +#define AR5K_IMR_RXDOPPLER 0x00400000 /* Doppler chirp received [5212+] */ #define AR5K_IMR_TIM 0x00800000 /* [5211+] */ -#define AR5K_IMR_BCNMISC 0x00800000 /* [5212+] */ +#define AR5K_IMR_BCNMISC 0x00800000 /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT, + CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */ #define AR5K_IMR_GPIO 0x01000000 /* GPIO (rf kill)*/ -#define AR5K_IMR_QCBRORN 0x02000000 /* CBR overrun (?) [5211+] */ -#define AR5K_IMR_QCBRURN 0x04000000 /* CBR underrun (?) [5211+] */ -#define AR5K_IMR_QTRIG 0x08000000 /* [5211+] */ +#define AR5K_IMR_QCBRORN 0x02000000 /* QCU CBR overrun (?) [5211+] */ +#define AR5K_IMR_QCBRURN 0x04000000 /* QCU CBR underrun (?) [5211+] */ +#define AR5K_IMR_QTRIG 0x08000000 /* QCU scheduling trigger [5211+] */ /* * Secondary interrupt mask registers [5211+] (0 - 4) @@ -414,13 +430,14 @@ #define AR5K_SIMR2_QCU_TXURN_S 0 #define AR5K_SIMR2_MCABT 0x00100000 /* Master Cycle Abort */ #define AR5K_SIMR2_SSERR 0x00200000 /* Signaled System Error */ -#define AR5K_SIMR2_DPERR 0x00400000 /* Det par Error (?) */ +#define AR5K_SIMR2_DPERR 0x00400000 /* Bus parity error */ #define AR5K_SIMR2_TIM 0x01000000 /* [5212+] */ #define AR5K_SIMR2_CAB_END 0x02000000 /* [5212+] */ #define AR5K_SIMR2_DTIM_SYNC 0x04000000 /* DTIM Sync lost [5212+] */ #define AR5K_SIMR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */ #define AR5K_SIMR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */ #define AR5K_SIMR2_DTIM 0x20000000 /* [5212+] */ +#define AR5K_SIMR2_TSFOOR 0x80000000 /* TSF OOR (?) */ #define AR5K_SIMR3 0x00b0 /* Register Address [5211+] */ #define AR5K_SIMR3_QCBRORN 0x000003ff /* Mask for QCBRORN */ @@ -586,15 +603,15 @@ #define AR5K_QCU_MISC_FRSHED_M 0x0000000f /* Frame sheduling mask */ #define AR5K_QCU_MISC_FRSHED_ASAP 0 /* ASAP */ #define AR5K_QCU_MISC_FRSHED_CBR 1 /* Constant Bit Rate */ -#define AR5K_QCU_MISC_FRSHED_DBA_GT 2 /* DMA Beacon alert gated (?) */ -#define AR5K_QCU_MISC_FRSHED_TIM_GT 3 /* Time gated (?) */ -#define AR5K_QCU_MISC_FRSHED_BCN_SENT_GT 4 /* Beacon sent gated (?) */ +#define AR5K_QCU_MISC_FRSHED_DBA_GT 2 /* DMA Beacon alert gated */ +#define AR5K_QCU_MISC_FRSHED_TIM_GT 3 /* TIMT gated */ +#define AR5K_QCU_MISC_FRSHED_BCN_SENT_GT 4 /* Beacon sent gated */ #define AR5K_QCU_MISC_ONESHOT_ENABLE 0x00000010 /* Oneshot enable */ -#define AR5K_QCU_MISC_CBREXP 0x00000020 /* CBR expired (normal queue) */ -#define AR5K_QCU_MISC_CBREXP_BCN 0x00000040 /* CBR expired (beacon queue) */ +#define AR5K_QCU_MISC_CBREXP_DIS 0x00000020 /* Disable CBR expired counter (normal queue) */ +#define AR5K_QCU_MISC_CBREXP_BCN_DIS 0x00000040 /* Disable CBR expired counter (beacon queue) */ #define AR5K_QCU_MISC_BCN_ENABLE 0x00000080 /* Enable Beacon use */ -#define AR5K_QCU_MISC_CBR_THRES_ENABLE 0x00000100 /* CBR threshold enabled */ -#define AR5K_QCU_MISC_RDY_VEOL_POLICY 0x00000200 /* TXE reset when RDYTIME enalbed */ +#define AR5K_QCU_MISC_CBR_THRES_ENABLE 0x00000100 /* CBR expired threshold enabled */ +#define AR5K_QCU_MISC_RDY_VEOL_POLICY 0x00000200 /* TXE reset when RDYTIME expired or VEOL */ #define AR5K_QCU_MISC_CBR_RESET_CNT 0x00000400 /* CBR threshold (counter) reset */ #define AR5K_QCU_MISC_DCU_EARLY 0x00000800 /* DCU early termination */ #define AR5K_QCU_MISC_DCU_CMP_EN 0x00001000 /* Enable frame compression */ @@ -663,6 +680,7 @@ #define AR5K_DCU_LCL_IFS_CW_MAX_S 10 #define AR5K_DCU_LCL_IFS_AIFS 0x0ff00000 /* Arbitrated Interframe Space */ #define AR5K_DCU_LCL_IFS_AIFS_S 20 +#define AR5K_DCU_LCL_IFS_AIFS_MAX 0xfc /* Anything above that can cause DCU to hang */ #define AR5K_QUEUE_DFS_LOCAL_IFS(_q) AR5K_QUEUE_REG(AR5K_DCU_LCL_IFS_BASE, _q) /* @@ -691,11 +709,7 @@ /* * DCU misc registers [5211+] * - * For some of the registers i couldn't find in the code - * (only backoff stuff is there realy) i tried to match the - * names with 802.11e parameters etc, so i guess VIRTCOL here - * means Virtual Collision and HCFPOLL means Hybrid Coordination - * factor Poll (CF- Poll). Arbiter lockout control controls the + * Note: Arbiter lockout control controls the * behaviour on low priority queues when we have multiple queues * with pending frames. Intra-frame lockout means we wait until * the queue's current frame transmits (with post frame backoff and bursting) @@ -705,15 +719,20 @@ * No lockout means there is no special handling. */ #define AR5K_DCU_MISC_BASE 0x1100 /* Register Address -Queue0 DCU_MISC */ -#define AR5K_DCU_MISC_BACKOFF 0x000007ff /* Mask for backoff threshold */ +#define AR5K_DCU_MISC_BACKOFF 0x0000003f /* Mask for backoff threshold */ +#define AR5K_DCU_MISC_ETS_RTS_POL 0x00000040 /* End of transmission series + station RTS/data failure count + reset policy (?) */ +#define AR5K_DCU_MISC_ETS_CW_POL 0x00000080 /* End of transmission series + CW reset policy */ +#define AR5K_DCU_MISC_FRAG_WAIT 0x00000100 /* Wait for next fragment */ #define AR5K_DCU_MISC_BACKOFF_FRAG 0x00000200 /* Enable backoff while bursting */ #define AR5K_DCU_MISC_HCFPOLL_ENABLE 0x00000800 /* CF - Poll enable */ #define AR5K_DCU_MISC_BACKOFF_PERSIST 0x00001000 /* Persistent backoff */ #define AR5K_DCU_MISC_FRMPRFTCH_ENABLE 0x00002000 /* Enable frame pre-fetch */ #define AR5K_DCU_MISC_VIRTCOL 0x0000c000 /* Mask for Virtual Collision (?) */ -#define AR5K_DCU_MISC_VIRTCOL_NORMAL 0 -#define AR5K_DCU_MISC_VIRTCOL_MODIFIED 1 -#define AR5K_DCU_MISC_VIRTCOL_IGNORE 2 +#define AR5K_DCU_MISC_VIRTCOL_NORMAL 0 +#define AR5K_DCU_MISC_VIRTCOL_IGNORE 1 #define AR5K_DCU_MISC_BCN_ENABLE 0x00010000 /* Enable Beacon use */ #define AR5K_DCU_MISC_ARBLOCK_CTL 0x00060000 /* Arbiter lockout control mask */ #define AR5K_DCU_MISC_ARBLOCK_CTL_S 17 @@ -768,8 +787,9 @@ #define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */ #define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */ #define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */ +#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10 #define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */ -#define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST 0x00400000 /* SIFC cnt reset policy (?) */ +#define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST 0x00400000 /* SIFS cnt reset policy (?) */ #define AR5K_DCU_GBL_IFS_MISC_AIFS_CNT_RST 0x00800000 /* AIFS cnt reset policy (?) */ #define AR5K_DCU_GBL_IFS_MISC_RND_LFSR_SL_DIS 0x01000000 /* Disable random LFSR slice */ @@ -820,8 +840,6 @@ #define AR5K_RESET_CTL_MAC 0x00000004 /* MAC reset (PCU+Baseband ?) [5210] */ #define AR5K_RESET_CTL_PHY 0x00000008 /* PHY reset [5210] */ #define AR5K_RESET_CTL_PCI 0x00000010 /* PCI Core reset (interrupts etc) */ -#define AR5K_RESET_CTL_CHIP (AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA | \ - AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY) /* * Sleep control register @@ -833,9 +851,11 @@ #define AR5K_SLEEP_CTL_SLE_S 16 #define AR5K_SLEEP_CTL_SLE_WAKE 0x00000000 /* Force chip awake */ #define AR5K_SLEEP_CTL_SLE_SLP 0x00010000 /* Force chip sleep */ -#define AR5K_SLEEP_CTL_SLE_ALLOW 0x00020000 +#define AR5K_SLEEP_CTL_SLE_ALLOW 0x00020000 /* Normal sleep policy */ #define AR5K_SLEEP_CTL_SLE_UNITS 0x00000008 /* [5211+] */ -/* more bits */ +#define AR5K_SLEEP_CTL_DUR_TIM_POL 0x00040000 /* Sleep duration timing policy */ +#define AR5K_SLEEP_CTL_DUR_WRITE_POL 0x00080000 /* Sleep duration write policy */ +#define AR5K_SLEEP_CTL_SLE_POL 0x00100000 /* Sleep policy mode */ /* * Interrupt pending register @@ -851,27 +871,28 @@ /* * PCI configuration register + * TODO: Fix LED stuff */ #define AR5K_PCICFG 0x4010 /* Register Address */ #define AR5K_PCICFG_EEAE 0x00000001 /* Eeprom access enable [5210] */ -#define AR5K_PCICFG_SLEEP_CLOCK_EN 0x00000002 /* Enable sleep clock (?) */ +#define AR5K_PCICFG_SLEEP_CLOCK_EN 0x00000002 /* Enable sleep clock */ #define AR5K_PCICFG_CLKRUNEN 0x00000004 /* CLKRUN enable [5211+] */ #define AR5K_PCICFG_EESIZE 0x00000018 /* Mask for EEPROM size [5211+] */ #define AR5K_PCICFG_EESIZE_S 3 #define AR5K_PCICFG_EESIZE_4K 0 /* 4K */ #define AR5K_PCICFG_EESIZE_8K 1 /* 8K */ #define AR5K_PCICFG_EESIZE_16K 2 /* 16K */ -#define AR5K_PCICFG_EESIZE_FAIL 3 /* Failed to get size (?) [5211+] */ +#define AR5K_PCICFG_EESIZE_FAIL 3 /* Failed to get size [5211+] */ #define AR5K_PCICFG_LED 0x00000060 /* Led status [5211+] */ #define AR5K_PCICFG_LED_NONE 0x00000000 /* Default [5211+] */ #define AR5K_PCICFG_LED_PEND 0x00000020 /* Scan / Auth pending */ #define AR5K_PCICFG_LED_ASSOC 0x00000040 /* Associated */ #define AR5K_PCICFG_BUS_SEL 0x00000380 /* Mask for "bus select" [5211+] (?) */ -#define AR5K_PCICFG_CBEFIX_DIS 0x00000400 /* Disable CBE fix (?) */ -#define AR5K_PCICFG_SL_INTEN 0x00000800 /* Enable interrupts when asleep (?) */ +#define AR5K_PCICFG_CBEFIX_DIS 0x00000400 /* Disable CBE fix */ +#define AR5K_PCICFG_SL_INTEN 0x00000800 /* Enable interrupts when asleep */ #define AR5K_PCICFG_LED_BCTL 0x00001000 /* Led blink (?) [5210] */ -#define AR5K_PCICFG_UNK 0x00001000 /* Passed on some parts durring attach (?) */ -#define AR5K_PCICFG_SL_INPEN 0x00002000 /* Sleep even whith pending interrupts (?) */ +#define AR5K_PCICFG_RETRY_FIX 0x00001000 /* Enable pci core retry fix */ +#define AR5K_PCICFG_SL_INPEN 0x00002000 /* Sleep even whith pending interrupts*/ #define AR5K_PCICFG_SPWR_DN 0x00010000 /* Mask for power status */ #define AR5K_PCICFG_LEDMODE 0x000e0000 /* Ledmode [5211+] */ #define AR5K_PCICFG_LEDMODE_PROP 0x00000000 /* Blink on standard traffic [5211+] */ @@ -884,7 +905,8 @@ #define AR5K_PCICFG_LEDSTATE \ (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE | \ AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW) -#define AR5K_PCICFG_SLEEP_CLOCK_RATE 0x03000000 /* Sleep clock rate (field) */ +#define AR5K_PCICFG_SLEEP_CLOCK_RATE 0x03000000 /* Sleep clock rate */ +#define AR5K_PCICFG_SLEEP_CLOCK_RATE_S 24 /* * "General Purpose Input/Output" (GPIO) control register @@ -906,8 +928,8 @@ #define AR5K_GPIOCR 0x4014 /* Register Address */ #define AR5K_GPIOCR_INT_ENA 0x00008000 /* Enable GPIO interrupt */ -#define AR5K_GPIOCR_INT_SELL 0x00000000 /* Generate interrupt when pin is off (?) */ -#define AR5K_GPIOCR_INT_SELH 0x00010000 /* Generate interrupt when pin is on */ +#define AR5K_GPIOCR_INT_SELL 0x00000000 /* Generate interrupt when pin is low */ +#define AR5K_GPIOCR_INT_SELH 0x00010000 /* Generate interrupt when pin is high */ #define AR5K_GPIOCR_IN(n) (0 << ((n) * 2)) /* Mode 0 for pin n */ #define AR5K_GPIOCR_OUT0(n) (1 << ((n) * 2)) /* Mode 1 for pin n */ #define AR5K_GPIOCR_OUT1(n) (2 << ((n) * 2)) /* Mode 2 for pin n */ @@ -925,7 +947,6 @@ #define AR5K_GPIODI 0x401c #define AR5K_GPIODI_M 0x0000002f - /* * Silicon revision register */ @@ -935,7 +956,59 @@ #define AR5K_SREV_VER 0x000000ff /* Mask for version */ #define AR5K_SREV_VER_S 4 +/* + * TXE write posting register + */ +#define AR5K_TXEPOST 0x4028 + +/* + * QCU sleep mask + */ +#define AR5K_QCU_SLEEP_MASK 0x402c + +/* 0x4068 is compression buffer configuration + * register on 5414 and pm configuration register + * on 5424 and newer pci-e chips. */ + +/* + * Compression buffer configuration + * register (enable/disable) [5414] + */ +#define AR5K_5414_CBCFG 0x4068 +#define AR5K_5414_CBCFG_BUF_DIS 0x10 /* Disable buffer */ + +/* + * PCI-E Power managment configuration + * and status register [5424+] + */ +#define AR5K_PCIE_PM_CTL 0x4068 /* Register address */ +/* Only 5424 */ +#define AR5K_PCIE_PM_CTL_L1_WHEN_D2 0x00000001 /* enable PCIe core enter L1 + when d2_sleep_en is asserted */ +#define AR5K_PCIE_PM_CTL_L0_L0S_CLEAR 0x00000002 /* Clear L0 and L0S counters */ +#define AR5K_PCIE_PM_CTL_L0_L0S_EN 0x00000004 /* Start L0 nd L0S counters */ +#define AR5K_PCIE_PM_CTL_LDRESET_EN 0x00000008 /* Enable reset when link goes + down */ +/* Wake On Wireless */ +#define AR5K_PCIE_PM_CTL_PME_EN 0x00000010 /* PME Enable */ +#define AR5K_PCIE_PM_CTL_AUX_PWR_DET 0x00000020 /* Aux power detect */ +#define AR5K_PCIE_PM_CTL_PME_CLEAR 0x00000040 /* Clear PME */ +#define AR5K_PCIE_PM_CTL_PSM_D0 0x00000080 +#define AR5K_PCIE_PM_CTL_PSM_D1 0x00000100 +#define AR5K_PCIE_PM_CTL_PSM_D2 0x00000200 +#define AR5K_PCIE_PM_CTL_PSM_D3 0x00000400 + +/* + * PCI-E Workaround enable register + */ +#define AR5K_PCIE_WAEN 0x407c +/* + * PCI-E Serializer/Desirializer + * registers + */ +#define AR5K_PCIE_SERDES 0x4080 +#define AR5K_PCIE_SERDES_RESET 0x4084 /*====EEPROM REGISTERS====*/ @@ -1008,14 +1081,28 @@ * EEPROM config register */ #define AR5K_EEPROM_CFG 0x6010 /* Register Addres */ -#define AR5K_EEPROM_CFG_SIZE_OVR 0x00000001 +#define AR5K_EEPROM_CFG_SIZE 0x00000003 /* Size determination override */ +#define AR5K_EEPROM_CFG_SIZE_AUTO 0 +#define AR5K_EEPROM_CFG_SIZE_4KBIT 1 +#define AR5K_EEPROM_CFG_SIZE_8KBIT 2 +#define AR5K_EEPROM_CFG_SIZE_16KBIT 3 #define AR5K_EEPROM_CFG_WR_WAIT_DIS 0x00000004 /* Disable write wait */ #define AR5K_EEPROM_CFG_CLK_RATE 0x00000018 /* Clock rate */ -#define AR5K_EEPROM_CFG_PROT_KEY 0x00ffff00 /* Protectio key */ +#define AR5K_EEPROM_CFG_CLK_RATE_S 3 +#define AR5K_EEPROM_CFG_CLK_RATE_156KHZ 0 +#define AR5K_EEPROM_CFG_CLK_RATE_312KHZ 1 +#define AR5K_EEPROM_CFG_CLK_RATE_625KHZ 2 +#define AR5K_EEPROM_CFG_PROT_KEY 0x00ffff00 /* Protection key */ +#define AR5K_EEPROM_CFG_PROT_KEY_S 8 #define AR5K_EEPROM_CFG_LIND_EN 0x01000000 /* Enable length indicator (?) */ /* + * TODO: Wake On Wireless registers + * Range 0x7000 - 0x7ce0 + */ + +/* * Protocol Control Unit (PCU) registers */ /* @@ -1047,11 +1134,13 @@ #define AR5K_STA_ID1_DESC_ANTENNA 0x00400000 /* Update antenna from descriptor */ #define AR5K_STA_ID1_RTS_DEF_ANTENNA 0x00800000 /* Use default antenna for RTS */ #define AR5K_STA_ID1_ACKCTS_6MB 0x01000000 /* Use 6Mbit/s for ACK/CTS */ -#define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* Use 11b base rate (for ACK/CTS ?) [5211+] */ -#define AR5K_STA_ID1_SELF_GEN_SECTORE 0x04000000 /* Self generate sectore (?) */ +#define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* Use 11b base rate for ACK/CTS [5211+] */ +#define AR5K_STA_ID1_SELFGEN_DEF_ANT 0x04000000 /* Use def. antenna for self generated frames */ #define AR5K_STA_ID1_CRYPT_MIC_EN 0x08000000 /* Enable MIC */ -#define AR5K_STA_ID1_KEYSRCH_MODE 0x10000000 /* Keysearch mode (?) */ +#define AR5K_STA_ID1_KEYSRCH_MODE 0x10000000 /* Look up key when key id != 0 */ #define AR5K_STA_ID1_PRESERVE_SEQ_NUM 0x20000000 /* Preserve sequence number */ +#define AR5K_STA_ID1_CBCIV_ENDIAN 0x40000000 /* ??? */ +#define AR5K_STA_ID1_KEYSRCH_MCAST 0x80000000 /* Do key cache search for mcast frames */ /* * First BSSID register (MAC address, lower 32bits) @@ -1310,16 +1399,16 @@ #define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040 #define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211) -#define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 +#define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Corrupted FCS */ #define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080 #define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211) -#define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 +#define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Dump channel info */ #define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100 #define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211) -#define AR5K_DIAG_SW_EN_SCRAM_SEED_5211 0x00000200 /* Enable scrambler seed */ -#define AR5K_DIAG_SW_EN_SCRAM_SEED_5210 0x00000400 +#define AR5K_DIAG_SW_EN_SCRAM_SEED_5210 0x00000400 /* Enable fixed scrambler seed */ +#define AR5K_DIAG_SW_EN_SCRAM_SEED_5211 0x00000200 #define AR5K_DIAG_SW_EN_SCRAM_SEED (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_EN_SCRAM_SEED_5210 : AR5K_DIAG_SW_EN_SCRAM_SEED_5211) #define AR5K_DIAG_SW_ECO_ENABLE 0x00000400 /* [5211+] */ @@ -1328,12 +1417,15 @@ #define AR5K_DIAG_SW_SCRAM_SEED_S 10 #define AR5K_DIAG_SW_DIS_SEQ_INC 0x00040000 /* Disable seqnum increment (?)[5210] */ #define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000 -#define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 +#define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 /* Accept frames of non-zero protocol number */ #define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \ AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211) -#define AR5K_DIAG_SW_OBSPT_M 0x000c0000 +#define AR5K_DIAG_SW_OBSPT_M 0x000c0000 /* Observation point select (?) */ #define AR5K_DIAG_SW_OBSPT_S 18 -/* more bits */ +#define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x0010000 /* Force RX Clear high */ +#define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000 /* Ignore virtual carrier sense */ +#define AR5K_DIAG_SW_CHANEL_IDLE_HIGH 0x0040000 /* Force channel idle high */ +#define AR5K_DIAG_SW_PHEAR_ME 0x0080000 /* ??? */ /* * TSF (clock) register (lower 32 bits) @@ -1544,16 +1636,16 @@ * * XXX: PCDAC steps (0.5dbm) or DBM ? * - * XXX: Mask changes for newer chips to 7f - * like tx power table ? */ #define AR5K_TXPC 0x80e8 /* Register Address */ -#define AR5K_TXPC_ACK_M 0x0000003f /* Mask for ACK tx power */ +#define AR5K_TXPC_ACK_M 0x0000003f /* ACK tx power */ #define AR5K_TXPC_ACK_S 0 -#define AR5K_TXPC_CTS_M 0x00003f00 /* Mask for CTS tx power */ +#define AR5K_TXPC_CTS_M 0x00003f00 /* CTS tx power */ #define AR5K_TXPC_CTS_S 8 -#define AR5K_TXPC_CHIRP_M 0x003f0000 /* Mask for CHIRP tx power */ -#define AR5K_TXPC_CHIRP_S 22 +#define AR5K_TXPC_CHIRP_M 0x003f0000 /* CHIRP tx power */ +#define AR5K_TXPC_CHIRP_S 16 +#define AR5K_TXPC_DOPPLER 0x0f000000 /* Doppler chirp span (?) */ +#define AR5K_TXPC_DOPPLER_S 24 /* * Profile count registers @@ -1564,14 +1656,19 @@ #define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle count (?) */ /* - * Quiet (period) control registers (?) + * Quiet period control registers */ #define AR5K_QUIET_CTL1 0x80fc /* Register Address */ -#define AR5K_QUIET_CTL1_NEXT_QT 0x0000ffff /* Mask for next quiet (period?) (?) */ -#define AR5K_QUIET_CTL1_QT_EN 0x00010000 /* Enable quiet (period?) */ +#define AR5K_QUIET_CTL1_NEXT_QT_TSF 0x0000ffff /* Next quiet period TSF (TU) */ +#define AR5K_QUIET_CTL1_NEXT_QT_TSF_S 0 +#define AR5K_QUIET_CTL1_QT_EN 0x00010000 /* Enable quiet period */ +#define AR5K_QUIET_CTL1_ACK_CTS_EN 0x00020000 /* Send ACK/CTS during quiet period */ + #define AR5K_QUIET_CTL2 0x8100 /* Register Address */ -#define AR5K_QUIET_CTL2_QT_PER 0x0000ffff /* Mask for quiet period (?) */ -#define AR5K_QUIET_CTL2_QT_DUR 0xffff0000 /* Mask for quiet duration (?) */ +#define AR5K_QUIET_CTL2_QT_PER 0x0000ffff /* Mask for quiet period periodicity */ +#define AR5K_QUIET_CTL2_QT_PER_S 0 +#define AR5K_QUIET_CTL2_QT_DUR 0xffff0000 /* Mask for quiet period duration */ +#define AR5K_QUIET_CTL2_QT_DUR_S 16 /* * TSF parameter register @@ -1581,12 +1678,15 @@ #define AR5K_TSF_PARM_INC_S 0 /* - * QoS register (?) + * QoS NOACK policy */ -#define AR5K_QOS 0x8108 /* Register Address */ -#define AR5K_QOS_NOACK_2BIT_VALUES 0x00000000 /* (field) */ -#define AR5K_QOS_NOACK_BIT_OFFSET 0x00000020 /* (field) */ -#define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000080 /* (field) */ +#define AR5K_QOS_NOACK 0x8108 /* Register Address */ +#define AR5K_QOS_NOACK_2BIT_VALUES 0x0000000f /* ??? */ +#define AR5K_QOS_NOACK_2BIT_VALUES_S 0 +#define AR5K_QOS_NOACK_BIT_OFFSET 0x00000070 /* ??? */ +#define AR5K_QOS_NOACK_BIT_OFFSET_S 4 +#define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000180 /* ??? */ +#define AR5K_QOS_NOACK_BYTE_OFFSET_S 8 /* * PHY error filter register @@ -1610,29 +1710,15 @@ /* * MIC QoS control register (?) */ -#define AR5K_MIC_QOS_CTL 0x8118 /* Register Address */ -#define AR5K_MIC_QOS_CTL_0 0x00000001 /* MIC QoS control 0 (?) */ -#define AR5K_MIC_QOS_CTL_1 0x00000004 /* MIC QoS control 1 (?) */ -#define AR5K_MIC_QOS_CTL_2 0x00000010 /* MIC QoS control 2 (?) */ -#define AR5K_MIC_QOS_CTL_3 0x00000040 /* MIC QoS control 3 (?) */ -#define AR5K_MIC_QOS_CTL_4 0x00000100 /* MIC QoS control 4 (?) */ -#define AR5K_MIC_QOS_CTL_5 0x00000400 /* MIC QoS control 5 (?) */ -#define AR5K_MIC_QOS_CTL_6 0x00001000 /* MIC QoS control 6 (?) */ -#define AR5K_MIC_QOS_CTL_7 0x00004000 /* MIC QoS control 7 (?) */ -#define AR5K_MIC_QOS_CTL_MQ_EN 0x00010000 /* Enable MIC QoS */ +#define AR5K_MIC_QOS_CTL 0x8118 /* Register Address */ +#define AR5K_MIC_QOS_CTL_OFF(_n) (1 << (_n * 2)) +#define AR5K_MIC_QOS_CTL_MQ_EN 0x00010000 /* Enable MIC QoS */ /* * MIC QoS select register (?) */ -#define AR5K_MIC_QOS_SEL 0x811c -#define AR5K_MIC_QOS_SEL_0 0x00000001 -#define AR5K_MIC_QOS_SEL_1 0x00000010 -#define AR5K_MIC_QOS_SEL_2 0x00000100 -#define AR5K_MIC_QOS_SEL_3 0x00001000 -#define AR5K_MIC_QOS_SEL_4 0x00010000 -#define AR5K_MIC_QOS_SEL_5 0x00100000 -#define AR5K_MIC_QOS_SEL_6 0x01000000 -#define AR5K_MIC_QOS_SEL_7 0x10000000 +#define AR5K_MIC_QOS_SEL 0x811c +#define AR5K_MIC_QOS_SEL_OFF(_n) (1 << (_n * 4)) /* * Misc mode control register (?) @@ -1667,6 +1753,11 @@ #define AR5K_TSF_THRES 0x813c /* + * TODO: Wake On Wireless registers + * Range: 0x8147 - 0x818c + */ + +/* * Rate -> ACK SIFS mapping table (32 entries) */ #define AR5K_RATE_ACKSIFS_BASE 0x8680 /* Register Address */ @@ -1781,7 +1872,8 @@ */ #define AR5K_PHY_TURBO 0x9804 /* Register Address */ #define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */ -#define AR5K_PHY_TURBO_SHORT 0x00000002 /* Short mode (20Mhz channels) (?) */ +#define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */ +#define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo mimo */ /* * PHY agility command register @@ -1791,6 +1883,11 @@ #define AR5K_PHY_TST1 0x9808 #define AR5K_PHY_AGC_DISABLE 0x08000000 /* Disable AGC to A2 (?)*/ #define AR5K_PHY_TST1_TXHOLD 0x00003800 /* Set tx hold (?) */ +#define AR5K_PHY_TST1_TXSRC_SRC 0x00000002 /* Used with bit 7 (?) */ +#define AR5K_PHY_TST1_TXSRC_SRC_S 1 +#define AR5K_PHY_TST1_TXSRC_ALT 0x00000080 /* Set input to tsdac (?) */ +#define AR5K_PHY_TST1_TXSRC_ALT_S 7 + /* * PHY timing register 3 [5112+] @@ -1815,15 +1912,23 @@ /* * PHY RF control registers - * (i think these are delay times, - * these calibration values exist - * in EEPROM) */ #define AR5K_PHY_RF_CTL2 0x9824 /* Register Address */ -#define AR5K_PHY_RF_CTL2_TXF2TXD_START 0x0000000f /* Mask for TX frame to TX d(esc?) start */ +#define AR5K_PHY_RF_CTL2_TXF2TXD_START 0x0000000f /* TX frame to TX data start */ +#define AR5K_PHY_RF_CTL2_TXF2TXD_START_S 0 #define AR5K_PHY_RF_CTL3 0x9828 /* Register Address */ -#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000000f /* Mask for TX end to XLNA on */ +#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000000f /* TX end to XLNA on */ +#define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 0 + +#define AR5K_PHY_ADC_CTL 0x982c +#define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF 0x00000003 +#define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF_S 0 +#define AR5K_PHY_ADC_CTL_PWD_DAC_OFF 0x00002000 +#define AR5K_PHY_ADC_CTL_PWD_BAND_GAP_OFF 0x00004000 +#define AR5K_PHY_ADC_CTL_PWD_ADC_OFF 0x00008000 +#define AR5K_PHY_ADC_CTL_INBUFGAIN_ON 0x00030000 +#define AR5K_PHY_ADC_CTL_INBUFGAIN_ON_S 16 #define AR5K_PHY_RF_CTL4 0x9834 /* Register Address */ #define AR5K_PHY_RF_CTL4_TXF2XPA_A_ON 0x00000001 /* TX frame to XPA A on (field) */ @@ -1845,14 +1950,19 @@ * PHY settling register */ #define AR5K_PHY_SETTLING 0x9844 /* Register Address */ -#define AR5K_PHY_SETTLING_AGC 0x0000007f /* Mask for AGC settling time */ -#define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Mask for Switch settlig time */ +#define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ +#define AR5K_PHY_SETTLING_AGC_S 0 +#define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */ +#define AR5K_PHY_SETTLINK_SWITCH_S 7 /* * PHY Gain registers */ #define AR5K_PHY_GAIN 0x9848 /* Register Address */ -#define AR5K_PHY_GAIN_TXRX_ATTEN 0x0003f000 /* Mask for TX-RX Attenuation */ +#define AR5K_PHY_GAIN_TXRX_ATTEN 0x0003f000 /* TX-RX Attenuation */ +#define AR5K_PHY_GAIN_TXRX_ATTEN_S 12 +#define AR5K_PHY_GAIN_TXRX_RF_MAX 0x007c0000 +#define AR5K_PHY_GAIN_TXRX_RF_MAX_S 18 #define AR5K_PHY_GAIN_OFFSET 0x984c /* Register Address */ #define AR5K_PHY_GAIN_OFFSET_RXTX_FLAG 0x00020000 /* RX-TX flag (?) */ @@ -1862,18 +1972,21 @@ * (for more infos read ANI patent) */ #define AR5K_PHY_DESIRED_SIZE 0x9850 /* Register Address */ -#define AR5K_PHY_DESIRED_SIZE_ADC 0x000000ff /* Mask for ADC desired size */ -#define AR5K_PHY_DESIRED_SIZE_PGA 0x0000ff00 /* Mask for PGA desired size */ -#define AR5K_PHY_DESIRED_SIZE_TOT 0x0ff00000 /* Mask for Total desired size */ +#define AR5K_PHY_DESIRED_SIZE_ADC 0x000000ff /* ADC desired size */ +#define AR5K_PHY_DESIRED_SIZE_ADC_S 0 +#define AR5K_PHY_DESIRED_SIZE_PGA 0x0000ff00 /* PGA desired size */ +#define AR5K_PHY_DESIRED_SIZE_PGA_S 8 +#define AR5K_PHY_DESIRED_SIZE_TOT 0x0ff00000 /* Total desired size */ +#define AR5K_PHY_DESIRED_SIZE_TOT_S 20 /* * PHY signal register * (for more infos read ANI patent) */ #define AR5K_PHY_SIG 0x9858 /* Register Address */ -#define AR5K_PHY_SIG_FIRSTEP 0x0003f000 /* Mask for FIRSTEP */ +#define AR5K_PHY_SIG_FIRSTEP 0x0003f000 /* FIRSTEP */ #define AR5K_PHY_SIG_FIRSTEP_S 12 -#define AR5K_PHY_SIG_FIRPWR 0x03fc0000 /* Mask for FIPWR */ +#define AR5K_PHY_SIG_FIRPWR 0x03fc0000 /* FIPWR */ #define AR5K_PHY_SIG_FIRPWR_S 18 /* @@ -1881,9 +1994,9 @@ * (for more infos read ANI patent) */ #define AR5K_PHY_AGCCOARSE 0x985c /* Register Address */ -#define AR5K_PHY_AGCCOARSE_LO 0x00007f80 /* Mask for AGC Coarse low */ +#define AR5K_PHY_AGCCOARSE_LO 0x00007f80 /* AGC Coarse low */ #define AR5K_PHY_AGCCOARSE_LO_S 7 -#define AR5K_PHY_AGCCOARSE_HI 0x003f8000 /* Mask for AGC Coarse high */ +#define AR5K_PHY_AGCCOARSE_HI 0x003f8000 /* AGC Coarse high */ #define AR5K_PHY_AGCCOARSE_HI_S 15 /* @@ -1892,6 +2005,8 @@ #define AR5K_PHY_AGCCTL 0x9860 /* Register address */ #define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */ #define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */ +#define AR5K_PHY_AGCCTL_NF_EN 0x00008000 /* Enable nf calibration to happen (?) */ +#define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */ /* * PHY noise floor status register @@ -1902,7 +2017,10 @@ #define AR5K_PHY_NF_RVAL(_n) (((_n) >> 19) & AR5K_PHY_NF_M) #define AR5K_PHY_NF_AVAL(_n) (-((_n) ^ AR5K_PHY_NF_M) + 1) #define AR5K_PHY_NF_SVAL(_n) (((_n) & AR5K_PHY_NF_M) | (1 << 9)) -#define AR5K_PHY_NF_THRESH62 0x00001000 /* Thresh62 -check ANI patent- (field) */ +#define AR5K_PHY_NF_THRESH62 0x0007f000 /* Thresh62 -check ANI patent- (field) */ +#define AR5K_PHY_NF_THRESH62_S 12 +#define AR5K_PHY_NF_MINCCA_PWR 0x0ff80000 /* ??? */ +#define AR5K_PHY_NF_MINCCA_PWR_S 19 /* * PHY ADC saturation register [5110] @@ -1942,24 +2060,31 @@ */ #define AR5K_PHY_SCR 0x9870 #define AR5K_PHY_SCR_32MHZ 0x0000001f + #define AR5K_PHY_SLMT 0x9874 #define AR5K_PHY_SLMT_32MHZ 0x0000007f + #define AR5K_PHY_SCAL 0x9878 #define AR5K_PHY_SCAL_32MHZ 0x0000000e + /* * PHY PLL (Phase Locked Loop) control register */ #define AR5K_PHY_PLL 0x987c -#define AR5K_PHY_PLL_20MHZ 0x13 /* For half rate (?) [5111+] */ -#define AR5K_PHY_PLL_40MHZ_5211 0x18 /* For 802.11a */ +#define AR5K_PHY_PLL_20MHZ 0x00000013 /* For half rate (?) */ +/* 40MHz -> 5GHz band */ +#define AR5K_PHY_PLL_40MHZ_5211 0x00000018 #define AR5K_PHY_PLL_40MHZ_5212 0x000000aa +#define AR5K_PHY_PLL_40MHZ_5413 0x00000004 #define AR5K_PHY_PLL_40MHZ (ah->ah_version == AR5K_AR5211 ? \ AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212) -#define AR5K_PHY_PLL_44MHZ_5211 0x19 /* For 802.11b/g */ +/* 44MHz -> 2.4GHz band */ +#define AR5K_PHY_PLL_44MHZ_5211 0x00000019 #define AR5K_PHY_PLL_44MHZ_5212 0x000000ab #define AR5K_PHY_PLL_44MHZ (ah->ah_version == AR5K_AR5211 ? \ AR5K_PHY_PLL_44MHZ_5211 : AR5K_PHY_PLL_44MHZ_5212) + #define AR5K_PHY_PLL_RF5111 0x00000000 #define AR5K_PHY_PLL_RF5112 0x00000040 #define AR5K_PHY_PLL_HALF_RATE 0x00000100 @@ -2026,6 +2151,19 @@ #define AR5K_PHY_RFSTG_DISABLE 0x00000021 /* + * BIN masks (?) + */ +#define AR5K_PHY_BIN_MASK_1 0x9900 +#define AR5K_PHY_BIN_MASK_2 0x9904 +#define AR5K_PHY_BIN_MASK_3 0x9908 + +#define AR5K_PHY_BIN_MASK_CTL 0x990c +#define AR5K_PHY_BIN_MASK_CTL_MASK_4 0x00003fff +#define AR5K_PHY_BIN_MASK_CTL_MASK_4_S 0 +#define AR5K_PHY_BIN_MASK_CTL_RATE 0xff000000 +#define AR5K_PHY_BIN_MASK_CTL_RATE_S 24 + +/* * PHY Antenna control register */ #define AR5K_PHY_ANT_CTL 0x9910 /* Register Address */ @@ -2072,6 +2210,7 @@ #define AR5K_PHY_OFDM_SELFCORR 0x9924 /* Register Address */ #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN 0x00000001 /* Enable cyclic RSSI thr 1 */ #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1 0x000000fe /* Mask for Cyclic RSSI threshold 1 */ +#define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 0 #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3 0x00000100 /* Cyclic RSSI threshold 3 (field) (?) */ #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN 0x00008000 /* Enable 1A RSSI threshold (?) */ #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR 0x00010000 /* 1A RSSI threshold (field) (?) */ @@ -2118,7 +2257,6 @@ #define AR5K_PHY_PAPD_PROBE_INI_5111 0x00004883 /* [5212+] */ #define AR5K_PHY_PAPD_PROBE_INI_5112 0x00004882 /* [5212+] */ - /* * PHY TX rate power registers [5112+] */ @@ -2140,6 +2278,8 @@ #define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038 /* Mask for tx clip (?) */ #define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3 #define AR5K_PHY_FRAME_CTL_PREP_CHINFO 0x00010000 /* Prepend chan info */ +#define AR5K_PHY_FRAME_CTL_EMU 0x80000000 +#define AR5K_PHY_FRAME_CTL_EMU_S 31 /*---[5110/5111]---*/ #define AR5K_PHY_FRAME_CTL_TIMING_ERR 0x01000000 /* PHY timing error */ #define AR5K_PHY_FRAME_CTL_PARITY_ERR 0x02000000 /* Parity error */ @@ -2158,48 +2298,36 @@ * PHY radar detection register [5111+] */ #define AR5K_PHY_RADAR 0x9954 - -/* Radar enable ........ ........ ........ .......1 */ #define AR5K_PHY_RADAR_ENABLE 0x00000001 -#define AR5K_PHY_RADAR_DISABLE 0x00000000 -#define AR5K_PHY_RADAR_ENABLE_S 0 - -/* This is the value found on the card .1.111.1 .1.1.... 111....1 1...1... -at power on. */ -#define AR5K_PHY_RADAR_PWONDEF_AR5213 0x5d50e188 - -/* This is the value found on the card .1.1.111 ..11...1 .1...1.1 1...11.1 -after DFS is enabled */ -#define AR5K_PHY_RADAR_ENABLED_AR5213 0x5731458d - -/* Finite Impulse Response (FIR) filter .1111111 ........ ........ ........ - * power out threshold. - * 7-bits, standard power range {0..127} in 1/2 dBm units. */ -#define AR5K_PHY_RADAR_FIRPWROUTTHR 0x7f000000 -#define AR5K_PHY_RADAR_FIRPWROUTTHR_S 24 - -/* Radar RSSI/SNR threshold. ........ 111111.. ........ ........ - * 6-bits, dBm range {0..63} in dBm units. */ -#define AR5K_PHY_RADAR_RADARRSSITHR 0x00fc0000 -#define AR5K_PHY_RADAR_RADARRSSITHR_S 18 - -/* Pulse height threshold ........ ......11 1111.... ........ - * 6-bits, dBm range {0..63} in dBm units. */ -#define AR5K_PHY_RADAR_PULSEHEIGHTTHR 0x0003f000 -#define AR5K_PHY_RADAR_PULSEHEIGHTTHR_S 12 - -/* Pulse RSSI/SNR threshold ........ ........ ....1111 11...... - * 6-bits, dBm range {0..63} in dBm units. */ -#define AR5K_PHY_RADAR_PULSERSSITHR 0x00000fc0 -#define AR5K_PHY_RADAR_PULSERSSITHR_S 6 - -/* Inband threshold ........ ........ ........ ..11111. - * 5-bits, units unknown {0..31} (? MHz ?) */ -#define AR5K_PHY_RADAR_INBANDTHR 0x0000003e +#define AR5K_PHY_RADAR_DISABLE 0x00000000 +#define AR5K_PHY_RADAR_INBANDTHR 0x0000003e /* Inband threshold + 5-bits, units unknown {0..31} + (? MHz ?) */ #define AR5K_PHY_RADAR_INBANDTHR_S 1 +#define AR5K_PHY_RADAR_PRSSI_THR 0x00000fc0 /* Pulse RSSI/SNR threshold + 6-bits, dBm range {0..63} + in dBm units. */ +#define AR5K_PHY_RADAR_PRSSI_THR_S 6 + +#define AR5K_PHY_RADAR_PHEIGHT_THR 0x0003f000 /* Pulse height threshold + 6-bits, dBm range {0..63} + in dBm units. */ +#define AR5K_PHY_RADAR_PHEIGHT_THR_S 12 + +#define AR5K_PHY_RADAR_RSSI_THR 0x00fc0000 /* Radar RSSI/SNR threshold. + 6-bits, dBm range {0..63} + in dBm units. */ +#define AR5K_PHY_RADAR_RSSI_THR_S 18 + +#define AR5K_PHY_RADAR_FIRPWR_THR 0x7f000000 /* Finite Impulse Response + filter power out threshold. + 7-bits, standard power range + {0..127} in 1/2 dBm units. */ +#define AR5K_PHY_RADAR_FIRPWR_THRS 24 + /* - * PHY antenna switch table registers [5110] + * PHY antenna switch table registers */ #define AR5K_PHY_ANT_SWITCH_TABLE_0 0x9960 #define AR5K_PHY_ANT_SWITCH_TABLE_1 0x9964 @@ -2210,25 +2338,65 @@ after DFS is enabled */ #define AR5K_PHY_NFTHRES 0x9968 /* - * PHY clock sleep registers [5112+] + * Sigma Delta register (?) [5213] */ -#define AR5K_PHY_SCLOCK 0x99f0 -#define AR5K_PHY_SCLOCK_32MHZ 0x0000000c -#define AR5K_PHY_SDELAY 0x99f4 -#define AR5K_PHY_SDELAY_32MHZ 0x000000ff -#define AR5K_PHY_SPENDING 0x99f8 -#define AR5K_PHY_SPENDING_14 0x00000014 -#define AR5K_PHY_SPENDING_18 0x00000018 -#define AR5K_PHY_SPENDING_RF5111 0x00000018 -#define AR5K_PHY_SPENDING_RF5112 0x00000014 -/* #define AR5K_PHY_SPENDING_RF5112A 0x0000000e */ -/* #define AR5K_PHY_SPENDING_RF5424 0x00000012 */ -#define AR5K_PHY_SPENDING_RF5413 0x00000014 -#define AR5K_PHY_SPENDING_RF2413 0x00000014 -#define AR5K_PHY_SPENDING_RF2425 0x00000018 +#define AR5K_PHY_SIGMA_DELTA 0x996C +#define AR5K_PHY_SIGMA_DELTA_ADC_SEL 0x00000003 +#define AR5K_PHY_SIGMA_DELTA_ADC_SEL_S 0 +#define AR5K_PHY_SIGMA_DELTA_FILT2 0x000000f8 +#define AR5K_PHY_SIGMA_DELTA_FILT2_S 3 +#define AR5K_PHY_SIGMA_DELTA_FILT1 0x00001f00 +#define AR5K_PHY_SIGMA_DELTA_FILT1_S 8 +#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ff3000 +#define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S 13 + +/* + * RF restart register [5112+] (?) + */ +#define AR5K_PHY_RESTART 0x9970 /* restart */ +#define AR5K_PHY_RESTART_DIV_GC 0x001c0000 /* Fast diversity gc_limit (?) */ +#define AR5K_PHY_RESTART_DIV_GC_S 18 + +/* + * RF Bus access request register (for synth-oly channel switching) + */ +#define AR5K_PHY_RFBUS_REQ 0x997C +#define AR5K_PHY_RFBUS_REQ_REQUEST 0x00000001 /* - * Misc PHY/radio registers [5110 - 5111] + * Spur mitigation masks (?) + */ +#define AR5K_PHY_TIMING_7 0x9980 +#define AR5K_PHY_TIMING_8 0x9984 +#define AR5K_PHY_TIMING_8_PILOT_MASK_2 0x000fffff +#define AR5K_PHY_TIMING_8_PILOT_MASK_2_S 0 + +#define AR5K_PHY_BIN_MASK2_1 0x9988 +#define AR5K_PHY_BIN_MASK2_2 0x998c +#define AR5K_PHY_BIN_MASK2_3 0x9990 + +#define AR5K_PHY_BIN_MASK2_4 0x9994 +#define AR5K_PHY_BIN_MASK2_4_MASK_4 0x00003fff +#define AR5K_PHY_BIN_MASK2_4_MASK_4_S 0 + +#define AR_PHY_TIMING_9 0x9998 +#define AR_PHY_TIMING_10 0x999c +#define AR_PHY_TIMING_10_PILOT_MASK_2 0x000fffff +#define AR_PHY_TIMING_10_PILOT_MASK_2_S 0 + +/* + * Spur mitigation control + */ +#define AR_PHY_TIMING_11 0x99a0 /* Register address */ +#define AR_PHY_TIMING_11_SPUR_DELTA_PHASE 0x000fffff /* Spur delta phase */ +#define AR_PHY_TIMING_11_SPUR_DELTA_PHASE_S 0 +#define AR_PHY_TIMING_11_SPUR_FREQ_SD 0x3ff00000 /* Freq sigma delta */ +#define AR_PHY_TIMING_11_SPUR_FREQ_SD_S 20 +#define AR_PHY_TIMING_11_USE_SPUR_IN_AGC 0x40000000 /* Spur filter in AGC detector */ +#define AR_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000 /* Spur filter in OFDM self correlator */ + +/* + * Gain tables */ #define AR5K_BB_GAIN_BASE 0x9b00 /* BaseBand Amplifier Gain table base address */ #define AR5K_BB_GAIN(_n) (AR5K_BB_GAIN_BASE + ((_n) << 2)) @@ -2248,9 +2416,10 @@ after DFS is enabled */ #define AR5K_PHY_CURRENT_RSSI 0x9c1c /* - * PHY RF Bus grant register (?) + * PHY RF Bus grant register */ #define AR5K_PHY_RFBUS_GRANT 0x9c20 +#define AR5K_PHY_RFBUS_GRANT_OK 0x00000001 /* * PHY ADC test register @@ -2294,6 +2463,31 @@ after DFS is enabled */ #define AR5K_PHY_CHAN_STATUS_RX_CLR_PAP 0x00000008 /* + * Heavy clip enable register + */ +#define AR5K_PHY_HEAVY_CLIP_ENABLE 0x99e0 + +/* + * PHY clock sleep registers [5112+] + */ +#define AR5K_PHY_SCLOCK 0x99f0 +#define AR5K_PHY_SCLOCK_32MHZ 0x0000000c +#define AR5K_PHY_SDELAY 0x99f4 +#define AR5K_PHY_SDELAY_32MHZ 0x000000ff +#define AR5K_PHY_SPENDING 0x99f8 +#define AR5K_PHY_SPENDING_14 0x00000014 +#define AR5K_PHY_SPENDING_18 0x00000018 +#define AR5K_PHY_SPENDING_RF5111 0x00000018 +#define AR5K_PHY_SPENDING_RF5112 0x00000014 +/* #define AR5K_PHY_SPENDING_RF5112A 0x0000000e */ +/* #define AR5K_PHY_SPENDING_RF5424 0x00000012 */ +#define AR5K_PHY_SPENDING_RF5413 0x00000018 +#define AR5K_PHY_SPENDING_RF2413 0x00000018 +#define AR5K_PHY_SPENDING_RF2316 0x00000018 +#define AR5K_PHY_SPENDING_RF2317 0x00000018 +#define AR5K_PHY_SPENDING_RF2425 0x00000014 + +/* * PHY PAPD I (power?) table (?) * (92! entries) */ @@ -2344,10 +2538,47 @@ after DFS is enabled */ #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000000f #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S 0 +/* Same address is used for antenna diversity activation */ +#define AR5K_PHY_FAST_ANT_DIV 0xa208 +#define AR5K_PHY_FAST_ANT_DIV_EN 0x00002000 + /* * PHY 2GHz gain register [5111+] */ -#define AR5K_PHY_GAIN_2GHZ 0xa20c -#define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX 0x00fc0000 +#define AR5K_PHY_GAIN_2GHZ 0xa20c +#define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX 0x00fc0000 #define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S 18 -#define AR5K_PHY_GAIN_2GHZ_INI_5111 0x6480416c +#define AR5K_PHY_GAIN_2GHZ_INI_5111 0x6480416c + +#define AR5K_PHY_CCK_RX_CTL_4 0xa21c +#define AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT 0x01f80000 +#define AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT_S 19 + +#define AR5K_PHY_DAG_CCK_CTL 0xa228 +#define AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR 0x00000200 +#define AR5K_PHY_DAG_CCK_CTL_RSSI_THR 0x0001fc00 +#define AR5K_PHY_DAG_CCK_CTL_RSSI_THR_S 10 + +#define AR5K_PHY_FAST_ADC 0xa24c + +#define AR5K_PHY_BLUETOOTH 0xa254 + +/* + * Transmit Power Control register + * [2413+] + */ +#define AR5K_PHY_TPC_RG1 0xa258 +#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN 0x0000c000 +#define AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S 14 + +#define AR5K_PHY_TPC_RG5 0xa26C +#define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP 0x0000000F +#define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP_S 0 +#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1 0x000003F0 +#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1_S 4 +#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2 0x0000FC00 +#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2_S 10 +#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3 0x003F0000 +#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S 16 +#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4 0x0FC00000 +#define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S 22 diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c index f5c3de890cd..8f1886834e6 100644 --- a/drivers/net/wireless/ath5k/reset.c +++ b/drivers/net/wireless/ath5k/reset.c @@ -173,8 +173,10 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) udelay(15); if (ah->ah_version == AR5K_AR5210) { - val &= AR5K_RESET_CTL_CHIP; - mask &= AR5K_RESET_CTL_CHIP; + val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA + | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY; + mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA + | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY; } else { val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND; mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND; @@ -361,16 +363,20 @@ int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI; /* Reset chipset */ - ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | - AR5K_RESET_CTL_BASEBAND | bus_flags); + if (ah->ah_version == AR5K_AR5210) { + ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | + AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA | + AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI); + mdelay(2); + } else { + ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | + AR5K_RESET_CTL_BASEBAND | bus_flags); + } if (ret) { ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n"); return -EIO; } - if (ah->ah_version == AR5K_AR5210) - udelay(2300); - /* ...wakeup again!*/ ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); if (ret) { @@ -537,13 +543,13 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, ath5k_hw_reg_write(ah, 0x0002a002, 0x982c); if (channel->hw_value == CHANNEL_G) - if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413) + if (ah->ah_mac_srev < AR5K_SREV_AR2413) ath5k_hw_reg_write(ah, 0x00f80d80, 0x994c); - else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424) + else if (ah->ah_mac_srev < AR5K_SREV_AR5424) ath5k_hw_reg_write(ah, 0x00380140, 0x994c); - else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425) + else if (ah->ah_mac_srev < AR5K_SREV_AR2425) ath5k_hw_reg_write(ah, 0x00fc0ec0, 0x994c); else /* 2425 */ @@ -909,7 +915,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, ath5k_hw_reg_write(ah, 0x000100aa, 0x8118); ath5k_hw_reg_write(ah, 0x00003210, 0x811c); ath5k_hw_reg_write(ah, 0x00000052, 0x8108); - if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2413) + if (ah->ah_mac_srev >= AR5K_SREV_AR2413) ath5k_hw_reg_write(ah, 0x00000004, 0x8120); } diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c index c43fd586116..eedb465d25d 100644 --- a/drivers/net/wireless/ath9k/beacon.c +++ b/drivers/net/wireless/ath9k/beacon.c @@ -16,7 +16,6 @@ /* Implementation of beacon processing. */ -#include <asm/unaligned.h> #include "core.h" /* @@ -26,7 +25,6 @@ * the operating mode of the station (AP or AdHoc). Parameters are AIFS * settings and channel width min/max */ - static int ath_beaconq_config(struct ath_softc *sc) { struct ath_hal *ah = sc->sc_ah; @@ -63,19 +61,18 @@ static int ath_beaconq_config(struct ath_softc *sc) * up all required antenna switch parameters, rate codes, and channel flags. * Beacons are always sent out at the lowest rate, and are not retried. */ - static void ath_beacon_setup(struct ath_softc *sc, - struct ath_vap *avp, struct ath_buf *bf) + struct ath_vap *avp, struct ath_buf *bf) { struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu; struct ath_hal *ah = sc->sc_ah; struct ath_desc *ds; - int flags, antenna; + struct ath9k_11n_rate_series series[4]; const struct ath9k_rate_table *rt; + int flags, antenna; u8 rix, rate; int ctsrate = 0; int ctsduration = 0; - struct ath9k_11n_rate_series series[4]; DPRINTF(sc, ATH_DBG_BEACON, "%s: m %p len %u\n", __func__, skb, skb->len); @@ -115,20 +112,21 @@ static void ath_beacon_setup(struct ath_softc *sc, rate |= rt->info[rix].shortPreamble; ath9k_hw_set11n_txdesc(ah, ds, - skb->len + FCS_LEN, /* frame length */ - ATH9K_PKT_TYPE_BEACON, /* Atheros packet type */ + skb->len + FCS_LEN, /* frame length */ + ATH9K_PKT_TYPE_BEACON, /* Atheros packet type */ avp->av_btxctl.txpower, /* txpower XXX */ - ATH9K_TXKEYIX_INVALID, /* no encryption */ - ATH9K_KEY_TYPE_CLEAR, /* no encryption */ - flags /* no ack, veol for beacons */ + ATH9K_TXKEYIX_INVALID, /* no encryption */ + ATH9K_KEY_TYPE_CLEAR, /* no encryption */ + flags /* no ack, + veol for beacons */ ); /* NB: beacon's BufLen must be a multiple of 4 bytes */ ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4), /* buffer length */ - true, /* first segment */ - true, /* last segment */ - ds /* first descriptor */ + true, /* first segment */ + true, /* last segment */ + ds /* first descriptor */ ); memzero(series, sizeof(struct ath9k_11n_rate_series) * 4); @@ -153,22 +151,23 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) struct ath_buf *bf; struct ath_vap *avp; struct sk_buff *skb; - int cabq_depth; struct ath_txq *cabq; struct ieee80211_tx_info *info; + int cabq_depth; + avp = sc->sc_vaps[if_id]; + ASSERT(avp); cabq = sc->sc_cabq; - ASSERT(avp); - if (avp->av_bcbuf == NULL) { DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n", __func__, avp, avp->av_bcbuf); return NULL; } + bf = avp->av_bcbuf; - skb = (struct sk_buff *) bf->bf_mpdu; + skb = (struct sk_buff *)bf->bf_mpdu; if (skb) { pci_unmap_single(sc->pdev, bf->bf_dmacontext, skb_end_pointer(skb) - skb->head, @@ -179,17 +178,19 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) bf->bf_mpdu = skb; if (skb == NULL) return NULL; + info = IEEE80211_SKB_CB(skb); if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { /* * TODO: make sure the seq# gets assigned properly (vs. other * TX frames) */ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; sc->seq_no += 0x10; hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); hdr->seq_ctrl |= cpu_to_le16(sc->seq_no); } + bf->bf_buf_addr = bf->bf_dmacontext = pci_map_single(sc->pdev, skb->data, skb_end_pointer(skb) - skb->head, @@ -241,7 +242,6 @@ static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id) * Startup beacon transmission for adhoc mode when they are sent entirely * by the hardware using the self-linked descriptor + veol trick. */ - static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) { struct ath_hal *ah = sc->sc_ah; @@ -278,7 +278,6 @@ static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id) * min/max, and enable aifs). The info structure does not need to be * persistant. */ - int ath_beaconq_setup(struct ath_hal *ah) { struct ath9k_tx_queue_info qi; @@ -299,26 +298,24 @@ int ath_beaconq_setup(struct ath_hal *ah) * the ATH interface. This routine also calculates the beacon "slot" for * staggared beacons in the mBSSID case. */ - int ath_beacon_alloc(struct ath_softc *sc, int if_id) { struct ath_vap *avp; - struct ieee80211_hdr *wh; + struct ieee80211_hdr *hdr; struct ath_buf *bf; struct sk_buff *skb; + __le64 tstamp; avp = sc->sc_vaps[if_id]; ASSERT(avp); /* Allocate a beacon descriptor if we haven't done so. */ if (!avp->av_bcbuf) { - /* - * Allocate beacon state for hostap/ibss. We know - * a buffer is available. - */ + /* Allocate beacon state for hostap/ibss. We know + * a buffer is available. */ avp->av_bcbuf = list_first_entry(&sc->sc_bbuf, - struct ath_buf, list); + struct ath_buf, list); list_del(&avp->av_bcbuf->list); if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP || @@ -362,9 +359,7 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) } /* - * NB: the beacon data buffer must be 32-bit aligned; - * we assume the wbuf routines will return us something - * with this alignment (perhaps should assert). + * NB: the beacon data buffer must be 32-bit aligned. * FIXME: Fill avp->av_btxctl.txpower and * avp->av_btxctl.shortPreamble */ @@ -375,6 +370,9 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) return -ENOMEM; } + tstamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; + sc->bc_tstamp = le64_to_cpu(tstamp); + /* * Calculate a TSF adjustment factor required for * staggered beacons. Note that we assume the format @@ -408,8 +406,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) __func__, "stagger", avp->av_bslot, intval, (unsigned long long)tsfadjust); - wh = (struct ieee80211_hdr *)skb->data; - memcpy(&wh[1], &val, sizeof(val)); + hdr = (struct ieee80211_hdr *)skb->data; + memcpy(&hdr[1], &val, sizeof(val)); } bf->bf_buf_addr = bf->bf_dmacontext = @@ -425,9 +423,8 @@ int ath_beacon_alloc(struct ath_softc *sc, int if_id) * Reclaim beacon resources and return buffer to the pool. * * Checks the VAP to put the beacon frame buffer back to the ATH object - * queue, and de-allocates any wbuf frames that were sent as CAB traffic. + * queue, and de-allocates any skbs that were sent as CAB traffic. */ - void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) { if (avp->av_bcbuf != NULL) { @@ -459,10 +456,7 @@ void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp) * Transmit one or more beacon frames at SWBA. Dynamic updates to the frame * contents are done as needed and the slot time is also adjusted based on * current state. - * - * This tasklet is not scheduled, it's called in ISR context. */ - void ath9k_beacon_tasklet(unsigned long data) { struct ath_softc *sc = (struct ath_softc *)data; @@ -490,6 +484,8 @@ void ath9k_beacon_tasklet(unsigned long data) * and wait for the next. Missed beacons indicate * a problem and should not occur. If we miss too * many consecutive beacons reset the device. + * + * FIXME: Clean up this mess !! */ if (ath9k_hw_numtxpending(ah, sc->sc_bhalq) != 0) { sc->sc_bmisscount++; @@ -505,19 +501,16 @@ void ath9k_beacon_tasklet(unsigned long data) __func__, sc->sc_bmisscount); if (show_cycles) { /* - * Display cycle counter stats - * from HW to aide in debug of - * stickiness. + * Display cycle counter stats from HW + * to aide in debug of stickiness. */ - DPRINTF(sc, - ATH_DBG_BEACON, + DPRINTF(sc, ATH_DBG_BEACON, "%s: busy times: rx_clear=%d, " "rx_frame=%d, tx_frame=%d\n", __func__, rx_clear, rx_frame, tx_frame); } else { - DPRINTF(sc, - ATH_DBG_BEACON, + DPRINTF(sc, ATH_DBG_BEACON, "%s: unable to obtain " "busy times\n", __func__); } @@ -529,8 +522,7 @@ void ath9k_beacon_tasklet(unsigned long data) } else if (sc->sc_bmisscount >= BSTUCK_THRESH) { if (sc->sc_flags & SC_OP_NO_RESET) { if (sc->sc_bmisscount == BSTUCK_THRESH) { - DPRINTF(sc, - ATH_DBG_BEACON, + DPRINTF(sc, ATH_DBG_BEACON, "%s: beacon is officially " "stuck\n", __func__); ath9k_hw_dmaRegDump(ah); @@ -542,13 +534,12 @@ void ath9k_beacon_tasklet(unsigned long data) ath_bstuck_process(sc); } } - return; } + if (sc->sc_bmisscount != 0) { if (sc->sc_flags & SC_OP_NO_RESET) { - DPRINTF(sc, - ATH_DBG_BEACON, + DPRINTF(sc, ATH_DBG_BEACON, "%s: resume beacon xmit after %u misses\n", __func__, sc->sc_bmisscount); } else { @@ -572,10 +563,12 @@ void ath9k_beacon_tasklet(unsigned long data) tsftu = TSF_TO_TU(tsf>>32, tsf); slot = ((tsftu % intval) * ATH_BCBUF) / intval; if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF]; + DPRINTF(sc, ATH_DBG_BEACON, - "%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n", - __func__, slot, (unsigned long long) tsf, tsftu, - intval, if_id); + "%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n", + __func__, slot, (unsigned long long)tsf, tsftu, + intval, if_id); + bfaddr = 0; if (if_id != ATH_IF_ID_ANY) { bf = ath_beacon_generate(sc, if_id); @@ -632,9 +625,8 @@ void ath9k_beacon_tasklet(unsigned long data) * Tasklet for Beacon Stuck processing * * Processing for Beacon Stuck. - * Basically calls the ath_internal_reset function to reset the chip. + * Basically resets the chip. */ - void ath_bstuck_process(struct ath_softc *sc) { DPRINTF(sc, ATH_DBG_BEACON, @@ -658,13 +650,12 @@ void ath_bstuck_process(struct ath_softc *sc) * interrupt when we stop seeing beacons from the AP * we've associated with. */ - void ath_beacon_config(struct ath_softc *sc, int if_id) { struct ath_hal *ah = sc->sc_ah; - u32 nexttbtt, intval; struct ath_beacon_config conf; enum ath9k_opmode av_opmode; + u32 nexttbtt, intval; if (if_id != ATH_IF_ID_ANY) av_opmode = sc->sc_vaps[if_id]->av_opmode; @@ -673,12 +664,6 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) memzero(&conf, sizeof(struct ath_beacon_config)); - /* FIXME: Use default values for now - Sujith */ - /* Query beacon configuration first */ - /* - * Protocol stack doesn't support dynamic beacon configuration, - * use default configurations. - */ conf.beacon_interval = sc->hw->conf.beacon_int ? sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL; conf.listen_interval = 1; @@ -687,8 +672,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval; /* extract tstamp from last beacon and convert to TU */ - nexttbtt = TSF_TO_TU(get_unaligned_le32(conf.u.last_tstamp + 4), - get_unaligned_le32(conf.u.last_tstamp)); + nexttbtt = TSF_TO_TU(sc->bc_tstamp >> 32, sc->bc_tstamp); + /* XXX conditionalize multi-bss support? */ if (sc->sc_ah->ah_opmode == ATH9K_M_HOSTAP) { /* @@ -704,12 +689,14 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) intval = conf.beacon_interval & ATH9K_BEACON_PERIOD; } - if (nexttbtt == 0) /* e.g. for ap mode */ + if (nexttbtt == 0) /* e.g. for ap mode */ nexttbtt = intval; - else if (intval) /* NB: can be 0 for monitor mode */ + else if (intval) /* NB: can be 0 for monitor mode */ nexttbtt = roundup(nexttbtt, intval); + DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n", __func__, nexttbtt, intval, conf.beacon_interval); + /* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */ if (sc->sc_ah->ah_opmode == ATH9K_M_STA) { struct ath9k_beacon_state bs; @@ -723,19 +710,19 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) * last beacon we received (which may be none). */ dtimperiod = conf.dtim_period; - if (dtimperiod <= 0) /* NB: 0 if not known */ + if (dtimperiod <= 0) /* NB: 0 if not known */ dtimperiod = 1; dtimcount = conf.dtim_count; - if (dtimcount >= dtimperiod) /* NB: sanity check */ - dtimcount = 0; /* XXX? */ - cfpperiod = 1; /* NB: no PCF support yet */ + if (dtimcount >= dtimperiod) /* NB: sanity check */ + dtimcount = 0; + cfpperiod = 1; /* NB: no PCF support yet */ cfpcount = 0; sleepduration = conf.listen_interval * intval; if (sleepduration <= 0) sleepduration = intval; -#define FUDGE 2 +#define FUDGE 2 /* * Pull nexttbtt forward to reflect the current * TSF and calculate dtim+cfp state for the result. @@ -759,6 +746,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod; bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod; bs.bs_cfpmaxduration = 0; + /* * Calculate the number of consecutive beacons to miss * before taking a BMISS interrupt. The configuration @@ -767,9 +755,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) * result to at most 15 beacons. */ if (sleepduration > intval) { - bs.bs_bmissthreshold = - conf.listen_interval * - ATH_DEFAULT_BMISS_LIMIT / 2; + bs.bs_bmissthreshold = conf.listen_interval * + ATH_DEFAULT_BMISS_LIMIT / 2; } else { bs.bs_bmissthreshold = DIV_ROUND_UP(conf.bmiss_timeout, intval); @@ -789,8 +776,8 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) * XXX fixed at 100ms */ - bs.bs_sleepduration = - roundup(IEEE80211_MS_TO_TU(100), sleepduration); + bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), + sleepduration); if (bs.bs_sleepduration > bs.bs_dtimperiod) bs.bs_sleepduration = bs.bs_dtimperiod; @@ -834,9 +821,9 @@ void ath_beacon_config(struct ath_softc *sc, int if_id) if (sc->sc_ah->ah_opmode == ATH9K_M_IBSS) { /* * Pull nexttbtt forward to reflect the current - * TSF . + * TSF */ -#define FUDGE 2 +#define FUDGE 2 if (!(intval & ATH9K_BEACON_RESET_TSF)) { tsf = ath9k_hw_gettsf64(ah); tsftu = TSF_TO_TU((u32)(tsf>>32), diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c index c262ef279ff..6c433a4d003 100644 --- a/drivers/net/wireless/ath9k/core.c +++ b/drivers/net/wireless/ath9k/core.c @@ -534,7 +534,8 @@ int ath_vap_attach(struct ath_softc *sc, avp->av_opmode = opmode; avp->av_bslot = -1; - ath9k_hw_set_tsfadjust(sc->sc_ah, 1); + if (opmode == ATH9K_M_HOSTAP) + ath9k_hw_set_tsfadjust(sc->sc_ah, 1); sc->sc_vaps[if_id] = avp; sc->sc_nvaps++; @@ -677,6 +678,12 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) sc->sc_imask |= ATH9K_INT_CST; + /* Note: We disable MIB interrupts for now as we don't yet + * handle processing ANI, otherwise you will get an interrupt + * storm after about 7 hours of usage making the system unusable + * with huge latency. Once we do have ANI processing included + * we can re-enable this interrupt. */ +#if 0 /* * Enable MIB interrupts when there are hardware phy counters. * Note we only do this (at the moment) for station mode. @@ -685,6 +692,7 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan) ((sc->sc_ah->ah_opmode == ATH9K_M_STA) || (sc->sc_ah->ah_opmode == ATH9K_M_IBSS))) sc->sc_imask |= ATH9K_INT_MIB; +#endif /* * Some hardware processes the TIM IE and fires an * interrupt when the TIM bit is set. For hardware @@ -1183,6 +1191,8 @@ void ath_deinit(struct ath_softc *sc) DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__); + tasklet_kill(&sc->intr_tq); + tasklet_kill(&sc->bcon_tasklet); ath_stop(sc); if (!(sc->sc_flags & SC_OP_INVALID)) ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h index b66de29cf66..872f0c5a0b0 100644 --- a/drivers/net/wireless/ath9k/core.h +++ b/drivers/net/wireless/ath9k/core.h @@ -976,7 +976,6 @@ struct ath_softc { u32 sc_keymax; /* size of key cache */ DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); /* key use bit map */ u8 sc_splitmic; /* split TKIP MIC keys */ - int sc_keytype; /* RX */ struct list_head sc_rxbuf; @@ -1001,6 +1000,7 @@ struct ath_softc { u32 sc_bhalq; u32 sc_bmisscount; u32 ast_be_xmit; /* beacons transmitted */ + u64 bc_tstamp; /* Rate */ struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c index 0251e59f2f8..272c7581660 100644 --- a/drivers/net/wireless/ath9k/hw.c +++ b/drivers/net/wireless/ath9k/hw.c @@ -2526,6 +2526,11 @@ static void ath9k_ani_reset(struct ath_hal *ah) } } +/* + * Process a MIB interrupt. We may potentially be invoked because + * any of the MIB counters overflow/trigger so don't assume we're + * here because a PHY error counter triggered. + */ void ath9k_hw_procmibevent(struct ath_hal *ah, const struct ath9k_node_stats *stats) { @@ -2533,18 +2538,20 @@ void ath9k_hw_procmibevent(struct ath_hal *ah, u32 phyCnt1, phyCnt2; DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Processing Mib Intr\n"); - + /* Reset these counters regardless */ REG_WRITE(ah, AR_FILT_OFDM, 0); REG_WRITE(ah, AR_FILT_CCK, 0); if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING)) REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR); + /* Clear the mib counters and save them in the stats */ ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats); ahp->ah_stats.ast_nodestats = *stats; if (!DO_ANI(ah)) return; + /* NB: these are not reset-on-read */ phyCnt1 = REG_READ(ah, AR_PHY_ERR_1); phyCnt2 = REG_READ(ah, AR_PHY_ERR_2); if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) || @@ -2552,6 +2559,7 @@ void ath9k_hw_procmibevent(struct ath_hal *ah, struct ar5416AniState *aniState = ahp->ah_curani; u32 ofdmPhyErrCnt, cckPhyErrCnt; + /* NB: only use ast_ani_*errs with AH_PRIVATE_DIAG */ ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase; ahp->ah_stats.ast_ani_ofdmerrs += ofdmPhyErrCnt - aniState->ofdmPhyErrCount; @@ -2562,11 +2570,17 @@ void ath9k_hw_procmibevent(struct ath_hal *ah, cckPhyErrCnt - aniState->cckPhyErrCount; aniState->cckPhyErrCount = cckPhyErrCnt; + /* + * NB: figure out which counter triggered. If both + * trigger we'll only deal with one as the processing + * clobbers the error counter so the trigger threshold + * check will never be true. + */ if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh) ath9k_hw_ani_ofdm_err_trigger(ah); if (aniState->cckPhyErrCount > aniState->cckTrigHigh) ath9k_hw_ani_cck_err_trigger(ah); - + /* NB: always restart to insure the h/w counters are reset */ ath9k_ani_restart(ah); } } diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c index 1ba18006f47..2caba440316 100644 --- a/drivers/net/wireless/ath9k/main.c +++ b/drivers/net/wireless/ath9k/main.c @@ -204,8 +204,6 @@ static int ath_key_config(struct ath_softc *sc, if (!ret) return -EIO; - if (mac) - sc->sc_keytype = hk.kv_type; return 0; } @@ -1507,7 +1505,6 @@ static int ath9k_set_key(struct ieee80211_hw *hw, case DISABLE_KEY: ath_key_delete(sc, key); clear_bit(key->keyidx, sc->sc_keymap); - sc->sc_keytype = ATH9K_CIPHER_CLR; break; default: ret = -EINVAL; @@ -1784,10 +1781,17 @@ static void ath_pci_remove(struct pci_dev *pdev) { struct ieee80211_hw *hw = pci_get_drvdata(pdev); struct ath_softc *sc = hw->priv; + enum ath9k_int status; - if (pdev->irq) + if (pdev->irq) { + ath9k_hw_set_interrupts(sc->sc_ah, 0); + /* clear the ISR */ + ath9k_hw_getisr(sc->sc_ah, &status); + sc->sc_flags |= SC_OP_INVALID; free_irq(pdev->irq, sc); + } ath_detach(sc); + pci_iounmap(pdev, sc->mem); pci_release_region(pdev, 0); pci_disable_device(pdev); diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c index 1cc9daf4455..cca2fc5b076 100644 --- a/drivers/net/wireless/ath9k/rc.c +++ b/drivers/net/wireless/ath9k/rc.c @@ -20,6 +20,7 @@ */ #include "core.h" +/* FIXME: remove this include! */ #include "../net/mac80211/rate.h" static u32 tx_triglevel_max; @@ -1812,20 +1813,18 @@ static void ath_rc_sib_init(struct ath_rate_node *ath_rc_priv) } -static void ath_setup_rates(struct ieee80211_local *local, struct sta_info *sta) +static void ath_setup_rates(struct ath_softc *sc, + struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, + struct ath_rate_node *rc_priv) { - struct ieee80211_supported_band *sband; - struct ieee80211_hw *hw = local_to_hw(local); - struct ath_softc *sc = hw->priv; - struct ath_rate_node *rc_priv = sta->rate_ctrl_priv; int i, j = 0; DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); - sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; for (i = 0; i < sband->n_bitrates; i++) { - if (sta->sta.supp_rates[local->hw.conf.channel->band] & BIT(i)) { + if (sta->supp_rates[sband->band] & BIT(i)) { rc_priv->neg_rates.rs_rates[j] = (sband->bitrates[i].bitrate * 2) / 10; j++; @@ -1852,19 +1851,17 @@ void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv) } /* Rate Control callbacks */ -static void ath_tx_status(void *priv, struct net_device *dev, +static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, struct sk_buff *skb) { struct ath_softc *sc = priv; struct ath_tx_info_priv *tx_info_priv; struct ath_node *an; - struct sta_info *sta; - struct ieee80211_local *local; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr; __le16 fc; - local = hw_to_local(sc->hw); hdr = (struct ieee80211_hdr *)skb->data; fc = hdr->frame_control; tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0]; @@ -1873,8 +1870,7 @@ static void ath_tx_status(void *priv, struct net_device *dev, an = ath_node_find(sc, hdr->addr1); spin_unlock_bh(&sc->node_lock); - sta = sta_info_get(local, hdr->addr1); - if (!an || !sta || !ieee80211_is_data(fc)) { + if (!an || !priv_sta || !ieee80211_is_data(fc)) { if (tx_info->driver_data[0] != NULL) { kfree(tx_info->driver_data[0]); tx_info->driver_data[0] = NULL; @@ -1882,24 +1878,22 @@ static void ath_tx_status(void *priv, struct net_device *dev, return; } if (tx_info->driver_data[0] != NULL) { - ath_rate_tx_complete(sc, an, sta->rate_ctrl_priv, tx_info_priv); + ath_rate_tx_complete(sc, an, priv_sta, tx_info_priv); kfree(tx_info->driver_data[0]); tx_info->driver_data[0] = NULL; } } static void ath_tx_aggr_resp(struct ath_softc *sc, - struct sta_info *sta, + struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, struct ath_node *an, u8 tidno) { - struct ieee80211_hw *hw = sc->hw; - struct ieee80211_local *local; struct ath_atx_tid *txtid; - struct ieee80211_supported_band *sband; u16 buffersize = 0; int state; - DECLARE_MAC_BUF(mac); + struct sta_info *si; if (!(sc->sc_flags & SC_OP_TXAGGR)) return; @@ -1908,11 +1902,16 @@ static void ath_tx_aggr_resp(struct ath_softc *sc, if (!txtid->paused) return; - local = hw_to_local(sc->hw); - sband = hw->wiphy->bands[hw->conf.channel->band]; + /* + * XXX: This is entirely busted, we aren't supposed to + * access the sta from here because it's internal + * to mac80211, and looking at the state without + * locking is wrong too. + */ + si = container_of(sta, struct sta_info, sta); buffersize = IEEE80211_MIN_AMPDU_BUF << sband->ht_info.ampdu_factor; /* FIXME */ - state = sta->ampdu_mlme.tid_state_tx[tidno]; + state = si->ampdu_mlme.tid_state_tx[tidno]; if (state & HT_ADDBA_RECEIVED_MSK) { txtid->addba_exchangecomplete = 1; @@ -1928,18 +1927,15 @@ static void ath_tx_aggr_resp(struct ath_softc *sc, } } -static void ath_get_rate(void *priv, struct net_device *dev, - struct ieee80211_supported_band *sband, - struct sk_buff *skb, - struct rate_selection *sel) +static void ath_get_rate(void *priv, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, + struct sk_buff *skb, struct rate_selection *sel) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct sta_info *sta; - struct ath_softc *sc = (struct ath_softc *)priv; + struct ath_softc *sc = priv; struct ieee80211_hw *hw = sc->hw; struct ath_tx_info_priv *tx_info_priv; - struct ath_rate_node *ath_rc_priv; + struct ath_rate_node *ath_rc_priv = priv_sta; struct ath_node *an; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); int is_probe = FALSE, chk, ret; @@ -1955,8 +1951,7 @@ static void ath_get_rate(void *priv, struct net_device *dev, ASSERT(tx_info->driver_data[0] != NULL); tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0]; - sta = sta_info_get(local, hdr->addr1); - lowest_idx = rate_lowest_index(local, sband, sta); + lowest_idx = rate_lowest_index(sband, sta); tx_info_priv->min_rate = (sband->bitrates[lowest_idx].bitrate * 2) / 10; /* lowest rate for management and multicast/broadcast frames */ if (!ieee80211_is_data(fc) || @@ -1965,8 +1960,6 @@ static void ath_get_rate(void *priv, struct net_device *dev, return; } - ath_rc_priv = sta->rate_ctrl_priv; - /* Find tx rate for unicast frames */ ath_rate_findrate(sc, ath_rc_priv, ATH_11N_TXMAXTRY, 4, @@ -1975,8 +1968,7 @@ static void ath_get_rate(void *priv, struct net_device *dev, &is_probe, false); if (is_probe) - sel->probe_idx = ((struct ath_tx_ratectrl *) - sta->rate_ctrl_priv)->probe_rate; + sel->probe_idx = ath_rc_priv->tx_ratectrl.probe_rate; /* Ratecontrol sometimes returns invalid rate index */ if (tx_info_priv->rcs[0].rix != 0xff) @@ -2020,37 +2012,31 @@ static void ath_get_rate(void *priv, struct net_device *dev, __func__, print_mac(mac, hdr->addr1)); } else if (chk == AGGR_EXCHANGE_PROGRESS) - ath_tx_aggr_resp(sc, sta, an, tid); + ath_tx_aggr_resp(sc, sband, sta, an, tid); } } } -static void ath_rate_init(void *priv, void *priv_sta, - struct ieee80211_local *local, - struct sta_info *sta) +static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta) { - struct ieee80211_supported_band *sband; - struct ieee80211_hw *hw = local_to_hw(local); - struct ieee80211_conf *conf = &local->hw.conf; - struct ath_softc *sc = hw->priv; + struct ath_softc *sc = priv; struct ath_rate_node *ath_rc_priv = priv_sta; int i, j = 0; DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); - sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; - - ath_setup_rates(local, sta); - if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { + ath_setup_rates(sc, sband, sta, ath_rc_priv); + if (sc->hw->conf.flags & IEEE80211_CONF_SUPPORT_HT_MODE) { for (i = 0; i < MCS_SET_SIZE; i++) { - if (conf->ht_conf.supp_mcs_set[i/8] & (1<<(i%8))) + if (sc->hw->conf.ht_conf.supp_mcs_set[i/8] & (1<<(i%8))) ath_rc_priv->neg_ht_rates.rs_rates[j++] = i; if (j == ATH_RATE_MAX) break; } ath_rc_priv->neg_ht_rates.rs_nrates = j; } - ath_rc_node_update(hw, priv_sta); + ath_rc_node_update(sc->hw, priv_sta); } static void ath_rate_clear(void *priv) @@ -2058,13 +2044,12 @@ static void ath_rate_clear(void *priv) return; } -static void *ath_rate_alloc(struct ieee80211_local *local) +static void *ath_rate_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) { - struct ieee80211_hw *hw = local_to_hw(local); struct ath_softc *sc = hw->priv; DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__); - return local->hw.priv; + return hw->priv; } static void ath_rate_free(void *priv) @@ -2072,7 +2057,7 @@ static void ath_rate_free(void *priv) return; } -static void *ath_rate_alloc_sta(void *priv, gfp_t gfp) +static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) { struct ath_softc *sc = priv; struct ath_vap *avp = sc->sc_vaps[0]; @@ -2092,7 +2077,8 @@ static void *ath_rate_alloc_sta(void *priv, gfp_t gfp) return rate_priv; } -static void ath_rate_free_sta(void *priv, void *priv_sta) +static void ath_rate_free_sta(void *priv, struct ieee80211_sta *sta, + void *priv_sta) { struct ath_rate_node *rate_priv = priv_sta; struct ath_softc *sc = priv; @@ -2111,7 +2097,7 @@ static struct rate_control_ops ath_rate_ops = { .alloc = ath_rate_alloc, .free = ath_rate_free, .alloc_sta = ath_rate_alloc_sta, - .free_sta = ath_rate_free_sta + .free_sta = ath_rate_free_sta, }; int ath_rate_control_register(void) diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 3fc6641e8bf..25929059c7d 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -239,11 +239,11 @@ static int ath_tx_prepare(struct ath_softc *sc, txctl->keyix = tx_info->control.hw_key->hw_key_idx; txctl->frmlen += tx_info->control.icv_len; - if (sc->sc_keytype == ATH9K_CIPHER_WEP) + if (tx_info->control.hw_key->alg == ALG_WEP) txctl->keytype = ATH9K_KEY_TYPE_WEP; - else if (sc->sc_keytype == ATH9K_CIPHER_TKIP) + else if (tx_info->control.hw_key->alg == ALG_TKIP) txctl->keytype = ATH9K_KEY_TYPE_TKIP; - else if (sc->sc_keytype == ATH9K_CIPHER_AES_CCM) + else if (tx_info->control.hw_key->alg == ALG_CCMP) txctl->keytype = ATH9K_KEY_TYPE_AES; } diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index bd65c485098..ecb02bdaab5 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -2258,7 +2258,7 @@ static int atmel_get_freq(struct net_device *dev, static int atmel_set_scan(struct net_device *dev, struct iw_request_info *info, - struct iw_param *vwrq, + struct iw_point *dwrq, char *extra) { struct atmel_private *priv = netdev_priv(dev); diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c index 12617cd0b78..d2388e8d179 100644 --- a/drivers/net/wireless/atmel_cs.c +++ b/drivers/net/wireless/atmel_cs.c @@ -158,7 +158,7 @@ static int atmel_probe(struct pcmcia_device *p_dev) DEBUG(0, "atmel_attach()\n"); /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE; + p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING; p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; p_dev->irq.Handler = NULL; diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 0f628a29d83..3bf74e236ab 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -815,7 +815,7 @@ void b43_dummy_transmission(struct b43_wldev *dev) break; udelay(10); } - for (i = 0x00; i < 0x0A; i++) { + for (i = 0x00; i < 0x19; i++) { value = b43_read16(dev, 0x0690); if (!(value & 0x0100)) break; @@ -4543,9 +4543,11 @@ static void b43_sprom_fixup(struct ssb_bus *bus) pdev = bus->host_pci; if (IS_PDEV(pdev, BROADCOM, 0x4318, ASUSTEK, 0x100F) || IS_PDEV(pdev, BROADCOM, 0x4320, DELL, 0x0003) || + IS_PDEV(pdev, BROADCOM, 0x4320, HP, 0x12f8) || IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0015) || IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0014) || - IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013)) + IS_PDEV(pdev, BROADCOM, 0x4320, LINKSYS, 0x0013) || + IS_PDEV(pdev, BROADCOM, 0x4320, MOTOROLA, 0x7010)) bus->sprom.boardflags_lo &= ~B43_BFL_BTCOEXIST; } } diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 7b9e99adb8c..713753781f4 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c @@ -44,23 +44,6 @@ static bool b43_is_hw_radio_enabled(struct b43_wldev *dev) return 0; } -/* Update the rfkill state */ -static void b43_rfkill_update_state(struct b43_wldev *dev) -{ - struct b43_rfkill *rfk = &(dev->wl->rfkill); - - if (!dev->radio_hw_enable) { - rfk->rfkill->state = RFKILL_STATE_HARD_BLOCKED; - return; - } - - if (!dev->phy.radio_on) - rfk->rfkill->state = RFKILL_STATE_SOFT_BLOCKED; - else - rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; - -} - /* The poll callback for the hardware button. */ static void b43_rfkill_poll(struct input_polled_dev *poll_dev) { @@ -78,7 +61,6 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev) if (unlikely(enabled != dev->radio_hw_enable)) { dev->radio_hw_enable = enabled; report_change = 1; - b43_rfkill_update_state(dev); b43info(wl, "Radio hardware status changed to %s\n", enabled ? "ENABLED" : "DISABLED"); } @@ -188,6 +170,11 @@ void b43_rfkill_init(struct b43_wldev *dev) "The built-in radio LED will not work.\n"); #endif /* CONFIG_RFKILL_INPUT */ +#if !defined(CONFIG_RFKILL_INPUT) && !defined(CONFIG_RFKILL_INPUT_MODULE) + b43warn(wl, "The rfkill-input subsystem is not available. " + "The built-in radio LED will not work.\n"); +#endif + err = input_register_polled_device(rfk->poll_dev); if (err) goto err_unreg_rfk; diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index 476add97e97..b32bf6a94f1 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c @@ -44,23 +44,6 @@ static bool b43legacy_is_hw_radio_enabled(struct b43legacy_wldev *dev) return 0; } -/* Update the rfkill state */ -static void b43legacy_rfkill_update_state(struct b43legacy_wldev *dev) -{ - struct b43legacy_rfkill *rfk = &(dev->wl->rfkill); - - if (!dev->radio_hw_enable) { - rfk->rfkill->state = RFKILL_STATE_HARD_BLOCKED; - return; - } - - if (!dev->phy.radio_on) - rfk->rfkill->state = RFKILL_STATE_SOFT_BLOCKED; - else - rfk->rfkill->state = RFKILL_STATE_UNBLOCKED; - -} - /* The poll callback for the hardware button. */ static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) { @@ -78,7 +61,6 @@ static void b43legacy_rfkill_poll(struct input_polled_dev *poll_dev) if (unlikely(enabled != dev->radio_hw_enable)) { dev->radio_hw_enable = enabled; report_change = 1; - b43legacy_rfkill_update_state(dev); b43legacyinfo(wl, "Radio hardware status changed to %s\n", enabled ? "ENABLED" : "DISABLED"); } diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c index a279bf1dc9b..6fc5e7361f2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c @@ -36,8 +36,6 @@ #include <linux/workqueue.h> -#include "../net/mac80211/rate.h" - #include "iwl-3945.h" #define RS_NAME "iwl-3945-rs" @@ -319,10 +317,10 @@ static void iwl3945_collect_tx_data(struct iwl3945_rs_sta *rs_sta, } } -static void rs_rate_init(void *priv_rate, void *priv_sta, - struct ieee80211_local *local, struct sta_info *sta) +static void rs_rate_init(void *priv, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta) { - struct iwl3945_rs_sta *rs_sta = (void *)sta->rate_ctrl_priv; + struct iwl3945_rs_sta *rs_sta = priv_sta; int i; IWL_DEBUG_RATE("enter\n"); @@ -333,22 +331,22 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, * after assoc.. */ for (i = IWL_RATE_COUNT - 1; i >= 0; i--) { - if (sta->sta.supp_rates[local->hw.conf.channel->band] & (1 << i)) { + if (sta->supp_rates[sband->band] & (1 << i)) { rs_sta->last_txrate_idx = i; break; } } /* For 5 GHz band it start at IWL_FIRST_OFDM_RATE */ - if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) + if (sband->band == IEEE80211_BAND_5GHZ) rs_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; IWL_DEBUG_RATE("leave\n"); } -static void *rs_alloc(struct ieee80211_local *local) +static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) { - return local->hw.priv; + return hw->priv; } /* rate scale requires free function to be implemented */ @@ -356,17 +354,24 @@ static void rs_free(void *priv) { return; } + static void rs_clear(void *priv) { return; } -static void *rs_alloc_sta(void *priv, gfp_t gfp) +static void *rs_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) { struct iwl3945_rs_sta *rs_sta; + struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; int i; + /* + * XXX: If it's using sta->drv_priv anyway, it might + * as well just put all the information there. + */ + IWL_DEBUG_RATE("enter\n"); rs_sta = kzalloc(sizeof(struct iwl3945_rs_sta), gfp); @@ -375,6 +380,8 @@ static void *rs_alloc_sta(void *priv, gfp_t gfp) return NULL; } + psta->rs_sta = rs_sta; + spin_lock_init(&rs_sta->lock); rs_sta->start_rate = IWL_RATE_INVALID; @@ -400,10 +407,14 @@ static void *rs_alloc_sta(void *priv, gfp_t gfp) return rs_sta; } -static void rs_free_sta(void *priv, void *priv_sta) +static void rs_free_sta(void *priv, struct ieee80211_sta *sta, + void *priv_sta) { + struct iwl3945_sta_priv *psta = (void *) sta->drv_priv; struct iwl3945_rs_sta *rs_sta = priv_sta; + psta->rs_sta = NULL; + IWL_DEBUG_RATE("enter\n"); del_timer_sync(&rs_sta->rate_scale_flush); kfree(rs_sta); @@ -445,26 +456,19 @@ static int rs_adjust_next_rate(struct iwl3945_priv *priv, int rate) * NOTE: Uses iwl3945_priv->retry_rate for the # of retries attempted by * the hardware for each rate. */ -static void rs_tx_status(void *priv_rate, - struct net_device *dev, +static void rs_tx_status(void *priv_rate, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, struct sk_buff *skb) { u8 retries, current_count; int scale_rate_index, first_index, last_index; unsigned long flags; - struct sta_info *sta; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct iwl3945_rs_sta *rs_sta; - struct ieee80211_supported_band *sband; + struct iwl3945_rs_sta *rs_sta = priv_sta; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); IWL_DEBUG_RATE("enter\n"); - sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; - - retries = info->status.retry_count; first_index = sband->bitrates[info->tx_rate_idx].hw_value; if ((first_index < 0) || (first_index >= IWL_RATE_COUNT)) { @@ -472,17 +476,11 @@ static void rs_tx_status(void *priv_rate, return; } - rcu_read_lock(); - - sta = sta_info_get(local, hdr->addr1); - if (!sta || !sta->rate_ctrl_priv) { - rcu_read_unlock(); + if (!priv_sta) { IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); return; } - rs_sta = (void *)sta->rate_ctrl_priv; - rs_sta->tx_packets++; scale_rate_index = first_index; @@ -549,8 +547,6 @@ static void rs_tx_status(void *priv_rate, spin_unlock_irqrestore(&rs_sta->lock, flags); - rcu_read_unlock(); - IWL_DEBUG_RATE("leave\n"); return; @@ -634,16 +630,15 @@ static u16 iwl3945_get_adjacent_rate(struct iwl3945_rs_sta *rs_sta, * rate table and must reference the driver allocated rate table * */ -static void rs_get_rate(void *priv_rate, struct net_device *dev, - struct ieee80211_supported_band *sband, - struct sk_buff *skb, - struct rate_selection *sel) +static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, + struct sk_buff *skb, struct rate_selection *sel) { u8 low = IWL_RATE_INVALID; u8 high = IWL_RATE_INVALID; u16 high_low; int index; - struct iwl3945_rs_sta *rs_sta; + struct iwl3945_rs_sta *rs_sta = priv_sta; struct iwl3945_rate_scale_data *window = NULL; int current_tpt = IWL_INV_TPT; int low_tpt = IWL_INV_TPT; @@ -651,34 +646,25 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, u32 fail_count; s8 scale_action = 0; unsigned long flags; - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct sta_info *sta; u16 fc, rate_mask; - struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_rate; + struct iwl3945_priv *priv = (struct iwl3945_priv *)priv_r; DECLARE_MAC_BUF(mac); IWL_DEBUG_RATE("enter\n"); - rcu_read_lock(); - - sta = sta_info_get(local, hdr->addr1); - /* Send management frames and broadcast/multicast data using lowest * rate. */ fc = le16_to_cpu(hdr->frame_control); if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || is_multicast_ether_addr(hdr->addr1) || - !sta || !sta->rate_ctrl_priv) { + !sta || !priv_sta) { IWL_DEBUG_RATE("leave: No STA priv data to update!\n"); - sel->rate_idx = rate_lowest_index(local, sband, sta); - rcu_read_unlock(); + sel->rate_idx = rate_lowest_index(sband, sta); return; } - rs_sta = (void *)sta->rate_ctrl_priv; - - rate_mask = sta->sta.supp_rates[sband->band]; + rate_mask = sta->supp_rates[sband->band]; index = min(rs_sta->last_txrate_idx & 0xffff, IWL_RATE_COUNT - 1); if (sband->band == IEEE80211_BAND_5GHZ) @@ -811,8 +797,6 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, else sel->rate_idx = rs_sta->last_txrate_idx; - rcu_read_unlock(); - IWL_DEBUG_RATE("leave: %d\n", index); } @@ -829,114 +813,28 @@ static struct rate_control_ops rs_ops = { .free_sta = rs_free_sta, }; -int iwl3945_fill_rs_info(struct ieee80211_hw *hw, char *buf, u8 sta_id) -{ - struct ieee80211_local *local = hw_to_local(hw); - struct iwl3945_priv *priv = hw->priv; - struct iwl3945_rs_sta *rs_sta; - struct sta_info *sta; - unsigned long flags; - int count = 0, i; - u32 samples = 0, success = 0, good = 0; - unsigned long now = jiffies; - u32 max_time = 0; - - rcu_read_lock(); - - sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr); - if (!sta || !sta->rate_ctrl_priv) { - if (sta) - IWL_DEBUG_RATE("leave - no private rate data!\n"); - else - IWL_DEBUG_RATE("leave - no station!\n"); - rcu_read_unlock(); - return sprintf(buf, "station %d not found\n", sta_id); - } - - rs_sta = (void *)sta->rate_ctrl_priv; - spin_lock_irqsave(&rs_sta->lock, flags); - i = IWL_RATE_54M_INDEX; - while (1) { - u64 mask; - int j; - - count += - sprintf(&buf[count], " %2dMbs: ", iwl3945_rates[i].ieee / 2); - - mask = (1ULL << (IWL_RATE_MAX_WINDOW - 1)); - for (j = 0; j < IWL_RATE_MAX_WINDOW; j++, mask >>= 1) - buf[count++] = - (rs_sta->win[i].data & mask) ? '1' : '0'; - - samples += rs_sta->win[i].counter; - good += rs_sta->win[i].success_counter; - success += rs_sta->win[i].success_counter * - iwl3945_rates[i].ieee; - - if (rs_sta->win[i].stamp) { - int delta = - jiffies_to_msecs(now - rs_sta->win[i].stamp); - - if (delta > max_time) - max_time = delta; - - count += sprintf(&buf[count], "%5dms\n", delta); - } else - buf[count++] = '\n'; - - j = iwl3945_get_prev_ieee_rate(i); - if (j == i) - break; - i = j; - } - spin_unlock_irqrestore(&rs_sta->lock, flags); - rcu_read_unlock(); - - /* Display the average rate of all samples taken. - * - * NOTE: We multiple # of samples by 2 since the IEEE measurement - * added from iwl3945_rates is actually 2X the rate */ - if (samples) - count += sprintf( - &buf[count], - "\nAverage rate is %3d.%02dMbs over last %4dms\n" - "%3d%% success (%d good packets over %d tries)\n", - success / (2 * samples), (success * 5 / samples) % 10, - max_time, good * 100 / samples, good, samples); - else - count += sprintf(&buf[count], "\nAverage rate: 0Mbs\n"); - - return count; -} - void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id) { struct iwl3945_priv *priv = hw->priv; s32 rssi = 0; unsigned long flags; - struct ieee80211_local *local = hw_to_local(hw); struct iwl3945_rs_sta *rs_sta; - struct sta_info *sta; + struct ieee80211_sta *sta; + struct iwl3945_sta_priv *psta; IWL_DEBUG_RATE("enter\n"); - if (!local->rate_ctrl->ops->name || - strcmp(local->rate_ctrl->ops->name, RS_NAME)) { - IWL_WARNING("iwl-3945-rs not selected as rate control algo!\n"); - IWL_DEBUG_RATE("leave - mac80211 picked the wrong RC algo.\n"); - return; - } - rcu_read_lock(); - sta = sta_info_get(local, priv->stations[sta_id].sta.sta.addr); - if (!sta || !sta->rate_ctrl_priv) { + sta = ieee80211_find_sta(hw, priv->stations[sta_id].sta.sta.addr); + psta = (void *) sta->drv_priv; + if (!sta || !psta) { IWL_DEBUG_RATE("leave - no private rate data!\n"); rcu_read_unlock(); return; } - rs_sta = (void *)sta->rate_ctrl_priv; + rs_sta = psta->rs_sta; spin_lock_irqsave(&rs_sta->lock, flags); diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h index f085d330bdc..98b17ae6ef2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.h @@ -176,15 +176,6 @@ static inline u8 iwl3945_get_prev_ieee_rate(u8 rate_index) } /** - * iwl3945_fill_rs_info - Fill an output text buffer with the rate representation - * - * NOTE: This is provided as a quick mechanism for a user to visualize - * the performance of the rate control algorithm and is not meant to be - * parsed software. - */ -extern int iwl3945_fill_rs_info(struct ieee80211_hw *, char *buf, u8 sta_id); - -/** * iwl3945_rate_scale_init - Initialize the rate scale table based on assoc info * * The specific throughput table used is based on the type of network diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h index 2a4933b5fb6..bdd32475b99 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.h +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h @@ -73,6 +73,10 @@ extern struct pci_device_id iwl3945_hw_card_ids[]; extern int iwl3945_param_hwcrypto; extern int iwl3945_param_queues_num; +struct iwl3945_sta_priv { + struct iwl3945_rs_sta *rs_sta; +}; + enum iwl3945_antenna { IWL_ANTENNA_DIVERSITY, IWL_ANTENNA_MAIN, diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 8b57b390c8b..93944de923c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -35,8 +35,6 @@ #include <linux/workqueue.h> -#include "../net/mac80211/rate.h" - #include "iwl-dev.h" #include "iwl-sta.h" #include "iwl-core.h" @@ -169,9 +167,9 @@ struct iwl_lq_sta { }; static void rs_rate_scale_perform(struct iwl_priv *priv, - struct net_device *dev, struct ieee80211_hdr *hdr, - struct sta_info *sta); + struct ieee80211_sta *sta, + struct iwl_lq_sta *lq_sta); static void rs_fill_link_cmd(const struct iwl_priv *priv, struct iwl_lq_sta *lq_sta, u32 rate_n_flags); @@ -357,20 +355,20 @@ static u32 rs_tl_get_load(struct iwl_lq_sta *lq_data, u8 tid) static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, struct iwl_lq_sta *lq_data, u8 tid, - struct sta_info *sta) + struct ieee80211_sta *sta) { DECLARE_MAC_BUF(mac); if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { IWL_DEBUG_HT("Starting Tx agg: STA: %s tid: %d\n", - print_mac(mac, sta->sta.addr), tid); - ieee80211_start_tx_ba_session(priv->hw, sta->sta.addr, tid); + print_mac(mac, sta->addr), tid); + ieee80211_start_tx_ba_session(priv->hw, sta->addr, tid); } } static void rs_tl_turn_on_agg(struct iwl_priv *priv, u8 tid, struct iwl_lq_sta *lq_data, - struct sta_info *sta) + struct ieee80211_sta *sta) { if ((tid < TID_MAX_LOAD_COUNT)) rs_tl_turn_on_agg_for_tid(priv, lq_data, tid, sta); @@ -770,7 +768,8 @@ out: /* * mac80211 sends us Tx status */ -static void rs_tx_status(void *priv_rate, struct net_device *dev, +static void rs_tx_status(void *priv_r, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, struct sk_buff *skb) { int status; @@ -778,11 +777,9 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, int rs_index, index = 0; struct iwl_lq_sta *lq_sta; struct iwl_link_quality_cmd *table; - struct sta_info *sta; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct iwl_priv *priv = (struct iwl_priv *)priv_rate; - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_hw *hw = local_to_hw(local); + struct iwl_priv *priv = (struct iwl_priv *)priv_r; + struct ieee80211_hw *hw = priv->hw; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct iwl_rate_scale_data *window = NULL; struct iwl_rate_scale_data *search_win = NULL; @@ -808,15 +805,7 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, if (retries > 15) retries = 15; - rcu_read_lock(); - - sta = sta_info_get(local, hdr->addr1); - - if (!sta || !sta->rate_ctrl_priv) - goto out; - - - lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv; + lq_sta = (struct iwl_lq_sta *)priv_sta; if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && !lq_sta->ibss_sta_added) @@ -962,9 +951,8 @@ static void rs_tx_status(void *priv_rate, struct net_device *dev, } /* See if there's a better rate or modulation mode to try. */ - rs_rate_scale_perform(priv, dev, hdr, sta); + rs_rate_scale_perform(priv, hdr, sta, lq_sta); out: - rcu_read_unlock(); return; } @@ -1140,7 +1128,7 @@ static s32 rs_get_best_rate(struct iwl_priv *priv, static int rs_switch_to_mimo2(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta, struct ieee80211_conf *conf, - struct sta_info *sta, + struct ieee80211_sta *sta, struct iwl_scale_tbl_info *tbl, int index) { u16 rate_mask; @@ -1148,10 +1136,10 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, s8 is_green = lq_sta->is_green; if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) || - !sta->sta.ht_info.ht_supported) + !sta->ht_info.ht_supported) return -1; - if (((sta->sta.ht_info.cap & IEEE80211_HT_CAP_SM_PS) >> 2) + if (((sta->ht_info.cap & IEEE80211_HT_CAP_SM_PS) >> 2) == WLAN_HT_CAP_SM_PS_STATIC) return -1; @@ -1208,7 +1196,7 @@ static int rs_switch_to_mimo2(struct iwl_priv *priv, static int rs_switch_to_siso(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta, struct ieee80211_conf *conf, - struct sta_info *sta, + struct ieee80211_sta *sta, struct iwl_scale_tbl_info *tbl, int index) { u16 rate_mask; @@ -1216,7 +1204,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, s32 rate; if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) || - !sta->sta.ht_info.ht_supported) + !sta->ht_info.ht_supported) return -1; IWL_DEBUG_RATE("LQ: try to switch to SISO\n"); @@ -1268,7 +1256,7 @@ static int rs_switch_to_siso(struct iwl_priv *priv, static int rs_move_legacy_other(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta, struct ieee80211_conf *conf, - struct sta_info *sta, + struct ieee80211_sta *sta, int index) { struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); @@ -1376,7 +1364,7 @@ out: static int rs_move_siso_to_other(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta, struct ieee80211_conf *conf, - struct sta_info *sta, int index) + struct ieee80211_sta *sta, int index) { u8 is_green = lq_sta->is_green; struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); @@ -1487,7 +1475,7 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, static int rs_move_mimo_to_other(struct iwl_priv *priv, struct iwl_lq_sta *lq_sta, struct ieee80211_conf *conf, - struct sta_info *sta, int index) + struct ieee80211_sta *sta, int index) { s8 is_green = lq_sta->is_green; struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); @@ -1680,12 +1668,11 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta) * Do rate scaling and search for new modulation mode. */ static void rs_rate_scale_perform(struct iwl_priv *priv, - struct net_device *dev, struct ieee80211_hdr *hdr, - struct sta_info *sta) + struct ieee80211_sta *sta, + struct iwl_lq_sta *lq_sta) { - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_hw *hw = local_to_hw(local); + struct ieee80211_hw *hw = priv->hw; struct ieee80211_conf *conf = &hw->conf; int low = IWL_RATE_INVALID; int high = IWL_RATE_INVALID; @@ -1700,7 +1687,6 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, __le16 fc; u16 rate_mask; u8 update_lq = 0; - struct iwl_lq_sta *lq_sta; struct iwl_scale_tbl_info *tbl, *tbl1; u16 rate_scale_index_msk = 0; u32 rate; @@ -1721,11 +1707,10 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, return; } - if (!sta || !sta->rate_ctrl_priv) + if (!sta || !lq_sta) return; - lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv; - lq_sta->supp_rates = sta->sta.supp_rates[lq_sta->band]; + lq_sta->supp_rates = sta->supp_rates[lq_sta->band]; tid = rs_tl_add_packet(lq_sta, hdr); @@ -2064,9 +2049,9 @@ out: static void rs_initialize_lq(struct iwl_priv *priv, struct ieee80211_conf *conf, - struct sta_info *sta) + struct ieee80211_sta *sta, + struct iwl_lq_sta *lq_sta) { - struct iwl_lq_sta *lq_sta; struct iwl_scale_tbl_info *tbl; int rate_idx; int i; @@ -2075,10 +2060,9 @@ static void rs_initialize_lq(struct iwl_priv *priv, u8 active_tbl = 0; u8 valid_tx_ant; - if (!sta || !sta->rate_ctrl_priv) + if (!sta || !lq_sta) goto out; - lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv; i = lq_sta->last_txrate_idx; if ((lq_sta->lq.sta_id == 0xff) && @@ -2119,37 +2103,30 @@ static void rs_initialize_lq(struct iwl_priv *priv, return; } -static void rs_get_rate(void *priv_rate, struct net_device *dev, - struct ieee80211_supported_band *sband, - struct sk_buff *skb, - struct rate_selection *sel) +static void rs_get_rate(void *priv_r, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta, + struct sk_buff *skb, struct rate_selection *sel) { int i; - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); - struct ieee80211_conf *conf = &local->hw.conf; + struct iwl_priv *priv = (struct iwl_priv *)priv_r; + struct ieee80211_conf *conf = &priv->hw->conf; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; - struct sta_info *sta; __le16 fc; - struct iwl_priv *priv = (struct iwl_priv *)priv_rate; struct iwl_lq_sta *lq_sta; IWL_DEBUG_RATE_LIMIT("rate scale calculate new rate for skb\n"); - rcu_read_lock(); - - sta = sta_info_get(local, hdr->addr1); - /* Send management frames and broadcast/multicast data using lowest * rate. */ fc = hdr->frame_control; if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1) || - !sta || !sta->rate_ctrl_priv) { - sel->rate_idx = rate_lowest_index(local, sband, sta); - goto out; + !sta || !priv_sta) { + sel->rate_idx = rate_lowest_index(sband, sta); + return; } - lq_sta = (struct iwl_lq_sta *)sta->rate_ctrl_priv; + lq_sta = (struct iwl_lq_sta *)priv_sta; i = lq_sta->last_txrate_idx; if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) && @@ -2167,23 +2144,22 @@ static void rs_get_rate(void *priv_rate, struct net_device *dev, lq_sta->lq.sta_id = sta_id; lq_sta->lq.rs_table[0].rate_n_flags = 0; lq_sta->ibss_sta_added = 1; - rs_initialize_lq(priv, conf, sta); + rs_initialize_lq(priv, conf, sta, lq_sta); } } if ((i < 0) || (i > IWL_RATE_COUNT)) { - sel->rate_idx = rate_lowest_index(local, sband, sta); - goto out; + sel->rate_idx = rate_lowest_index(sband, sta); + return; } if (sband->band == IEEE80211_BAND_5GHZ) i -= IWL_FIRST_OFDM_RATE; sel->rate_idx = i; -out: - rcu_read_unlock(); } -static void *rs_alloc_sta(void *priv_rate, gfp_t gfp) +static void *rs_alloc_sta(void *priv_rate, struct ieee80211_sta *sta, + gfp_t gfp) { struct iwl_lq_sta *lq_sta; struct iwl_priv *priv; @@ -2206,20 +2182,16 @@ static void *rs_alloc_sta(void *priv_rate, gfp_t gfp) return lq_sta; } -static void rs_rate_init(void *priv_rate, void *priv_sta, - struct ieee80211_local *local, - struct sta_info *sta) +static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband, + struct ieee80211_sta *sta, void *priv_sta) { int i, j; - struct ieee80211_conf *conf = &local->hw.conf; - struct ieee80211_supported_band *sband; - struct iwl_priv *priv = (struct iwl_priv *)priv_rate; + struct iwl_priv *priv = (struct iwl_priv *)priv_r; + struct ieee80211_conf *conf = &priv->hw->conf; struct iwl_lq_sta *lq_sta = priv_sta; - sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; - lq_sta->flush_timer = 0; - lq_sta->supp_rates = sta->sta.supp_rates[sband->band]; + lq_sta->supp_rates = sta->supp_rates[sband->band]; for (j = 0; j < LQ_SIZE; j++) for (i = 0; i < IWL_RATE_COUNT; i++) rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); @@ -2232,17 +2204,17 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, lq_sta->ibss_sta_added = 0; if (priv->iw_mode == NL80211_IFTYPE_AP) { - u8 sta_id = iwl_find_station(priv, sta->sta.addr); + u8 sta_id = iwl_find_station(priv, sta->addr); DECLARE_MAC_BUF(mac); /* for IBSS the call are from tasklet */ IWL_DEBUG_RATE("LQ: ADD station %s\n", - print_mac(mac, sta->sta.addr)); + print_mac(mac, sta->addr)); if (sta_id == IWL_INVALID_STATION) { IWL_DEBUG_RATE("LQ: ADD station %s\n", - print_mac(mac, sta->sta.addr)); - sta_id = iwl_add_station_flags(priv, sta->sta.addr, + print_mac(mac, sta->addr)); + sta_id = iwl_add_station_flags(priv, sta->addr, 0, CMD_ASYNC, NULL); } if ((sta_id != IWL_INVALID_STATION)) { @@ -2256,11 +2228,11 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, /* Find highest tx rate supported by hardware and destination station */ lq_sta->last_txrate_idx = 3; for (i = 0; i < sband->n_bitrates; i++) - if (sta->sta.supp_rates[sband->band] & BIT(i)) + if (sta->supp_rates[sband->band] & BIT(i)) lq_sta->last_txrate_idx = i; /* For MODE_IEEE80211A, skip over cck rates in global rate table */ - if (local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) + if (sband->band == IEEE80211_BAND_5GHZ) lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; lq_sta->is_dup = 0; @@ -2301,7 +2273,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, lq_sta->tx_agg_tid_en = IWL_AGG_ALL_TID; lq_sta->drv = priv; - rs_initialize_lq(priv, conf, sta); + rs_initialize_lq(priv, conf, sta, lq_sta); } static void rs_fill_link_cmd(const struct iwl_priv *priv, @@ -2423,9 +2395,9 @@ static void rs_fill_link_cmd(const struct iwl_priv *priv, lq_cmd->agg_params.agg_time_limit = cpu_to_le16(4000); } -static void *rs_alloc(struct ieee80211_local *local) +static void *rs_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) { - return local->hw.priv; + return hw->priv; } /* rate scale requires free function to be implemented */ static void rs_free(void *priv_rate) @@ -2446,12 +2418,12 @@ static void rs_clear(void *priv_rate) #endif /* CONFIG_IWLWIFI_DEBUG */ } -static void rs_free_sta(void *priv_rate, void *priv_sta) +static void rs_free_sta(void *priv_r, struct ieee80211_sta *sta, + void *priv_sta) { struct iwl_lq_sta *lq_sta = priv_sta; - struct iwl_priv *priv; + struct iwl_priv *priv = priv_r; - priv = (struct iwl_priv *)priv_rate; IWL_DEBUG_RATE("enter\n"); kfree(lq_sta); IWL_DEBUG_RATE("leave\n"); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 27376276976..204abab7644 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2504,8 +2504,7 @@ static void iwl4965_post_associate(struct iwl_priv *priv) priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; - if (priv->current_ht_config.is_ht) - iwl_set_rxon_ht(priv, &priv->current_ht_config); + iwl_set_rxon_ht(priv, &priv->current_ht_config); iwl_set_rxon_chain(priv); priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); @@ -2568,8 +2567,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv) iwl_chain_noise_reset(priv); priv->start_calib = 1; - /* we have just associated, don't start scan too early */ - priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN; } static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf); @@ -2878,6 +2875,13 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co goto out; } + if (conf->flags & IEEE80211_CONF_PS) + ret = iwl_power_set_user_mode(priv, IWL_POWER_INDEX_3); + else + ret = iwl_power_set_user_mode(priv, IWL_POWER_MODE_CAM); + if (ret) + IWL_DEBUG_MAC80211("Error setting power level\n"); + IWL_DEBUG_MAC80211("TX Power old=%d new=%d\n", priv->tx_power_user_lmt, conf->power_level); @@ -3171,6 +3175,10 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, priv->power_data.dtim_period = bss_conf->dtim_period; priv->timestamp = bss_conf->timestamp; priv->assoc_capability = bss_conf->assoc_capability; + + /* we have just associated, don't start scan too early + * leave time for EAPOL exchange to complete + */ priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN_AFTER_ASSOC; mutex_lock(&priv->mutex); @@ -3189,9 +3197,9 @@ static void iwl4965_bss_info_changed(struct ieee80211_hw *hw, static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len) { - int ret; unsigned long flags; struct iwl_priv *priv = hw->priv; + int ret; IWL_DEBUG_MAC80211("enter\n"); @@ -3210,20 +3218,27 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t ssid_len) goto out_unlock; } - /* we don't schedule scan within next_scan_jiffies period */ + /* We don't schedule scan within next_scan_jiffies period. + * Avoid scanning during possible EAPOL exchange, return + * success immediately. + */ if (priv->next_scan_jiffies && time_after(priv->next_scan_jiffies, jiffies)) { IWL_DEBUG_SCAN("scan rejected: within next scan period\n"); - ret = -EAGAIN; + queue_work(priv->workqueue, &priv->scan_completed); + ret = 0; goto out_unlock; } + /* if we just finished scan ask for delay */ if (iwl_is_associated(priv) && priv->last_scan_jiffies && time_after(priv->last_scan_jiffies + IWL_DELAY_NEXT_SCAN, jiffies)) { IWL_DEBUG_SCAN("scan rejected: within previous scan period\n"); - ret = -EAGAIN; + queue_work(priv->workqueue, &priv->scan_completed); + ret = 0; goto out_unlock; } + if (ssid_len) { priv->one_direct_scan = 1; priv->direct_ssid_len = min_t(u8, ssid_len, IW_ESSID_MAX_SIZE); @@ -4228,13 +4243,13 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e pci_set_master(pdev); - err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); if (!err) - err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK); + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); if (err) { - err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (!err) - err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); /* both attempts failed: */ if (err) { printk(KERN_WARNING "%s: No suitable DMA available.\n", diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index d80184ee911..4c312c55f90 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -646,8 +646,14 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) struct iwl_rxon_cmd *rxon = &priv->staging_rxon; u32 val; - if (!ht_info->is_ht) + if (!ht_info->is_ht) { + rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED_MSK | + RXON_FLG_CHANNEL_MODE_PURE_40_MSK | + RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | + RXON_FLG_FAT_PROT_MSK | + RXON_FLG_HT_PROT_MSK); return; + } /* Set up channel bandwidth: 20 MHz only, or 20/40 mixed if fat ok */ if (iwl_is_fat_tx_allowed(priv, NULL)) @@ -697,8 +703,12 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info) } EXPORT_SYMBOL(iwl_set_rxon_ht); -/* - * Determine how many receiver/antenna chains to use. +#define IWL_NUM_RX_CHAINS_MULTIPLE 3 +#define IWL_NUM_RX_CHAINS_SINGLE 2 +#define IWL_NUM_IDLE_CHAINS_DUAL 2 +#define IWL_NUM_IDLE_CHAINS_SINGLE 1 + +/* Determine how many receiver/antenna chains to use. * More provides better reception via diversity. Fewer saves power. * MIMO (dual stream) requires at least 2, but works better with 3. * This does not determine *which* chains to use, just how many. @@ -711,9 +721,9 @@ static int iwl_get_active_rx_chain_count(struct iwl_priv *priv) /* # of Rx chains to use when expecting MIMO. */ if (is_single || (!is_cam && (priv->current_ht_config.sm_ps == WLAN_HT_CAP_SM_PS_STATIC))) - return 2; + return IWL_NUM_RX_CHAINS_SINGLE; else - return 3; + return IWL_NUM_RX_CHAINS_MULTIPLE; } static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) @@ -724,10 +734,11 @@ static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt) switch (priv->current_ht_config.sm_ps) { case WLAN_HT_CAP_SM_PS_STATIC: case WLAN_HT_CAP_SM_PS_DYNAMIC: - idle_cnt = (is_cam) ? 2 : 1; + idle_cnt = (is_cam) ? IWL_NUM_IDLE_CHAINS_DUAL : + IWL_NUM_IDLE_CHAINS_SINGLE; break; case WLAN_HT_CAP_SM_PS_DISABLED: - idle_cnt = (is_cam) ? active_cnt : 1; + idle_cnt = (is_cam) ? active_cnt : IWL_NUM_IDLE_CHAINS_SINGLE; break; case WLAN_HT_CAP_SM_PS_INVALID: default: @@ -796,7 +807,7 @@ void iwl_set_rxon_chain(struct iwl_priv *priv) priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain); - if (!is_single && (active_rx_cnt >= 2) && is_cam) + if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam) priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; else priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index 52629fbd835..662edf4f8d2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -64,7 +64,7 @@ #define CSR_BASE (0x000) #define CSR_HW_IF_CONFIG_REG (CSR_BASE+0x000) /* hardware interface config */ -#define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ +#define CSR_INT_COALESCING (CSR_BASE+0x004) /* accum ints, 32-usec units */ #define CSR_INT (CSR_BASE+0x008) /* host interrupt status/ack */ #define CSR_INT_MASK (CSR_BASE+0x00c) /* host interrupt enable */ #define CSR_FH_INT_STATUS (CSR_BASE+0x010) /* busmaster int status/ack*/ diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index cd11c0ca299..a72efdf6d1d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -247,8 +247,8 @@ #define FH_RCSR_CHNL0_RX_CONFIG_RBDBC_SIZE_MSK (0x00F00000) /* bits 20-23 */ #define FH_RCSR_CHNL0_RX_CONFIG_DMA_CHNL_EN_MSK (0xC0000000) /* bits 30-31*/ -#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT (20) -#define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_BITSHIFT (4) +#define FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS (20) +#define FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS (4) #define RX_RB_TIMEOUT (0x10) #define FH_RCSR_RX_CONFIG_CHNL_EN_PAUSE_VAL (0x00000000) @@ -260,8 +260,9 @@ #define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_12K (0x00020000) #define FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_16K (0x00030000) -#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000) -#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000) +#define FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY (0x00000004) +#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_NO_INT_VAL (0x00000000) +#define FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL (0x00001000) /** diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 38b2946b1d8..7cde9d76ff5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c @@ -376,7 +376,9 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) { int ret; unsigned long flags; - unsigned int rb_size; + u32 rb_size; + const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */ + const u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT why this stalls RX */ spin_lock_irqsave(&priv->lock, flags); ret = iwl_grab_nic_access(priv); @@ -398,26 +400,32 @@ int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) /* Tell device where to find RBD circular buffer in DRAM */ iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, - rxq->dma_addr >> 8); + (u32)(rxq->dma_addr >> 8)); /* Tell device where in DRAM to update its Rx status */ iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, (priv->shared_phys + priv->rb_closed_offset) >> 4); - /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ + /* Enable Rx DMA + * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set becuase of HW bug in + * the credit mechanism in 5000 HW RX FIFO + * Direct rx interrupts to hosts + * Rx buffer size 4 or 8k + * RB timeout 0x10 + * 256 RBDs + */ iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | + FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | - rb_size | - /* 0x10 << 4 | */ - (RX_QUEUE_SIZE_LOG << - FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); - - /* - * iwl_write32(priv,CSR_INT_COAL_REG,0); - */ + rb_size| + (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)| + (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); iwl_release_nic_access(priv); + + iwl_write32(priv, CSR_INT_COALESCING, 0x40); + spin_unlock_irqrestore(&priv->lock, flags); return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 09c264be049..bf855c35b0c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -463,11 +463,6 @@ void iwl_init_scan_params(struct iwl_priv *priv) int iwl_scan_initiate(struct iwl_priv *priv) { - if (priv->iw_mode == NL80211_IFTYPE_AP) { - IWL_ERROR("APs don't scan.\n"); - return 0; - } - if (!iwl_is_ready_rf(priv)) { IWL_DEBUG_SCAN("Aborting scan due to not ready.\n"); return -EIO; @@ -479,8 +474,7 @@ int iwl_scan_initiate(struct iwl_priv *priv) } if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) { - IWL_DEBUG_SCAN("Scan request while abort pending. " - "Queuing.\n"); + IWL_DEBUG_SCAN("Scan request while abort pending\n"); return -EAGAIN; } diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index e9feca4033f..907a53ebc6e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c @@ -1200,10 +1200,9 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) /* If a Tx command is being handled and it isn't in the actual * command queue then there a command routing bug has been introduced * in the queue management code. */ - if (txq_id != IWL_CMD_QUEUE_NUM) - IWL_ERROR("Error wrong command queue %d command id 0x%X\n", - txq_id, pkt->hdr.cmd); - BUG_ON(txq_id != IWL_CMD_QUEUE_NUM); + if (WARN(txq_id != IWL_CMD_QUEUE_NUM, + "wrong command queue %d, command id 0x%X\n", txq_id, pkt->hdr.cmd)) + return; cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 62b26befddc..d15a2c99795 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -7370,15 +7370,6 @@ static ssize_t show_temperature(struct device *d, static DEVICE_ATTR(temperature, S_IRUGO, show_temperature, NULL); -static ssize_t show_rs_window(struct device *d, - struct device_attribute *attr, - char *buf) -{ - struct iwl3945_priv *priv = d->driver_data; - return iwl3945_fill_rs_info(priv->hw, buf, IWL_AP_ID); -} -static DEVICE_ATTR(rs_window, S_IRUGO, show_rs_window, NULL); - static ssize_t show_tx_power(struct device *d, struct device_attribute *attr, char *buf) { @@ -7840,7 +7831,6 @@ static struct attribute *iwl3945_sysfs_entries[] = { #endif &dev_attr_power_level.attr, &dev_attr_retry_rate.attr, - &dev_attr_rs_window.attr, &dev_attr_statistics.attr, &dev_attr_status.attr, &dev_attr_temperature.attr, @@ -7908,6 +7898,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e SET_IEEE80211_DEV(hw, &pdev->dev); hw->rate_control_algorithm = "iwl-3945-rs"; + hw->sta_data_size = sizeof(struct iwl3945_sta_priv); IWL_DEBUG_INFO("*** LOAD DRIVER ***\n"); priv = hw->priv; diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index aee19fa844e..a912fb68c09 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c @@ -1949,7 +1949,7 @@ int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1, cmd.hdr.size = cpu_to_le16(sizeof(cmd)); cmd.action = cpu_to_le16(CMD_ACT_SET); cmd.enable = !!enable; - cmd.usesnr = !!enable; + cmd.usesnr = !!usesnr; cmd.P0 = p0; cmd.P1 = p1; cmd.P2 = p2; diff --git a/drivers/net/wireless/libertas/cmd.h b/drivers/net/wireless/libertas/cmd.h index d002160f597..36be4c9703e 100644 --- a/drivers/net/wireless/libertas/cmd.h +++ b/drivers/net/wireless/libertas/cmd.h @@ -32,6 +32,12 @@ int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0, int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1, int8_t p2, int usesnr); +int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0, + int8_t p1, int8_t p2); + +int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1, + int8_t p2, int usesnr); + int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra, struct cmd_header *resp); diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h index 58d11a35e61..076a636e8f6 100644 --- a/drivers/net/wireless/libertas/defs.h +++ b/drivers/net/wireless/libertas/defs.h @@ -189,7 +189,6 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in #define MRVDRV_CMD_UPLD_RDY 0x0008 #define MRVDRV_CARDEVENT 0x0010 - /* Automatic TX control default levels */ #define POW_ADAPT_DEFAULT_P0 13 #define POW_ADAPT_DEFAULT_P1 15 diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h index acb889e2590..f6f3753da30 100644 --- a/drivers/net/wireless/libertas/dev.h +++ b/drivers/net/wireless/libertas/dev.h @@ -58,6 +58,7 @@ struct lbs_802_11_security { u8 WPA2enabled; u8 wep_enabled; u8 auth_mode; + u32 key_mgmt; }; /** Current Basic Service Set State Structure */ diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index 11297dcf9fc..82c3e5a50ea 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c @@ -1025,6 +1025,18 @@ static int lbs_set_rate(struct net_device *dev, struct iw_request_info *info, new_rate); goto out; } + if (priv->fwrelease < 0x09000000) { + ret = lbs_set_power_adapt_cfg(priv, 0, + POW_ADAPT_DEFAULT_P0, + POW_ADAPT_DEFAULT_P1, + POW_ADAPT_DEFAULT_P2); + if (ret) + goto out; + } + ret = lbs_set_tpc_cfg(priv, 0, TPC_DEFAULT_P0, TPC_DEFAULT_P1, + TPC_DEFAULT_P2, 1); + if (ret) + goto out; } /* Try the newer command first (Firmware Spec 5.1 and above) */ @@ -1598,8 +1610,20 @@ static int lbs_set_encodeext(struct net_device *dev, } out: - if (ret == 0) { /* key installation is time critical: postpone not! */ - lbs_do_association_work(priv); + if (ret == 0) { + /* 802.1x and WPA rekeying must happen as quickly as possible, + * especially during the 4-way handshake; thus if in + * infrastructure mode, and either (a) 802.1x is enabled or + * (b) WPA is being used, set the key right away. + */ + if (assoc_req->mode == IW_MODE_INFRA && + ((assoc_req->secinfo.key_mgmt & IW_AUTH_KEY_MGMT_802_1X) || + (assoc_req->secinfo.key_mgmt & IW_AUTH_KEY_MGMT_PSK) || + assoc_req->secinfo.WPAenabled || + assoc_req->secinfo.WPA2enabled)) { + lbs_do_association_work(priv); + } else + lbs_postpone_association_work(priv); } else { lbs_cancel_association_work(priv); } @@ -1707,13 +1731,17 @@ static int lbs_set_auth(struct net_device *dev, case IW_AUTH_TKIP_COUNTERMEASURES: case IW_AUTH_CIPHER_PAIRWISE: case IW_AUTH_CIPHER_GROUP: - case IW_AUTH_KEY_MGMT: case IW_AUTH_DROP_UNENCRYPTED: /* * libertas does not use these parameters */ break; + case IW_AUTH_KEY_MGMT: + assoc_req->secinfo.key_mgmt = dwrq->value; + updated = 1; + break; + case IW_AUTH_WPA_VERSION: if (dwrq->value & IW_AUTH_WPA_VERSION_DISABLED) { assoc_req->secinfo.WPAenabled = 0; @@ -1793,6 +1821,10 @@ static int lbs_get_auth(struct net_device *dev, lbs_deb_enter(LBS_DEB_WEXT); switch (dwrq->flags & IW_AUTH_INDEX) { + case IW_AUTH_KEY_MGMT: + dwrq->value = priv->secinfo.key_mgmt; + break; + case IW_AUTH_WPA_VERSION: dwrq->value = 0; if (priv->secinfo.WPAenabled) diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c index f479c1af678..25bae7933aa 100644 --- a/drivers/net/wireless/netwave_cs.c +++ b/drivers/net/wireless/netwave_cs.c @@ -398,7 +398,7 @@ static int netwave_probe(struct pcmcia_device *link) link->io.IOAddrLines = 5; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = &netwave_interrupt; diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 9a2fcc0163d..50904771f29 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -5291,7 +5291,7 @@ static int orinoco_ioctl_getrid(struct net_device *dev, /* Trigger a scan (look for other cells in the vicinity) */ static int orinoco_ioctl_setscan(struct net_device *dev, struct iw_request_info *info, - struct iw_param *srq, + struct iw_point *srq, char *extra) { struct orinoco_private *priv = netdev_priv(dev); diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c index 1ccf5a40cf0..9eaa252c243 100644 --- a/drivers/net/wireless/orinoco_cs.c +++ b/drivers/net/wireless/orinoco_cs.c @@ -121,7 +121,7 @@ orinoco_cs_probe(struct pcmcia_device *link) link->priv = dev; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = orinoco_interrupt; link->irq.Instance = dev; diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c index bac58ed03e5..de5e8f44b20 100644 --- a/drivers/net/wireless/p54/p54common.c +++ b/drivers/net/wireless/p54/p54common.c @@ -149,7 +149,8 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) u32 code = le32_to_cpu(bootrec->code); switch (code) { case BR_CODE_COMPONENT_ID: - priv->fw_interface = be32_to_cpup(bootrec->data); + priv->fw_interface = be32_to_cpup((__be32 *) + bootrec->data); switch (priv->fw_interface) { case FW_FMAC: printk(KERN_INFO "p54: FreeMAC firmware\n"); @@ -181,9 +182,8 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) priv->rx_end = le32_to_cpu(desc->rx_end) - 0x3500; priv->headroom = desc->headroom; priv->tailroom = desc->tailroom; - if (bootrec->len == 11) - priv->rx_mtu = (size_t) le16_to_cpu( - (__le16)bootrec->data[10]); + if (le32_to_cpu(bootrec->len) == 11) + priv->rx_mtu = le16_to_cpu(bootrec->rx_mtu); else priv->rx_mtu = (size_t) 0x620 - priv->tx_hdr_len; @@ -306,11 +306,11 @@ static int p54_convert_rev1(struct ieee80211_hw *dev, return 0; } -const char* p54_rf_chips[] = { "NULL", "Indigo?", "Duette", +static const char *p54_rf_chips[] = { "NULL", "Indigo?", "Duette", "Frisbee", "Xbow", "Longbow" }; static int p54_init_xbow_synth(struct ieee80211_hw *dev); -int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) +static int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) { struct p54_common *priv = dev->priv; struct eeprom_pda_wrap *wrap = NULL; @@ -617,7 +617,7 @@ static void p54_rx_eeprom_readback(struct ieee80211_hw *dev, if (!priv->eeprom) return ; - memcpy(priv->eeprom, eeprom->data, eeprom->len); + memcpy(priv->eeprom, eeprom->data, le16_to_cpu(eeprom->len)); complete(&priv->eeprom_comp); } @@ -777,8 +777,9 @@ int p54_read_eeprom(struct ieee80211_hw *dev) hdr->len = cpu_to_le16(blocksize + sizeof(*eeprom_hdr)); eeprom_hdr->offset = cpu_to_le16(offset); eeprom_hdr->len = cpu_to_le16(blocksize); - p54_assign_address(dev, NULL, hdr, hdr->len + sizeof(*hdr)); - priv->tx(dev, hdr, hdr->len + sizeof(*hdr), 0); + p54_assign_address(dev, NULL, hdr, le16_to_cpu(hdr->len) + + sizeof(*hdr)); + priv->tx(dev, hdr, le16_to_cpu(hdr->len) + sizeof(*hdr), 0); if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) { printk(KERN_ERR "%s: device does not respond!\n", @@ -1247,18 +1248,20 @@ static void p54_configure_filter(struct ieee80211_hw *dev, if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { if (*total_flags & FIF_BCN_PRBRESP_PROMISC) - p54_set_filter(dev, priv->filter_type, NULL); + p54_set_filter(dev, le16_to_cpu(priv->filter_type), + NULL); else - p54_set_filter(dev, priv->filter_type, priv->bssid); + p54_set_filter(dev, le16_to_cpu(priv->filter_type), + priv->bssid); } if (changed_flags & FIF_PROMISC_IN_BSS) { if (*total_flags & FIF_PROMISC_IN_BSS) - p54_set_filter(dev, priv->filter_type | - cpu_to_le16(0x8), NULL); + p54_set_filter(dev, le16_to_cpu(priv->filter_type) | + 0x8, NULL); else - p54_set_filter(dev, priv->filter_type & - ~cpu_to_le16(0x8), priv->bssid); + p54_set_filter(dev, le16_to_cpu(priv->filter_type) & + ~0x8, priv->bssid); } } diff --git a/drivers/net/wireless/p54/p54common.h b/drivers/net/wireless/p54/p54common.h index 4da736c789a..2fa994cfcfe 100644 --- a/drivers/net/wireless/p54/p54common.h +++ b/drivers/net/wireless/p54/p54common.h @@ -18,7 +18,8 @@ struct bootrec { __le32 code; __le32 len; - u32 data[0]; + u32 data[10]; + __le16 rx_mtu; } __attribute__((packed)); struct bootrec_exp_if { diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 7444f372977..1912f5e9a0a 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c @@ -218,17 +218,17 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data, usb_submit_urb(data_urb, GFP_ATOMIC); } -__le32 p54u_lm87_chksum(const u32 *data, size_t length) +static __le32 p54u_lm87_chksum(const u32 *data, size_t length) { - __le32 chk = 0; + u32 chk = 0; length >>= 2; while (length--) { - chk ^= cpu_to_le32(*data++); + chk ^= *data++; chk = (chk >> 5) ^ (chk << 3); } - return chk; + return cpu_to_le32(chk); } static void p54u_tx_lm87(struct ieee80211_hw *dev, diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 963960dc30f..44da0d19b5c 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c @@ -325,7 +325,7 @@ static int ray_probe(struct pcmcia_device *p_dev) p_dev->io.IOAddrLines = 5; /* Interrupt setup. For PCMCIA, driver takes what's given */ - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; p_dev->irq.Handler = &ray_interrupt; diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 00e965b9da7..2b414899dfa 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c @@ -1627,7 +1627,6 @@ static int rndis_iw_set_encode_ext(struct net_device *dev, static int rndis_iw_set_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - struct iw_param *param = &wrqu->param; struct usbnet *usbdev = dev->priv; union iwreq_data evt; int ret = -EINVAL; @@ -1635,7 +1634,7 @@ static int rndis_iw_set_scan(struct net_device *dev, devdbg(usbdev, "SIOCSIWSCAN"); - if (param->flags == 0) { + if (wrqu->data.flags == 0) { tmp = ccpu2(1); ret = rndis_set_oid(usbdev, OID_802_11_BSSID_LIST_SCAN, &tmp, sizeof(tmp)); diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index b686dc45483..f839ce044af 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -1,5 +1,5 @@ -config RT2X00 - tristate "Ralink driver support" +menuconfig RT2X00 + bool "Ralink driver support" depends on MAC80211 && WLAN_80211 && EXPERIMENTAL ---help--- This will enable the experimental support for the Ralink drivers, @@ -17,39 +17,6 @@ config RT2X00 if RT2X00 -config RT2X00_LIB - tristate - -config RT2X00_LIB_PCI - tristate - select RT2X00_LIB - -config RT2X00_LIB_USB - tristate - select RT2X00_LIB - -config RT2X00_LIB_FIRMWARE - boolean - depends on RT2X00_LIB - select FW_LOADER - -config RT2X00_LIB_CRYPTO - boolean - depends on RT2X00_LIB - -config RT2X00_LIB_RFKILL - boolean - depends on RT2X00_LIB - depends on RFKILL - default y - -config RT2X00_LIB_LEDS - boolean - depends on RT2X00_LIB - depends on NEW_LEDS - depends on LEDS_CLASS - default y - config RT2400PCI tristate "Ralink rt2400 (PCI/PCMCIA) support" depends on PCI @@ -109,6 +76,38 @@ config RT73USB When compiled as a module, this driver will be called "rt73usb.ko". +config RT2X00_LIB_PCI + tristate + select RT2X00_LIB + +config RT2X00_LIB_USB + tristate + select RT2X00_LIB + +config RT2X00_LIB + tristate + +config RT2X00_LIB_FIRMWARE + boolean + select FW_LOADER + +config RT2X00_LIB_CRYPTO + boolean + +config RT2X00_LIB_RFKILL + boolean + default y if (RT2X00_LIB=y && RFKILL=y) || (RT2X00_LIB=m && RFKILL!=n) + +comment "rt2x00 rfkill support disabled due to modularized RFKILL and built-in rt2x00" + depends on RT2X00_LIB=y && RFKILL=m + +config RT2X00_LIB_LEDS + boolean + default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n) + +comment "rt2x00 leds support disabled due to modularized LEDS_CLASS and built-in rt2x00" + depends on RT2X00_LIB=y && LEDS_CLASS=m + config RT2X00_LIB_DEBUGFS bool "Ralink debugfs support" depends on RT2X00_LIB && MAC80211_DEBUGFS diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index 485c40de5cc..2c6cc5c374f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -543,7 +543,8 @@ int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, * provided but key 0 is not, then the key is not found * by the hardware during RX). */ - key->hw_key_idx = 0; + if (cmd == SET_KEY) + key->hw_key_idx = 0; if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) set_key = rt2x00dev->ops->lib->config_pairwise_key; diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 2c36b91ff4c..a461620b489 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -381,7 +381,7 @@ static int rt61pci_config_shared_key(struct rt2x00_dev *rt2x00dev, if (reg && reg == mask) return -ENOSPC; - key->hw_key_idx += reg ? (ffz(reg) - 1) : 0; + key->hw_key_idx += reg ? ffz(reg) : 0; /* * Upload key to hardware @@ -477,7 +477,7 @@ static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, return -ENOSPC; } - key->hw_key_idx += reg ? (ffz(reg) - 1) : 0; + key->hw_key_idx += reg ? ffz(reg) : 0; /* * Upload key to hardware diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 27dde3e3460..934f8e03c5a 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -393,7 +393,7 @@ static int rt73usb_config_shared_key(struct rt2x00_dev *rt2x00dev, if (reg && reg == mask) return -ENOSPC; - key->hw_key_idx += reg ? (ffz(reg) - 1) : 0; + key->hw_key_idx += reg ? ffz(reg) : 0; /* * Upload key to hardware @@ -494,7 +494,7 @@ static int rt73usb_config_pairwise_key(struct rt2x00_dev *rt2x00dev, return -ENOSPC; } - key->hw_key_idx += reg ? (ffz(reg) - 1) : 0; + key->hw_key_idx += reg ? ffz(reg) : 0; /* * Upload key to hardware diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c index e368759d1d8..67b26d3c3cd 100644 --- a/drivers/net/wireless/spectrum_cs.c +++ b/drivers/net/wireless/spectrum_cs.c @@ -195,7 +195,7 @@ spectrum_cs_probe(struct pcmcia_device *link) link->priv = dev; /* Interrupt setup */ - link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; link->irq.IRQInfo1 = IRQ_LEVEL_ID; link->irq.Handler = orinoco_interrupt; link->irq.Instance = dev; diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c index 00a3559e5aa..b5de38a9b79 100644 --- a/drivers/net/wireless/wavelan_cs.c +++ b/drivers/net/wireless/wavelan_cs.c @@ -4496,7 +4496,7 @@ wavelan_probe(struct pcmcia_device *p_dev) p_dev->io.IOAddrLines = 3; /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; p_dev->irq.Handler = wavelan_interrupt; diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index b6d4e04b8ab..74a5ad2f122 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -1917,7 +1917,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev) p_dev->io.IOAddrLines = 5; /* Interrupt setup */ - p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; + p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT; p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID; p_dev->irq.Handler = wl3501_interrupt; diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index a3da014f928..fe1867b25ff 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -611,7 +611,7 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, q = &zd_hw_mac(hw)->ack_wait_queue; spin_lock_irqsave(&q->lock, flags); - for (skb = q->next; skb != (struct sk_buff *)q; skb = skb->next) { + skb_queue_walk(q, skb) { struct ieee80211_hdr *tx_hdr; tx_hdr = (struct ieee80211_hdr *)skb->data; diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c index da8b7433e3a..a60ae86bd5c 100644 --- a/drivers/net/wireless/zd1211rw/zd_usb.c +++ b/drivers/net/wireless/zd1211rw/zd_usb.c @@ -58,6 +58,7 @@ static struct usb_device_id usb_ids[] = { { USB_DEVICE(0x0586, 0x3407), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x129b, 0x1666), .driver_info = DEVICE_ZD1211 }, { USB_DEVICE(0x157e, 0x300a), .driver_info = DEVICE_ZD1211 }, + { USB_DEVICE(0x0105, 0x145f), .driver_info = DEVICE_ZD1211 }, /* ZD1211B */ { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, { USB_DEVICE(0x157e, 0x300d), .driver_info = DEVICE_ZD1211B }, diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index 40337a06c18..146ca9cd156 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c @@ -320,15 +320,15 @@ static int disable_slot(struct hotplug_slot *slot) return -ENODEV; } + /* remove the device from the pci core */ + pci_remove_bus_device(dev); + /* queue work item to blow away this sysfs entry and other * parts. */ INIT_WORK(&dslot->remove_work, remove_slot_worker); queue_work(dummyphp_wq, &dslot->remove_work); - /* blow away this sysfs entry and other parts. */ - remove_slot(dslot); - pci_dev_put(dev); } return 0; diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index ab31f5ba665..9d934ddee95 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -258,7 +258,7 @@ static int pcie_poll_cmd(struct controller *ctrl) return 1; } } - while (timeout > 1000) { + while (timeout > 0) { msleep(10); timeout -= 10; if (!pciehp_readw(ctrl, SLOTSTATUS, &slot_status)) { diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 8d0e60ac849..c3edcdc08e7 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -2348,11 +2348,34 @@ static void __init iommu_exit_mempool(void) } +static int blacklist_iommu(const struct dmi_system_id *id) +{ + printk(KERN_INFO "%s detected; disabling IOMMU\n", + id->ident); + dmar_disabled = 1; + return 0; +} + +static struct dmi_system_id __initdata intel_iommu_dmi_table[] = { + { /* Some DG33BU BIOS revisions advertised non-existent VT-d */ + .callback = blacklist_iommu, + .ident = "Intel DG33BU", + { DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "DG33BU"), + } + }, + { } +}; + + void __init detect_intel_iommu(void) { if (swiotlb || no_iommu || iommu_detected || dmar_disabled) return; if (early_dmar_detect()) { + dmi_check_system(intel_iommu_dmi_table); + if (dmar_disabled) + return; iommu_detected = 1; } } diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 9a7c9e1408a..851f5b83cdb 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -527,7 +527,7 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) */ pci_read_config_dword(child_dev, child_pos + PCI_EXP_DEVCAP, ®32); - if (!(reg32 & PCI_EXP_DEVCAP_RBER && !aspm_force)) { + if (!(reg32 & PCI_EXP_DEVCAP_RBER) && !aspm_force) { printk("Pre-1.1 PCIe device detected, " "disable ASPM for %s. It can be enabled forcedly" " with 'pcie_aspm=force'\n", pci_name(pdev)); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index cce2f4cb1fb..36698e57b97 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -304,6 +304,9 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, } else { res->start = l64; res->end = l64 + sz64; + printk(KERN_DEBUG "PCI: %s reg %x 64bit mmio: [%llx, %llx]\n", + pci_name(dev), pos, (unsigned long long)res->start, + (unsigned long long)res->end); } } else { sz = pci_size(l, sz, mask); @@ -313,6 +316,9 @@ static int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type, res->start = l; res->end = l + sz; + printk(KERN_DEBUG "PCI: %s reg %x %s: [%llx, %llx]\n", pci_name(dev), + pos, (res->flags & IORESOURCE_IO) ? "io port":"32bit mmio", + (unsigned long long)res->start, (unsigned long long)res->end); } out: @@ -383,7 +389,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) res->start = base; if (!res->end) res->end = limit + 0xfff; - printk(KERN_INFO "PCI: bridge %s io port: [%llx, %llx]\n", pci_name(dev), res->start, res->end); + printk(KERN_DEBUG "PCI: bridge %s io port: [%llx, %llx]\n", + pci_name(dev), (unsigned long long) res->start, + (unsigned long long) res->end); } res = child->resource[1]; @@ -395,7 +403,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM; res->start = base; res->end = limit + 0xfffff; - printk(KERN_INFO "PCI: bridge %s 32bit mmio: [%llx, %llx]\n", pci_name(dev), res->start, res->end); + printk(KERN_DEBUG "PCI: bridge %s 32bit mmio: [%llx, %llx]\n", + pci_name(dev), (unsigned long long) res->start, + (unsigned long long) res->end); } res = child->resource[2]; @@ -431,7 +441,9 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM | IORESOURCE_PREFETCH; res->start = base; res->end = limit + 0xfffff; - printk(KERN_INFO "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n", pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64)?"64":"32",res->start, res->end); + printk(KERN_DEBUG "PCI: bridge %s %sbit mmio pref: [%llx, %llx]\n", + pci_name(dev), (res->flags & PCI_PREF_RANGE_TYPE_64) ? "64" : "32", + (unsigned long long) res->start, (unsigned long long) res->end); } } diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 3b3b5f17879..4edfc4731bd 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -162,7 +162,7 @@ EXPORT_SYMBOL(pci_find_slot); * time. */ struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, - const struct pci_dev *from) + struct pci_dev *from) { struct pci_dev *pdev; @@ -263,7 +263,7 @@ static int match_pci_dev_by_id(struct device *dev, void *data) * this file. */ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id, - const struct pci_dev *from) + struct pci_dev *from) { struct device *dev; struct device *dev_start = NULL; @@ -303,7 +303,7 @@ static struct pci_dev *pci_get_dev_by_id(const struct pci_device_id *id, */ struct pci_dev *pci_get_subsys(unsigned int vendor, unsigned int device, unsigned int ss_vendor, unsigned int ss_device, - const struct pci_dev *from) + struct pci_dev *from) { struct pci_dev *pdev; struct pci_device_id *id; diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 1aad599816f..3abbfad9dda 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -540,7 +540,11 @@ static void pci_bus_dump_res(struct pci_bus *bus) if (!res) continue; - printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n", bus->number, i, (res->flags & IORESOURCE_IO)? "io port":"mmio", res->start, res->end); + printk(KERN_INFO "bus: %02x index %x %s: [%llx, %llx]\n", + bus->number, i, + (res->flags & IORESOURCE_IO) ? "io port" : "mmio", + (unsigned long long) res->start, + (unsigned long long) res->end); } } diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 4174d9656e3..34c83d3ca0f 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -427,6 +427,18 @@ static int pcmcia_device_probe(struct device * dev) p_drv = to_pcmcia_drv(dev->driver); s = p_dev->socket; + /* The PCMCIA code passes the match data in via dev->driver_data + * which is an ugly hack. Once the driver probe is called it may + * and often will overwrite the match data so we must save it first + * + * handle pseudo multifunction devices: + * there are at most two pseudo multifunction devices. + * if we're matching against the first, schedule a + * call which will then check whether there are two + * pseudo devices, and if not, add the second one. + */ + did = p_dev->dev.driver_data; + ds_dbg(1, "trying to bind %s to %s\n", p_dev->dev.bus_id, p_drv->drv.name); @@ -455,21 +467,14 @@ static int pcmcia_device_probe(struct device * dev) goto put_module; } - /* handle pseudo multifunction devices: - * there are at most two pseudo multifunction devices. - * if we're matching against the first, schedule a - * call which will then check whether there are two - * pseudo devices, and if not, add the second one. - */ - did = p_dev->dev.driver_data; if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) pcmcia_add_device_later(p_dev->socket, 0); - put_module: +put_module: if (ret) module_put(p_drv->owner); - put_dev: +put_dev: if (ret) put_device(dev); return (ret); diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index c48f3f69bda..da397215322 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -748,7 +748,9 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops add_timer(&skt->poll_timer); - device_create_file(&skt->socket.dev, &dev_attr_status); + ret = device_create_file(&skt->socket.dev, &dev_attr_status); + if (ret) + goto out_err_8; } dev_set_drvdata(dev, sinfo); @@ -758,6 +760,8 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops do { skt = &sinfo->skt[i]; + device_remove_file(&skt->socket.dev, &dev_attr_status); + out_err_8: del_timer_sync(&skt->poll_timer); pcmcia_unregister_socket(&skt->socket); diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index e0ce65fca4e..9a50f245774 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -113,7 +113,8 @@ ccwgroup_release (struct device *dev) for (i = 0; i < gdev->count; i++) { if (gdev->cdev[i]) { - dev_set_drvdata(&gdev->cdev[i]->dev, NULL); + if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) + dev_set_drvdata(&gdev->cdev[i]->dev, NULL); put_device(&gdev->cdev[i]->dev); } } @@ -296,6 +297,7 @@ error: if (dev_get_drvdata(&gdev->cdev[i]->dev) == gdev) dev_set_drvdata(&gdev->cdev[i]->dev, NULL); put_device(&gdev->cdev[i]->dev); + gdev->cdev[i] = NULL; } mutex_unlock(&gdev->reg_mutex); put_device(&gdev->dev); diff --git a/drivers/s390/cio/chp.c b/drivers/s390/cio/chp.c index db00b059173..f1216cf6fa8 100644 --- a/drivers/s390/cio/chp.c +++ b/drivers/s390/cio/chp.c @@ -423,7 +423,7 @@ int chp_new(struct chp_id chpid) ret = sysfs_create_group(&chp->dev.kobj, &chp_attr_group); if (ret) { device_unregister(&chp->dev); - goto out_free; + goto out; } mutex_lock(&channel_subsystems[chpid.cssid]->mutex); if (channel_subsystems[chpid.cssid]->cm_enabled) { @@ -432,14 +432,15 @@ int chp_new(struct chp_id chpid) sysfs_remove_group(&chp->dev.kobj, &chp_attr_group); device_unregister(&chp->dev); mutex_unlock(&channel_subsystems[chpid.cssid]->mutex); - goto out_free; + goto out; } } channel_subsystems[chpid.cssid]->chps[chpid.id] = chp; mutex_unlock(&channel_subsystems[chpid.cssid]->mutex); - return ret; + goto out; out_free: kfree(chp); +out: return ret; } diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c index 33bff8fec7d..326f4cc7f92 100644 --- a/drivers/s390/cio/cio.c +++ b/drivers/s390/cio/cio.c @@ -174,6 +174,7 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */ CIO_TRACE_EVENT(4, sch->dev.bus_id); orb = &to_io_private(sch)->orb; + memset(orb, 0, sizeof(union orb)); /* sch is always under 2G. */ orb->cmd.intparm = (u32)(addr_t)sch; orb->cmd.fmt = 1; @@ -208,8 +209,10 @@ cio_start_key (struct subchannel *sch, /* subchannel structure */ case 1: /* status pending */ case 2: /* busy */ return -EBUSY; - default: /* device/path not operational */ + case 3: /* device/path not operational */ return cio_start_handle_notoper(sch, lpm); + default: + return ccode; } } diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 51489eff6b0..1261e1a9e8c 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c @@ -633,6 +633,11 @@ channel_subsystem_release(struct device *dev) css = to_css(dev); mutex_destroy(&css->mutex); + if (css->pseudo_subchannel) { + /* Implies that it has been generated but never registered. */ + css_subchannel_release(&css->pseudo_subchannel->dev); + css->pseudo_subchannel = NULL; + } kfree(css); } @@ -785,11 +790,15 @@ init_channel_subsystem (void) } channel_subsystems[i] = css; ret = setup_css(i); - if (ret) - goto out_free; + if (ret) { + kfree(channel_subsystems[i]); + goto out_unregister; + } ret = device_register(&css->device); - if (ret) - goto out_free_all; + if (ret) { + put_device(&css->device); + goto out_unregister; + } if (css_chsc_characteristics.secm) { ret = device_create_file(&css->device, &dev_attr_cm_enable); @@ -802,7 +811,7 @@ init_channel_subsystem (void) } ret = register_reboot_notifier(&css_reboot_notifier); if (ret) - goto out_pseudo; + goto out_unregister; css_init_done = 1; /* Enable default isc for I/O subchannels. */ @@ -810,18 +819,12 @@ init_channel_subsystem (void) for_each_subchannel(__init_channel_subsystem, NULL); return 0; -out_pseudo: - device_unregister(&channel_subsystems[i]->pseudo_subchannel->dev); out_file: - device_remove_file(&channel_subsystems[i]->device, - &dev_attr_cm_enable); + if (css_chsc_characteristics.secm) + device_remove_file(&channel_subsystems[i]->device, + &dev_attr_cm_enable); out_device: device_unregister(&channel_subsystems[i]->device); -out_free_all: - kfree(channel_subsystems[i]->pseudo_subchannel->lock); - kfree(channel_subsystems[i]->pseudo_subchannel); -out_free: - kfree(channel_subsystems[i]); out_unregister: while (i > 0) { struct channel_subsystem *css; @@ -829,6 +832,7 @@ out_unregister: i--; css = channel_subsystems[i]; device_unregister(&css->pseudo_subchannel->dev); + css->pseudo_subchannel = NULL; if (css_chsc_characteristics.secm) device_remove_file(&css->device, &dev_attr_cm_enable); diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 550508df952..84cc9ea346d 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -658,6 +658,13 @@ ccw_device_offline(struct ccw_device *cdev) { struct subchannel *sch; + /* Allow ccw_device_offline while disconnected. */ + if (cdev->private->state == DEV_STATE_DISCONNECTED || + cdev->private->state == DEV_STATE_NOT_OPER) { + cdev->private->flags.donotify = 0; + ccw_device_done(cdev, DEV_STATE_NOT_OPER); + return 0; + } if (ccw_device_is_orphan(cdev)) { ccw_device_done(cdev, DEV_STATE_OFFLINE); return 0; diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index c7ab1b86451..908f50b17e2 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -760,7 +760,7 @@ static int qeth_get_problem(struct ccw_device *cdev, struct irb *irb) if (sense[SENSE_COMMAND_REJECT_BYTE] & SENSE_COMMAND_REJECT_FLAG) { QETH_DBF_TEXT(TRACE, 2, "CMDREJi"); - return 0; + return 1; } if ((sense[2] == 0xaf) && (sense[3] == 0xfe)) { QETH_DBF_TEXT(TRACE, 2, "AFFE"); @@ -884,6 +884,7 @@ static void qeth_irq(struct ccw_device *cdev, unsigned long intparm, } rc = qeth_get_problem(cdev, irb); if (rc) { + qeth_clear_ipacmd_list(card); qeth_schedule_recovery(card); goto out; } @@ -4147,6 +4148,7 @@ static void qeth_core_remove_device(struct ccwgroup_device *gdev) unsigned long flags; struct qeth_card *card = dev_get_drvdata(&gdev->dev); + QETH_DBF_TEXT(SETUP, 2, "removedv"); if (card->discipline.ccwgdriver) { card->discipline.ccwgdriver->remove(gdev); qeth_core_free_discipline(card); diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c index 3ac3cc1e03c..955ba7a31b9 100644 --- a/drivers/s390/net/qeth_l2_main.c +++ b/drivers/s390/net/qeth_l2_main.c @@ -395,7 +395,8 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) } if (card->state == CARD_STATE_SOFTSETUP) { qeth_l2_process_vlans(card, 1); - qeth_l2_del_all_mc(card); + if (!card->use_hard_stop) + qeth_l2_del_all_mc(card); qeth_clear_ipacmd_list(card); card->state = CARD_STATE_HARDSETUP; } @@ -559,7 +560,8 @@ static int qeth_l2_request_initial_mac(struct qeth_card *card) "device %s: x%x\n", CARD_BUS_ID(card), rc); } - if (card->info.guestlan) { + if ((card->info.type == QETH_CARD_TYPE_IQD) || + (card->info.guestlan)) { rc = qeth_setadpparms_change_macaddr(card); if (rc) { QETH_DBF_MESSAGE(2, "couldn't get MAC address on " @@ -825,7 +827,6 @@ static int qeth_l2_open(struct net_device *dev) } card->data.state = CH_STATE_UP; card->state = CARD_STATE_UP; - card->dev->flags |= IFF_UP; netif_start_queue(dev); if (!card->lan_online && netif_carrier_ok(dev)) @@ -840,7 +841,6 @@ static int qeth_l2_stop(struct net_device *dev) QETH_DBF_TEXT(TRACE, 4, "qethstop"); netif_tx_disable(dev); - card->dev->flags &= ~IFF_UP; if (card->state == CARD_STATE_UP) card->state = CARD_STATE_SOFTSETUP; return 0; @@ -1137,9 +1137,13 @@ static int qeth_l2_recover(void *ptr) if (!rc) PRINT_INFO("Device %s successfully recovered!\n", CARD_BUS_ID(card)); - else + else { + rtnl_lock(); + dev_close(card->dev); + rtnl_unlock(); PRINT_INFO("Device %s could not be recovered!\n", CARD_BUS_ID(card)); + } return 0; } diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index dd72c3c2016..99547dea44d 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2795,7 +2795,6 @@ static int qeth_l3_open(struct net_device *dev) return -ENODEV; card->data.state = CH_STATE_UP; card->state = CARD_STATE_UP; - card->dev->flags |= IFF_UP; netif_start_queue(dev); if (!card->lan_online && netif_carrier_ok(dev)) @@ -2809,7 +2808,6 @@ static int qeth_l3_stop(struct net_device *dev) QETH_DBF_TEXT(TRACE, 4, "qethstop"); netif_tx_disable(dev); - card->dev->flags &= ~IFF_UP; if (card->state == CARD_STATE_UP) card->state = CARD_STATE_SOFTSETUP; return 0; @@ -3218,9 +3216,13 @@ static int qeth_l3_recover(void *ptr) if (!rc) PRINT_INFO("Device %s successfully recovered!\n", CARD_BUS_ID(card)); - else + else { + rtnl_lock(); + dev_close(card->dev); + rtnl_unlock(); PRINT_INFO("Device %s could not be recovered!\n", CARD_BUS_ID(card)); + } return 0; } diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 391dd29749f..51b6a05f4d1 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c @@ -152,10 +152,8 @@ static int zfcp_ccw_set_offline(struct ccw_device *ccw_device) */ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) { - struct zfcp_adapter *adapter; + struct zfcp_adapter *adapter = dev_get_drvdata(&ccw_device->dev); - down(&zfcp_data.config_sema); - adapter = dev_get_drvdata(&ccw_device->dev); switch (event) { case CIO_GONE: dev_warn(&adapter->ccw_device->dev, "device gone\n"); @@ -174,8 +172,6 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event) 89, NULL); break; } - zfcp_erp_wait(adapter); - up(&zfcp_data.config_sema); return 1; } diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c index e984469bb98..56196c98c07 100644 --- a/drivers/s390/scsi/zfcp_fc.c +++ b/drivers/s390/scsi/zfcp_fc.c @@ -39,18 +39,6 @@ struct zfcp_gpn_ft { struct scatterlist sg_resp[ZFCP_GPN_FT_BUFFERS]; }; -static struct zfcp_port *zfcp_get_port_by_did(struct zfcp_adapter *adapter, - u32 d_id) -{ - struct zfcp_port *port; - - list_for_each_entry(port, &adapter->port_list_head, list) - if ((port->d_id == d_id) && - !atomic_test_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status)) - return port; - return NULL; -} - static void _zfcp_fc_incoming_rscn(struct zfcp_fsf_req *fsf_req, u32 range, struct fcp_rscn_element *elem) { @@ -341,12 +329,13 @@ void zfcp_test_link(struct zfcp_port *port) zfcp_port_get(port); retval = zfcp_fc_adisc(port); - if (retval == 0 || retval == -EBUSY) + if (retval == 0) return; /* send of ADISC was not possible */ zfcp_port_put(port); - zfcp_erp_port_forced_reopen(port, 0, 65, NULL); + if (retval != -EBUSY) + zfcp_erp_port_forced_reopen(port, 0, 65, NULL); } static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter) @@ -363,7 +352,6 @@ static int zfcp_scan_get_nameserver(struct zfcp_adapter *adapter) if (ret) return ret; zfcp_erp_wait(adapter); - zfcp_port_put(adapter->nameserver_port); } return !atomic_test_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->nameserver_port->status); @@ -475,7 +463,7 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) struct zfcp_adapter *adapter = ct->port->adapter; struct zfcp_port *port, *tmp; u32 d_id; - int ret = 0, x; + int ret = 0, x, last = 0; if (ct->status) return -EIO; @@ -492,19 +480,24 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) down(&zfcp_data.config_sema); /* first entry is the header */ - for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES; x++) { + for (x = 1; x < ZFCP_GPN_FT_MAX_ENTRIES && !last; x++) { if (x % (ZFCP_GPN_FT_ENTRIES + 1)) acc++; else acc = sg_virt(++sg); + last = acc->control & 0x80; d_id = acc->port_id[0] << 16 | acc->port_id[1] << 8 | acc->port_id[2]; /* skip the adapter's port and known remote ports */ - if (acc->wwpn == fc_host_port_name(adapter->scsi_host) || - zfcp_get_port_by_did(adapter, d_id)) + if (acc->wwpn == fc_host_port_name(adapter->scsi_host)) + continue; + port = zfcp_get_port_by_wwpn(adapter, acc->wwpn); + if (port) { + zfcp_port_get(port); continue; + } port = zfcp_port_enqueue(adapter, acc->wwpn, ZFCP_STATUS_PORT_DID_DID | @@ -513,8 +506,6 @@ static int zfcp_scan_eval_gpn_ft(struct zfcp_gpn_ft *gpn_ft) ret = PTR_ERR(port); else zfcp_erp_port_reopen(port, 0, 149, NULL); - if (acc->control & 0x80) /* last entry */ - break; } zfcp_erp_wait(adapter); diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 19c1ca91387..49dbeb754e5 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -710,10 +710,10 @@ static void zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *req) static int zfcp_fsf_sbal_check(struct zfcp_qdio_queue *queue) { - spin_lock(&queue->lock); + spin_lock_bh(&queue->lock); if (atomic_read(&queue->count)) return 1; - spin_unlock(&queue->lock); + spin_unlock_bh(&queue->lock); return 0; } @@ -722,13 +722,13 @@ static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) long ret; struct zfcp_qdio_queue *req_q = &adapter->req_q; - spin_unlock(&req_q->lock); + spin_unlock_bh(&req_q->lock); ret = wait_event_interruptible_timeout(adapter->request_wq, zfcp_fsf_sbal_check(req_q), 5 * HZ); if (ret > 0) return 0; - spin_lock(&req_q->lock); + spin_lock_bh(&req_q->lock); return -EIO; } @@ -870,14 +870,14 @@ int zfcp_fsf_status_read(struct zfcp_adapter *adapter) volatile struct qdio_buffer_element *sbale; int retval = -EIO; - spin_lock(&adapter->req_q.lock); + spin_lock_bh(&adapter->req_q.lock); if (zfcp_fsf_req_sbal_get(adapter)) goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_UNSOLICITED_STATUS, ZFCP_REQ_NO_QTCB, adapter->pool.fsf_req_status_read); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { retval = PTR_ERR(req); goto out; } @@ -910,7 +910,7 @@ failed_buf: zfcp_fsf_req_free(req); zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); out: - spin_unlock(&adapter->req_q.lock); + spin_unlock_bh(&adapter->req_q.lock); return retval; } @@ -988,7 +988,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, req_flags, adapter->pool.fsf_req_abort); - if (unlikely(IS_ERR(req))) + if (IS_ERR(req)) goto out; if (unlikely(!(atomic_read(&unit->status) & @@ -1106,13 +1106,13 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, struct zfcp_fsf_req *req; int ret = -EIO; - spin_lock(&adapter->req_q.lock); + spin_lock_bh(&adapter->req_q.lock); if (zfcp_fsf_req_sbal_get(adapter)) goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_GENERIC, ZFCP_REQ_AUTO_CLEANUP, pool); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { ret = PTR_ERR(req); goto out; } @@ -1148,7 +1148,7 @@ failed_send: if (erp_action) erp_action->fsf_req = NULL; out: - spin_unlock(&adapter->req_q.lock); + spin_unlock_bh(&adapter->req_q.lock); return ret; } @@ -1223,7 +1223,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els) goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS, ZFCP_REQ_AUTO_CLEANUP, NULL); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { ret = PTR_ERR(req); goto out; } @@ -1263,14 +1263,14 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) struct zfcp_adapter *adapter = erp_action->adapter; int retval = -EIO; - spin_lock(&adapter->req_q.lock); + spin_lock_bh(&adapter->req_q.lock); if (!atomic_read(&adapter->req_q.count)) goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA, ZFCP_REQ_AUTO_CLEANUP, adapter->pool.fsf_req_erp); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { retval = PTR_ERR(req); goto out; } @@ -1295,7 +1295,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) erp_action->fsf_req = NULL; } out: - spin_unlock(&adapter->req_q.lock); + spin_unlock_bh(&adapter->req_q.lock); return retval; } @@ -1306,13 +1306,13 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, struct zfcp_fsf_req *req = NULL; int retval = -EIO; - spin_lock(&adapter->req_q.lock); + spin_lock_bh(&adapter->req_q.lock); if (zfcp_fsf_req_sbal_get(adapter)) goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA, 0, NULL); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { retval = PTR_ERR(req); goto out; } @@ -1334,7 +1334,7 @@ int zfcp_fsf_exchange_config_data_sync(struct zfcp_adapter *adapter, zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(req); out: - spin_unlock(&adapter->req_q.lock); + spin_unlock_bh(&adapter->req_q.lock); if (!retval) wait_event(req->completion_wq, req->status & ZFCP_STATUS_FSFREQ_COMPLETED); @@ -1359,13 +1359,13 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) return -EOPNOTSUPP; - spin_lock(&adapter->req_q.lock); + spin_lock_bh(&adapter->req_q.lock); if (!atomic_read(&adapter->req_q.count)) goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, ZFCP_REQ_AUTO_CLEANUP, adapter->pool.fsf_req_erp); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { retval = PTR_ERR(req); goto out; } @@ -1385,7 +1385,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) erp_action->fsf_req = NULL; } out: - spin_unlock(&adapter->req_q.lock); + spin_unlock_bh(&adapter->req_q.lock); return retval; } @@ -1405,13 +1405,13 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) return -EOPNOTSUPP; - spin_lock(&adapter->req_q.lock); + spin_lock_bh(&adapter->req_q.lock); if (!atomic_read(&adapter->req_q.count)) goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0, NULL); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { retval = PTR_ERR(req); goto out; } @@ -1427,7 +1427,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(req); out: - spin_unlock(&adapter->req_q.lock); + spin_unlock_bh(&adapter->req_q.lock); if (!retval) wait_event(req->completion_wq, req->status & ZFCP_STATUS_FSFREQ_COMPLETED); @@ -1531,7 +1531,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) struct zfcp_fsf_req *req; int retval = -EIO; - spin_lock(&adapter->req_q.lock); + spin_lock_bh(&adapter->req_q.lock); if (zfcp_fsf_req_sbal_get(adapter)) goto out; @@ -1539,7 +1539,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) FSF_QTCB_OPEN_PORT_WITH_DID, ZFCP_REQ_AUTO_CLEANUP, adapter->pool.fsf_req_erp); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { retval = PTR_ERR(req); goto out; } @@ -1562,7 +1562,7 @@ int zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) erp_action->fsf_req = NULL; } out: - spin_unlock(&adapter->req_q.lock); + spin_unlock_bh(&adapter->req_q.lock); return retval; } @@ -1603,14 +1603,14 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) struct zfcp_fsf_req *req; int retval = -EIO; - spin_lock(&adapter->req_q.lock); + spin_lock_bh(&adapter->req_q.lock); if (zfcp_fsf_req_sbal_get(adapter)) goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PORT, ZFCP_REQ_AUTO_CLEANUP, adapter->pool.fsf_req_erp); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { retval = PTR_ERR(req); goto out; } @@ -1633,7 +1633,7 @@ int zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) erp_action->fsf_req = NULL; } out: - spin_unlock(&adapter->req_q.lock); + spin_unlock_bh(&adapter->req_q.lock); return retval; } @@ -1700,14 +1700,14 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) struct zfcp_fsf_req *req; int retval = -EIO; - spin_lock(&adapter->req_q.lock); + spin_lock_bh(&adapter->req_q.lock); if (zfcp_fsf_req_sbal_get(adapter)) goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_PHYSICAL_PORT, ZFCP_REQ_AUTO_CLEANUP, adapter->pool.fsf_req_erp); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { retval = PTR_ERR(req); goto out; } @@ -1731,7 +1731,7 @@ int zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) erp_action->fsf_req = NULL; } out: - spin_unlock(&adapter->req_q.lock); + spin_unlock_bh(&adapter->req_q.lock); return retval; } @@ -1875,14 +1875,14 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) struct zfcp_fsf_req *req; int retval = -EIO; - spin_lock(&adapter->req_q.lock); + spin_lock_bh(&adapter->req_q.lock); if (zfcp_fsf_req_sbal_get(adapter)) goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_OPEN_LUN, ZFCP_REQ_AUTO_CLEANUP, adapter->pool.fsf_req_erp); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { retval = PTR_ERR(req); goto out; } @@ -1910,7 +1910,7 @@ int zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) erp_action->fsf_req = NULL; } out: - spin_unlock(&adapter->req_q.lock); + spin_unlock_bh(&adapter->req_q.lock); return retval; } @@ -1965,13 +1965,13 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) struct zfcp_fsf_req *req; int retval = -EIO; - spin_lock(&adapter->req_q.lock); + spin_lock_bh(&adapter->req_q.lock); if (zfcp_fsf_req_sbal_get(adapter)) goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_CLOSE_LUN, ZFCP_REQ_AUTO_CLEANUP, adapter->pool.fsf_req_erp); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { retval = PTR_ERR(req); goto out; } @@ -1995,7 +1995,7 @@ int zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) erp_action->fsf_req = NULL; } out: - spin_unlock(&adapter->req_q.lock); + spin_unlock_bh(&adapter->req_q.lock); return retval; } @@ -2228,7 +2228,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, adapter->pool.fsf_req_scsi); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { retval = PTR_ERR(req); goto out; } @@ -2351,7 +2351,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter, goto out; req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, adapter->pool.fsf_req_scsi); - if (unlikely(IS_ERR(req))) + if (IS_ERR(req)) goto out; req->status |= ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT; @@ -2417,12 +2417,12 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, return ERR_PTR(-EINVAL); } - spin_lock(&adapter->req_q.lock); + spin_lock_bh(&adapter->req_q.lock); if (zfcp_fsf_req_sbal_get(adapter)) goto out; req = zfcp_fsf_req_create(adapter, fsf_cfdc->command, 0, NULL); - if (unlikely(IS_ERR(req))) { + if (IS_ERR(req)) { retval = -EPERM; goto out; } @@ -2447,7 +2447,7 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter, zfcp_fsf_start_timer(req, ZFCP_FSF_REQUEST_TIMEOUT); retval = zfcp_fsf_req_send(req); out: - spin_unlock(&adapter->req_q.lock); + spin_unlock_bh(&adapter->req_q.lock); if (!retval) { wait_event(req->completion_wq, diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index d6dbd653fde..69d632d851d 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -423,9 +423,9 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter) /* clear QDIOUP flag, thus do_QDIO is not called during qdio_shutdown */ req_q = &adapter->req_q; - spin_lock(&req_q->lock); + spin_lock_bh(&req_q->lock); atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status); - spin_unlock(&req_q->lock); + spin_unlock_bh(&req_q->lock); qdio_shutdown(adapter->ccw_device, QDIO_FLAG_CLEANUP_USING_CLEAR); diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index c7f06298bd3..4e0322b1c1e 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -63,7 +63,7 @@ comment "SCSI support type (disk, tape, CD-ROM)" config BLK_DEV_SD tristate "SCSI disk support" depends on SCSI - select CRC_T10DIF + select CRC_T10DIF if BLK_DEV_INTEGRITY ---help--- If you want to use SCSI hard disks, Fibre Channel disks, Serial ATA (SATA) or Parallel ATA (PATA) hard disks, diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index 994da56fffe..708e475896b 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -425,7 +425,7 @@ static int alua_check_sense(struct scsi_device *sdev, /* * LUN Not Accessible - ALUA state transition */ - return NEEDS_RETRY; + return ADD_TO_MLQUEUE; if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0b) /* * LUN Not Accessible -- Target port in standby state @@ -447,18 +447,18 @@ static int alua_check_sense(struct scsi_device *sdev, /* * Power On, Reset, or Bus Device Reset, just retry. */ - return NEEDS_RETRY; + return ADD_TO_MLQUEUE; if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) { /* * ALUA state changed */ - return NEEDS_RETRY; + return ADD_TO_MLQUEUE; } if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) { /* * Implicit ALUA state transition failed */ - return NEEDS_RETRY; + return ADD_TO_MLQUEUE; } break; } @@ -490,7 +490,7 @@ static int alua_stpg(struct scsi_device *sdev, int state, if (!err) return SCSI_DH_IO; err = alua_check_sense(sdev, &sense_hdr); - if (retry > 0 && err == NEEDS_RETRY) { + if (retry > 0 && err == ADD_TO_MLQUEUE) { retry--; goto retry; } @@ -535,7 +535,7 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_dh_data *h) return SCSI_DH_IO; err = alua_check_sense(sdev, &sense_hdr); - if (err == NEEDS_RETRY) + if (err == ADD_TO_MLQUEUE) goto retry; sdev_printk(KERN_INFO, sdev, "%s: rtpg sense code %02x/%02x/%02x\n", diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index b9d23e9e9a4..ef693e8412e 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c @@ -439,7 +439,7 @@ static int clariion_check_sense(struct scsi_device *sdev, * Unit Attention Code. This is the first IO * to the new path, so just retry. */ - return NEEDS_RETRY; + return ADD_TO_MLQUEUE; break; } @@ -514,7 +514,7 @@ retry: return SCSI_DH_IO; err = clariion_check_sense(sdev, &sshdr); - if (retry > 0 && err == NEEDS_RETRY) { + if (retry > 0 && err == ADD_TO_MLQUEUE) { retry--; goto retry; } diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 2dee69da35c..6e2f130d56d 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c @@ -551,7 +551,7 @@ static int rdac_check_sense(struct scsi_device *sdev, * * Just retry and wait. */ - return NEEDS_RETRY; + return ADD_TO_MLQUEUE; break; case ILLEGAL_REQUEST: if (sense_hdr->asc == 0x94 && sense_hdr->ascq == 0x01) { @@ -568,7 +568,7 @@ static int rdac_check_sense(struct scsi_device *sdev, /* * Power On, Reset, or Bus Device Reset, just retry. */ - return NEEDS_RETRY; + return ADD_TO_MLQUEUE; break; } /* success just means we do not care what scsi-ml does */ diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 45a3b93eed5..bf41887cdd6 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1834,7 +1834,6 @@ clear_risc_ints: WRT_REG_WORD(®->isp.hccr, HCCR_CLR_HOST_INT); } spin_unlock_irq(&ha->hardware_lock); - ha->isp_ops->enable_intrs(ha); fail: return ret; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 26afe44265c..6d0f0e5f282 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -1740,6 +1740,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) if (ret) goto probe_failed; + ha->isp_ops->enable_intrs(ha); + scsi_scan_host(host); qla2x00_alloc_sysfs_attr(ha); diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 4a1cf6377f6..90535089672 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -914,6 +914,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd, ds[i].d_count = sg_dma_len(s); } sg_count -= n; + sg = s; } } else { cmd->dataseg[0].d_base = 0; diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 880051c89bd..39ce3aba1da 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -391,7 +391,7 @@ static int scsi_check_sense(struct scsi_cmnd *scmd) case HARDWARE_ERROR: if (scmd->device->retry_hwerror) - return NEEDS_RETRY; + return ADD_TO_MLQUEUE; else return SUCCESS; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index ff5d56b3ee4..62307bd794a 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -852,7 +852,7 @@ static void scsi_end_bidi_request(struct scsi_cmnd *cmd) void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) { int result = cmd->result; - int this_count = scsi_bufflen(cmd); + int this_count; struct request_queue *q = cmd->device->request_queue; struct request *req = cmd->request; int error = 0; @@ -908,6 +908,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) */ if (scsi_end_request(cmd, error, good_bytes, result == 0) == NULL) return; + this_count = blk_rq_bytes(req); /* good_bytes = 0, or (inclusive) there were leftovers and * result = 0, so scsi_end_request couldn't retry. diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 84b4879cff1..34d0de6cd51 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -1080,7 +1080,8 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, * PDT=1Fh none (no FDD connected to the requested logical unit) */ if (((result[0] >> 5) == 1 || starget->pdt_1f_for_no_lun) && - (result[0] & 0x1f) == 0x1f) { + (result[0] & 0x1f) == 0x1f && + !scsi_is_wlun(lun)) { SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO "scsi scan: peripheral device type" " of 31, no device added\n")); diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 2a2bc89aba8..e5e7d785645 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1875,7 +1875,6 @@ static int sd_probe(struct device *dev) dev_set_drvdata(dev, sdkp); add_disk(gd); - blk_register_filter(gd); sd_dif_config_host(sdkp); sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n", @@ -1909,7 +1908,6 @@ static int sd_remove(struct device *dev) struct scsi_disk *sdkp = dev_get_drvdata(dev); device_del(&sdkp->dev); - blk_unregister_filter(sdkp->disk); del_gendisk(sdkp->disk); sd_shutdown(dev); diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 3292965bfd8..27f5bfd1def 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -656,7 +656,6 @@ static int sr_probe(struct device *dev) dev_set_drvdata(dev, cd); disk->flags |= GENHD_FL_REMOVABLE; add_disk(disk); - blk_register_filter(disk); sdev_printk(KERN_DEBUG, sdev, "Attached scsi CD-ROM %s\n", cd->cdi.name); @@ -895,7 +894,6 @@ static int sr_remove(struct device *dev) { struct scsi_cd *cd = dev_get_drvdata(dev); - blk_unregister_filter(cd->disk); del_gendisk(cd->disk); mutex_lock(&sr_ref_mutex); diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c index 3a6da80b081..61fb8b6d19a 100644 --- a/drivers/serial/atmel_serial.c +++ b/drivers/serial/atmel_serial.c @@ -131,7 +131,8 @@ struct atmel_uart_char { struct atmel_uart_port { struct uart_port uart; /* uart */ struct clk *clk; /* uart clock */ - unsigned short suspended; /* is port suspended? */ + int may_wakeup; /* cached value of device_may_wakeup for times we need to disable it */ + u32 backup_imr; /* IMR saved during suspend */ int break_active; /* break being received */ short use_dma_rx; /* enable PDC receiver */ @@ -984,8 +985,15 @@ static void atmel_serial_pm(struct uart_port *port, unsigned int state, * This is called on uart_open() or a resume event. */ clk_enable(atmel_port->clk); + + /* re-enable interrupts if we disabled some on suspend */ + UART_PUT_IER(port, atmel_port->backup_imr); break; case 3: + /* Back up the interrupt mask and disable all interrupts */ + atmel_port->backup_imr = UART_GET_IMR(port); + UART_PUT_IDR(port, -1); + /* * Disable the peripheral clock for this serial port. * This is called on uart_close() or a suspend event. @@ -1475,13 +1483,12 @@ static int atmel_serial_suspend(struct platform_device *pdev, cpu_relax(); } - if (device_may_wakeup(&pdev->dev) - && !atmel_serial_clk_will_stop()) - enable_irq_wake(port->irq); - else { - uart_suspend_port(&atmel_uart, port); - atmel_port->suspended = 1; - } + /* we can not wake up if we're running on slow clock */ + atmel_port->may_wakeup = device_may_wakeup(&pdev->dev); + if (atmel_serial_clk_will_stop()) + device_set_wakeup_enable(&pdev->dev, 0); + + uart_suspend_port(&atmel_uart, port); return 0; } @@ -1491,11 +1498,8 @@ static int atmel_serial_resume(struct platform_device *pdev) struct uart_port *port = platform_get_drvdata(pdev); struct atmel_uart_port *atmel_port = to_atmel_uart_port(port); - if (atmel_port->suspended) { - uart_resume_port(&atmel_uart, port); - atmel_port->suspended = 0; - } else - disable_irq_wake(port->irq); + uart_resume_port(&atmel_uart, port); + device_set_wakeup_enable(&pdev->dev, atmel_port->may_wakeup); return 0; } @@ -1513,6 +1517,8 @@ static int __devinit atmel_serial_probe(struct platform_device *pdev) BUILD_BUG_ON(!is_power_of_2(ATMEL_SERIAL_RINGSIZE)); port = &atmel_ports[pdev->id]; + port->backup_imr = 0; + atmel_init_port(port, pdev); if (!atmel_use_dma_rx(&port->uart)) { diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 6a29f9330a7..3f90f1bbbbc 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -127,8 +127,13 @@ #define UCR3_RXDSEN (1<<6) /* Receive status interrupt enable */ #define UCR3_AIRINTEN (1<<5) /* Async IR wake interrupt enable */ #define UCR3_AWAKEN (1<<4) /* Async wake interrupt enable */ -#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz */ -#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz */ +#ifdef CONFIG_ARCH_IMX +#define UCR3_REF25 (1<<3) /* Ref freq 25 MHz, only on mx1 */ +#define UCR3_REF30 (1<<2) /* Ref Freq 30 MHz, only on mx1 */ +#endif +#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3 +#define UCR3_RXDMUXSEL (1<<2) /* RXD Muxed Input Select, on mx2/mx3 */ +#endif #define UCR3_INVT (1<<1) /* Inverted Infrared transmission */ #define UCR3_BPEN (1<<0) /* Preset registers enable */ #define UCR4_CTSTL_32 (32<<10) /* CTS trigger level (32 chars) */ @@ -445,7 +450,7 @@ static irqreturn_t imx_int(int irq, void *dev_id) readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN) imx_txint(irq, dev_id); - if (sts & USR1_RTSS) + if (sts & USR1_RTSD) imx_rtsint(irq, dev_id); return IRQ_HANDLED; @@ -598,6 +603,12 @@ static int imx_startup(struct uart_port *port) temp |= (UCR2_RXEN | UCR2_TXEN); writel(temp, sport->port.membase + UCR2); +#if defined CONFIG_ARCH_MX2 || defined CONFIG_ARCH_MX3 + temp = readl(sport->port.membase + UCR3); + temp |= UCR3_RXDMUXSEL; + writel(temp, sport->port.membase + UCR3); +#endif + /* * Enable modem status interrupts */ @@ -1133,13 +1144,19 @@ static int serial_imx_probe(struct platform_device *pdev) if(pdata && (pdata->flags & IMXUART_HAVE_RTSCTS)) sport->have_rtscts = 1; - if (pdata->init) - pdata->init(pdev); + if (pdata->init) { + ret = pdata->init(pdev); + if (ret) + goto clkput; + } uart_add_one_port(&imx_reg, &sport->port); platform_set_drvdata(pdev, &sport->port); return 0; +clkput: + clk_put(sport->clk); + clk_disable(sport->clk); unmap: iounmap(sport->port.membase); free: diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index 34c7c987568..0e53354c1cf 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c @@ -47,9 +47,10 @@ MODULE_ALIAS("platform:pxa2xx-spi"); #define MAX_BUSES 3 -#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR) -#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) -#define IS_DMA_ALIGNED(x) (((u32)(x)&0x07)==0) +#define DMA_INT_MASK (DCSR_ENDINTR | DCSR_STARTINTR | DCSR_BUSERR) +#define RESET_DMA_CHANNEL (DCSR_NODESC | DMA_INT_MASK) +#define IS_DMA_ALIGNED(x) (((x) & 0x07) == 0) +#define MAX_DMA_LEN 8191 /* * for testing SSCR1 changes that require SSP restart, basically @@ -144,7 +145,6 @@ struct driver_data { size_t tx_map_len; u8 n_bytes; u32 dma_width; - int cs_change; int (*write)(struct driver_data *drv_data); int (*read)(struct driver_data *drv_data); irqreturn_t (*transfer_handler)(struct driver_data *drv_data); @@ -406,8 +406,45 @@ static void giveback(struct driver_data *drv_data) struct spi_transfer, transfer_list); + /* Delay if requested before any change in chip select */ + if (last_transfer->delay_usecs) + udelay(last_transfer->delay_usecs); + + /* Drop chip select UNLESS cs_change is true or we are returning + * a message with an error, or next message is for another chip + */ if (!last_transfer->cs_change) drv_data->cs_control(PXA2XX_CS_DEASSERT); + else { + struct spi_message *next_msg; + + /* Holding of cs was hinted, but we need to make sure + * the next message is for the same chip. Don't waste + * time with the following tests unless this was hinted. + * + * We cannot postpone this until pump_messages, because + * after calling msg->complete (below) the driver that + * sent the current message could be unloaded, which + * could invalidate the cs_control() callback... + */ + + /* get a pointer to the next message, if any */ + spin_lock_irqsave(&drv_data->lock, flags); + if (list_empty(&drv_data->queue)) + next_msg = NULL; + else + next_msg = list_entry(drv_data->queue.next, + struct spi_message, queue); + spin_unlock_irqrestore(&drv_data->lock, flags); + + /* see if the next and current messages point + * to the same chip + */ + if (next_msg && next_msg->spi != msg->spi) + next_msg = NULL; + if (!next_msg || msg->state == ERROR_STATE) + drv_data->cs_control(PXA2XX_CS_DEASSERT); + } msg->state = NULL; if (msg->complete) @@ -490,10 +527,9 @@ static void dma_transfer_complete(struct driver_data *drv_data) msg->actual_length += drv_data->len - (drv_data->rx_end - drv_data->rx); - /* Release chip select if requested, transfer delays are - * handled in pump_transfers */ - if (drv_data->cs_change) - drv_data->cs_control(PXA2XX_CS_DEASSERT); + /* Transfer delays and chip select release are + * handled in pump_transfers or giveback + */ /* Move to next transfer */ msg->state = next_transfer(drv_data); @@ -602,10 +638,9 @@ static void int_transfer_complete(struct driver_data *drv_data) drv_data->cur_msg->actual_length += drv_data->len - (drv_data->rx_end - drv_data->rx); - /* Release chip select if requested, transfer delays are - * handled in pump_transfers */ - if (drv_data->cs_change) - drv_data->cs_control(PXA2XX_CS_DEASSERT); + /* Transfer delays and chip select release are + * handled in pump_transfers or giveback + */ /* Move to next transfer */ drv_data->cur_msg->state = next_transfer(drv_data); @@ -840,23 +875,40 @@ static void pump_transfers(unsigned long data) return; } - /* Delay if requested at end of transfer*/ + /* Delay if requested at end of transfer before CS change */ if (message->state == RUNNING_STATE) { previous = list_entry(transfer->transfer_list.prev, struct spi_transfer, transfer_list); if (previous->delay_usecs) udelay(previous->delay_usecs); + + /* Drop chip select only if cs_change is requested */ + if (previous->cs_change) + drv_data->cs_control(PXA2XX_CS_DEASSERT); } - /* Check transfer length */ - if (transfer->len > 8191) - { - dev_warn(&drv_data->pdev->dev, "pump_transfers: transfer " - "length greater than 8191\n"); - message->status = -EINVAL; - giveback(drv_data); - return; + /* Check for transfers that need multiple DMA segments */ + if (transfer->len > MAX_DMA_LEN && chip->enable_dma) { + + /* reject already-mapped transfers; PIO won't always work */ + if (message->is_dma_mapped + || transfer->rx_dma || transfer->tx_dma) { + dev_err(&drv_data->pdev->dev, + "pump_transfers: mapped transfer length " + "of %lu is greater than %d\n", + transfer->len, MAX_DMA_LEN); + message->status = -EINVAL; + giveback(drv_data); + return; + } + + /* warn ... we force this to PIO mode */ + if (printk_ratelimit()) + dev_warn(&message->spi->dev, "pump_transfers: " + "DMA disabled for transfer length %ld " + "greater than %d\n", + (long)drv_data->len, MAX_DMA_LEN); } /* Setup the transfer state based on the type of transfer */ @@ -878,7 +930,6 @@ static void pump_transfers(unsigned long data) drv_data->len = transfer->len & DCMD_LENGTH; drv_data->write = drv_data->tx ? chip->write : null_writer; drv_data->read = drv_data->rx ? chip->read : null_reader; - drv_data->cs_change = transfer->cs_change; /* Change speed and bit per word on a per transfer */ cr0 = chip->cr0; @@ -925,7 +976,7 @@ static void pump_transfers(unsigned long data) &dma_thresh)) if (printk_ratelimit()) dev_warn(&message->spi->dev, - "pump_transfer: " + "pump_transfers: " "DMA burst size reduced to " "match bits_per_word\n"); } @@ -939,8 +990,23 @@ static void pump_transfers(unsigned long data) message->state = RUNNING_STATE; - /* Try to map dma buffer and do a dma transfer if successful */ - if ((drv_data->dma_mapped = map_dma_buffers(drv_data))) { + /* Try to map dma buffer and do a dma transfer if successful, but + * only if the length is non-zero and less than MAX_DMA_LEN. + * + * Zero-length non-descriptor DMA is illegal on PXA2xx; force use + * of PIO instead. Care is needed above because the transfer may + * have have been passed with buffers that are already dma mapped. + * A zero-length transfer in PIO mode will not try to write/read + * to/from the buffers + * + * REVISIT large transfers are exactly where we most want to be + * using DMA. If this happens much, split those transfers into + * multiple DMA segments rather than forcing PIO. + */ + drv_data->dma_mapped = 0; + if (drv_data->len > 0 && drv_data->len <= MAX_DMA_LEN) + drv_data->dma_mapped = map_dma_buffers(drv_data); + if (drv_data->dma_mapped) { /* Ensure we have the correct interrupt handler */ drv_data->transfer_handler = dma_transfer; diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c index 070c6219e2d..ac0e3e4b3c5 100644 --- a/drivers/spi/spi_mpc83xx.c +++ b/drivers/spi/spi_mpc83xx.c @@ -267,16 +267,13 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t) cs->hw_mode |= SPMODE_LEN(bits_per_word); if ((mpc83xx_spi->spibrg / hz) > 64) { + cs->hw_mode |= SPMODE_DIV16; pm = mpc83xx_spi->spibrg / (hz * 64); if (pm > 16) { - cs->hw_mode |= SPMODE_DIV16; - pm /= 16; - if (pm > 16) { - dev_err(&spi->dev, "Requested speed is too " - "low: %d Hz. Will use %d Hz instead.\n", - hz, mpc83xx_spi->spibrg / 1024); - pm = 16; - } + dev_err(&spi->dev, "Requested speed is too " + "low: %d Hz. Will use %d Hz instead.\n", + hz, mpc83xx_spi->spibrg / 1024); + pm = 16; } } else pm = mpc83xx_spi->spibrg / (hz * 4); @@ -315,11 +312,20 @@ static int mpc83xx_spi_bufs(struct spi_device *spi, struct spi_transfer *t) if (t->bits_per_word) bits_per_word = t->bits_per_word; len = t->len; - if (bits_per_word > 8) + if (bits_per_word > 8) { + /* invalid length? */ + if (len & 1) + return -EINVAL; len /= 2; - if (bits_per_word > 16) + } + if (bits_per_word > 16) { + /* invalid length? */ + if (len & 1) + return -EINVAL; len /= 2; + } mpc83xx_spi->count = len; + INIT_COMPLETION(mpc83xx_spi->done); /* enable rx ints */ diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index 98abc73c1a1..3eb414b84a9 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c @@ -430,7 +430,7 @@ static int s3c24xx_spi_resume(struct platform_device *pdev) #endif MODULE_ALIAS("platform:s3c2410-spi"); -static struct platform_driver s3c24xx_spidrv = { +static struct platform_driver s3c24xx_spi_driver = { .remove = __exit_p(s3c24xx_spi_remove), .suspend = s3c24xx_spi_suspend, .resume = s3c24xx_spi_resume, @@ -442,12 +442,12 @@ static struct platform_driver s3c24xx_spidrv = { static int __init s3c24xx_spi_init(void) { - return platform_driver_probe(&s3c24xx_spidrv, s3c24xx_spi_probe); + return platform_driver_probe(&s3c24xx_spi_driver, s3c24xx_spi_probe); } static void __exit s3c24xx_spi_exit(void) { - platform_driver_unregister(&s3c24xx_spidrv); + platform_driver_unregister(&s3c24xx_spi_driver); } module_init(s3c24xx_spi_init); diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 87ab2443e66..0ffabf5c0b6 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -471,6 +471,7 @@ static int ssb_devices_register(struct ssb_bus *bus) #endif break; case SSB_BUSTYPE_SSB: + dev->dma_mask = &dev->coherent_dma_mask; break; } diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 07228721caf..0da2c25bab3 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c @@ -640,14 +640,13 @@ static void usbatm_cancel_send(struct usbatm_data *instance, atm_dbg(instance, "%s entered\n", __func__); spin_lock_irq(&instance->sndqueue.lock); - for (skb = instance->sndqueue.next, n = skb->next; - skb != (struct sk_buff *)&instance->sndqueue; - skb = n, n = skb->next) + skb_queue_walk_safe(&instance->sndqueue, skb, n) { if (UDSL_SKB(skb)->atm.vcc == vcc) { atm_dbg(instance, "%s: popping skb 0x%p\n", __func__, skb); __skb_unlink(skb, &instance->sndqueue); usbatm_pop(vcc, skb); } + } spin_unlock_irq(&instance->sndqueue.lock); tasklet_disable(&instance->tx_channel.tasklet); diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 8abd4e59bf4..8ab389dca2b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1876,7 +1876,8 @@ int usb_add_hcd(struct usb_hcd *hcd, * with IRQF_SHARED. As usb_hcd_irq() will always disable * interrupts we can remove it here. */ - irqflags &= ~IRQF_DISABLED; + if (irqflags & IRQF_SHARED) + irqflags &= ~IRQF_DISABLED; snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d", hcd->driver->description, hcd->self.busnum); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 6a5cb018383..d99963873e3 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -2683,35 +2683,17 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, USB_PORT_STAT_C_ENABLE); #endif - /* Try to use the debounce delay for protection against - * port-enable changes caused, for example, by EMI. - */ - if (portchange & (USB_PORT_STAT_C_CONNECTION | - USB_PORT_STAT_C_ENABLE)) { - status = hub_port_debounce(hub, port1); - if (status < 0) { - if (printk_ratelimit()) - dev_err (hub_dev, "connect-debounce failed, " - "port %d disabled\n", port1); - portstatus &= ~USB_PORT_STAT_CONNECTION; - } else { - portstatus = status; - } - } - /* Try to resuscitate an existing device */ udev = hdev->children[port1-1]; if ((portstatus & USB_PORT_STAT_CONNECTION) && udev && udev->state != USB_STATE_NOTATTACHED) { - usb_lock_device(udev); if (portstatus & USB_PORT_STAT_ENABLE) { status = 0; /* Nothing to do */ - } else if (!udev->persist_enabled) { - status = -ENODEV; /* Mustn't resuscitate */ #ifdef CONFIG_USB_SUSPEND - } else if (udev->state == USB_STATE_SUSPENDED) { + } else if (udev->state == USB_STATE_SUSPENDED && + udev->persist_enabled) { /* For a suspended device, treat this as a * remote wakeup event. */ @@ -2726,7 +2708,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, #endif } else { - status = usb_reset_device(udev); + status = -ENODEV; /* Don't resuscitate */ } usb_unlock_device(udev); @@ -2741,6 +2723,19 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, usb_disconnect(&hdev->children[port1-1]); clear_bit(port1, hub->change_bits); + if (portchange & (USB_PORT_STAT_C_CONNECTION | + USB_PORT_STAT_C_ENABLE)) { + status = hub_port_debounce(hub, port1); + if (status < 0) { + if (printk_ratelimit()) + dev_err(hub_dev, "connect-debounce failed, " + "port %d disabled\n", port1); + portstatus &= ~USB_PORT_STAT_CONNECTION; + } else { + portstatus = status; + } + } + /* Return now if debouncing failed or nothing is connected */ if (!(portstatus & USB_PORT_STAT_CONNECTION)) { @@ -2748,7 +2743,7 @@ static void hub_port_connect_change(struct usb_hub *hub, int port1, if ((wHubCharacteristics & HUB_CHAR_LPSM) < 2 && !(portstatus & (1 << USB_PORT_FEAT_POWER))) set_port_feature(hdev, port1, USB_PORT_FEAT_POWER); - + if (portstatus & USB_PORT_STAT_ENABLE) goto done; return; diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 1cfccf102a2..45ad556169f 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -223,7 +223,7 @@ static int dr_controller_setup(struct fsl_udc *udc) fsl_writel(tmp, &dr_regs->endpointlistaddr); VDBG("vir[qh_base] is %p phy[qh_base] is 0x%8x reg is 0x%8x", - (int)udc->ep_qh, (int)tmp, + udc->ep_qh, (int)tmp, fsl_readl(&dr_regs->endpointlistaddr)); /* Config PHY interface */ diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 574c53831a0..bb54cca4c54 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -787,7 +787,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_TIPB, OMAP_DMA_AMODE_CONSTANT, - (unsigned long) io_v2p(UDC_DATA_DMA), + UDC_DATA_DMA, 0, 0); } } else { @@ -804,7 +804,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_TIPB, OMAP_DMA_AMODE_CONSTANT, - (unsigned long) io_v2p(UDC_DATA_DMA), + UDC_DATA_DMA, 0, 0); /* EMIFF or SDRC */ omap_set_dma_dest_burst_mode(ep->lch, diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index d9d53f289ca..8409e0705d6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -145,16 +145,6 @@ static int handshake (struct ehci_hcd *ehci, void __iomem *ptr, return -ETIMEDOUT; } -static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr, - u32 mask, u32 done, int usec) -{ - int error = handshake(ehci, ptr, mask, done, usec); - if (error) - ehci_to_hcd(ehci)->state = HC_STATE_HALT; - - return error; -} - /* force HC to halt state from unknown (EHCI spec section 2.3) */ static int ehci_halt (struct ehci_hcd *ehci) { @@ -173,6 +163,22 @@ static int ehci_halt (struct ehci_hcd *ehci) STS_HALT, STS_HALT, 16 * 125); } +static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr, + u32 mask, u32 done, int usec) +{ + int error; + + error = handshake(ehci, ptr, mask, done, usec); + if (error) { + ehci_halt(ehci); + ehci_to_hcd(ehci)->state = HC_STATE_HALT; + ehci_err(ehci, "force halt; handhake %p %08x %08x -> %d\n", + ptr, mask, done, error); + } + + return error; +} + /* put TDI/ARC silicon into EHCI mode */ static void tdi_reset (struct ehci_hcd *ehci) { diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index b7853c8bac0..4a0c5a78b2e 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -437,6 +437,9 @@ static int enable_periodic (struct ehci_hcd *ehci) u32 cmd; int status; + if (ehci->periodic_sched++) + return 0; + /* did clearing PSE did take effect yet? * takes effect only at frame boundaries... */ @@ -461,6 +464,9 @@ static int disable_periodic (struct ehci_hcd *ehci) u32 cmd; int status; + if (--ehci->periodic_sched) + return 0; + /* did setting PSE not take effect yet? * takes effect only at frame boundaries... */ @@ -544,13 +550,10 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) : (qh->usecs * 8); /* maybe enable periodic schedule processing */ - if (!ehci->periodic_sched++) - return enable_periodic (ehci); - - return 0; + return enable_periodic(ehci); } -static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) +static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh) { unsigned i; unsigned period; @@ -586,9 +589,7 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) qh_put (qh); /* maybe turn off periodic schedule */ - ehci->periodic_sched--; - if (!ehci->periodic_sched) - (void) disable_periodic (ehci); + return disable_periodic(ehci); } static void intr_deschedule (struct ehci_hcd *ehci, struct ehci_qh *qh) @@ -1562,9 +1563,7 @@ itd_link_urb ( urb->hcpriv = NULL; timer_action (ehci, TIMER_IO_WATCHDOG); - if (unlikely (!ehci->periodic_sched++)) - return enable_periodic (ehci); - return 0; + return enable_periodic(ehci); } #define ISO_ERRS (EHCI_ISOC_BUF_ERR | EHCI_ISOC_BABBLE | EHCI_ISOC_XACTERR) @@ -1642,7 +1641,7 @@ itd_complete ( ehci_urb_done(ehci, urb, 0); retval = true; urb = NULL; - ehci->periodic_sched--; + (void) disable_periodic(ehci); ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; if (unlikely (list_empty (&stream->td_list))) { @@ -1951,9 +1950,7 @@ sitd_link_urb ( urb->hcpriv = NULL; timer_action (ehci, TIMER_IO_WATCHDOG); - if (!ehci->periodic_sched++) - return enable_periodic (ehci); - return 0; + return enable_periodic(ehci); } /*-------------------------------------------------------------------------*/ @@ -2019,7 +2016,7 @@ sitd_complete ( ehci_urb_done(ehci, urb, 0); retval = true; urb = NULL; - ehci->periodic_sched--; + (void) disable_periodic(ehci); ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; if (list_empty (&stream->td_list)) { @@ -2243,8 +2240,7 @@ restart: if (unlikely (modified)) { if (likely(ehci->periodic_sched > 0)) goto restart; - /* maybe we can short-circuit this scan! */ - disable_periodic(ehci); + /* short-circuit this scan */ now_uframe = clock; break; } diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index a0017486ad4..58b2b8fc943 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -9,6 +9,7 @@ comment "Enable Host or Gadget support to see Inventra options" # (M)HDRC = (Multipoint) Highspeed Dual-Role Controller config USB_MUSB_HDRC depends on (USB || USB_GADGET) && HAVE_CLK + depends on !SUPERH select TWL4030_USB if MACH_OMAP_3430SDP tristate 'Inventra Highspeed Dual Role Controller (TI, ...)' help diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index c5b8f0296fc..128e949db47 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -100,8 +100,8 @@ #include <linux/io.h> #ifdef CONFIG_ARM -#include <asm/arch/hardware.h> -#include <asm/arch/memory.h> +#include <mach/hardware.h> +#include <mach/memory.h> #include <asm/mach-types.h> #endif diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 298b22e6ad0..9d2dcb121c5 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -35,8 +35,8 @@ #include <linux/io.h> #include <asm/mach-types.h> -#include <asm/arch/hardware.h> -#include <asm/arch/mux.h> +#include <mach/hardware.h> +#include <mach/mux.h> #include "musb_core.h" #include "omap2430.h" diff --git a/drivers/usb/musb/omap2430.h b/drivers/usb/musb/omap2430.h index 786a62071f7..dc7670718cd 100644 --- a/drivers/usb/musb/omap2430.h +++ b/drivers/usb/musb/omap2430.h @@ -11,8 +11,8 @@ #define __MUSB_OMAP243X_H__ #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3430) -#include <asm/arch/hardware.h> -#include <asm/arch/usb.h> +#include <mach/hardware.h> +#include <mach/usb.h> /* * OMAP2430-specific definitions diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 442cba69cce..1279553381e 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -72,6 +72,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */ { USB_DEVICE(0x10C4, 0x80F6) }, /* Suunto sports instrument */ + { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */ { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */ { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ @@ -83,6 +84,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ + { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ @@ -93,6 +95,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ + { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */ { } /* Terminating Entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 984f6eff4c4..3dc93b542b3 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -654,6 +654,9 @@ static struct usb_device_id id_table_combined [] = { .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { USB_DEVICE(RATOC_VENDOR_ID, RATOC_PRODUCT_ID_USB60F) }, { USB_DEVICE(FTDI_VID, FTDI_REU_TINY_PID) }, + { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 382265bba96..8a5b6df3a97 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -750,6 +750,7 @@ #define PAPOUCH_VID 0x5050 /* Vendor ID */ #define PAPOUCH_TMU_PID 0x0400 /* TMU USB Thermometer */ +#define PAPOUCH_QUIDO4x4_PID 0x0900 /* Quido 4/4 Module */ /* * ACG Identification Technologies GmbH products (http://www.acg.de/). @@ -838,6 +839,10 @@ /* Rig Expert Ukraine devices */ #define FTDI_REU_TINY_PID 0xED22 /* RigExpert Tiny */ +/* Domintell products http://www.domintell.com */ +#define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ +#define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */ + /* Commands */ #define FTDI_SIO_RESET 0 /* Reset the port */ #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 9f9cd36455f..73f8277f88f 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -218,6 +218,7 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po /* ZTE PRODUCTS */ #define ZTE_VENDOR_ID 0x19d2 #define ZTE_PRODUCT_MF628 0x0015 +#define ZTE_PRODUCT_CDMA_TECH 0xfffe static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, @@ -347,6 +348,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 706033753ad..ea1a103c99b 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -14,7 +14,7 @@ Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> */ -#define DRIVER_VERSION "v.1.2.13a" +#define DRIVER_VERSION "v.1.3.2" #define DRIVER_AUTHOR "Kevin Lloyd <klloyd@sierrawireless.com>" #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" @@ -30,9 +30,6 @@ #define SWIMS_USB_REQUEST_SetPower 0x00 #define SWIMS_USB_REQUEST_SetNmea 0x07 -#define SWIMS_USB_REQUEST_SetMode 0x0B -#define SWIMS_USB_REQUEST_GetSwocInfo 0x0A -#define SWIMS_SET_MODE_Modem 0x0001 /* per port private data */ #define N_IN_URB 4 @@ -163,7 +160,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ - { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ + { USB_DEVICE(0x03f0, 0x1b1d) }, /* HP ev2200 a.k.a MC5720 */ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ { USB_DEVICE(0x1199, 0x0024) }, /* Sierra Wireless MC5727 */ { USB_DEVICE(0x1199, 0x0220) }, /* Sierra Wireless MC5725 */ @@ -175,6 +172,8 @@ static struct usb_device_id id_table [] = { /* Sierra Wireless Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x0025, 0xFF, 0xFF, 0xFF) }, { USB_DEVICE(0x1199, 0x0026) }, /* Sierra Wireless Device */ + { USB_DEVICE(0x1199, 0x0027) }, /* Sierra Wireless Device */ + { USB_DEVICE(0x1199, 0x0028) }, /* Sierra Wireless Device */ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ @@ -187,6 +186,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x1199, 0x6821) }, /* Sierra Wireless AirCard 875U */ { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780 */ { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781 */ + { USB_DEVICE(0x1199, 0x683A) }, /* Sierra Wireless MC8785 */ { USB_DEVICE(0x1199, 0x683B) }, /* Sierra Wireless MC8785 Composite */ { USB_DEVICE(0x1199, 0x683C) }, /* Sierra Wireless MC8790 */ { USB_DEVICE(0x1199, 0x683D) }, /* Sierra Wireless MC8790 */ @@ -204,6 +204,8 @@ static struct usb_device_id id_table [] = { /* Sierra Wireless Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6890, 0xFF, 0xFF, 0xFF)}, /* Sierra Wireless Device */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6891, 0xFF, 0xFF, 0xFF)}, + /* Sierra Wireless Device */ { USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)}, { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index e39c779e416..9a3e495c769 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -1744,7 +1744,7 @@ static int ti_download_firmware(struct ti_device *tdev, int type) if (buffer) { memcpy(buffer, fw_p->data, fw_p->size); memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size); - ti_do_download(dev, pipe, buffer, fw_p->size); + status = ti_do_download(dev, pipe, buffer, fw_p->size); kfree(buffer); } release_firmware(fw_p); diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index b157c48e8b7..4f7f9e3ae0a 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -733,7 +733,9 @@ int usb_serial_probe(struct usb_interface *interface, ((le16_to_cpu(dev->descriptor.idVendor) == ATEN_VENDOR_ID) && (le16_to_cpu(dev->descriptor.idProduct) == ATEN_PRODUCT_ID)) || ((le16_to_cpu(dev->descriptor.idVendor) == ALCOR_VENDOR_ID) && - (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID))) { + (le16_to_cpu(dev->descriptor.idProduct) == ALCOR_PRODUCT_ID)) || + ((le16_to_cpu(dev->descriptor.idVendor) == SIEMENS_VENDOR_ID) && + (le16_to_cpu(dev->descriptor.idProduct) == SIEMENS_PRODUCT_ID_EF81))) { if (interface != dev->actconfig->interface[0]) { /* check out the endpoints of the other interface*/ iface_desc = dev->actconfig->interface[0]->cur_altsetting; diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index c76034672c1..3d9249632ae 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -146,18 +146,6 @@ config USB_STORAGE_KARMA on the resulting scsi device node returns the Karma to normal operation. -config USB_STORAGE_SIERRA - bool "Sierra Wireless TRU-Install Feature Support" - depends on USB_STORAGE - help - Say Y here to include additional code to support Sierra Wireless - products with the TRU-Install feature (e.g., AC597E, AC881U). - - This code switches the Sierra Wireless device from being in - Mass Storage mode to Modem mode. It also has the ability to - support host software upgrades should full Linux support be added - to TRU-Install. - config USB_STORAGE_CYPRESS_ATACB bool "SAT emulation on Cypress USB/ATA Bridge with ATACB" depends on USB_STORAGE diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index bc3415b475c..7f8beb5366a 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile @@ -21,11 +21,10 @@ usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += karma.o -usb-storage-obj-$(CONFIG_USB_STORAGE_SIERRA) += sierra_ms.o usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ - initializers.o $(usb-storage-obj-y) + initializers.o sierra_ms.o $(usb-storage-obj-y) ifneq ($(CONFIG_USB_LIBUSUAL),) obj-$(CONFIG_USB) += libusual.o diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index ba412e68d47..cd155475cb6 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -160,6 +160,13 @@ UNUSUAL_DEV( 0x0421, 0x0019, 0x0592, 0x0592, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_MAX_SECTORS_64 ), +/* Reported by Filip Joelsson <filip@blueturtle.nu> */ +UNUSUAL_DEV( 0x0421, 0x005d, 0x0001, 0x0600, + "Nokia", + "Nokia 3110c", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + /* Reported by Mario Rettig <mariorettig@web.de> */ UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100, "Nokia", @@ -232,6 +239,20 @@ UNUSUAL_DEV( 0x0421, 0x04b9, 0x0551, 0x0551, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +/* Reported by Richard Nauber <RichardNauber@web.de> */ +UNUSUAL_DEV( 0x0421, 0x04fa, 0x0601, 0x0601, + "Nokia", + "6300", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + +/* Patch for Nokia 5310 capacity */ +UNUSUAL_DEV( 0x0421, 0x006a, 0x0000, 0x0591, + "Nokia", + "5310", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, "SMSC", @@ -987,6 +1008,13 @@ UNUSUAL_DEV( 0x069b, 0x3004, 0x0001, 0x0001, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +/* Reported by Adrian Pilchowiec <adi1981@epf.pl> */ +UNUSUAL_DEV( 0x071b, 0x3203, 0x0000, 0x0000, + "RockChip", + "MP3", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64), + /* Reported by Massimiliano Ghilardi <massimiliano.ghilardi@gmail.com> * This USB MP3/AVI player device fails and disconnects if more than 128 * sectors (64kB) are read/written in a single command, and may be present @@ -1576,7 +1604,6 @@ UNUSUAL_DEV( 0x10d6, 0x2200, 0x0100, 0x0100, US_SC_DEVICE, US_PR_DEVICE, NULL, 0), -#ifdef CONFIG_USB_STORAGE_SIERRA /* Reported by Kevin Lloyd <linux@sierrawireless.com> * Entry is needed for the initializer function override, * which instructs the device to load as a modem @@ -1587,7 +1614,6 @@ UNUSUAL_DEV( 0x1199, 0x0fff, 0x0000, 0x9999, "USB MMC Storage", US_SC_DEVICE, US_PR_DEVICE, sierra_ms_init, 0), -#endif /* Reported by Jaco Kroon <jaco@kroon.co.za> * The usb-storage module found on the Digitech GNX4 (and supposedly other diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 73679aa506d..27016fd2cad 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -102,9 +102,7 @@ #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB #include "cypress_atacb.h" #endif -#ifdef CONFIG_USB_STORAGE_SIERRA #include "sierra_ms.h" -#endif /* Some informational data */ MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 5a24c6411d3..75dac578104 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -208,6 +208,36 @@ static unsigned long compute_hozval(unsigned long xres, unsigned long lcdcon2) return value; } +static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo) +{ + /* Turn off the LCD controller and the DMA controller */ + lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, + sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); + + /* Wait for the LCDC core to become idle */ + while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) + msleep(10); + + lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); +} + +static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo) +{ + atmel_lcdfb_stop_nowait(sinfo); + + /* Wait for DMA engine to become idle... */ + while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) + msleep(10); +} + +static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo) +{ + lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon); + lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, + (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) + | ATMEL_LCDC_PWR); +} + static void atmel_lcdfb_update_dma(struct fb_info *info, struct fb_var_screeninfo *var) { @@ -420,26 +450,8 @@ static void atmel_lcdfb_reset(struct atmel_lcdfb_info *sinfo) { might_sleep(); - /* LCD power off */ - lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); - - /* wait for the LCDC core to become idle */ - while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) - msleep(10); - - /* DMA disable */ - lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); - - /* wait for DMA engine to become idle */ - while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) - msleep(10); - - /* LCD power on */ - lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, - (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR); - - /* DMA enable */ - lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon); + atmel_lcdfb_stop(sinfo); + atmel_lcdfb_start(sinfo); } /** @@ -471,14 +483,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) info->var.xres, info->var.yres, info->var.xres_virtual, info->var.yres_virtual); - /* Turn off the LCD controller and the DMA controller */ - lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET); - - /* Wait for the LCDC core to become idle */ - while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY) - msleep(10); - - lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0); + atmel_lcdfb_stop_nowait(sinfo); if (info->var.bits_per_pixel == 1) info->fix.visual = FB_VISUAL_MONO01; @@ -583,13 +588,7 @@ static int atmel_lcdfb_set_par(struct fb_info *info) while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) msleep(10); - dev_dbg(info->device, " * re-enable DMA engine\n"); - /* ...and enable it with updated configuration */ - lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon); - - dev_dbg(info->device, " * re-enable LCDC core\n"); - lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, - (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR); + atmel_lcdfb_start(sinfo); dev_dbg(info->device, " * DONE\n"); @@ -1032,11 +1031,20 @@ static int atmel_lcdfb_suspend(struct platform_device *pdev, pm_message_t mesg) struct fb_info *info = platform_get_drvdata(pdev); struct atmel_lcdfb_info *sinfo = info->par; + /* + * We don't want to handle interrupts while the clock is + * stopped. It may take forever. + */ + lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL); + sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL); lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0); if (sinfo->atmel_lcdfb_power_control) sinfo->atmel_lcdfb_power_control(0); + + atmel_lcdfb_stop(sinfo); atmel_lcdfb_stop_clock(sinfo); + return 0; } @@ -1046,9 +1054,15 @@ static int atmel_lcdfb_resume(struct platform_device *pdev) struct atmel_lcdfb_info *sinfo = info->par; atmel_lcdfb_start_clock(sinfo); + atmel_lcdfb_start(sinfo); if (sinfo->atmel_lcdfb_power_control) sinfo->atmel_lcdfb_power_control(1); lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon); + + /* Enable FIFO & DMA errors */ + lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI + | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI); + return 0; } diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 614a5c7017b..6799a6de66f 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c @@ -130,8 +130,8 @@ static ssize_t geodewdt_write(struct file *file, const char __user *data, return len; } -static int geodewdt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long geodewdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = argp; @@ -198,7 +198,7 @@ static const struct file_operations geodewdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = geodewdt_write, - .ioctl = geodewdt_ioctl, + .unlocked_ioctl = geodewdt_ioctl, .open = geodewdt_open, .release = geodewdt_release, }; diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c index b82405cfb4c..89fcefcc851 100644 --- a/drivers/watchdog/ibmasr.c +++ b/drivers/watchdog/ibmasr.c @@ -85,7 +85,6 @@ static void __asr_toggle(void) outb(reg & ~asr_toggle_mask, asr_write_addr); reg = inb(asr_read_addr); - spin_unlock(&asr_lock); } static void asr_toggle(void) diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 0ed84162437..6d9f3d4a998 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c @@ -173,8 +173,8 @@ static const struct watchdog_info ident = { .identity = "PNX4008 Watchdog", }; -static long pnx4008_wdt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long pnx4008_wdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { int ret = -ENOTTY; int time; diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index 6756bcb009e..c9c73b69c5e 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c @@ -182,8 +182,8 @@ static ssize_t rc32434_wdt_write(struct file *file, const char *data, return 0; } -static int rc32434_wdt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long rc32434_wdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { void __user *argp = (void __user *)arg; int new_timeout; @@ -242,7 +242,7 @@ static struct file_operations rc32434_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = rc32434_wdt_write, - .ioctl = rc32434_wdt_ioctl, + .unlocked_ioctl = rc32434_wdt_ioctl, .open = rc32434_wdt_open, .release = rc32434_wdt_release, }; diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 9108efa73e7..bf92802f2bb 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c @@ -144,8 +144,8 @@ static int rdc321x_wdt_release(struct inode *inode, struct file *file) return 0; } -static int rdc321x_wdt_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) { void __user *argp = (void __user *)arg; unsigned int value; @@ -204,7 +204,7 @@ static ssize_t rdc321x_wdt_write(struct file *file, const char __user *buf, static const struct file_operations rdc321x_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, - .ioctl = rdc321x_wdt_ioctl, + .unlocked_ioctl = rdc321x_wdt_ioctl, .open = rdc321x_wdt_open, .write = rdc321x_wdt_write, .release = rdc321x_wdt_release, diff --git a/drivers/watchdog/wdt285.c b/drivers/watchdog/wdt285.c index db362c34958..191ea630210 100644 --- a/drivers/watchdog/wdt285.c +++ b/drivers/watchdog/wdt285.c @@ -115,8 +115,8 @@ static int watchdog_release(struct inode *inode, struct file *file) return 0; } -static ssize_t watchdog_write(struct file *file, const char *data, - size_t len, loff_t *ppos) +static ssize_t watchdog_write(struct file *file, const char __user *data, + size_t len, loff_t *ppos) { /* * Refresh the timer. @@ -133,21 +133,22 @@ static const struct watchdog_info ident = { }; static long watchdog_ioctl(struct file *file, unsigned int cmd, - unsigned long arg) + unsigned long arg) { unsigned int new_margin; + int __user *int_arg = (int __user *)arg; int ret = -ENOTTY; switch (cmd) { case WDIOC_GETSUPPORT: ret = 0; - if (copy_to_user((void *)arg, &ident, sizeof(ident))) + if (copy_to_user((void __user *)arg, &ident, sizeof(ident))) ret = -EFAULT; break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: - ret = put_user(0, (int *)arg); + ret = put_user(0, int_arg); break; case WDIOC_KEEPALIVE: @@ -156,7 +157,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, break; case WDIOC_SETTIMEOUT: - ret = get_user(new_margin, (int *)arg); + ret = get_user(new_margin, int_arg); if (ret) break; @@ -171,7 +172,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, watchdog_ping(); /* Fall */ case WDIOC_GETTIMEOUT: - ret = put_user(soft_margin, (int *)arg); + ret = put_user(soft_margin, int_arg); break; } return ret; diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c index d4427cb8697..2e15da5459c 100644 --- a/drivers/xen/balloon.c +++ b/drivers/xen/balloon.c @@ -60,7 +60,7 @@ #define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10)) -#define BALLOON_CLASS_NAME "memory" +#define BALLOON_CLASS_NAME "xen_memory" struct balloon_stats { /* We aim for 'current allocation' == 'target allocation'. */ |